reorganise ALU tests, move get_cu_inputs function to common location
[soc.git] / src / soc / fu / alu / test / test_pipe_caller.py
index 5c57679e754dca6e49bd897424d22316c5b5ee85..50e8e9b11c01153f6f3f7ebbe36b5658db67a66f 100644 (file)
@@ -6,7 +6,7 @@ import unittest
 from soc.decoder.isa.caller import ISACaller, special_sprs
 from soc.decoder.power_decoder import (create_pdecode)
 from soc.decoder.power_decoder2 import (PowerDecode2)
-from soc.decoder.power_enums import (XER_bits, Function, InternalOp)
+from soc.decoder.power_enums import (XER_bits, Function, InternalOp, CryIn)
 from soc.decoder.selectable_int import SelectableInt
 from soc.simulator.program import Program
 from soc.decoder.isa.all import ISA
@@ -24,45 +24,62 @@ class TestCase:
         self.name = name
 
 
-def set_alu_inputs(alu, 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
+def get_cu_inputs(dec2, sim):
+    """naming (res) must conform to ALUFunctionUnit input regspec
+    """
+    res = {}
 
+    # RA (or RC)
     reg1_ok = yield dec2.e.read_reg1.ok
     if reg1_ok:
         data1 = yield dec2.e.read_reg1.data
-        data1 = sim.gpr(data1).value
-    else:
-        data1 = 0
+        res['ra'] = sim.gpr(data1).value
 
-    yield alu.p.data_i.a.eq(data1)
-
-    # If there's an immediate, set the B operand to that
+    # RB (or immediate)
     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)
-
-
+        res['rb'] = sim.gpr(data2).value
 
-def set_extra_alu_inputs(alu, dec2, sim):
+    # XER.ca
     cry_in = yield dec2.e.input_carry
-    if cry_in:
+    if cry_in == CryIn.CA.value:
         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)
-        print ("extra inputs: CA/32", carry, carry32)
-    oe = yield dec2.e.oe.data & dec2.e.oe.ok
+        res['xer_ca'] = carry | (carry32<<1)
+
+    # XER.so
+    oe = yield dec2.e.oe.data[0] & dec2.e.oe.ok
     if oe:
         so = 1 if sim.spr['XER'][XER_bits['SO']] else 0
+        res['xer_so'] = so
+
+    return res
+
+
+
+def set_alu_inputs(alu, 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
+
+    inp = yield from get_cu_inputs(dec2, sim)
+    if 'ra' in inp:
+        yield alu.p.data_i.a.eq(inp['ra'])
+    if 'rb' in inp:
+        yield alu.p.data_i.b.eq(inp['rb'])
+
+    # If there's an immediate, set the B operand to that
+    imm_ok = yield dec2.e.imm_data.imm_ok
+    if imm_ok:
+        data2 = yield dec2.e.imm_data.imm
+        yield alu.p.data_i.b.eq(data2)
+
+    if 'xer_ca' in inp:
+        yield alu.p.data_i.xer_ca.eq(inp['xer_ca'])
+        print ("extra inputs: CA/32", bin(inp['xer_ca']))
+    if 'xer_so' in inp:
+        so = inp['xer_so']
         print ("extra inputs: so", so)
         yield alu.p.data_i.xer_so.eq(so)
 
@@ -210,7 +227,6 @@ class TestRunner(FHDLTestCase):
                     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
                     opname = code.split(' ')[0]
                     yield from simulator.call(opname)