Rework RAM port for nMigen compliance
[gram.git] / gram / core / crossbar.py
index 5efbd2b079e620a012efd896d38a3d4b5f25cb6f..c81abc77e1a597ccf7e4ec9d09e8c3912151d9e6 100644 (file)
@@ -72,17 +72,16 @@ class gramCrossbar(Elaboratable):
         self.rank_bits = log2_int(self.nranks, False)
 
         self.masters = []
+        self._pending_submodules = []
 
     def get_port(self, mode="both", data_width=None, clock_domain="sys", reverse=False):
-        if self.finalized:
-            raise FinalizeError
-
         if data_width is None:
             # use internal data_width when no width adaptation is requested
             data_width = self.controller.data_width
+            print("data_width=", data_width)
 
         # Crossbar port ----------------------------------------------------------------------------
-        port = LiteDRAMNativePort(
+        port = gramNativePort(
             mode          = mode,
             address_width = self.rca_bits + self.bank_bits - self.rank_bits,
             data_width    = self.controller.data_width,
@@ -92,13 +91,13 @@ class gramCrossbar(Elaboratable):
 
         # Clock domain crossing --------------------------------------------------------------------
         if clock_domain != "sys":
-            new_port = LiteDRAMNativePort(
+            new_port = gramNativePort(
                 mode          = mode,
                 address_width = port.address_width,
                 data_width    = port.data_width,
                 clock_domain  = clock_domain,
                 id            = port.id)
-            self.submodules += LiteDRAMNativePortCDC(new_port, port)
+            self._pending_submodules.append(gramNativePortCDC(new_port, port))
             port = new_port
 
         # Data width convertion --------------------------------------------------------------------
@@ -107,14 +106,14 @@ class gramCrossbar(Elaboratable):
                 addr_shift = -log2_int(data_width//self.controller.data_width)
             else:
                 addr_shift = log2_int(self.controller.data_width//data_width)
-            new_port = LiteDRAMNativePort(
+            new_port = gramNativePort(
                 mode          = mode,
                 address_width = port.address_width + addr_shift,
                 data_width    = data_width,
                 clock_domain  = clock_domain,
                 id            = port.id)
-            self.submodules += ClockDomainsRenamer(clock_domain)(
-                LiteDRAMNativePortConverter(new_port, port, reverse))
+            self._pending_submodules.append(ClockDomainsRenamer(clock_domain)(
+                gramNativePortConverter(new_port, port, reverse)))
             port = new_port
 
         return port
@@ -122,14 +121,16 @@ class gramCrossbar(Elaboratable):
     def elaborate(self, platform):
         m = Module()
 
+        m.submodules += self._pending_submodules
+
         controller = self.controller
         nmasters   = len(self.masters)
 
         # Address mapping --------------------------------------------------------------------------
         cba_shifts = {"ROW_BANK_COL": controller.settings.geom.colbits - controller.address_align}
         cba_shift = cba_shifts[controller.settings.address_mapping]
-        m_ba      = [m.get_bank_address(self.bank_bits, cba_shift)for m in self.masters]
-        m_rca     = [m.get_row_column_address(self.bank_bits, self.rca_bits, cba_shift) for m in self.masters]
+        m_ba      = [master.get_bank_address(self.bank_bits, cba_shift) for master in self.masters]
+        m_rca     = [master.get_row_column_address(self.bank_bits, self.rca_bits, cba_shift) for master in self.masters]
 
         master_readys       = [0]*nmasters
         master_wdata_readys = [0]*nmasters
@@ -195,17 +196,18 @@ class gramCrossbar(Elaboratable):
             m.d.comb += master.rdata.valid.eq(master_rdata_valid)
 
         # Route data writes ------------------------------------------------------------------------
-        wdata_cases = {}
-        for nm, master in enumerate(self.masters):
-            wdata_cases[2**nm] = [
-                controller.wdata.eq(master.wdata.data),
-                controller.wdata_we.eq(master.wdata.we)
-            ]
-        wdata_cases["default"] = [
-            controller.wdata.eq(0),
-            controller.wdata_we.eq(0)
-        ]
-        m.d.comb += Case(Cat(*master_wdata_readys), wdata_cases)
+        with m.Switch(Cat(*master_wdata_readys)):
+            with m.Case():
+                m.d.comb += [
+                    controller.wdata.eq(0),
+                    controller.wdata_we.eq(0),
+                ]
+            for nm, master in enumerate(self.masters):
+                with m.Case(2**nm):
+                    m.d.comb += [
+                        controller.wdata.eq(master.wdata.data),
+                        controller.wdata_we.eq(master.wdata.we),
+                    ]
 
         # Route data reads -------------------------------------------------------------------------
         for master in self.masters: