add in 2 more ALUs, now 4x4 scoreboard
[soc.git] / src / scoreboard / issue_unit.py
index d1f58d111420aaf681062d7a8767454d003f6683..4f010b4bf4c16f14c4b79a6bdac07ec671540066 100644 (file)
@@ -1,10 +1,59 @@
 from nmigen.compat.sim import run_simulation
 from nmigen.cli import verilog, rtlil
 from nmigen import Module, Signal, Cat, Array, Const, Record, Elaboratable
-from nmutil.latch import SRLatch
 from nmigen.lib.coding import Decoder
 
-from shadow_fn import ShadowFn
+from .shadow_fn import ShadowFn
+
+
+class RegDecode(Elaboratable):
+    """ decodes registers into unary
+
+        Inputs
+
+        * :wid:         register file width
+    """
+    def __init__(self, wid):
+        self.reg_width = wid
+
+        # inputs
+        self.enable_i = Signal(reset_less=True) # enable decoders
+        self.dest_i = Signal(max=wid, reset_less=True) # Dest R# in
+        self.src1_i = Signal(max=wid, reset_less=True) # oper1 R# in
+        self.src2_i = Signal(max=wid, reset_less=True) # oper2 R# in
+
+        # outputs
+        self.dest_o = Signal(wid, reset_less=True) # Dest unary out
+        self.src1_o = Signal(wid, reset_less=True) # oper1 unary out
+        self.src2_o = Signal(wid, reset_less=True) # oper2 unary out
+
+    def elaborate(self, platform):
+        m = Module()
+        m.submodules.dest_d = dest_d = Decoder(self.reg_width)
+        m.submodules.src1_d = src1_d = Decoder(self.reg_width)
+        m.submodules.src2_d = src2_d = Decoder(self.reg_width)
+
+        # dest decoder: write-pending
+        for d, i, o in [(dest_d, self.dest_i, self.dest_o),
+                     (src1_d, self.src1_i, self.src1_o),
+                     (src2_d, self.src2_i, self.src2_o)]:
+            m.d.comb += d.i.eq(i)
+            m.d.comb += d.n.eq(~self.enable_i)
+            m.d.comb += o.eq(d.o)
+
+        return m
+
+    def __iter__(self):
+        yield self.enable_i
+        yield self.dest_i
+        yield self.src1_i
+        yield self.src2_i
+        yield self.dest_o
+        yield self.src1_o
+        yield self.src2_o
+
+    def ports(self):
+        return list(self)
 
 
 class IssueUnit(Elaboratable):
@@ -21,25 +70,22 @@ class IssueUnit(Elaboratable):
 
         # inputs
         self.store_i = Signal(reset_less=True) # instruction is a store
-        self.dest_i = Signal(max=wid, reset_less=True) # Dest R# in 
-        self.src1_i = Signal(max=wid, reset_less=True) # oper1 R# in
-        self.src2_i = Signal(max=wid, reset_less=True) # oper2 R# in
+        self.dest_i = Signal(wid, reset_less=True) # Dest R in (unary)
 
         self.g_wr_pend_i = Signal(wid, reset_less=True) # write pending vector
 
-        self.insn_i = Array(Signal(reset_less=True, name="insn_i") \
-                               for i in range(n_insns))
-        self.busy_i = Array(Signal(reset_less=True, name="busy_i") \
-                               for i in range(n_insns))
+        self.insn_i = Signal(n_insns, reset_less=True, name="insn_i")
+        self.busy_i = Signal(n_insns, reset_less=True, name="busy_i")
 
         # outputs
-        self.fn_issue_o = Array(Signal(reset_less=True, name="fn_issue_o") \
-                               for i in range(n_insns))
+        self.fn_issue_o = Signal(n_insns, reset_less=True, name="fn_issue_o")
         self.g_issue_o = Signal(reset_less=True)
 
     def elaborate(self, platform):
         m = Module()
-        m.submodules.dest_d = dest_d = Decoder(self.reg_width)
+
+        if self.n_insns == 0:
+            return m
 
         # temporaries
         waw_stall = Signal(reset_less=True)
@@ -47,9 +93,7 @@ class IssueUnit(Elaboratable):
         pend = Signal(self.reg_width, reset_less=True)
 
         # dest decoder: write-pending
-        m.d.comb += dest_d.i.eq(self.dest_i)
-        m.d.comb += dest_d.n.eq(~self.store_i) # decode is inverted
-        m.d.comb += pend.eq(dest_d.o & self.g_wr_pend_i)
+        m.d.comb += pend.eq(self.dest_i & self.g_wr_pend_i & (~self.store_i))
         m.d.comb += waw_stall.eq(pend.bool())
 
         ib_l = []
@@ -67,6 +111,7 @@ class IssueUnit(Elaboratable):
         yield self.dest_i
         yield self.src1_i
         yield self.src2_i
+        yield self.reg_enable_i
         yield self.g_wr_pend_i
         yield from self.insn_i
         yield from self.busy_i
@@ -84,10 +129,10 @@ class IntFPIssueUnit(Elaboratable):
         self.issue_o = Signal(reset_less=True)
 
         # some renames
-        self.int_write_pending_i = self.i.g_wr_pend_i
-        self.fp_write_pending_i = self.f.g_wr_pend_i
-        self.int_write_pending_i.name = 'int_write_pending_i'
-        self.fp_write_pending_i.name = 'fp_write_pending_i'
+        self.int_wr_pend_i = self.i.g_wr_pend_i
+        self.fp_wr_pend_i = self.f.g_wr_pend_i
+        self.int_wr_pend_i.name = 'int_wr_pend_i'
+        self.fp_wr_pend_i.name = 'fp_wr_pend_i'
 
     def elaborate(self, platform):
         m = Module()
@@ -117,13 +162,13 @@ def issue_unit_sim(dut):
     yield
     yield dut.issue_i.eq(0)
     yield
-    yield dut.go_read_i.eq(1)
+    yield dut.go_rd_i.eq(1)
     yield
-    yield dut.go_read_i.eq(0)
+    yield dut.go_rd_i.eq(0)
     yield
-    yield dut.go_write_i.eq(1)
+    yield dut.go_wr_i.eq(1)
     yield
-    yield dut.go_write_i.eq(0)
+    yield dut.go_wr_i.eq(0)
     yield
 
 def test_issue_unit():