diff --git a/litex/soc/cores/cpu/gowin_emcu/core.py b/litex/soc/cores/cpu/gowin_emcu/core.py index 1fc88f363..407cbd27d 100644 --- a/litex/soc/cores/cpu/gowin_emcu/core.py +++ b/litex/soc/cores/cpu/gowin_emcu/core.py @@ -1,42 +1,51 @@ +# +# This file is part of LiteX. +# +# Copyright (c) 2021 Ilia Sergachev +# 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):