add function unit dependency cell
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 4 May 2019 06:35:15 +0000 (07:35 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 4 May 2019 06:35:15 +0000 (07:35 +0100)
src/scoreboard/fu_dep_cell.py [new file with mode: 0644]

diff --git a/src/scoreboard/fu_dep_cell.py b/src/scoreboard/fu_dep_cell.py
new file mode 100644 (file)
index 0000000..a7b6d91
--- /dev/null
@@ -0,0 +1,84 @@
+from nmigen.compat.sim import run_simulation
+from nmigen.cli import verilog, rtlil
+from nmigen import Module, Signal, Elaboratable
+from nmutil.latch import SRLatch
+
+
+class FUDependenceCell(Elaboratable):
+    """ implements 11.4.7 mitch alsup dependence cell, p27
+    """
+    def __init__(self):
+        # inputs
+        self.rd_pend_i = Signal(reset_less=True)     # read pending in (left)
+        self.wr_pend_i = Signal(reset_less=True)     # write pending in (left)
+        self.issue_i = Signal(reset_less=True)    # Issue in (top)
+
+        self.go_write_i = Signal(reset_less=True) # Go Write in (left)
+        self.go_read_i = Signal(reset_less=True)  # Go Read in (left)
+
+        # outputs (latched rd/wr pend)
+        self.rd_pend_o = Signal(reset_less=True)   # read pending out (right)
+        self.wr_pend_o = Signal(reset_less=True)   # write pending out (right)
+
+    def elaborate(self, platform):
+        m = Module()
+        m.submodules.rd_l = rd_l = SRLatch()
+        m.submodules.wr_l = wr_l = SRLatch()
+
+        # write latch: reset on go_write HI, set on write pending and issue
+        m.d.sync += wr_l.s.eq(self.issue_i & self.wr_pend_i)
+        m.d.sync += wr_l.r.eq(self.go_write_i)
+
+        # read latch: reset on go_read HI, set on read pending and issue
+        m.d.sync += rd_l.s.eq(self.issue_i & self.rd_pend_i)
+        m.d.sync += rd_l.r.eq(self.go_read_i)
+
+        # Read/Write Pending Latches (read out horizontally)
+        m.d.comb += self.wr_pend_o.eq(wr_l.qn)
+        m.d.comb += self.rd_pend_o.eq(rd_l.qn)
+
+        return m
+
+    def __iter__(self):
+        yield self.rd_pend_i
+        yield self.wr_pend_i
+        yield self.issue_i
+        yield self.go_write_i
+        yield self.go_read_i
+        yield self.rd_pend_o
+        yield self.wr_pend_o
+                
+    def ports(self):
+        return list(self)
+
+
+def dcell_sim(dut):
+    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_read_i.eq(1)
+    yield
+    yield dut.go_read_i.eq(0)
+    yield
+    yield dut.go_write_i.eq(1)
+    yield
+    yield dut.go_write_i.eq(0)
+    yield
+
+def test_dcell():
+    dut = FUDependenceCell()
+    vl = rtlil.convert(dut, ports=dut.ports())
+    with open("test_fu_dcell.il", "w") as f:
+        f.write(vl)
+
+    run_simulation(dut, dcell_sim(dut), vcd_name='test_fu_dcell.vcd')
+
+if __name__ == '__main__':
+    test_dcell()