From: Luke Kenneth Casson Leighton Date: Sun, 31 May 2020 23:07:42 +0000 (+0100) Subject: add logical compunit test X-Git-Tag: div_pipeline~705 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3924f545019e566c5af1d7d067286ee374a3c7ed;p=soc.git add logical compunit test --- diff --git a/src/soc/fu/compunits/compunits.py b/src/soc/fu/compunits/compunits.py index bfaa693a..d40549d5 100644 --- a/src/soc/fu/compunits/compunits.py +++ b/src/soc/fu/compunits/compunits.py @@ -48,6 +48,9 @@ from soc.experiment.compalu_multi import MultiCompUnit from soc.fu.alu.pipeline import ALUBasePipe from soc.fu.alu.pipe_data import ALUPipeSpec +from soc.fu.logical.pipeline import LogicalBasePipe +from soc.fu.logical.pipe_data import LogicalPipeSpec + from soc.fu.cr.pipeline import CRBasePipe from soc.fu.cr.pipe_data import CRPipeSpec @@ -97,6 +100,9 @@ class FunctionUnitBaseMulti: class ALUFunctionUnit(FunctionUnitBaseSingle): def __init__(self): super().__init__(ALUPipeSpec, ALUBasePipe) +class LogicalFunctionUnit(FunctionUnitBaseSingle): + def __init__(self): super().__init__(LogicalPipeSpec, LogicalBasePipe) + class CRFunctionUnit(FunctionUnitBaseSingle): def __init__(self): super().__init__(CRPipeSpec, CRBasePipe) diff --git a/src/soc/fu/compunits/test/test_alu_compunit.py b/src/soc/fu/compunits/test/test_alu_compunit.py index da867e77..840bda32 100644 --- a/src/soc/fu/compunits/test/test_alu_compunit.py +++ b/src/soc/fu/compunits/test/test_alu_compunit.py @@ -1,5 +1,5 @@ import unittest -from soc.decoder.power_enums import (XER_bits,) +from soc.decoder.power_enums import (XER_bits, Function) # XXX bad practice: use of global variables from soc.fu.alu.test.test_pipe_caller import ALUTestCase # creates the tests @@ -11,7 +11,8 @@ from soc.fu.compunits.test.test_compunit import TestRunner class ALUTestRunner(TestRunner): def __init__(self, test_data): - super().__init__(test_data, ALUFunctionUnit, self) + super().__init__(test_data, ALUFunctionUnit, self, + Function.ALU) def get_cu_inputs(self, dec2, sim): """naming (res) must conform to ALUFunctionUnit input regspec diff --git a/src/soc/fu/compunits/test/test_compunit.py b/src/soc/fu/compunits/test/test_compunit.py index 06aef9fe..62d2f2aa 100644 --- a/src/soc/fu/compunits/test/test_compunit.py +++ b/src/soc/fu/compunits/test/test_compunit.py @@ -104,11 +104,12 @@ def get_cu_rd_mask(n_src, inp): class TestRunner(FHDLTestCase): - def __init__(self, test_data, fukls, iodef): + def __init__(self, test_data, fukls, iodef, funit): super().__init__("run_all") self.test_data = test_data self.fukls = fukls - self.iodef = iodef + self.iodef = iodef + self.funit = funit def run_all(self): m = Module() @@ -149,7 +150,7 @@ class TestRunner(FHDLTestCase): yield instruction.eq(ins) # raw binary instr. yield Settle() fn_unit = yield pdecode2.e.fn_unit - self.assertEqual(fn_unit, Function.ALU.value) + self.assertEqual(fn_unit, self.funit.value) # set operand and get inputs yield from set_operand(cu, pdecode2, sim) diff --git a/src/soc/fu/compunits/test/test_logical_compunit.py b/src/soc/fu/compunits/test/test_logical_compunit.py new file mode 100644 index 00000000..1c9258b8 --- /dev/null +++ b/src/soc/fu/compunits/test/test_logical_compunit.py @@ -0,0 +1,90 @@ +import unittest +from soc.decoder.power_enums import (XER_bits, Function) + +# XXX bad practice: use of global variables +from soc.fu.logical.test.test_pipe_caller import LogicalTestCase +from soc.fu.logical.test.test_pipe_caller import test_data + +from soc.fu.compunits.compunits import LogicalFunctionUnit +from soc.fu.compunits.test.test_compunit import TestRunner + + +class LogicalTestRunner(TestRunner): + def __init__(self, test_data): + super().__init__(test_data, LogicalFunctionUnit, self, + Function.LOGICAL) + + def get_cu_inputs(self, dec2, sim): + """naming (res) must conform to LogicalFunctionUnit input regspec + """ + res = {} + + # RA (or RC) + reg3_ok = yield dec2.e.read_reg3.ok + reg1_ok = yield dec2.e.read_reg1.ok + assert reg3_ok != reg1_ok + if reg3_ok: + data1 = yield dec2.e.read_reg3.data + res['a'] = sim.gpr(data1).value + elif reg1_ok: + data1 = yield dec2.e.read_reg1.data + res['a'] = sim.gpr(data1).value + + # RB (or immediate) + reg2_ok = yield dec2.e.read_reg2.ok + if reg2_ok: + data2 = yield dec2.e.read_reg2.data + res['b'] = sim.gpr(data2).value + + return res + + def check_cu_outputs(self, res, dec2, sim, code): + """naming (res) must conform to LogicalFunctionUnit output regspec + """ + + # RT + out_reg_valid = yield dec2.e.write_reg.ok + if out_reg_valid: + write_reg_idx = yield dec2.e.write_reg.data + expected = sim.gpr(write_reg_idx).value + cu_out = res['o'] + print(f"expected {expected:x}, actual: {cu_out:x}") + self.assertEqual(expected, cu_out, code) + + rc = yield dec2.e.rc.data + op = yield dec2.e.insn_type + cridx_ok = yield dec2.e.write_cr.ok + cridx = yield dec2.e.write_cr.data + + print ("check extra output", repr(code), cridx_ok, cridx) + + if rc: + self.assertEqual(cridx_ok, 1, code) + self.assertEqual(cridx, 0, code) + + # CR (CR0-7) + if cridx_ok: + cr_expected = sim.crl[cridx].get_range().value + cr_actual = res['cr0'] + print ("CR", cridx, cr_expected, cr_actual) + self.assertEqual(cr_expected, cr_actual, "CR%d %s" % (cridx, code)) + + # XER.ca + cry_out = yield dec2.e.output_carry + if cry_out: + expected_carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0 + xer_ca = res['xer_ca'] + real_carry = xer_ca & 0b1 # 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 = bool(xer_ca & 0b10) # XXX CO32 + self.assertEqual(expected_carry32, real_carry32, code) + + +if __name__ == "__main__": + unittest.main(exit=False) + suite = unittest.TestSuite() + suite.addTest(LogicalTestRunner(test_data)) + + runner = unittest.TextTestRunner() + runner.run(suite) diff --git a/src/soc/fu/logical/logical_input_record.py b/src/soc/fu/logical/logical_input_record.py index c6641a01..34d1dd91 100644 --- a/src/soc/fu/logical/logical_input_record.py +++ b/src/soc/fu/logical/logical_input_record.py @@ -21,6 +21,7 @@ class CompLogicalOpSubset(Record): ('zero_a', 1), ('input_carry', CryIn), ('invert_out', 1), + ('write_cr', Layout((("data", 3), ("ok", 1)))), # Data ('output_carry', 1), ('is_32bit', 1), ('is_signed', 1), diff --git a/src/soc/fu/logical/pipe_data.py b/src/soc/fu/logical/pipe_data.py index ccb6d95e..86e03622 100644 --- a/src/soc/fu/logical/pipe_data.py +++ b/src/soc/fu/logical/pipe_data.py @@ -8,7 +8,7 @@ from soc.fu.logical.logical_input_record import CompLogicalOpSubset class LogicalInputData(IntegerData): regspec = [('INT', 'a', '0:63'), - ('INT', 'rb', '0:63'), + ('INT', 'b', '0:63'), ] def __init__(self, pspec): super().__init__(pspec)