add in busy_prev/next signal to work out which unit was activated
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 23 May 2019 13:23:32 +0000 (14:23 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 23 May 2019 13:23:32 +0000 (14:23 +0100)
src/experiment/score6600.py
src/scoreboard/shadow.py

index 60c729eebae57c282f4644971bc7739140f8e054..b265bf976c1e6d7fc184df6865959000f7857c2d 100644 (file)
@@ -9,7 +9,7 @@ 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, RegDecode
-from scoreboard.shadow import ShadowMatrix
+from scoreboard.shadow import ShadowMatrix, WaWGrid
 
 from compalu import ComputationUnitNoDelay
 
@@ -127,6 +127,8 @@ class FunctionUnits(Elaboratable):
         self.req_rel_o = Signal(n_int_alus, reset_less=True)
         self.fn_issue_i = Signal(n_int_alus, reset_less=True)
 
+        # Note: FURegs wr_pend_o is also outputted from here, for use in WaWGrid
+
     def elaborate(self, platform):
         m = Module()
 
@@ -147,6 +149,7 @@ class FunctionUnits(Elaboratable):
 
         m.d.comb += intfudeps.rd_pend_i.eq(intregdeps.rd_pend_o)
         m.d.comb += intfudeps.wr_pend_i.eq(intregdeps.wr_pend_o)
+        self.wr_pend_o = intregdeps.wr_pend_o # also output for use in WaWGrid
 
         m.d.comb += intfudeps.issue_i.eq(self.fn_issue_i)
         m.d.comb += intfudeps.go_rd_i.eq(self.go_rd_i)
@@ -238,6 +241,13 @@ class Scoreboard(Elaboratable):
         go_rd_rst = Signal(n_int_fus, reset_less=True)
         go_wr_rst = Signal(n_int_fus, reset_less=True)
 
+        # Write-after-Write grid: selects one shadow to enable, based
+        # on which unit(s) have writes pending and the current instruction
+        # also needing to write
+        m.submodules.wawgrid = wawgrid = WaWGrid(n_int_fus, n_int_fus)
+        busy_prev = Signal(n_int_fus)
+        busy_curr = Signal(n_int_fus)
+
         #---------
         # ok start wiring things together...
         # "now hear de word of de looord... dem bones dem bones dem dryy bones"
@@ -315,6 +325,14 @@ class Scoreboard(Elaboratable):
         # (instead of e.g. a ring buffer).
         # XXX TODO
 
+        # when written, the shadow can be cancelled (and was good)
+        m.d.comb += shadows.s_good_i[0:n_int_fus].eq(go_wr_o[0:n_int_fus])
+
+        # work out the current-activated busy unit (by recording the old one)
+        with m.If(self.issue_o): # only update busy_prev if instruction issued
+            m.d.sync += busy_prev.eq(cu.busy_o)
+        m.d.comb += busy_curr.eq(~busy_prev & cu.busy_o)
+
         #---------
         # Connect Register File(s)
         #---------
index 95dc4ad27b4cfdf6c0f74b5cd988bc1167ac61ab..fd5cb8649a44e664cd986b49d78ba48a8eb6eaa6 100644 (file)
@@ -1,6 +1,6 @@
 from nmigen.compat.sim import run_simulation
 from nmigen.cli import verilog, rtlil
-from nmigen import Module, Signal, Cat, Array, Const, Elaboratable
+from nmigen import Module, Signal, Cat, Array, Const, Elaboratable, Repl
 from nmigen.lib.coding import Decoder
 
 from nmutil.latch import SRLatch, latchregister
@@ -163,6 +163,28 @@ class ShadowMatrix(Elaboratable):
         return list(self)
 
 
+class WaWGrid(Elaboratable):
+    """ An NxM grid-selector which raises a 2D bit selected by N and M
+    """
+
+    def __init__(self, n_fus, shadow_wid):
+        self.n_fus = n_fus
+        self.shadow_wid = shadow_wid
+
+        self.shadow_i = Signal(shadow_wid, reset_less=True)
+        self.fu_i = Signal(n_fus, reset_less=True)
+
+        self.waw_o = Array(Signal(shadow_wid, name="waw_o", reset_less=True) \
+                            for f in range(n_fus))
+
+    def elaborate(self, platform):
+        m = Module()
+        for i in range(self.n_fus):
+            v = Repl(self.fu_i[i], self.shadow_wid)
+            m.d.comb += self.waw_o[i].eq(v & self.shadow_i)
+        return m
+
+
 def shadow_sim(dut):
     yield dut.dest_i.eq(1)
     yield dut.issue_i.eq(1)