debugging test_alu_compunit.py
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 28 May 2020 11:55:58 +0000 (12:55 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 28 May 2020 11:55:58 +0000 (12:55 +0100)
src/soc/experiment/compalu_multi.py
src/soc/fu/compunits/test/test_alu_compunit.py
src/soc/fu/regspec.py

index 403748127f74f7c9fce51f6e74ab073913e21c9b..815ff15a77b98a8e57c56a450d225d89aa5d278c 100644 (file)
@@ -52,6 +52,7 @@ class CompUnitRecord(RegSpec, RecordObject):
         RegSpec.__init__(self, rwid, n_src, n_dst)
         RecordObject.__init__(self, name)
         self._subkls = subkls
+        n_src, n_dst = self._n_src, self._n_dst
 
         # create source operands
         src = []
@@ -101,9 +102,10 @@ class MultiCompUnit(RegSpecALUAPI, Elaboratable):
         * :n_dst:       number of destination operands
         """
         RegSpecALUAPI.__init__(self, rwid, alu)
-        self.n_src, self.n_dst = n_src, n_dst
         self.opsubsetkls = opsubsetkls
         self.cu = cu = CompUnitRecord(opsubsetkls, rwid, n_src, n_dst)
+        n_src, n_dst = self.n_src, self.n_dst = cu._n_src, cu._n_dst
+        print ("n_src %d n_dst %d" % (self.n_src, self.n_dst))
 
         # convenience names for src operands
         for i in range(n_src):
@@ -213,7 +215,7 @@ class MultiCompUnit(RegSpecALUAPI, Elaboratable):
         drl = []
         for i in range(self.n_dst):
             name = "data_r%d" % i
-            data_r = Signal(self.cu._get_srcwid(i), name=name, reset_less=True)
+            data_r = Signal(self.cu._get_dstwid(i), name=name, reset_less=True)
             latchregister(m, self.get_out(i), data_r, req_l.q[i], name + "_l")
             drl.append(data_r)
 
@@ -225,6 +227,7 @@ class MultiCompUnit(RegSpecALUAPI, Elaboratable):
         # 2nd operand in the input "regspec".  see for example
         # soc.fu.alu.pipe_data.ALUInputData
         sl = []
+        print ("src_i", self.src_i)
         for i in range(self.n_src):
             sl.append([self.src_i[i], self.get_in(i), src_l.q[i], Const(1,1)])
 
index 0d83e4c5a7f11c4a64ca60ce9d62f6baa539eb63..c14d683f8cbe7efa179d4e6a63dcaec56771696e 100644 (file)
@@ -12,11 +12,38 @@ from soc.simulator.program import Program
 from soc.decoder.isa.all import ISA
 
 from soc.fu.alu.test.test_pipe_caller import TestCase, ALUTestCase, test_data
-from soc.fu.compunits import ALUFunctionUnit
+from soc.fu.compunits.compunits import ALUFunctionUnit
 import random
 
-
-def set_alu_inputs(alu, dec2, sim):
+def set_cu_input(cu, idx, data):
+    yield cu.src_i[idx].eq(data)
+    while True:
+        rd_rel_o = yield cu.rd.rel[idx]
+        print ("rd_rel %d wait" % idx, rd_rel_o)
+        if rd_rel_o:
+            break
+        yield
+    yield cu.rd.go[idx].eq(1)
+    yield
+    yield cu.rd.go[idx].eq(0)
+
+
+def get_cu_output(cu, idx):
+    while True:
+        wr_relall_o = yield cu.wr.rel
+        wr_rel_o = yield cu.wr.rel[idx]
+        print ("wr_rel %d wait" % idx, hex(wr_relall_o), wr_rel_o)
+        if wr_rel_o:
+            break
+        yield
+    yield cu.wr.go[idx].eq(1)
+    yield
+    result = yield cu.dst_i[idx]
+    yield cu.wr.go[idx].eq(0)
+    return result
+
+
+def set_cu_inputs(cu, dec2, sim):
     # TODO: see https://bugs.libre-soc.org/show_bug.cgi?id=305#c43
     # detect the immediate here (with m.If(self.i.ctx.op.imm_data.imm_ok))
     # and place it into data_i.b
@@ -33,29 +60,35 @@ def set_alu_inputs(alu, dec2, sim):
     else:
         data1 = 0
 
-    yield alu.p.data_i.a.eq(data1)
+    if reg3_ok or reg1_ok:
+        yield from set_cu_input(cu, 0, data1)
 
     # If there's an immediate, set the B operand to that
     reg2_ok = yield dec2.e.read_reg2.ok
-    imm_ok = yield dec2.e.imm_data.imm_ok
-    if imm_ok:
-        data2 = yield dec2.e.imm_data.imm
-    elif reg2_ok:
+    if reg2_ok:
         data2 = yield dec2.e.read_reg2.data
         data2 = sim.gpr(data2).value
     else:
         data2 = 0
-    yield alu.p.data_i.b.eq(data2)
+
+    if reg2_ok:
+        yield from set_cu_input(cu, 1, data2)
 
 
+def set_operand(cu, dec2, sim):
+    yield from cu.oper_i.eq_from_execute1(dec2.e)
+    yield cu.issue_i.eq(1)
+    yield
+    yield cu.issue_i.eq(0)
+    yield
 
-def set_extra_alu_inputs(alu, dec2, sim):
+
+def set_extra_cu_inputs(cu, dec2, sim):
     carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0
     carry32 = 1 if sim.spr['XER'][XER_bits['CA32']] else 0
-    yield alu.p.data_i.xer_ca[0].eq(carry)
-    yield alu.p.data_i.xer_ca[1].eq(carry32)
+    yield from set_cu_input(cu, 2, carry | (carry32<<1))
     so = 1 if sim.spr['XER'][XER_bits['SO']] else 0
-    yield alu.p.data_i.xer_so.eq(so)
+    yield from set_cu_input(cu, 3, so)
 
 
 
@@ -74,9 +107,6 @@ class TestRunner(FHDLTestCase):
         m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
         m.submodules.cu = cu = ALUFunctionUnit()
 
-        comb += cu.oper_i.eq_from_execute1(pdecode2.e)
-        comb += alu.p.valid_i.eq(1)
-        comb += alu.n.ready_i.eq(1)
         comb += pdecode2.dec.raw_opcode_in.eq(instruction)
         sim = Simulator(m)
 
@@ -86,11 +116,11 @@ class TestRunner(FHDLTestCase):
                 print(test.name)
                 program = test.program
                 self.subTest(test.name)
-                simulator = ISA(pdecode2, test.regs, test.sprs, 0)
+                sim = ISA(pdecode2, test.regs, test.sprs, 0)
                 gen = program.generate_instructions()
                 instructions = list(zip(gen, program.assembly.splitlines()))
 
-                index = simulator.pc.CIA.value//4
+                index = sim.pc.CIA.value//4
                 while index < len(instructions):
                     ins, code = instructions[index]
 
@@ -103,55 +133,51 @@ class TestRunner(FHDLTestCase):
                     yield Settle()
                     fn_unit = yield pdecode2.e.fn_unit
                     self.assertEqual(fn_unit, Function.ALU.value)
-                    yield from set_alu_inputs(alu, pdecode2, simulator)
-                    yield from set_extra_alu_inputs(alu, pdecode2, simulator)
+                    yield from set_operand(cu, pdecode2, sim)
+                    yield from set_cu_inputs(cu, pdecode2, sim)
+                    yield from set_extra_cu_inputs(cu, pdecode2, sim)
                     yield
                     opname = code.split(' ')[0]
-                    yield from simulator.call(opname)
-                    index = simulator.pc.CIA.value//4
+                    yield from sim.call(opname)
+                    index = sim.pc.CIA.value//4
 
-                    vld = yield alu.n.valid_o
-                    while not vld:
-                        yield
-                        vld = yield alu.n.valid_o
-                    yield
-                    alu_out = yield alu.n.data_o.o.data
                     out_reg_valid = yield pdecode2.e.write_reg.ok
                     if out_reg_valid:
                         write_reg_idx = yield pdecode2.e.write_reg.data
-                        expected = simulator.gpr(write_reg_idx).value
-                        print(f"expected {expected:x}, actual: {alu_out:x}")
-                        self.assertEqual(expected, alu_out, code)
-                    yield from self.check_extra_alu_outputs(alu, pdecode2,
-                                                            simulator, code)
+                        expected = sim.gpr(write_reg_idx).value
+                        cu_out = yield from get_cu_output(cu, 0)
+                        print(f"expected {expected:x}, actual: {cu_out:x}")
+                        self.assertEqual(expected, cu_out, code)
+                    yield from self.check_extra_cu_outputs(cu, pdecode2,
+                                                            sim, code)
 
         sim.add_sync_process(process)
         with sim.write_vcd("simulator.vcd", "simulator.gtkw",
                             traces=[]):
             sim.run()
 
-    def check_extra_alu_outputs(self, alu, dec2, sim, code):
+    def check_extra_cu_outputs(self, cu, dec2, sim, code):
         rc = yield dec2.e.rc.data
         if rc:
             cr_expected = sim.crl[0].get_range().value
-            cr_actual = yield alu.n.data_o.cr0.data
+            cr_actual = yield cu.n.data_o.cr0.data
             self.assertEqual(cr_expected, cr_actual, code)
 
         op = yield dec2.e.insn_type
         if op == InternalOp.OP_CMP.value or \
            op == InternalOp.OP_CMPEQB.value:
             bf = yield dec2.dec.BF
-            cr_actual = yield alu.n.data_o.cr0.data
+            cr_actual = yield cu.n.data_o.cr0.data
             cr_expected = sim.crl[bf].get_range().value
             self.assertEqual(cr_expected, cr_actual, code)
 
         cry_out = yield dec2.e.output_carry
         if cry_out:
             expected_carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0
-            real_carry = yield alu.n.data_o.xer_ca.data[0] # XXX CO not CO32
+            real_carry = yield cu.n.data_o.xer_ca.data[0] # XXX CO not CO32
             self.assertEqual(expected_carry, real_carry, code)
             expected_carry32 = 1 if sim.spr['XER'][XER_bits['CA32']] else 0
-            real_carry32 = yield alu.n.data_o.xer_ca.data[1] # XXX CO32
+            real_carry32 = yield cu.n.data_o.xer_ca.data[1] # XXX CO32
             self.assertEqual(expected_carry32, real_carry32, code)
 
 
index 009f1fbc5e63caa579f3fbf3337f54941760c7df..e7a4cf8e3d88936f0aba3c6b550a943aaab1d692 100644 (file)
@@ -19,6 +19,7 @@ which MultiCompUnit port, how wide the connection is, and so on.
 
 
 def get_regspec_bitwidth(regspec, srcdest, idx):
+    print ("get_regspec_bitwidth", regspec, srcdest, idx)
     bitspec = regspec[srcdest][idx]
     wid = 0
     print (bitspec)