From b607de473d5570e46b401b39e353c9a2c21ea775 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 22 Apr 2022 17:03:02 +0200 Subject: [PATCH] cpu/cortex_m3: Review/Cleanup (Apply similar changes than for Cortex-M1). --- litex/soc/cores/cpu/cortex_m3/core.py | 182 ++++++++++++++++++-------- 1 file changed, 125 insertions(+), 57 deletions(-) diff --git a/litex/soc/cores/cpu/cortex_m3/core.py b/litex/soc/cores/cpu/cortex_m3/core.py index f515efb52..d5944b62d 100644 --- a/litex/soc/cores/cpu/cortex_m3/core.py +++ b/litex/soc/cores/cpu/cortex_m3/core.py @@ -2,14 +2,19 @@ # This file is part of LiteX. # # Copyright (c) 2022 Ilia Sergachev +# Copyright (c) 2022 Florent Kermarrec # SPDX-License-Identifier: BSD-2-Clause import os + from migen import * -from litex.soc.interconnect import wishbone + from litex.soc.cores.cpu import CPU from litex.soc.interconnect import axi +class Open(Signal): pass + +# Cortex-M3 ---------------------------------------------------------------------------------------- class CortexM3(CPU): variants = ["standard"] @@ -23,85 +28,148 @@ class CortexM3(CPU): gcc_flags = "-march=armv7-m -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): return { - "rom": 0x0000_0000, - "main_ram": 0x1000_0000, - "sram": 0x2000_0000, - "csr": 0xA000_0000 + "rom" : 0x0000_0000, + "sram" : 0x2000_0000, + "main_ram" : 0x1000_0000, + "csr" : 0xa000_0000, } - def __init__(self, platform, variant, *args, **kwargs): - super().__init__(*args, **kwargs) - self.platform = platform - self.reset = Signal() - self.interrupt = Signal(2) - pbus = wishbone.Interface(data_width=32, adr_width=30) - ibus = wishbone.Interface(data_width=32, adr_width=30) - self.periph_buses = [pbus, ibus] - self.memory_buses = [] + def __init__(self, platform, variant="standard"): + self.platform = platform + self.reset = Signal() + self.interrupt = Signal(2) + ibus = axi.AXILiteInterface(data_width=32, address_width=32) + dbus = axi.AXILiteInterface(data_width=32, address_width=32) + self.periph_buses = [ibus, dbus] + self.memory_buses = [] - def _mem_size(x): - return log2_int(x // 512) + # Peripheral Bus AXI <-> AXILite conversion. + ibus_axi = axi.AXIInterface(data_width=self.data_width, address_width=32) + self.submodules += axi.AXI2AXILite(ibus_axi, ibus) + dbus_axi = axi.AXIInterface(data_width=self.data_width, address_width=32) + self.submodules += axi.AXI2AXILite(dbus_axi, dbus) + # CPU Instance. self.cpu_params = dict( + # Clk/Rst. i_HCLK = ClockSignal("sys"), i_SYSRESETn = ~(ResetSignal() | self.reset), - p_NUM_IRQ = len(self.interrupt), - i_IRQ = self.interrupt, - i_DBGRESETn = ~(ResetSignal() | self.reset), + + # Control/Status. p_MPU_PRESENT = 0, - p_ITCM_SIZE = _mem_size(0 * 1024), # embedded ROM - p_DTCM_SIZE = _mem_size(0 * 1024), # embedded RAM - p_TRACE_LVL = 0, - p_DEBUG_LVL = 2, + p_TRACE_LVL = 0, + p_DEBUG_LVL = 2, + + # Interrupts. + p_NUM_IRQ = len(self.interrupt), + i_IRQ = self.interrupt, + + # Embedded ROM/SRAM. + p_ITCM_SIZE = 0, # Use LiteX's ROM. + p_DTCM_SIZE = 0, # Use LiteX's RAM. i_CFGITCMEN = 0, # 1 = alias ITCM at 0x0 + + # Debug. + i_DBGRESETn = ~(ResetSignal() | self.reset), + + # Instruction Bus (AXI). + o_AWVALIDC = ibus_axi.aw.valid, + i_AWREADYC = ibus_axi.aw.ready, + o_AWADDRC = ibus_axi.aw.addr, + o_AWBURSTC = ibus_axi.aw.burst, + o_AWCACHEC = ibus_axi.aw.cache, + o_AWLENC = ibus_axi.aw.len, + o_AWLOCKC = ibus_axi.aw.lock, + o_AWPROTC = ibus_axi.aw.prot, + o_AWSIZEC = ibus_axi.aw.size, + + o_WVALIDC = ibus_axi.w.valid, + i_WREADYC = ibus_axi.w.ready, + o_WLASTC = ibus_axi.w.last, + o_WSTRBC = ibus_axi.w.strb, + o_HWDATAC = ibus_axi.w.data, + + i_BVALIDC = ibus_axi.b.valid, + o_BREADYC = ibus_axi.b.ready, + i_BRESPC = ibus_axi.b.resp, + + o_ARVALIDC = ibus_axi.ar.valid, + i_ARREADYC = ibus_axi.ar.ready, + o_ARADDRC = ibus_axi.ar.addr, + o_ARBURSTC = ibus_axi.ar.burst, + o_ARCACHEC = ibus_axi.ar.cache, + o_ARLENC = ibus_axi.ar.len, + o_ARLOCKC = ibus_axi.ar.lock, + o_ARPROTC = ibus_axi.ar.prot, + o_ARSIZEC = ibus_axi.ar.size, + + i_RVALIDC = ibus_axi.r.valid, + o_RREADYC = ibus_axi.r.ready, + i_RLASTC = ibus_axi.r.last, + i_RRESPC = ibus_axi.r.resp, + i_HRDATAC = ibus_axi.r.data, + + # Data Bus (AXI). + o_AWVALIDS = dbus_axi.aw.valid, + i_AWREADYS = dbus_axi.aw.ready, + o_AWADDRS = dbus_axi.aw.addr, + o_AWBURSTS = dbus_axi.aw.burst, + o_AWCACHES = dbus_axi.aw.cache, + o_AWLENS = dbus_axi.aw.len, + o_AWLOCKS = dbus_axi.aw.lock, + o_AWPROTS = dbus_axi.aw.prot, + o_AWSIZES = dbus_axi.aw.size, + + o_WVALIDS = dbus_axi.w.valid, + i_WREADYS = dbus_axi.w.ready, + o_WLASTS = dbus_axi.w.last, + o_WSTRBS = dbus_axi.w.strb, + o_HWDATAS = dbus_axi.w.data, + + i_BVALIDS = dbus_axi.b.valid, + o_BREADYS = dbus_axi.b.ready, + i_BRESPS = dbus_axi.b.resp, + + o_ARVALIDS = dbus_axi.ar.valid, + i_ARREADYS = dbus_axi.ar.ready, + o_ARADDRS = dbus_axi.ar.addr, + o_ARBURSTS = dbus_axi.ar.burst, + o_ARCACHES = dbus_axi.ar.cache, + o_ARLENS = dbus_axi.ar.len, + o_ARLOCKS = dbus_axi.ar.lock, + o_ARPROTS = dbus_axi.ar.prot, + o_ARSIZES = dbus_axi.ar.size, + + i_RVALIDS = dbus_axi.r.valid, + o_RREADYS = dbus_axi.r.ready, + i_RLASTS = dbus_axi.r.last, + i_RRESPS = dbus_axi.r.resp, + i_HRDATAS = dbus_axi.r.data, ) - - def connect_axi(axi_bus, suffix): - layout = axi_bus.layout_flat() - dir_map = {DIR_M_TO_S: 'o', DIR_S_TO_M: 'i'} - for group, signal, direction in layout: - if signal in ['id', 'qos', 'first']: - continue - if signal == 'last': - if group in ['b', 'a', 'ar', 'aw']: - continue - prefix = 'H' if signal == 'data' else '' - direction = dir_map[direction] - self.cpu_params[f'{direction}_{prefix}{group.upper()}{signal.upper()}{suffix}'] = \ - getattr(getattr(axi_bus, group), signal) - - ibus_axi = axi.AXIInterface(data_width=self.data_width, address_width=32) - ibus_a2w = axi.AXI2Wishbone(ibus_axi, ibus, base_address=0) - self.submodules += ibus_a2w - connect_axi(ibus_axi, 'C') - - pbus_axi = axi.AXIInterface(data_width=self.data_width, address_width=32) - pbus_a2w = axi.AXI2Wishbone(pbus_axi, pbus, base_address=0) - self.submodules += pbus_a2w - connect_axi(pbus_axi, 'S') - platform.add_source_dir("AT426-BU-98000-r0p1-00rel0/vivado/Arm_ipi_repository/CM3DbgAXI/rtl") - def connect_jtag(self, pads): + def add_jtag(self, pads): self.cpu_params.update( p_JTAG_PRESENT = 1, i_SWDITMS = pads.tms, i_TDI = pads.tdi, o_TDO = pads.tdo, - o_nTDOEN = Signal(), + o_nTDOEN = Open(), i_nTRST = pads.ntrst, i_SWCLKTCK = pads.tck, - o_JTAGNSW = Signal(), # Indicates debug mode, JTAG or SWD - o_JTAGTOP = Signal(), # ? - o_SWDO = Signal(), # TODO - o_SWDOEN = Signal(), # TODO + o_JTAGNSW = Open(), # Indicates debug mode, JTAG or SWD + o_JTAGTOP = Open(), # ? + o_SWDO = Open(), # TODO + o_SWDOEN = Open(), # TODO ) def do_finalize(self):