LDSTDepCell can act as a matrix
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 2 Jun 2019 00:47:01 +0000 (01:47 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 2 Jun 2019 00:47:01 +0000 (01:47 +0100)
src/experiment/score6600.py
src/scoreboard/ldst_dep_cell.py
src/scoreboard/ldst_matrix.py [deleted file]

index 12d4d625f7f0feb4cde64b5a25da88cc84cc72bd..4c55e0bddbdb08dfa56b6747c67f31bfa0b1bd75 100644 (file)
@@ -22,6 +22,29 @@ from copy import deepcopy
 from math import log
 
 
+class Memory(Elaboratable):
+    def __init__(self, regwid, addrw):
+        depth = (1<<addrw) / (regwid/8)
+        self.adr   = Signal(addrw)
+        self.dat_r = Signal(regwid)
+        self.dat_w = Signal(regwid)
+        self.we    = Signal()
+        self.mem   = Memory(width=regwid, depth=depth, init=range(0, depth))
+
+    def elaborate(self, platform):
+        m = Module()
+        m.submodules.rdport = rdport = self.mem.read_port()
+        m.submodules.wrport = wrport = self.mem.write_port()
+        m.d.comb += [
+            rdport.addr.eq(self.adr[2:]),
+            self.dat_r.eq(rdport.data),
+            wrport.addr.eq(self.adr),
+            wrport.data.eq(self.dat_w),
+            wrport.en.eq(self.we),
+        ]
+        return m
+
+
 class CompUnitsBase(Elaboratable):
     """ Computation Unit Base class.
 
index be10578aa3d56e0552cd2756a67e22834a884127..5f8ff890937b53609a6b3788be546d9c18cb6c73 100644 (file)
@@ -1,6 +1,15 @@
 """ Mitch Alsup 6600-style LD/ST scoreboard Dependency Cell
 
+Relevant comments (p45-46):
+
+* If there are no WAR dependencies on a Load instruction with a computed
+  address it can assert Bank_Addressable and Translate_Addressable.
+
+* If there are no RAW dependencies on a Store instruction with both a
+  write permission and store data present it can assert Bank_Addressable
+
 Relevant bugreports:
+
 * http://bugs.libre-riscv.org/show_bug.cgi?id=81
 
 """
@@ -28,8 +37,8 @@ class LDSTDepCell(Elaboratable):
         self.stwd_hit_i = Signal(n_ls, reset_less=True) # st w/ hit in (right)
 
         # outputs (latched rd/wr pend)
-        self.ld_hold_st_o = Signal(n_ls, reset_less=True) # ld holds st out (l)
-        self.st_hold_ld_o = Signal(n_ls, reset_less=True) # st holds ld out (l)
+        self.ld_hold_st_o = Signal(reset_less=True) # ld holds st out (l)
+        self.st_hold_ld_o = Signal(reset_less=True) # st holds ld out (l)
 
     def elaborate(self, platform):
         m = Module()
@@ -41,7 +50,7 @@ class LDSTDepCell(Elaboratable):
         die = Repl(self.go_die_i, self.n_ls)
 
         # issue & store & load - used for both WAR and RAW Setting
-        i_s_l = Signal(reset_less=True)
+        i_s_l = Signal(self.n_ls, reset_less=True)
         m.d.comb += i_s_l.eq(issue & self.stor_i & self.load_i)
 
         # write after read latch: loads block stores
@@ -53,8 +62,8 @@ class LDSTDepCell(Elaboratable):
         m.d.comb += raw_l.r.eq(die | self.stor_i) # reset on ST
 
         # Hold results (read out horizontally, accumulate in OR fashion)
-        m.d.comb += self.ld_hold_st_o.eq(war_l.qn & self.load_hit_i)
-        m.d.comb += self.st_hold_ld_o.eq(raw_l.qn & self.stwd_hit_i)
+        m.d.comb += self.ld_hold_st_o.eq((war_l.qn & self.load_hit_i).bool())
+        m.d.comb += self.st_hold_ld_o.eq((raw_l.qn & self.stwd_hit_i).bool())
 
         return m
 
diff --git a/src/scoreboard/ldst_matrix.py b/src/scoreboard/ldst_matrix.py
deleted file mode 100644 (file)
index dc9d736..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-""" Mitch Alsup 6600-style LD/ST Memory Scoreboard Matrix (sparse vector)
-
-6600 LD/ST Dependency Table Matrix inputs / outputs
----------------------------------------------------
-
-Relevant comments (p45-46):
-
-* If there are no WAR dependencies on a Load instruction with a computed
-  address it can assert Bank_Addressable and Translate_Addressable.
-
-* If there are no RAW dependencies on a Store instruction with both a
-  write permission and store data present it can assert Bank_Addressable
-
-Relevant bugreports:
-* http://bugs.libre-riscv.org/show_bug.cgi?id=81
-
-"""
-
-from nmigen.compat.sim import run_simulation
-from nmigen.cli import verilog, rtlil
-from nmigen import Module, Signal, Elaboratable, Array, Cat, Const
-
-from ldst_dep_cell import LDSTDepCell
-
-
-class LDSTDepMatrix(Elaboratable):
-    """ implements 11.4.12 mitch alsup LD/ST Dependency Matrix, p46
-        actually a sparse matrix along the diagonal.
-
-        load-hold-store and store-hold-load accumulate in a priority-picking
-        fashion, ORing together.  the OR gate from the dependency cell is
-        here.
-    """
-    def __init__(self, n_ldst):
-        self.n_ldst = n_ldst                  # X and Y (FUs)
-        self.load_i = Signal(n_ldst, reset_less=True)  # load pending in
-        self.stor_i = Signal(n_ldst, reset_less=True)  # store pending in
-        self.issue_i = Signal(n_ldst, reset_less=True) # Issue in
-
-        self.load_hit_i = Signal(n_ldst, reset_less=True) # load hit in
-        self.stwd_hit_i = Signal(n_ldst, reset_less=True) # store w/data hit in
-
-        # outputs
-        self.ld_hold_st_o = Signal(reset_less=True) # load holds st out
-        self.st_hold_ld_o = Signal(reset_less=True) # st holds load out
-
-    def elaborate(self, platform):
-        m = Module()
-
-        # ---
-        # matrix of dependency cells
-        # ---
-        dm = Array(LDSTDepCell() for f in range(self.n_ldst))
-        for fu in range(self.n_ldst):
-            setattr(m.submodules, "dm_fu%d" % (fu), dm[fu])
-
-        # ---
-        # connect Function Unit vector
-        # ---
-        lhs_l = []
-        shl_l = []
-        load_l = []
-        stor_l = []
-        issue_l = []
-        lh_l = []
-        sh_l = []
-        for fu in range(self.n_ldst):
-            dc = dm[fu]
-            # accumulate load-hold-store / store-hold-load bits
-            lhs_l.append(dc.ld_hold_st_o)
-            shl_l.append(dc.st_hold_ld_o)
-            # accumulate inputs (for Cat'ing later) - TODO: must be a better way
-            load_l.append(dc.load_i)
-            stor_l.append(dc.stor_i)
-            issue_l.append(dc.issue_i)
-            lh_l.append(dc.load_hit_i)
-            sh_l.append(dc.stwd_hit_i)
-
-        # connect cell inputs using Cat(*list_of_stuff)
-        m.d.comb += [Cat(*load_l).eq(self.load_i),
-                     Cat(*stor_l).eq(self.stor_i),
-                     Cat(*issue_l).eq(self.issue_i),
-                     Cat(*lh_l).eq(self.load_hit_i),
-                     Cat(*sh_l).eq(self.stwd_hit_i),
-                    ]
-        # set the load-hold-store / store-hold-load OR-accumulated outputs
-        m.d.comb += self.ld_hold_st_o.eq(Cat(*lhs_l).bool())
-        m.d.comb += self.st_hold_ld_o.eq(Cat(*shl_l).bool())
-
-        return m
-
-    def __iter__(self):
-        yield self.load_i
-        yield self.stor_i
-        yield self.issue_i
-        yield self.load_hit_i
-        yield self.stwd_hit_i
-        yield self.ld_hold_st_o
-        yield self.st_hold_ld_o
-
-    def ports(self):
-        return list(self)
-
-def d_matrix_sim(dut):
-    """ XXX TODO
-    """
-    yield dut.dest_i.eq(1)
-    yield dut.issue_i.eq(1)
-    yield
-    yield dut.issue_i.eq(0)
-    yield
-    yield dut.src1_i.eq(1)
-    yield dut.issue_i.eq(1)
-    yield
-    yield dut.issue_i.eq(0)
-    yield
-    yield dut.go_rd_i.eq(1)
-    yield
-    yield dut.go_rd_i.eq(0)
-    yield
-    yield dut.go_wr_i.eq(1)
-    yield
-    yield dut.go_wr_i.eq(0)
-    yield
-
-def test_d_matrix():
-    dut = LDSTDepMatrix(n_ldst=4)
-    vl = rtlil.convert(dut, ports=dut.ports())
-    with open("test_ld_st_matrix.il", "w") as f:
-        f.write(vl)
-
-    run_simulation(dut, d_matrix_sim(dut), vcd_name='test_ld_st_matrix.vcd')
-
-if __name__ == '__main__':
-    test_d_matrix()