From 74844db3b9fdc663aee61b2a1f3730d38664d04e Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 30 Dec 2020 15:35:27 +0100 Subject: [PATCH] cores/cpu: add optional add_soc_components method and use it to add VexRiscv-SMP's PLIC/CLINT and Microwatt's XCIS. Also shorten XCIS name on Microwatt from HOSTXICS to XCIS. --- litex/soc/cores/cpu/microwatt/core.py | 16 ++++--- litex/soc/cores/cpu/microwatt/irq.h | 12 +++--- litex/soc/cores/cpu/vexriscv_smp/core.py | 54 ++++++++++++++---------- litex/soc/integration/soc.py | 6 +-- 4 files changed, 51 insertions(+), 37 deletions(-) diff --git a/litex/soc/cores/cpu/microwatt/core.py b/litex/soc/cores/cpu/microwatt/core.py index bd3643fb6..87c9bf8a6 100644 --- a/litex/soc/cores/cpu/microwatt/core.py +++ b/litex/soc/cores/cpu/microwatt/core.py @@ -31,7 +31,11 @@ class Microwatt(CPU): @property def mem_map(self): - return {"csr": 0xc0000000} + return { + "csr": 0xc0000000, + "xicsicp": 0xc3ff0000, + "xicsics": 0xc3ff1000 + } @property def gcc_flags(self): @@ -112,7 +116,7 @@ class Microwatt(CPU): self.reset_address = reset_address assert reset_address == 0x00000000 - def add_xics(self, soc, soc_region_cls): + def add_soc_components(self, soc, soc_region_cls): self.submodules.xics = XICSSlave( platform = self.platform, variant = self.variant, @@ -120,10 +124,10 @@ class Microwatt(CPU): int_level_in = self.interrupt, endianness = self.endianness ) - xicsicp_region = soc_region_cls(origin=soc.mem_map.get("hostxicsicp", 0xc3ff0000), size=4096, cached=False) - xicsics_region = soc_region_cls(origin=soc.mem_map.get("hostxicsics", 0xc3ff1000), size=4096, cached=False) - soc.bus.add_slave(name="hostxicsicp", slave=self.xics.icp_bus, region=xicsicp_region) - soc.bus.add_slave(name="hostxicsics", slave=self.xics.ics_bus, region=xicsics_region) + xicsicp_region = soc_region_cls(origin=soc.mem_map.get("xicsicp"), size=4096, cached=False) + xicsics_region = soc_region_cls(origin=soc.mem_map.get("xicsics"), size=4096, cached=False) + soc.bus.add_slave(name="xicsicp", slave=self.xics.icp_bus, region=xicsicp_region) + soc.bus.add_slave(name="xicsics", slave=self.xics.ics_bus, region=xicsics_region) @staticmethod def add_sources(platform, use_ghdl_yosys_plugin=False): diff --git a/litex/soc/cores/cpu/microwatt/irq.h b/litex/soc/cores/cpu/microwatt/irq.h index 58fe8f7f7..a6332d08c 100644 --- a/litex/soc/cores/cpu/microwatt/irq.h +++ b/litex/soc/cores/cpu/microwatt/irq.h @@ -35,32 +35,32 @@ void isr(uint64_t vec); uint8_t inline xics_icp_readb(int reg) { - return *((uint8_t*)(HOSTXICSICP_BASE + reg)); + return *((uint8_t*)(XICSICP_BASE + reg)); } void inline xics_icp_writeb(int reg, uint8_t value) { - *((uint8_t*)(HOSTXICSICP_BASE + reg)) = value; + *((uint8_t*)(XICSICP_BASE + reg)) = value; } uint32_t inline xics_icp_readw(int reg) { - return *((uint32_t*)(HOSTXICSICP_BASE + reg)); + return *((uint32_t*)(XICSICP_BASE + reg)); } void inline xics_icp_writew(int reg, uint32_t value) { - *((uint32_t*)(HOSTXICSICP_BASE + reg)) = value; + *((uint32_t*)(XICSICP_BASE + reg)) = value; } uint32_t inline xics_ics_read_xive(int irq_number) { - return *((uint32_t*)(HOSTXICSICS_BASE + 0x800 + (irq_number << 2))); + return *((uint32_t*)(XICSICS_BASE + 0x800 + (irq_number << 2))); } void inline xics_ics_write_xive(int irq_number, uint32_t priority) { - *((uint32_t*)(HOSTXICSICS_BASE + 0x800 + (irq_number << 2))) = priority; + *((uint32_t*)(XICSICS_BASE + 0x800 + (irq_number << 2))) = priority; } void inline mtmsrd(uint64_t val) diff --git a/litex/soc/cores/cpu/vexriscv_smp/core.py b/litex/soc/cores/cpu/vexriscv_smp/core.py index d8276e9a9..aacdad69f 100644 --- a/litex/soc/cores/cpu/vexriscv_smp/core.py +++ b/litex/soc/cores/cpu/vexriscv_smp/core.py @@ -90,6 +90,7 @@ class VexRiscvSMP(CPU): "main_ram": 0x40000000, "csr": 0xf0000000, "clint": 0xf0010000, + "plic": 0xf0c00000, } @property @@ -211,8 +212,6 @@ class VexRiscvSMP(CPU): self.jtag_tdi = Signal() self.interrupt = Signal(32) self.pbus = pbus = wishbone.Interface() - self.cbus = cbus = wishbone.Interface() - self.plicbus = plicbus = wishbone.Interface() self.periph_buses = [pbus] self.memory_buses = [] # Added dynamically @@ -247,25 +246,7 @@ class VexRiscvSMP(CPU): o_peripheral_SEL = pbus.sel, i_peripheral_ERR = pbus.err, o_peripheral_CTI = pbus.cti, - o_peripheral_BTE = pbus.bte, - - # CLINT Bus (Slave) - i_clintWishbone_CYC = cbus.cyc, - i_clintWishbone_STB = cbus.stb, - o_clintWishbone_ACK = cbus.ack, - i_clintWishbone_WE = cbus.we, - i_clintWishbone_ADR = cbus.adr, - o_clintWishbone_DAT_MISO = cbus.dat_r, - i_clintWishbone_DAT_MOSI = cbus.dat_w, - - # PLIC Bus (Slave) - i_plicWishbone_CYC = plicbus.cyc, - i_plicWishbone_STB = plicbus.stb, - o_plicWishbone_ACK = plicbus.ack, - i_plicWishbone_WE = plicbus.we, - i_plicWishbone_ADR = plicbus.adr, - o_plicWishbone_DAT_MISO = plicbus.dat_r, - i_plicWishbone_DAT_MOSI = plicbus.dat_w + o_peripheral_BTE = pbus.bte ) if VexRiscvSMP.coherent_dma: @@ -306,6 +287,36 @@ class VexRiscvSMP(CPU): platform.add_source(os.path.join(vdir, "RamXilinx.v"), "verilog") platform.add_source(os.path.join(vdir, self.cluster_name + ".v"), "verilog") + def add_soc_components(self, soc, soc_region_cls): + # Define number of CPUs + soc.add_config("CPU_COUNT", VexRiscvSMP.cpu_count) + + # Add PLIC as Bus Slave + self.plicbus = plicbus = wishbone.Interface() + self.cpu_params.update( + i_plicWishbone_CYC = plicbus.cyc, + i_plicWishbone_STB = plicbus.stb, + o_plicWishbone_ACK = plicbus.ack, + i_plicWishbone_WE = plicbus.we, + i_plicWishbone_ADR = plicbus.adr, + o_plicWishbone_DAT_MISO = plicbus.dat_r, + i_plicWishbone_DAT_MOSI = plicbus.dat_w + ) + soc.bus.add_slave("plic", self.plicbus, region=soc_region_cls(origin=soc.mem_map.get("plic"), size=0x400000, cached=False)) + + # Add CLINT as Bus Slave + self.clintbus = clintbus = wishbone.Interface() + self.cpu_params.update( + i_clintWishbone_CYC = clintbus.cyc, + i_clintWishbone_STB = clintbus.stb, + o_clintWishbone_ACK = clintbus.ack, + i_clintWishbone_WE = clintbus.we, + i_clintWishbone_ADR = clintbus.adr, + o_clintWishbone_DAT_MISO = clintbus.dat_r, + i_clintWishbone_DAT_MOSI = clintbus.dat_w, + ) + soc.bus.add_slave("clint", clintbus, region=soc_region_cls(origin=soc.mem_map.get("clint"), size=0x10000, cached=False)) + def add_memory_buses(self, address_width, data_width): VexRiscvSMP.litedram_width = data_width @@ -344,7 +355,6 @@ class VexRiscvSMP(CPU): i_dBridge_dram_rdata_payload_data = dbus.rdata.data, ) - def do_finalize(self): assert hasattr(self, "reset_address") self.specials += Instance(self.cluster_name, **self.cpu_params) diff --git a/litex/soc/integration/soc.py b/litex/soc/integration/soc.py index 79e1f3c52..16db19962 100644 --- a/litex/soc/integration/soc.py +++ b/litex/soc/integration/soc.py @@ -896,9 +896,9 @@ class SoC(Module): self.comb += self.cpu.reset.eq(self.ctrl.reset) self.add_config("CPU_RESET_ADDR", reset_address) - # Specific Microwatt IROs integration FIXME (remove or provide generic integration method) - if isinstance(self.cpu, cpu.Microwatt) and "irq" in variant: - self.cpu.add_xics(self, SoCRegion) + # Add CPU's SoC components (if any) + if hasattr(self.cpu, "add_soc_components"): + self.cpu.add_soc_components(soc=self, soc_region_cls=SoCRegion) # FIXME: avoid passing SoCRegion. # Add constants self.add_config("CPU_TYPE", str(name))