From dcc881db924370d8aba828e7a3a4990211723eb7 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 12 May 2020 20:58:19 +1000 Subject: [PATCH 1/5] soc: Don't create a share intercon with only one master and one slave This creates a lot of useless churn in the resulting verilog. Instead use a point to point interconnect in that case. Signed-off-by: Benjamin Herrenschmidt --- litex/soc/integration/soc.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/litex/soc/integration/soc.py b/litex/soc/integration/soc.py index b2e492968..42366b6c1 100644 --- a/litex/soc/integration/soc.py +++ b/litex/soc/integration/soc.py @@ -824,7 +824,14 @@ class SoC(Module): # SoC Bus Interconnect --------------------------------------------------------------------- bus_masters = self.bus.masters.values() bus_slaves = [(self.bus.regions[n].decoder(self.bus), s) for n, s in self.bus.slaves.items()] - if len(bus_masters) and len(bus_slaves): + # One master and one slave, use a point to point interconnect, this is useful for + # generating standalone components such as LiteDRAM whose external control + # interface is a wishbone. + if len(bus_masters) == 1 and len(bus_slaves) == 1: + self.submodules.bus_interconnect = wishbone.InterconnectPointToPoint( + master = list(bus_masters)[0], + slave = list(self.bus.slaves.values())[0]) + elif len(bus_masters) and len(bus_slaves): self.submodules.bus_interconnect = wishbone.InterconnectShared( masters = bus_masters, slaves = bus_slaves, From f28f2471303349e886b3636a0f55d7d533c3c084 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 12 May 2020 21:30:19 +1000 Subject: [PATCH 2/5] soc: Don't create a wishbone slave to LiteDRAM with no CPU When creating a standalone LiteDRAM core with no CPU, there is no need to create a wishbone slave to LiteDRAM interface. Signed-off-by: Benjamin Herrenschmidt --- litex/soc/integration/soc.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/litex/soc/integration/soc.py b/litex/soc/integration/soc.py index 42366b6c1..55bedb629 100644 --- a/litex/soc/integration/soc.py +++ b/litex/soc/integration/soc.py @@ -1034,7 +1034,8 @@ class LiteXSoC(SoC): sdram_size = min(sdram_size, size) # Add SDRAM region - self.bus.add_region("main_ram", SoCRegion(origin=origin, size=sdram_size)) + if self.cpu_type is not None: + self.bus.add_region("main_ram", SoCRegion(origin=origin, size=sdram_size)) # SoC [<--> L2 Cache] <--> LiteDRAM -------------------------------------------------------- if len(self.cpu.memory_buses): @@ -1085,7 +1086,7 @@ class LiteXSoC(SoC): # Else raise Error. else: raise NotImplementedError - else: + elif self.cpu_type is not None: # When CPU has no direct memory interface, create a Wishbone Slave interface to LiteDRAM. # Request a LiteDRAM native port. From ecbd40284a0c1d56c95cc1c13886847549365f2b Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 12 May 2020 21:31:23 +1000 Subject: [PATCH 3/5] soc: Don't update CSR alignment when there is no CPU The alignment specified by the standalone core config should be honored. Signed-off-by: Benjamin Herrenschmidt --- litex/soc/integration/soc.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/litex/soc/integration/soc.py b/litex/soc/integration/soc.py index 55bedb629..651f450d7 100644 --- a/litex/soc/integration/soc.py +++ b/litex/soc/integration/soc.py @@ -781,7 +781,13 @@ class SoC(Module): for n, (origin, size) in enumerate(self.cpu.io_regions.items()): self.bus.add_region("io{}".format(n), SoCIORegion(origin=origin, size=size, cached=False)) self.mem_map.update(self.cpu.mem_map) # FIXME - self.csr.update_alignment(self.cpu.data_width) + + # We don't want the CSR alignemnt reduced from 64-bit to 32-bit on + # a standalone system with a 64-bit WB and no CPU. + # Should we instead only update alignment if the CPU is *bigger* + # than the CSR ? + if name != "None": + self.csr.update_alignment(self.cpu.data_width) # Add Bus Masters/CSR/IRQs if not isinstance(self.cpu, cpu.CPUNone): if reset_address is None: From 520c17e96d6fcba23de9435bc6f38379da09d7ec Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 12 May 2020 21:35:12 +1000 Subject: [PATCH 4/5] soc_core: Add option to override CSR base When creating standalone IP cores such as standalone LiteDRAM without a CPU, the CSR are presented externally via a wishbone with just enough address bits to access individual CSRs (14), and no address decoding otherwise. It is expected that the design using such core will have its own address decoder gating cyc/stb. However, such a design might still need to use LiteX code such as the sdram init code, which relies on the generated csr.h. Thus we want to be able to control the CSR base address used by that generated csr.h. This could be handled instead by having the "host" code provide modified csr_{read,write}_simple() that include the necessary base address. However, such an approach would make things complicated if the design includes multiple such standalone cores with separate CSR busses (such as LiteDRAM and LiteEth). Signed-off-by: Benjamin Herrenschmidt --- litex/soc/integration/soc_core.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index 68499ad2b..6873659ce 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -85,6 +85,7 @@ class SoCCore(LiteXSoC): csr_alignment = 32, csr_address_width = 14, csr_paging = 0x800, + csr_base = None, # Identifier parameters ident = "", ident_version = False, @@ -183,7 +184,9 @@ class SoCCore(LiteXSoC): if with_timer: self.add_timer(name="timer0") - # Add CSR bridge + # Add CSR bridge. Potentially override CSR base + if csr_base is not None: + self.mem_map["csr"] = csr_base; self.add_csr_bridge(self.mem_map["csr"]) # Methods -------------------------------------------------------------------------------------- From f628ff6b47d90c783c60bbada5abbf7bc0fc6660 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 12 May 2020 21:37:36 +1000 Subject: [PATCH 5/5] WB2CSR: Use CSR address_width for the wishbone bus Currently, we create a wishbone interface with the default address width (30 bits) for the bridge. Instead, create an interface that has the same number of address bits as the CSR bus. Signed-off-by: Benjamin Herrenschmidt --- litex/soc/interconnect/wishbone2csr.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/litex/soc/interconnect/wishbone2csr.py b/litex/soc/interconnect/wishbone2csr.py index b9544aad6..c9e307790 100644 --- a/litex/soc/interconnect/wishbone2csr.py +++ b/litex/soc/interconnect/wishbone2csr.py @@ -10,12 +10,12 @@ from litex.soc.interconnect import csr_bus, wishbone class WB2CSR(Module): def __init__(self, bus_wishbone=None, bus_csr=None): - if bus_wishbone is None: - bus_wishbone = wishbone.Interface() - self.wishbone = bus_wishbone if bus_csr is None: bus_csr = csr_bus.Interface() self.csr = bus_csr + if bus_wishbone is None: + bus_wishbone = wishbone.Interface(adr_width=bus_csr.address_width) + self.wishbone = bus_wishbone # # #