remove Shadow class, replace with ShadowFn, use multi-bit SRLatch
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 29 May 2019 23:39:51 +0000 (00:39 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 29 May 2019 23:39:51 +0000 (00:39 +0100)
src/experiment/score6600.py
src/scoreboard/shadow.py
src/scoreboard/shadow_fn.py

index d9144826c73ee3408152833088efb0f1f3006419..9724210e988c3f6f85f9826cd8860ccd8965f2db 100644 (file)
@@ -717,11 +717,11 @@ def scoreboard_branch_sim(dut, alusim):
 
         if True:
             insts = []
-            #insts.append( (3, 5, 2, 0, (0, 0)) )
+            insts.append( (3, 5, 2, 0, (0, 0)) )
             branch_ok = []
             branch_fail = []
-            branch_ok.append  ( (5, 7, 5, 1, (1, 0)) )
-            #branch_ok.append( None )
+            #branch_ok.append  ( (5, 7, 5, 1, (1, 0)) )
+            branch_ok.append( None )
             branch_fail.append( (1, 1, 2, 0, (0, 1)) )
             #branch_fail.append( None )
             insts.append( (6, 4, (branch_ok, branch_fail), 4, (0, 0)) )
index 034f34fc4ffc558f562fe4b29c4ef9b1a504166c..12f20893b5accb78ac69a8c64aff8b97eb47f05c 100644 (file)
@@ -6,88 +6,6 @@ from nmigen.lib.coding import Decoder
 from scoreboard.shadow_fn import ShadowFn
 
 
-class Shadow(Elaboratable):
-    """ implements shadowing 11.5.1, p55
-
-        shadowing can be used for branches as well as exceptions (interrupts),
-        load/store hold (exceptions again), and vector-element predication
-        (once the predicate is known, which it may not be at instruction issue)
-
-        Inputs
-        * :shadow_wid:  number of shadow/fail/good/go_die sets
-
-        notes:
-        * when shadow_wid = 0, recover and shadown are Consts (i.e. do nothing)
-    """
-    def __init__(self, shadow_wid=0, syncreset=False):
-        self.shadow_wid = shadow_wid
-        self.syncreset = syncreset
-
-        if shadow_wid:
-            # inputs
-            self.issue_i = Signal(reset_less=True)
-            self.reset_i = Signal(reset_less=True)
-            self.shadow_i = Signal(shadow_wid, reset_less=True)
-            self.s_fail_i = Signal(shadow_wid, reset_less=True)
-            self.s_good_i = Signal(shadow_wid, reset_less=True)
-            # outputs
-            self.go_die_o = Signal(reset_less=True)
-            self.shadown_o = Signal(reset_less=True)
-        else:
-            # outputs when no shadowing needed
-            self.shadown_o = Const(1)
-            self.go_die_o = Const(0)
-
-    def elaborate(self, platform):
-        m = Module()
-        s_latches = []
-        for i in range(self.shadow_wid):
-            sh = ShadowFn(self.syncreset)
-            setattr(m.submodules, "shadow%d" % i, sh)
-            s_latches.append(sh)
-
-        # shadow / recover (optional: shadow_wid > 0)
-        if self.shadow_wid:
-            i_l = []
-            d_l = []
-            fail_l = []
-            good_l = []
-            shi_l = []
-            sho_l = []
-            rec_l = []
-            # get list of latch signals. really must be a better way to do this
-            for l in s_latches:
-                i_l.append(l.issue_i)
-                d_l.append(l.reset_i)
-                shi_l.append(l.shadow_i)
-                fail_l.append(l.s_fail_i)
-                good_l.append(l.s_good_i)
-                sho_l.append(l.shadow_o)
-                rec_l.append(l.recover_o)
-            m.d.comb += Cat(*i_l).eq(Repl(self.issue_i, self.shadow_wid))
-            m.d.comb += Cat(*d_l).eq(Repl(self.reset_i, self.shadow_wid))
-            m.d.comb += Cat(*fail_l).eq(self.s_fail_i)
-            m.d.comb += Cat(*good_l).eq(self.s_good_i)
-            m.d.comb += Cat(*shi_l).eq(self.shadow_i)
-            m.d.comb += self.shadown_o.eq(~(Cat(*sho_l).bool()))
-            m.d.comb += self.go_die_o.eq(Cat(*rec_l).bool())
-
-        return m
-
-    def __iter__(self):
-        if self.shadow_wid:
-            yield self.reset_i
-            yield self.issue_i
-            yield self.shadow_i
-            yield self.s_fail_i
-            yield self.s_good_i
-        yield self.go_die_o
-        yield self.shadown_o
-
-    def ports(self):
-        return list(self)
-
-
 class ShadowMatrix(Elaboratable):
     """ Matrix of Shadow Functions.  One per FU.
 
@@ -138,7 +56,7 @@ class ShadowMatrix(Elaboratable):
         m = Module()
         shadows = []
         for i in range(self.n_fus):
-            sh = Shadow(self.shadow_wid, self.syncreset)
+            sh = ShadowFn(self.shadow_wid, self.syncreset)
             setattr(m.submodules, "sh%d" % i, sh)
             shadows.append(sh)
             # connect shadow/fail/good to all shadows
index ae87e614000f4689ab6a75c2927548f248488f70..69a56a5ceec13014e07a3d0e74715e9506a097e5 100644 (file)
@@ -1,54 +1,75 @@
 from nmigen.compat.sim import run_simulation
 from nmigen.cli import verilog, rtlil
-from nmigen import Module, Signal, Cat, Elaboratable
+from nmigen import Module, Signal, Cat, Repl, Const, Elaboratable
 from nmutil.latch import SRLatch
 
 
 class ShadowFn(Elaboratable):
     """ implements shadowing 11.5.1, p55, just the individual shadow function
+
+        shadowing can be used for branches as well as exceptions (interrupts),
+        load/store hold (exceptions again), and vector-element predication
+        (once the predicate is known, which it may not be at instruction issue)
+
+        Inputs
+        * :shadow_wid:  number of shadow/fail/good/go_die sets
+
+        notes:
+        * when shadow_wid = 0, recover and shadown are Consts (i.e. do nothing)
     """
-    def __init__(self, syncreset=False):
+    def __init__(self, slen, syncreset=False):
 
+        self.slen = slen
         self.syncreset = syncreset
 
-        # inputs
-        self.issue_i = Signal(reset_less=True)
-        self.shadow_i  = Signal(reset_less=True)
-        self.reset_i  = Signal(reset_less=True)
-        self.s_fail_i  = Signal(reset_less=True)
-        self.s_good_i  = Signal(reset_less=True)
-
-        # outputs
-        self.shadow_o = Signal(reset_less=True)
-        self.recover_o = Signal(reset_less=True)
+        if self.slen:
+            # inputs
+            self.issue_i = Signal(reset_less=True)
+            self.shadow_i  = Signal(slen, reset_less=True)
+            self.reset_i  = Signal(reset_less=True)
+            self.s_fail_i  = Signal(slen, reset_less=True)
+            self.s_good_i  = Signal(slen, reset_less=True)
+
+            # outputs
+            self.shadown_o = Signal(reset_less=True)
+            self.go_die_o = Signal(reset_less=True)
+        else:
+            # outputs when no shadowing needed
+            self.shadown_o = Const(1)
+            self.go_die_o = Const(0)
 
     def elaborate(self, platform):
         m = Module()
-        m.submodules.sl = sl = SRLatch(sync=False)
+        if self.slen == 0:
+            return
+
+        m.submodules.sl = sl = SRLatch(sync=False, llen=self.slen)
 
-        reset_r = Signal()
+        r_ext = Repl(self.reset_i, self.slen)
+        reset_r = Signal(self.slen)
         if self.syncreset:
-            m.d.comb += reset_r.eq(self.s_good_i | self.s_fail_i | self.reset_i)
+            m.d.comb += reset_r.eq(self.s_good_i | self.s_fail_i | r_ext)
         else:
-            m.d.comb += reset_r.eq(self.s_good_i | self.s_fail_i | self.reset_i)
+            m.d.comb += reset_r.eq(self.s_good_i | self.s_fail_i | r_ext)
 
-        m.d.comb += sl.s.eq(self.shadow_i & self.issue_i & \
+        i_ext = Repl(self.issue_i, self.slen)
+        m.d.comb += sl.s.eq(self.shadow_i & i_ext & \
                             ~self.s_good_i & ~reset_r)
-        m.d.comb += sl.r.eq(self.reset_i | reset_r | self.s_good_i | \
-                            (self.issue_i & ~self.shadow_i))
-        m.d.comb += self.recover_o.eq(sl.qlq & self.s_fail_i)
-        m.d.comb += self.shadow_o.eq(sl.qlq)
+        m.d.comb += sl.r.eq(r_ext | reset_r | self.s_good_i | \
+                            (i_ext & ~self.shadow_i))
+        m.d.comb += self.go_die_o.eq((sl.qlq & self.s_fail_i).bool())
+        m.d.comb += self.shadown_o.eq(~sl.qlq.bool())
 
         return m
 
     def __iter__(self):
         yield self.issue_i
-        yield self.s_reset_i
+        yield self.reset_i
         yield self.shadow_i
         yield self.s_fail_i
         yield self.s_good_i
-        yield self.shadow_o
-        yield self.recover_o
+        yield self.shadown_o
+        yield self.go_die_o
 
     def ports(self):
         return list(self)
@@ -78,7 +99,7 @@ def shadow_fn_unit_sim(dut):
 
 
 def test_shadow_fn_unit():
-    dut = ShadowFn()
+    dut = ShadowFn(4)
     vl = rtlil.convert(dut, ports=dut.ports())
     with open("test_shadow_fn_unit.il", "w") as f:
         f.write(vl)