make bgt accessible outside of CU
[soc.git] / src / experiment / score6600.py
index f47836686d21b2bb655a5e94518ea3ceb34be690..9966e9ac06f4a07615923e5a49d21adc886999c0 100644 (file)
@@ -13,7 +13,7 @@ from scoreboard.shadow import ShadowMatrix, WaWGrid
 
 from compalu import ComputationUnitNoDelay
 
-from alu_hier import ALU
+from alu_hier import ALU, BranchALU
 from nmutil.latch import SRLatch
 
 from random import randint
@@ -26,23 +26,34 @@ class CompUnits(Elaboratable):
 
             * :rwid:   bit width of register file(s) - both FP and INT
             * :n_units: number of ALUs
+
+            Note: bgt unit is returned so that a shadow unit can be created
+            for it
+
         """
         self.n_units = n_units
         self.rwid = rwid
 
+        # inputs
         self.issue_i = Signal(n_units, reset_less=True)
         self.go_rd_i = Signal(n_units, reset_less=True)
         self.go_wr_i = Signal(n_units, reset_less=True)
         self.shadown_i = Signal(n_units, reset_less=True)
         self.go_die_i = Signal(n_units, reset_less=True)
+
+        # outputs
         self.busy_o = Signal(n_units, reset_less=True)
         self.rd_rel_o = Signal(n_units, reset_less=True)
         self.req_rel_o = Signal(n_units, reset_less=True)
 
+        # in/out register data (note: not register#, actual data)
         self.dest_o = Signal(rwid, reset_less=True)
         self.src1_data_i = Signal(rwid, reset_less=True)
         self.src2_data_i = Signal(rwid, reset_less=True)
 
+        # Branch ALU
+        self.bgt = BranchALU(self.rwid)
+
     def elaborate(self, platform):
         m = Module()
 
@@ -51,16 +62,20 @@ class CompUnits(Elaboratable):
         sub = ALU(self.rwid)
         mul = ALU(self.rwid)
         shf = ALU(self.rwid)
+        bgt = self.bgt
+
         m.submodules.comp1 = comp1 = ComputationUnitNoDelay(self.rwid, 2, add)
         m.submodules.comp2 = comp2 = ComputationUnitNoDelay(self.rwid, 2, sub)
         m.submodules.comp3 = comp3 = ComputationUnitNoDelay(self.rwid, 2, mul)
         m.submodules.comp4 = comp4 = ComputationUnitNoDelay(self.rwid, 2, shf)
-        int_alus = [comp1, comp2, comp3, comp4]
+        m.submodules.br1 = br1 = ComputationUnitNoDelay(self.rwid, 2, bgt)
+        int_alus = [comp1, comp2, comp3, comp4, br1]
 
         m.d.comb += comp1.oper_i.eq(Const(0, 2)) # op=add
         m.d.comb += comp2.oper_i.eq(Const(1, 2)) # op=sub
         m.d.comb += comp3.oper_i.eq(Const(2, 2)) # op=mul
         m.d.comb += comp4.oper_i.eq(Const(3, 2)) # op=shf
+        m.d.comb += br1.oper_i.eq(Const(0, 2)) # op=bgt
 
         go_rd_l = []
         go_wr_l = []
@@ -228,9 +243,10 @@ class Scoreboard(Elaboratable):
         fp_src2 = self.fpregs.read_port("src2")
 
         # Int ALUs and Comp Units
-        n_int_alus = 4
+        n_int_alus = 5
         m.submodules.cu = cu = CompUnits(self.rwid, n_int_alus)
         m.d.comb += cu.go_die_i.eq(0)
+        bgt = cu.bgt # get at the branch computation unit
 
         # Int FUs
         m.submodules.intfus = intfus = FunctionUnits(self.n_regs, n_int_alus)
@@ -250,8 +266,9 @@ class Scoreboard(Elaboratable):
         m.submodules.issueunit = issueunit
 
         # Shadow Matrix.  currently n_int_fus shadows, to be used for
-        # write-after-write hazards
-        m.submodules.shadows = shadows = ShadowMatrix(n_int_fus, n_int_fus)
+        # write-after-write hazards.  NOTE: there is one extra for branches,
+        # so the shadow width is increased by 1
+        m.submodules.shadows = shadows = ShadowMatrix(n_int_fus, 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)
@@ -347,7 +364,7 @@ class Scoreboard(Elaboratable):
         # if the previous is completed (!busy) don't cast the shadow!
         m.d.comb += prev_shadow.eq(~fn_issue_o & fn_issue_prev & cu.busy_o)
         for i in range(n_int_fus):
-            m.d.comb += shadows.shadow_i[i].eq(prev_shadow)
+            m.d.comb += shadows.shadow_i[i][0:n_int_fus].eq(prev_shadow)
 
         #---------
         # Connect Register File(s)
@@ -389,7 +406,7 @@ IADD = 0
 ISUB = 1
 IMUL = 2
 ISHF = 3
-IBGE = 4
+IBGT = 4
 IBLT = 5
 IBEQ = 6
 IBNE = 7
@@ -401,8 +418,8 @@ class RegSim:
 
     def op(self, op, src1, src2, dest):
         maxbits = (1 << self.rwidth) - 1
-        src1 = self.regs[src1]
-        src2 = self.regs[src2]
+        src1 = self.regs[src1] & maxbits
+        src2 = self.regs[src2] & maxbits
         if op == IADD:
             val = src1 + src2
         elif op == ISUB:
@@ -411,7 +428,7 @@ class RegSim:
             val = src1 * src2
         elif op == ISHF:
             val = src1 >> (src2 & maxbits)
-        elif op == IBGE:
+        elif op == IBGT:
             val = int(src1 > src2)
         elif op == IBLT:
             val = int(src1 < src2)
@@ -579,7 +596,7 @@ def scoreboard_sim(dut, alusim):
 
     yield dut.int_store_i.eq(1)
 
-    for i in range(2):
+    for i in range(20):
 
         # set random values in the registers
         for i in range(1, dut.n_regs):
@@ -603,7 +620,7 @@ def scoreboard_sim(dut, alusim):
                 #src2 = 3
                 #dest = 2
 
-                op = randint(0, 3)
+                op = randint(0, 4)
                 #op = i % 2
                 #op = 0
 
@@ -680,18 +697,6 @@ def scoreboard_sim(dut, alusim):
         yield from alusim.dump(dut)
 
 
-def explore_groups(dut):
-    from nmigen.hdl.ir import Fragment
-    from nmigen.hdl.xfrm import LHSGroupAnalyzer
-
-    fragment = dut.elaborate(platform=None)
-    fr = Fragment.get(fragment, platform=None)
-
-    groups = LHSGroupAnalyzer()(fragment._statements)
-
-    print (groups)
-
-
 def test_scoreboard():
     dut = Scoreboard(16, 8)
     alusim = RegSim(16, 8)