soc_sdram: improve readibility and convert l2_size to minimal allowed if provided...
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Thu, 19 Sep 2019 03:16:01 +0000 (05:16 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Thu, 19 Sep 2019 03:36:57 +0000 (05:36 +0200)
litex/soc/integration/soc_sdram.py

index c148fac874f4e4db0189a9adbef64c13475f578e..a28b9bc37968c280fe99fa670c222bc02b70cff5 100644 (file)
@@ -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)