split out register decode from issue unit
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 10 May 2019 05:43:01 +0000 (06:43 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 10 May 2019 05:43:01 +0000 (06:43 +0100)
src/experiment/cscore.py
src/scoreboard/issue_unit.py

index d83a0ad16e1e8c5b4c1257494c0ae1127c370911..be085c51ad814c02c5446616168659767b6bdfd8 100644 (file)
@@ -8,7 +8,7 @@ from scoreboard.fu_fu_matrix import FUFUDepMatrix
 from scoreboard.fu_reg_matrix import FURegDepMatrix
 from scoreboard.global_pending import GlobalPending
 from scoreboard.group_picker import GroupPicker
-from scoreboard.issue_unit import IntFPIssueUnit
+from scoreboard.issue_unit import IntFPIssueUnit, RegDecode
 
 from compalu import ComputationUnitNoDelay
 
@@ -112,6 +112,8 @@ class Scoreboard(Elaboratable):
         m.submodules.g_int_wr_pend_v = g_int_wr_pend_v
 
         # INT/FP Issue Unit
+        regdecode = RegDecode(self.n_regs)
+        m.submodules.regdecode = regdecode
         issueunit = IntFPIssueUnit(self.n_regs, n_int_fus, n_fp_fus)
         m.submodules.issueunit = issueunit
 
@@ -125,9 +127,11 @@ class Scoreboard(Elaboratable):
         # Issue Unit is where it starts.  set up some in/outs for this module
         #---------
         m.d.comb += [issueunit.i.store_i.eq(self.int_store_i),
-                     issueunit.i.dest_i.eq(self.int_dest_i),
-                     issueunit.i.src1_i.eq(self.int_src1_i),
-                     issueunit.i.src2_i.eq(self.int_src2_i),
+                     regdecode.dest_i.eq(self.int_dest_i),
+                     regdecode.src1_i.eq(self.int_src1_i),
+                     regdecode.src2_i.eq(self.int_src2_i),
+                     regdecode.enable_i.eq(1),
+                     issueunit.i.dest_i.eq(regdecode.dest_o),
                      self.issue_o.eq(issueunit.issue_o)
                     ]
         self.int_insn_i = issueunit.i.insn_i # enabled by instruction decode
@@ -143,9 +147,9 @@ class Scoreboard(Elaboratable):
             fn_issue_l.append(fu.issue_i)
             fn_busy_l.append(fu.busy_o)
             m.d.sync += fu.issue_i.eq(issueunit.i.fn_issue_o[i])
-            m.d.comb += fu.dest_i.eq(issueunit.i.dest_i)
-            m.d.comb += fu.src1_i.eq(issueunit.i.src1_i)
-            m.d.comb += fu.src2_i.eq(issueunit.i.src2_i)
+            m.d.comb += fu.dest_i.eq(self.int_dest_i)
+            m.d.comb += fu.src1_i.eq(self.int_src1_i)
+            m.d.comb += fu.src2_i.eq(self.int_src2_i)
             # XXX sync, so as to stop a simulation infinite loop
             m.d.comb += issueunit.i.busy_i[i].eq(fu.busy_o)
 
index 728ecdf5cbd03f1eb018d85e5833004a92e0207a..187804a269f12430e8c490aef52928d4ab163958 100644 (file)
@@ -6,6 +6,56 @@ from nmigen.lib.coding import Decoder
 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):
     """ implements 11.4.14 issue unit, p50
 
@@ -20,9 +70,7 @@ 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
 
@@ -38,7 +86,6 @@ class IssueUnit(Elaboratable):
 
     def elaborate(self, platform):
         m = Module()
-        m.submodules.dest_d = dest_d = Decoder(self.reg_width)
 
         if self.n_insns == 0:
             return m
@@ -49,9 +96,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 = []