From e97c1e36fb5773c3b5e09b854ddeca979ef9728d Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Thu, 19 Sep 2019 05:16:01 +0200 Subject: [PATCH] soc_sdram: improve readibility and convert l2_size to minimal allowed if provided l2_size is lower --- litex/soc/integration/soc_sdram.py | 73 +++++++++++++++++------------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/litex/soc/integration/soc_sdram.py b/litex/soc/integration/soc_sdram.py index c148fac87..a28b9bc37 100644 --- a/litex/soc/integration/soc_sdram.py +++ b/litex/soc/integration/soc_sdram.py @@ -18,6 +18,9 @@ from litedram import dfii, core __all__ = ["SoCSDRAM", "soc_sdram_args", "soc_sdram_argdict"] +# Controller Injector ------------------------------------------------------------------------------ + +# FIXME: move to LiteDRAM class ControllerInjector(Module, AutoCSR): def __init__(self, phy, geom_settings, timing_settings, clk_freq, **kwargs): @@ -36,6 +39,7 @@ class ControllerInjector(Module, AutoCSR): self.submodules.crossbar = core.LiteDRAMCrossbar(controller.interface) +# SoCSDRAM ----------------------------------------------------------------------------------------- class SoCSDRAM(SoCCore): csr_map = { @@ -51,9 +55,9 @@ class SoCSDRAM(SoCCore): raise NotImplementedError("BIOS supports SDRAM initialization only for csr_data_width=8") self.l2_size = l2_size - self._sdram_phy = [] + self._sdram_phy = [] self._wb_sdram_ifs = [] - self._wb_sdram = wishbone.Interface() + self._wb_sdram = wishbone.Interface() def add_wb_sdram_if(self, interface): if self.finalized: @@ -62,53 +66,60 @@ class SoCSDRAM(SoCCore): def register_sdram(self, phy, geom_settings, timing_settings, use_axi=False, use_full_memory_we=True, **kwargs): assert not self._sdram_phy - self._sdram_phy.append(phy) # encapsulate in list to prevent CSR scanning + self._sdram_phy.append(phy) # encapsulate in list to prevent CSR scanning + # LiteDRAM core ------------------------------------------------------------------------------- self.submodules.sdram = ControllerInjector( phy, geom_settings, timing_settings, self.clk_freq, **kwargs) + # LiteDRAM port ------------------------------------------------------------------------------- + port = self.sdram.crossbar.get_port() + port.data_width = 2**int(log2(port.data_width)) # Round to nearest power of 2 + + # Parameters ------ ------------------------------------------------------------------------ main_ram_size = 2**(geom_settings.bankbits + geom_settings.rowbits + geom_settings.colbits)*phy.settings.databits//8 main_ram_size = min(main_ram_size, 0x20000000) # FIXME: limit to 512MB for now - self.config["L2_SIZE"] = self.l2_size - # add a Wishbone interface to the DRAM + l2_size = 2**int(log2(self.l2_size)) # Round to nearest power of 2 + l2_size = max(l2_size, int(2*port.data_width/8)) # L2 has a minimal size, use it if lower + + # SoC <--> L2 Cache Wishbone interface ----------------------------------------------------- wb_sdram = wishbone.Interface() self.add_wb_sdram_if(wb_sdram) self.register_mem("main_ram", self.mem_map["main_ram"], wb_sdram, main_ram_size) - if self.l2_size: - port = self.sdram.crossbar.get_port() - port.data_width = 2**int(log2(port.data_width)) # Round to nearest power of 2 - l2_size = 2**int(log2(self.l2_size)) # Round to nearest power of 2 - l2_cache = wishbone.Cache(l2_size//4, self._wb_sdram, wishbone.Interface(port.data_width)) - # XXX Vivado ->2018.2 workaround, Vivado is not able to map correctly our L2 cache. - # Issue is reported to Xilinx, Remove this if ever fixed by Xilinx... - from litex.build.xilinx.vivado import XilinxVivadoToolchain - if isinstance(self.platform.toolchain, XilinxVivadoToolchain) and use_full_memory_we: - from migen.fhdl.simplify import FullMemoryWE - self.submodules.l2_cache = FullMemoryWE()(l2_cache) - else: - self.submodules.l2_cache = l2_cache - if use_axi: - axi_port = LiteDRAMAXIPort( - port.data_width, - port.address_width + log2_int(port.data_width//8)) - axi2native = LiteDRAMAXI2Native(axi_port, port) - self.submodules += axi2native - self.submodules.wishbone_bridge = LiteDRAMWishbone2AXI(self.l2_cache.slave, axi_port) - else: - self.submodules.wishbone_bridge = LiteDRAMWishbone2Native(self.l2_cache.slave, port) + # L2 Cache --------------------------------------------------------------------------------- + l2_cache = wishbone.Cache(l2_size//4, self._wb_sdram, wishbone.Interface(port.data_width)) + # XXX Vivado ->2018.2 workaround, Vivado is not able to map correctly our L2 cache. + # Issue is reported to Xilinx, Remove this if ever fixed by Xilinx... + from litex.build.xilinx.vivado import XilinxVivadoToolchain + if isinstance(self.platform.toolchain, XilinxVivadoToolchain) and use_full_memory_we: + from migen.fhdl.simplify import FullMemoryWE + self.submodules.l2_cache = FullMemoryWE()(l2_cache) + else: + self.submodules.l2_cache = l2_cache + self.config["L2_SIZE"] = l2_size + + # L2 Cache <--> LiteDRAM bridge ------------------------------------------------------------ + if use_axi: + axi_port = LiteDRAMAXIPort( + port.data_width, + port.address_width + log2_int(port.data_width//8)) + axi2native = LiteDRAMAXI2Native(axi_port, port) + self.submodules += axi2native + self.submodules.wishbone_bridge = LiteDRAMWishbone2AXI(self.l2_cache.slave, axi_port) + else: + self.submodules.wishbone_bridge = LiteDRAMWishbone2Native(self.l2_cache.slave, port) def do_finalize(self): if not self.integrated_main_ram_size: if not self._sdram_phy: - raise FinalizeError("Need to call SDRAMSoC.register_sdram()") + raise FinalizeError("Need to call SoCSDRAM.register_sdram()") - # arbitrate wishbone interfaces to the DRAM - self.submodules.wb_sdram_con = wishbone.Arbiter( - self._wb_sdram_ifs, self._wb_sdram) + # Arbitrate wishbone interfaces to the DRAM + self.submodules.wb_sdram_con = wishbone.Arbiter(self._wb_sdram_ifs, self._wb_sdram) SoCCore.do_finalize(self)