cpu/gowin_emcu: Minor cosmetic cleanups, add copyright.

This commit is contained in:
Florent Kermarrec 2021-12-09 16:01:41 +01:00
parent 7286f95f55
commit 230ba5f7ba
1 changed files with 97 additions and 85 deletions

View File

@ -1,42 +1,51 @@
#
# This file is part of LiteX.
#
# Copyright (c) 2021 Ilia Sergachev <ilia.sergachev@protonmail.ch>
# SPDX-License-Identifier: BSD-2-Clause
from migen import *
from litex.soc.interconnect import wishbone, ahb
from litex.soc.cores.cpu import CPU
# AHB Flash ----------------------------------------------------------------------------------------
class AHBFlash(Module):
def __init__(self, bus):
addr = Signal(13)
read_enable = Signal()
read = Signal()
self.comb += bus.resp.eq(0)
self.submodules.fsm = fsm = FSM()
fsm.act("IDLE",
bus.readyout.eq(1),
If(bus.sel & bus.trans[1],
NextValue(addr, bus.addr[2:]),
NextState('READ'),
NextState("READ"),
)
)
fsm.act("READ",
read_enable.eq(1),
NextState('WAIT'),
read.eq(1),
NextState("WAIT"),
)
fsm.act('WAIT',
NextState('IDLE')
fsm.act("WAIT",
NextState("IDLE")
)
self.specials += Instance(
'FLASH256K',
o_DOUT=bus.rdata,
i_DIN=Signal(32),
i_XADR=addr[6:],
i_YADR=addr[:6],
i_XE=~ResetSignal(),
i_YE=~ResetSignal(),
i_SE=read_enable,
i_PROG=0,
i_ERASE=0,
i_NVSTR=0
self.specials += Instance("FLASH256K",
o_DOUT = bus.rdata,
i_DIN = Signal(32),
i_XADR = addr[6:],
i_YADR = addr[:6],
i_XE = ~ResetSignal("sys"),
i_YE = ~ResetSignal("sys"),
i_SE = read,
i_PROG = 0,
i_ERASE = 0,
i_NVSTR = 0
)
# Gowin EMCU ---------------------------------------------------------------------------------------
class GowinEMCU(CPU):
variants = ["standard"]
@ -46,11 +55,14 @@ class GowinEMCU(CPU):
data_width = 32
endianness = "little"
gcc_triple = "arm-none-eabi"
gcc_flags = '-mcpu=cortex-m3 -mthumb'
gcc_flags = "-mcpu=cortex-m3 -mthumb"
linker_output_format = "elf32-littlearm"
nop = "nop"
io_regions = {0x4000_0000: 0x2000_0000,
0xA000_0000: 0x6000_0000} # Origin, Length.
io_regions = {
# Origin, Length.
0x4000_0000: 0x2000_0000,
0xa000_0000: 0x6000_0000
}
@property
def mem_map(self):
@ -62,90 +74,90 @@ class GowinEMCU(CPU):
def __init__(self, platform, variant, *args, **kwargs):
super().__init__(*args, **kwargs)
self.reset = Signal()
self.reset = Signal()
self.bus_reset = Signal()
bus_reset_n = Signal()
self.comb += self.bus_reset.eq(~bus_reset_n)
self.interrupt = Signal(5)
self.reset_address = self.mem_map['rom'] + 0
self.interrupt = Signal(5)
self.reset_address = self.mem_map["rom"] + 0
self.gpio_in = Signal(16)
self.gpio_out = Signal(16)
self.gpio_in = Signal(16)
self.gpio_out = Signal(16)
self.gpio_out_en = Signal(16)
self.cpu_params = dict()
self.cpu_params.update(
i_MTXREMAP=Signal(4, reset=0b1111),
o_MTXHRESETN=bus_reset_n,
i_MTXREMAP = Signal(4, reset=0b1111),
o_MTXHRESETN = bus_reset_n,
i_FLASHERR=Signal(),
i_FLASHINT=Signal(),
i_FLASHERR = Signal(),
i_FLASHINT = Signal(),
i_FCLK=ClockSignal(),
i_PORESETN=~self.reset,
i_SYSRESETN=~self.reset,
i_RTCSRCCLK=Signal(), # TODO - RTC clk in
i_FCLK = ClockSignal("sys"),
i_PORESETN = ~self.reset,
i_SYSRESETN = ~self.reset,
i_RTCSRCCLK = Signal(), # TODO - RTC clk in
i_IOEXPINPUTI=self.gpio_in,
o_IOEXPOUTPUTO=self.gpio_out,
o_IOEXPOUTPUTENO=self.gpio_out_en,
i_IOEXPINPUTI = self.gpio_in,
o_IOEXPOUTPUTO = self.gpio_out,
o_IOEXPOUTPUTENO = self.gpio_out_en,
i_GPINT=self.interrupt,
o_INTMONITOR=Signal(),
i_GPINT = self.interrupt,
o_INTMONITOR = Signal(),
)
# 32b CPU SRAM split between 8 SRAMs x 4 bit each
sram_dw = 32
sram_dw = 32
single_sram_dw = 4
n_srams = sram_dw // single_sram_dw
sram0_addr = Signal(13)
sram0_addr = Signal(13)
sram0_rdata = Signal(sram_dw)
sram0_wdata = Signal(sram_dw)
sram0_cs = Signal()
sram0_wren = Signal(4)
sram0_cs = Signal()
sram0_wren = Signal(4)
self.cpu_params.update(
i_SRAM0RDATA=sram0_rdata,
o_SRAM0ADDR=sram0_addr,
o_SRAM0WREN=sram0_wren,
o_SRAM0WDATA=sram0_wdata,
o_SRAM0CS=sram0_cs,
i_SRAM0RDATA = sram0_rdata,
o_SRAM0ADDR = sram0_addr,
o_SRAM0WREN = sram0_wren,
o_SRAM0WDATA = sram0_wdata,
o_SRAM0CS = sram0_cs,
)
for i in range(n_srams):
self.specials += Instance(
'SDPB',
p_READ_MODE=0,
p_BIT_WIDTH_0=single_sram_dw,
p_BIT_WIDTH_1=single_sram_dw,
p_RESET_MODE='SYNC',
p_BLK_SEL_0=0b111,
p_BLK_SEL_1=0b111,
o_DO=Cat(sram0_rdata[i * single_sram_dw: (i + 1) * single_sram_dw], Signal(sram_dw - single_sram_dw)),
i_DI=Cat(sram0_wdata[i * single_sram_dw: (i + 1) * single_sram_dw], Signal(sram_dw - single_sram_dw)),
i_ADA=Cat(Signal(2), sram0_addr[:-1]),
i_ADB=Cat(Signal(2), sram0_addr[:-1]),
i_CEA=sram0_wren[i // 2],
i_CEB=~sram0_wren[i // 2],
i_CLKA=ClockSignal(),
i_CLKB=ClockSignal(),
i_RESETA=0,
i_RESETB=self.bus_reset,
i_OCE=1,
i_BLKSELA=Cat(sram0_cs, sram0_cs, sram0_cs),
i_BLKSELB=Cat(sram0_cs, sram0_cs, sram0_cs),
self.specials += Instance("SDPB",
p_READ_MODE = 0,
p_BIT_WIDTH_0 = single_sram_dw,
p_BIT_WIDTH_1 = single_sram_dw,
p_RESET_MODE = "SYNC",
p_BLK_SEL_0 = 0b111,
p_BLK_SEL_1 = 0b111,
o_DO = Cat(sram0_rdata[i * single_sram_dw: (i + 1) * single_sram_dw], Signal(sram_dw - single_sram_dw)),
i_DI = Cat(sram0_wdata[i * single_sram_dw: (i + 1) * single_sram_dw], Signal(sram_dw - single_sram_dw)),
i_ADA = Cat(Signal(2), sram0_addr[:-1]),
i_ADB = Cat(Signal(2), sram0_addr[:-1]),
i_CEA = sram0_wren[i // 2],
i_CEB = ~sram0_wren[i // 2],
i_CLKA = ClockSignal(),
i_CLKB = ClockSignal(),
i_RESETA = 0,
i_RESETB = self.bus_reset,
i_OCE = 1,
i_BLKSELA = Cat(sram0_cs, sram0_cs, sram0_cs),
i_BLKSELB = Cat(sram0_cs, sram0_cs, sram0_cs),
)
# Boot Flash memory connected via AHB
ahb_flash = ahb.Interface()
for s, _ in ahb_flash.master_signals:
if s in ['wdata', 'write', 'mastlock', 'prot']:
if s in ["wdata", "write", "mastlock", "prot"]:
continue
self.cpu_params[f'o_TARGFLASH0H{s.upper()}'] = getattr(ahb_flash, s)
self.cpu_params[f"o_TARGFLASH0H{s.upper()}"] = getattr(ahb_flash, s)
for s, _ in ahb_flash.slave_signals:
self.cpu_params[f'i_TARGFLASH0H{s.upper()}'] = getattr(ahb_flash, s)
self.cpu_params[f"i_TARGFLASH0H{s.upper()}"] = getattr(ahb_flash, s)
flash = ResetInserter()(AHBFlash(ahb_flash))
self.comb += flash.reset.eq(self.bus_reset)
self.submodules += flash
@ -157,30 +169,30 @@ class GowinEMCU(CPU):
ahb_targexp0 = ahb.Interface()
for s, _ in ahb_targexp0.master_signals:
# TODO: due to unexpected writes by the CPU bus is currently forced read-only
if s == 'write':
if s == "write":
continue
self.cpu_params[f'o_TARGEXP0H{s.upper()}'] = getattr(ahb_targexp0, s)
self.cpu_params[f"o_TARGEXP0H{s.upper()}"] = getattr(ahb_targexp0, s)
for s, _ in ahb_targexp0.slave_signals:
self.cpu_params[f'i_TARGEXP0H{s.upper()}'] = getattr(ahb_targexp0, s)
self.cpu_params[f"i_TARGEXP0H{s.upper()}"] = getattr(ahb_targexp0, s)
self.submodules += ahb.AHB2Wishbone(ahb_targexp0, self.pbus)
def connect_uart(self, pads, n=0):
assert n in (0, 1), "this CPU has 2 built-in UARTs, 0 and 1"
self.cpu_params.update({
f'i_UART{n}RXDI': pads.rx,
f'o_UART{n}TXDO': pads.tx,
f'o_UART{n}BAUDTICK': Signal()
f"i_UART{n}RXDI": pads.rx,
f"o_UART{n}TXDO": pads.tx,
f"o_UART{n}BAUDTICK": Signal()
})
def connect_jtag(self, pads):
self.cpu_params.update(
i_DAPSWDITMS=pads.tms,
i_DAPTDI=pads.tdi,
o_DAPTDO=pads.tdo,
o_DAPNTDOEN=Signal(),
i_DAPNTRST=~self.reset,
i_DAPSWCLKTCK=pads.tck,
o_DAPJTAGNSW=Signal(), # indicates debug mode, JTAG or SWD
i_DAPSWDITMS = pads.tms,
i_DAPTDI = pads.tdi,
o_DAPTDO = pads.tdo,
o_DAPNTDOEN = Signal(),
i_DAPNTRST = ~self.reset,
i_DAPSWCLKTCK = pads.tck,
o_DAPJTAGNSW = Signal(), # Indicates debug mode, JTAG or SWD
)
def do_finalize(self):