have to bring in a reset signal into the shadow units to get them to go to
[soc.git] / src / experiment / score6600.py
index c7a36b26cf4e5e4e32771e7d1114bc0750cafe96..eca0ae22486490ff0e3a8713edf7a4d170c27a5d 100644 (file)
@@ -16,6 +16,7 @@ from alu_hier import ALU, BranchALU
 from nmutil.latch import SRLatch
 
 from random import randint, seed
+from copy import deepcopy
 
 
 class CompUnits(Elaboratable):
@@ -52,7 +53,7 @@ class CompUnits(Elaboratable):
 
         # Branch ALU and CU
         self.bgt = BranchALU(self.rwid)
-        self.br1 = ComputationUnitNoDelay(self.rwid, 2, self.bgt)
+        self.br1 = ComputationUnitNoDelay(self.rwid, 3, self.bgt)
 
     def elaborate(self, platform):
         m = Module()
@@ -77,7 +78,7 @@ class CompUnits(Elaboratable):
         comb += comp2.oper_i.eq(Const(1, 2)) # op=sub
         comb += comp3.oper_i.eq(Const(2, 2)) # op=mul
         comb += comp4.oper_i.eq(Const(3, 2)) # op=shf
-        comb += br1.oper_i.eq(Const(0, 2)) # op=bgt
+        comb += br1.oper_i.eq(Const(4, 3)) # op=bgt
 
         go_rd_l = []
         go_wr_l = []
@@ -142,6 +143,7 @@ class FunctionUnits(Elaboratable):
 
         self.go_rd_i = Signal(n_int_alus, reset_less=True)
         self.go_wr_i = Signal(n_int_alus, reset_less=True)
+        self.go_die_i = Signal(n_int_alus, reset_less=True)
         self.req_rel_o = Signal(n_int_alus, reset_less=True)
         self.fn_issue_i = Signal(n_int_alus, reset_less=True)
 
@@ -174,6 +176,7 @@ class FunctionUnits(Elaboratable):
         comb += intfudeps.issue_i.eq(self.fn_issue_i)
         comb += intfudeps.go_rd_i.eq(self.go_rd_i)
         comb += intfudeps.go_wr_i.eq(self.go_wr_i)
+        comb += intfudeps.go_die_i.eq(self.go_die_i)
         comb += self.readable_o.eq(intfudeps.readable_o)
         comb += self.writable_o.eq(intfudeps.writable_o)
 
@@ -184,6 +187,7 @@ class FunctionUnits(Elaboratable):
 
         comb += intregdeps.go_rd_i.eq(self.go_rd_i)
         comb += intregdeps.go_wr_i.eq(self.go_wr_i)
+        comb += intregdeps.go_die_i.eq(self.go_die_i)
         comb += intregdeps.issue_i.eq(self.fn_issue_i)
 
         comb += self.dest_rsel_o.eq(intregdeps.dest_rsel_o)
@@ -272,9 +276,6 @@ class Scoreboard(Elaboratable):
         m.submodules.shadows = shadows = ShadowMatrix(n_int_fus, n_int_fus)
         m.submodules.bshadow = bshadow = ShadowMatrix(n_int_fus, 1)
 
-        # combined go_rd/wr + go_die (go_die used to reset latches)
-        go_rd_rst = Signal(n_int_fus, reset_less=True)
-        go_wr_rst = Signal(n_int_fus, reset_less=True)
         # record previous instruction to cast shadow on current instruction
         fn_issue_prev = Signal(n_int_fus)
         prev_shadow = Signal(n_int_fus)
@@ -318,6 +319,19 @@ class Scoreboard(Elaboratable):
         comb += issueunit.i.busy_i.eq(cu.busy_o)
         comb += self.busy_o.eq(cu.busy_o.bool())
 
+        #---------
+        # merge shadow matrices outputs
+        #---------
+        
+        # these are explained in ShadowMatrix docstring, and are to be
+        # connected to the FUReg and FUFU Matrices, to get them to reset
+        anydie = Signal(n_int_fus, reset_less=True)
+        allshadown = Signal(n_int_fus, reset_less=True)
+        shreset = Signal(n_int_fus, reset_less=True)
+        comb += allshadown.eq(shadows.shadown_o & bshadow.shadown_o)
+        comb += anydie.eq(shadows.go_die_o | bshadow.go_die_o)
+        comb += shreset.eq(bspec.match_g_o | bspec.match_f_o)
+
         #---------
         # connect fu-fu matrix
         #---------
@@ -327,9 +341,11 @@ class Scoreboard(Elaboratable):
         go_wr_o = intpick1.go_wr_o
         go_rd_i = intfus.go_rd_i
         go_wr_i = intfus.go_wr_i
+        go_die_i = intfus.go_die_i
         # NOTE: connect to the shadowed versions so that they can "die" (reset)
-        comb += go_rd_i[0:n_int_fus].eq(go_rd_rst[0:n_int_fus]) # rd
-        comb += go_wr_i[0:n_int_fus].eq(go_wr_rst[0:n_int_fus]) # wr
+        comb += go_rd_i[0:n_int_fus].eq(go_rd_o[0:n_int_fus]) # rd
+        comb += go_wr_i[0:n_int_fus].eq(go_wr_o[0:n_int_fus]) # wr
+        comb += go_die_i[0:n_int_fus].eq(anydie[0:n_int_fus]) # die
 
         # Connect Picker
         #---------
@@ -345,17 +361,7 @@ class Scoreboard(Elaboratable):
         #---------
 
         comb += shadows.issue_i.eq(fn_issue_o)
-        # these are explained in ShadowMatrix docstring, and are to be
-        # connected to the FUReg and FUFU Matrices, to get them to reset
-        # NOTE: do NOT connect these to the Computation Units.  The CUs need to
-        # do something slightly different (due to the revolving-door SRLatches)
-        anydie = Signal(n_int_fus, reset_less=True)
-        allshadown = Signal(n_int_fus, reset_less=True)
-        comb += allshadown.eq(shadows.shadown_o & bshadow.shadown_o)
-        comb += anydie.eq(shadows.go_die_o | bshadow.go_die_o)
-        comb += go_rd_rst.eq(go_rd_o | anydie)
-        comb += go_wr_rst.eq(go_wr_o | anydie)
-
+        comb += shadows.reset_i[0:n_int_fus].eq(shreset[0:n_int_fus])
         #---------
         # NOTE; this setup is for the instruction order preservation...
 
@@ -389,10 +395,13 @@ class Scoreboard(Elaboratable):
 
         # issue captures shadow_i (if enabled)
         comb += bshadow.issue_i.eq(fn_issue_o)
+        comb += bshadow.reset_i[0:n_int_fus].eq(shreset[0:n_int_fus])
 
         # instruction being issued (fn_issue_o) has a shadow cast by the branch
         with m.If(self.branch_succ_i | self.branch_fail_i):
-            comb += bshadow.shadow_i[fn_issue_o][0].eq(1)
+            for i in range(n_int_fus):
+                with m.If(fn_issue_o & (Const(1<<i))):
+                    comb += bshadow.shadow_i[i][0].eq(1)
 
         # finally, we need an indicator to the test infrastructure as to
         # whether the branch succeeded or failed, plus, link up to the
@@ -401,9 +410,9 @@ class Scoreboard(Elaboratable):
         with m.If(cu.br1.issue_i):
             sync += bspec.active_i.eq(1)
         with m.If(self.branch_succ_i):
-            comb += bspec.good_i.eq(fn_issue_o & 0xf)
+            comb += bspec.good_i.eq(fn_issue_o & 0x1f)
         with m.If(self.branch_fail_i):
-            comb += bspec.fail_i.eq(fn_issue_o & 0xf)
+            comb += bspec.fail_i.eq(fn_issue_o & 0x1f)
 
         # branch is active (TODO: a better signal: this is over-using the
         # go_write signal - actually the branch should not be "writing")
@@ -490,9 +499,11 @@ class RegSim:
         elif op == IBNE:
             val = int(src1 != src2)
         val &= maxbits
-        self.regs[dest] = val
+        self.setval(dest, val)
+        return val
 
     def setval(self, dest, val):
+        print ("sim setval", dest, hex(val))
         self.regs[dest] = val
 
     def dump(self, dut):
@@ -576,7 +587,7 @@ def scoreboard_branch_sim(dut, alusim):
 
     yield dut.int_store_i.eq(1)
 
-    for i in range(2):
+    for i in range(1):
 
         # set random values in the registers
         for i in range(1, dut.n_regs):
@@ -586,7 +597,9 @@ def scoreboard_branch_sim(dut, alusim):
             alusim.setval(i, val)
 
         # create some instructions: branches create a tree
-        insts = create_random_ops(dut, 1, True)
+        insts = create_random_ops(dut, 0, True)
+        #insts.append((6, 6, 1, 2, (0, 0)))
+        insts.append((4, 3, 3, 0, (0, 0)))
 
         src1 = randint(1, dut.n_regs-1)
         src2 = randint(1, dut.n_regs-1)
@@ -598,13 +611,15 @@ def scoreboard_branch_sim(dut, alusim):
 
         insts.append((src1, src2, (branch_ok, branch_fail), op, (0, 0)))
 
+        siminsts = deepcopy(insts)
+
         # issue instruction(s)
         i = -1
         instrs = insts
         branch_direction = 0
         while instrs:
             i += 1
-            (src1, src2, dest, op, (shadow_on, shadow_off)) = insts.pop()
+            (src1, src2, dest, op, (shadow_on, shadow_off)) = insts.pop(0)
             if branch_direction == 1 and shadow_off:
                 continue # branch was "success" and this is a "failed"... skip
             if branch_direction == 2 and shadow_on:
@@ -612,7 +627,7 @@ def scoreboard_branch_sim(dut, alusim):
             is_branch = op >= 4
             if is_branch:
                 branch_ok, branch_fail = dest
-                dest = -1
+                dest = src2
                 # ok zip up the branch success / fail instructions and
                 # drop them into the queue, one marked "to have branch success"
                 # the other to be marked shadow branch "fail".
@@ -620,9 +635,10 @@ def scoreboard_branch_sim(dut, alusim):
                 for ok, fl in zip(branch_ok, branch_fail):
                     instrs.append((ok[0], ok[1], ok[2], ok[3], (1, 0)))
                     instrs.append((fl[0], fl[1], fl[2], fl[3], (0, 1)))
-            print ("instr %d: (%d, %d, %d, %d)" % (i, src1, src2, dest, op))
+            print ("instr %d: (%d, %d, %d, %d, (%d, %d))" % \
+                            (i, src1, src2, dest, op, shadow_on, shadow_off))
             yield from int_instr(dut, op, src1, src2, dest,
-                  shadow_on, shadow_off)
+                                 shadow_on, shadow_off)
             yield
             yield from wait_for_issue(dut)
             branch_direction = yield dut.branch_direction_o # way branch went
@@ -631,17 +647,20 @@ def scoreboard_branch_sim(dut, alusim):
         yield
         yield from wait_for_busy_clear(dut)
 
-        for (src1, src2, dest, op, (shadow_on, shadow_off)) in insts:
+        i = -1
+        for (src1, src2, dest, op, (shadow_on, shadow_off)) in siminsts:
+            i += 1
             is_branch = op >= 4
             if is_branch:
                 branch_ok, branch_fail = dest
-                dest = None
+                dest = src2
+            print ("sim %d: (%d, %d, %d, %d)" % (i, src1, src2, dest, op))
             branch_res = alusim.op(op, src1, src2, dest)
             if is_branch:
                 if branch_res:
-                    insts.append(branch_ok)
+                    siminsts += branch_ok
                 else:
-                    insts.append(branch_fail)
+                    siminsts += branch_fail
 
         # check status
         yield from alusim.check(dut)