Fix regressions from #ebe5cef
authorJean THOMAS <git0@pub.jeanthomas.me>
Tue, 28 Jul 2020 13:33:43 +0000 (15:33 +0200)
committerJean THOMAS <git0@pub.jeanthomas.me>
Tue, 28 Jul 2020 13:33:43 +0000 (15:33 +0200)
gram/core/crossbar.py
gram/core/multiplexer.py

index 05a31f3d7cf4fd6f4eeb107a796fcd20a36f2655..e7f127c9a053b80c4d51ed15d18f948ffe10f522 100644 (file)
@@ -13,6 +13,26 @@ import gram.stream as stream
 
 __ALL__ = ["gramCrossbar"]
 
+class DelayLine(Elaboratable):
+    def __init__(self, delay):
+        if delay < 1:
+            raise ValueError("delay value must be 1+")
+        self.delay = delay
+
+        self.i = Signal()
+        self.o = Signal()
+
+    def elaborate(self, platform):
+        m = Module()
+
+        buffer = Signal(self.delay)
+        m.d.sync += [
+            buffer.eq(Cat(self.i, buffer))
+        ]
+        m.d.comb += self.o.eq(buffer[-1])
+
+        return m
+
 class gramCrossbar(Elaboratable):
     """Multiplexes LiteDRAMController (slave) between ports (masters)
 
@@ -111,8 +131,7 @@ class gramCrossbar(Elaboratable):
                 for other_nb, other_arbiter in enumerate(arbiters):
                     if other_nb != nb:
                         other_bank = getattr(controller, "bank"+str(other_nb))
-                        locked = locked | (other_bank.lock & (
-                            other_arbiter.grant == nm))
+                        locked = locked | (other_bank.lock & (other_arbiter.grant == nm))
                 master_locked.append(locked)
 
             # Arbitrate ----------------------------------------------------------------------------
@@ -140,18 +159,16 @@ class gramCrossbar(Elaboratable):
 
         # Delay write/read signals based on their latency
         for nm, master_wdata_ready in enumerate(master_wdata_readys):
-            for i in range(self.write_latency):
-                new_master_wdata_ready = Signal()
-                m.d.sync += new_master_wdata_ready.eq(master_wdata_ready)
-                master_wdata_ready = new_master_wdata_ready
-            master_wdata_readys[nm] = master_wdata_ready
+            delayline = DelayLine(self.write_latency)
+            m.submodules += delayline
+            m.d.comb += delayline.i.eq(master_wdata_ready)
+            master_wdata_readys[nm] = delayline.o
 
         for nm, master_rdata_valid in enumerate(master_rdata_valids):
-            for i in range(self.read_latency):
-                new_master_rdata_valid = Signal()
-                m.d.sync += new_master_rdata_valid.eq(master_rdata_valid)
-                master_rdata_valid = new_master_rdata_valid
-            master_rdata_valids[nm] = master_rdata_valid
+            delayline = DelayLine(self.read_latency)
+            m.submodules += delayline
+            m.d.comb += delayline.i.eq(master_rdata_valid)
+            master_rdata_valids[nm] = delayline.o
 
         for master, master_ready in zip(self.masters, master_readys):
             m.d.comb += master.cmd.ready.eq(master_ready)
index d2401872f06ee62c697fdb6a02e2e68acdfed0e8..e8f769a837bebe3b4ef973bdbaa306bf1adc2ced 100644 (file)
@@ -330,14 +330,10 @@ class Multiplexer(Elaboratable):
         m.d.comb += twtrcon.valid.eq(choose_req.accept() & choose_req.write())
 
         # Read/write turnaround --------------------------------------------------------------------
-        read_available = Signal()
-        write_available = Signal()
-        reads = [req.valid & req.is_read for req in requests]
-        writes = [req.valid & req.is_write for req in requests]
-        m.d.comb += [
-            read_available.eq(reads.any()),
-            write_available.eq(writes.any())
-        ]
+        reads = Signal(len(requests))
+        m.d.comb += reads.eq(Cat([req.valid & req.is_read for req in requests]))
+        writes = Signal(len(requests))
+        m.d.comb += writes.eq(Cat([req.valid & req.is_write for req in requests]))
 
         # Anti Starvation --------------------------------------------------------------------------
         m.submodules.read_antistarvation = read_antistarvation = _AntiStarvation(settings.read_time)
@@ -345,9 +341,8 @@ class Multiplexer(Elaboratable):
 
         # Refresh ----------------------------------------------------------------------------------
         m.d.comb += [bm.refresh_req.eq(refresher.cmd.valid) for bm in bank_machines]
-        go_to_refresh = Signal()
-        bm_refresh_gnts = [bm.refresh_gnt for bm in bank_machines]
-        m.d.comb += go_to_refresh.eq(bm_refresh_gnts.all())
+        bm_refresh_gnts = Signal(len(bank_machines))
+        m.d.comb += bm_refresh_gnts.eq(Cat([bm.refresh_gnt for bm in bank_machines]))
 
         # Datapath ---------------------------------------------------------------------------------
         all_rddata = [p.rddata for p in dfi.phases]
@@ -398,12 +393,12 @@ class Multiplexer(Elaboratable):
                         choose_req.cmd.ready.eq(cas_allowed),
                     ]
 
-                with m.If(write_available):
-                    # TODO: switch only after several cycles of ~read_available?
-                    with m.If(~read_available | read_antistarvation.max_time):
+                with m.If(writes.any()):
+                    # TODO: switch only after several cycles of ~reads.any()?
+                    with m.If(~reads.any() | read_antistarvation.max_time):
                         m.next = "RTW"
 
-                with m.If(go_to_refresh):
+                with m.If(bm_refresh_gnts.all()):
                     m.next = "Refresh"
 
             with m.State("Write"):
@@ -424,11 +419,11 @@ class Multiplexer(Elaboratable):
                         choose_req.cmd.ready.eq(cas_allowed),
                     ]
 
-                with m.If(read_available):
-                    with m.If(~write_available | write_antistarvation.max_time):
+                with m.If(reads.any()):
+                    with m.If(~writes.any() | write_antistarvation.max_time):
                         m.next = "WTR"
 
-                with m.If(go_to_refresh):
+                with m.If(bm_refresh_gnts.all()):
                     m.next = "Refresh"
 
             with m.State("Refresh"):