do dependency row as multi-bit SRLatch
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 29 May 2019 20:46:40 +0000 (21:46 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 29 May 2019 20:46:40 +0000 (21:46 +0100)
src/scoreboard/dependence_cell.py

index e12f216302f2c1f64257d0e7b9508300be05bec3..f5b85184d6dc3bcb8f147f8be8c032d73de7bad4 100644 (file)
@@ -1,6 +1,6 @@
 from nmigen.compat.sim import run_simulation
 from nmigen.cli import verilog, rtlil
 from nmigen.compat.sim import run_simulation
 from nmigen.cli import verilog, rtlil
-from nmigen import Module, Signal, Elaboratable, Array, Cat
+from nmigen import Module, Signal, Elaboratable, Array, Cat, Repl
 from nmutil.latch import SRLatch
 
 
 from nmutil.latch import SRLatch
 
 
@@ -25,34 +25,35 @@ class DepCell(Elaboratable):
         asynchronous) would be reset at the exact moment that GO was requested,
         and the RSEL would be garbage.
     """
         asynchronous) would be reset at the exact moment that GO was requested,
         and the RSEL would be garbage.
     """
-    def __init__(self):
+    def __init__(self, llen):
+        self.llen = llen
         # inputs
         # inputs
-        self.reg_i = Signal(reset_less=True)     # reg bit in (top)
+        self.reg_i = Signal(llen, reset_less=True)     # reg bit in (top)
         self.issue_i = Signal(reset_less=True)   # Issue in (top)
         self.issue_i = Signal(reset_less=True)   # Issue in (top)
-        self.hazard_i = Signal(reset_less=True)  # to check hazard
+        self.hazard_i = Signal(llen, reset_less=True)  # to check hazard
         self.go_i = Signal(reset_less=True)      # Go read/write in (left)
         self.die_i = Signal(reset_less=True)     # Die in (left)
         self.go_i = Signal(reset_less=True)      # Go read/write in (left)
         self.die_i = Signal(reset_less=True)     # Die in (left)
-        self.q_o = Signal(reset_less=True)       # Latch out (register active)
+        self.q_o = Signal(llen, reset_less=True)       # Latch out (reg active)
 
         # for Register File Select Lines (vertical)
 
         # for Register File Select Lines (vertical)
-        self.rsel_o = Signal(reset_less=True)  # reg sel (bottom)
+        self.rsel_o = Signal(llen, reset_less=True)  # reg sel (bottom)
         # for Function Unit "forward progress" (horizontal)
         # for Function Unit "forward progress" (horizontal)
-        self.fwd_o = Signal(reset_less=True)   # FU forard progress (right)
+        self.fwd_o = Signal(llen, reset_less=True)   # FU forard progress (right)
 
     def elaborate(self, platform):
         m = Module()
 
     def elaborate(self, platform):
         m = Module()
-        m.submodules.l = l = SRLatch(sync=False) # async latch
+        m.submodules.l = l = SRLatch(sync=False, llen=self.llen) # async latch
 
         # reset on go HI, set on dest and issue
 
         # reset on go HI, set on dest and issue
-        m.d.comb += l.s.eq(self.issue_i & self.reg_i)
-        m.d.comb += l.r.eq(self.go_i | self.die_i)
+        m.d.comb += l.s.eq(Repl(self.issue_i, self.llen) & self.reg_i)
+        m.d.comb += l.r.eq(Repl(self.go_i | self.die_i, self.llen))
 
         # Function Unit "Forward Progress".
         m.d.comb += self.fwd_o.eq((l.q) & self.hazard_i) # & ~self.issue_i)
 
         # Register Select. Activated on go read/write and *current* latch set
         m.d.comb += self.q_o.eq(l.qlq)
 
         # Function Unit "Forward Progress".
         m.d.comb += self.fwd_o.eq((l.q) & self.hazard_i) # & ~self.issue_i)
 
         # Register Select. Activated on go read/write and *current* latch set
         m.d.comb += self.q_o.eq(l.qlq)
-        m.d.comb += self.rsel_o.eq(l.qlq & self.go_i)
+        m.d.comb += self.rsel_o.eq(l.qlq & Repl(self.go_i, self.llen))
 
         return m
 
 
         return m
 
@@ -70,40 +71,41 @@ class DepCell(Elaboratable):
         return list(self)
 
 
         return list(self)
 
 
-class DependenceCell(Elaboratable):
+class DependencyRow(Elaboratable):
     """ implements 11.4.7 mitch alsup dependence cell, p27
     """
     """ implements 11.4.7 mitch alsup dependence cell, p27
     """
-    def __init__(self):
+    def __init__(self, n_reg):
+        self.n_reg = n_reg
         # inputs
         # inputs
-        self.dest_i = Signal(reset_less=True)     # Dest in (top)
-        self.src1_i = Signal(reset_less=True)     # oper1 in (top)
-        self.src2_i = Signal(reset_less=True)     # oper2 in (top)
+        self.dest_i = Signal(n_reg, reset_less=True)     # Dest in (top)
+        self.src1_i = Signal(n_reg, reset_less=True)     # oper1 in (top)
+        self.src2_i = Signal(n_reg, reset_less=True)     # oper2 in (top)
         self.issue_i = Signal(reset_less=True)    # Issue in (top)
 
         self.issue_i = Signal(reset_less=True)    # Issue in (top)
 
-        self.rd_pend_i = Signal(reset_less=True) # Read pending in (top)
-        self.wr_pend_i = Signal(reset_less=True) # Write pending in (top)
-        self.rd_rsel_o = Signal(reset_less=True) # Read pending out (bottom)
-        self.wr_rsel_o = Signal(reset_less=True) # Write pending out (bottom)
+        self.rd_pend_i = Signal(n_reg, reset_less=True) # Read pend in (top)
+        self.wr_pend_i = Signal(n_reg, reset_less=True) # Write pend in (top)
+        self.rd_rsel_o = Signal(n_reg, reset_less=True) # Read pend out (bot)
+        self.wr_rsel_o = Signal(n_reg, reset_less=True) # Write pend out (bot)
 
         self.go_wr_i = Signal(reset_less=True) # Go Write in (left)
         self.go_rd_i = Signal(reset_less=True)  # Go Read in (left)
         self.go_die_i = Signal(reset_less=True) # Go Die in (left)
 
         # for Register File Select Lines (vertical)
 
         self.go_wr_i = Signal(reset_less=True) # Go Write in (left)
         self.go_rd_i = Signal(reset_less=True)  # Go Read in (left)
         self.go_die_i = Signal(reset_less=True) # Go Die in (left)
 
         # for Register File Select Lines (vertical)
-        self.dest_rsel_o = Signal(reset_less=True)  # dest reg sel (bottom)
-        self.src1_rsel_o = Signal(reset_less=True)  # src1 reg sel (bottom)
-        self.src2_rsel_o = Signal(reset_less=True)  # src2 reg sel (bottom)
+        self.dest_rsel_o = Signal(n_reg, reset_less=True)  # dest reg sel (bot)
+        self.src1_rsel_o = Signal(n_reg, reset_less=True)  # src1 reg sel (bot)
+        self.src2_rsel_o = Signal(n_reg, reset_less=True)  # src2 reg sel (bot)
 
         # for Function Unit "forward progress" (horizontal)
 
         # for Function Unit "forward progress" (horizontal)
-        self.dest_fwd_o = Signal(reset_less=True)   # dest FU fw (right)
-        self.src1_fwd_o = Signal(reset_less=True)   # src1 FU fw (right)
-        self.src2_fwd_o = Signal(reset_less=True)   # src2 FU fw (right)
+        self.dest_fwd_o = Signal(n_reg, reset_less=True)   # dest FU fw (right)
+        self.src1_fwd_o = Signal(n_reg, reset_less=True)   # src1 FU fw (right)
+        self.src2_fwd_o = Signal(n_reg, reset_less=True)   # src2 FU fw (right)
 
     def elaborate(self, platform):
         m = Module()
 
     def elaborate(self, platform):
         m = Module()
-        m.submodules.dest_c = dest_c = DepCell()
-        m.submodules.src1_c = src1_c = DepCell()
-        m.submodules.src2_c = src2_c = DepCell()
+        m.submodules.dest_c = dest_c = DepCell(self.n_reg)
+        m.submodules.src1_c = src1_c = DepCell(self.n_reg)
+        m.submodules.src2_c = src2_c = DepCell(self.n_reg)
 
         # connect issue and die
         for c in [dest_c, src1_c, src2_c]:
 
         # connect issue and die
         for c in [dest_c, src1_c, src2_c]:
@@ -123,7 +125,7 @@ class DependenceCell(Elaboratable):
 
         # wark-wark: yes, writing to the same reg you are reading is *NOT*
         # a write-after-read hazard.
 
         # wark-wark: yes, writing to the same reg you are reading is *NOT*
         # a write-after-read hazard.
-        selfhazard = Signal(reset_less=False)
+        selfhazard = Signal(self.n_reg, reset_less=False)
         m.d.comb += selfhazard.eq((self.dest_i & self.src1_i) |
                                   (self.dest_i & self.src2_i))
 
         m.d.comb += selfhazard.eq((self.dest_i & self.src1_i) |
                                   (self.dest_i & self.src2_i))
 
@@ -168,139 +170,6 @@ class DependenceCell(Elaboratable):
         return list(self)
 
 
         return list(self)
 
 
-class DependencyRow(Elaboratable):
-    def __init__(self, n_reg_col):
-        self.n_reg_col = n_reg_col
-
-        # ----
-        # fields all match DependencyCell precisely
-
-        self.dest_i = Signal(n_reg_col, reset_less=True)
-        self.src1_i = Signal(n_reg_col, reset_less=True)
-        self.src2_i = Signal(n_reg_col, reset_less=True)
-
-        self.rd_pend_i = Signal(n_reg_col, reset_less=True)
-        self.wr_pend_i = Signal(n_reg_col, reset_less=True)
-
-        self.rd_rsel_o = Signal(n_reg_col, reset_less=True)
-        self.wr_rsel_o = Signal(n_reg_col, reset_less=True)
-
-        self.issue_i = Signal(reset_less=True)
-        self.go_wr_i = Signal(reset_less=True)
-        self.go_rd_i = Signal(reset_less=True)
-        self.go_die_i = Signal(reset_less=True)
-
-        self.dest_rsel_o = Signal(n_reg_col, reset_less=True)
-        self.src1_rsel_o = Signal(n_reg_col, reset_less=True)
-        self.src2_rsel_o = Signal(n_reg_col, reset_less=True)
-
-        self.dest_fwd_o = Signal(n_reg_col, reset_less=True)
-        self.src1_fwd_o = Signal(n_reg_col, reset_less=True)
-        self.src2_fwd_o = Signal(n_reg_col, reset_less=True)
-
-    def elaborate(self, platform):
-        m = Module()
-        rcell = Array(DependenceCell() for f in range(self.n_reg_col))
-        for rn in range(self.n_reg_col):
-            setattr(m.submodules, "dm_r%d" % rn, rcell[rn])
-
-        # ---
-        # connect Dep dest/src to module dest/src
-        # ---
-        rd_pend_i = []
-        wr_pend_i = []
-        rd_rsel_o = []
-        wr_rsel_o = []
-        dest_i = []
-        src1_i = []
-        src2_i = []
-        for rn in range(self.n_reg_col):
-            dc = rcell[rn]
-            # accumulate cell inputs dest/src1/src2
-            rd_pend_i.append(dc.rd_pend_i)
-            wr_pend_i.append(dc.wr_pend_i)
-            rd_rsel_o.append(dc.rd_rsel_o)
-            wr_rsel_o.append(dc.wr_rsel_o)
-            dest_i.append(dc.dest_i)
-            src1_i.append(dc.src1_i)
-            src2_i.append(dc.src2_i)
-        # wire up inputs from module to row cell inputs (Cat is gooood)
-        m.d.comb += [Cat(*dest_i).eq(self.dest_i),
-                     Cat(*src1_i).eq(self.src1_i),
-                     Cat(*src2_i).eq(self.src2_i),
-                     Cat(*rd_pend_i).eq(self.rd_pend_i),
-                     Cat(*wr_pend_i).eq(self.wr_pend_i),
-                     self.rd_rsel_o.eq(Cat(*rd_rsel_o)),
-                     self.wr_rsel_o.eq(Cat(*wr_rsel_o)),
-                    ]
-
-        # ---
-        # connect Dep die/issue_i/go_rd_i/go_wr_i to module issue_i/go_rd/go_wr
-        # ---
-        for rn in range(self.n_reg_col):
-            dc = rcell[rn]
-            m.d.comb += [dc.go_rd_i.eq(self.go_rd_i),
-                         dc.go_wr_i.eq(self.go_wr_i),
-                         dc.issue_i.eq(self.issue_i),
-                         dc.go_die_i.eq(self.go_die_i),
-                    ]
-
-        # ---
-        # connect Function Unit vector
-        # ---
-        dest_fwd_o = []
-        src1_fwd_o = []
-        src2_fwd_o = []
-        for rn in range(self.n_reg_col):
-            dc = rcell[rn]
-            # accumulate cell fwd outputs for dest/src1/src2
-            dest_fwd_o.append(dc.dest_fwd_o)
-            src1_fwd_o.append(dc.src1_fwd_o)
-            src2_fwd_o.append(dc.src2_fwd_o)
-        # connect cell fwd outputs to FU Vector Out [Cat is gooood]
-        m.d.comb += [self.dest_fwd_o.eq(Cat(*dest_fwd_o)),
-                     self.src1_fwd_o.eq(Cat(*src1_fwd_o)),
-                     self.src2_fwd_o.eq(Cat(*src2_fwd_o))
-                    ]
-
-        # ---
-        # connect Reg Selection vector
-        # ---
-        dest_rsel_o = []
-        src1_rsel_o = []
-        src2_rsel_o = []
-        for rn in range(self.n_reg_col):
-            dc = rcell[rn]
-            # accumulate cell reg-select outputs dest/src1/src2
-            dest_rsel_o.append(dc.dest_rsel_o)
-            src1_rsel_o.append(dc.src1_rsel_o)
-            src2_rsel_o.append(dc.src2_rsel_o)
-        # connect cell reg-select outputs to Reg Vector Out
-        m.d.comb += self.dest_rsel_o.eq(Cat(*dest_rsel_o))
-        m.d.comb += self.src1_rsel_o.eq(Cat(*src1_rsel_o))
-        m.d.comb += self.src2_rsel_o.eq(Cat(*src2_rsel_o))
-
-        return m
-
-    def __iter__(self):
-        yield self.dest_i
-        yield self.src1_i
-        yield self.src2_i
-        yield self.issue_i
-        yield self.go_wr_i
-        yield self.go_rd_i
-        yield self.go_die_i
-        yield self.dest_rsel_o
-        yield self.src1_rsel_o
-        yield self.src2_rsel_o
-        yield self.dest_fwd_o
-        yield self.src1_fwd_o
-        yield self.src2_fwd_o
-
-    def ports(self):
-        return list(self)
-
-
 def dcell_sim(dut):
     yield dut.dest_i.eq(1)
     yield dut.issue_i.eq(1)
 def dcell_sim(dut):
     yield dut.dest_i.eq(1)
     yield dut.issue_i.eq(1)
@@ -329,11 +198,6 @@ def test_dcell():
     with open("test_drow.il", "w") as f:
         f.write(vl)
 
     with open("test_drow.il", "w") as f:
         f.write(vl)
 
-    dut = DependenceCell()
-    vl = rtlil.convert(dut, ports=dut.ports())
-    with open("test_dcell.il", "w") as f:
-        f.write(vl)
-
     run_simulation(dut, dcell_sim(dut), vcd_name='test_dcell.vcd')
 
 if __name__ == '__main__':
     run_simulation(dut, dcell_sim(dut), vcd_name='test_dcell.vcd')
 
 if __name__ == '__main__':