From: Luke Kenneth Casson Leighton Date: Wed, 10 Jun 2020 11:31:54 +0000 (+0100) Subject: cookie-cut alu test_pipe_caller.py over X-Git-Tag: div_pipeline~434 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=591145c798b7e3f1cbf972aa3397a4e0e54114d1;p=soc.git cookie-cut alu test_pipe_caller.py over --- diff --git a/src/soc/fu/div/test/test_pipe_caller.py b/src/soc/fu/div/test/test_pipe_caller.py index 3b58490d..2e66f90a 100644 --- a/src/soc/fu/div/test/test_pipe_caller.py +++ b/src/soc/fu/div/test/test_pipe_caller.py @@ -6,63 +6,65 @@ 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) +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 -from soc.fu.div.pipeline import DivBasePipe -from soc.fu.div.pipe_data import DivPipeSpec -import random - -class TestCase: - def __init__(self, program, regs, sprs, name): - self.program = program - self.regs = regs - self.sprs = sprs - self.name = name +from soc.fu.test.common import (TestCase, DIVHelpers) +from soc.fu.div.pipeline import DIVBasePipe +from soc.fu.div.pipe_data import DIVPipeSpec +import random -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 DIVFunctionUnit input regspec + """ + res = {} - reg3_ok = yield dec2.e.read_reg3.ok + # RA (or RC) reg1_ok = yield dec2.e.read_reg1.ok - assert reg3_ok != reg1_ok - if reg3_ok: - data1 = yield dec2.e.read_reg3.data - data1 = sim.gpr(data1).value - elif 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 + + # XER.ca + cry_in = yield dec2.e.input_carry + 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 + 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 + + print ("alu get_cu_inputs", res) + + 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 -def set_extra_alu_inputs(alu, 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) - so = 1 if sim.spr['XER'][XER_bits['SO']] else 0 - yield alu.p.data_i.xer_so.eq(so) + inp = yield from get_cu_inputs(dec2, sim) + yield from DIVHelpers.set_int_ra(alu, dec2, inp) + yield from DIVHelpers.set_int_rb(alu, dec2, inp) + + yield from DIVHelpers.set_xer_ca(alu, dec2, inp) + yield from DIVHelpers.set_xer_so(alu, dec2, inp) # This test bench is a bit different than is usual. Initially when I @@ -72,7 +74,7 @@ def set_extra_alu_inputs(alu, dec2, sim): # should have. However, this was really slow, since it needed to # create and tear down the dut and simulator for every test case. -# Now, instead of doing that, every test case in ALUTestCase puts some +# Now, instead of doing that, every test case in DIVTestCase puts some # data into the test_data list below, describing the instructions to # be tested and the initial state. Once all the tests have been run, # test_data gets passed to TestRunner which then sets up the DUT and @@ -83,97 +85,112 @@ def set_extra_alu_inputs(alu, dec2, sim): # massively. Before, it took around 1 minute on my computer, now it # takes around 3 seconds -test_data = [] +class DIVTestCase(FHDLTestCase): + test_data = [] -class DivTestCase(FHDLTestCase): def __init__(self, name): super().__init__(name) self.test_name = name - def run_tst_program(self, prog, initial_regs=[0] * 32, initial_sprs={}): - tc = TestCase(prog, initial_regs, initial_sprs, self.test_name) - test_data.append(tc) + def run_tst_program(self, prog, initial_regs=None, initial_sprs=None): + tc = TestCase(prog, self.test_name, initial_regs, initial_sprs) + self.test_data.append(tc) + + def test_1_regression(self): + lst = [f"extsw 3, 1"] + initial_regs = [0] * 32 + initial_regs[1] = 0xb6a1fc6c8576af91 + self.run_tst_program(Program(lst), initial_regs) + lst = [f"subf 3, 1, 2"] + initial_regs = [0] * 32 + initial_regs[1] = 0x3d7f3f7ca24bac7b + initial_regs[2] = 0xf6b2ac5e13ee15c2 + self.run_tst_program(Program(lst), initial_regs) + lst = [f"subf 3, 1, 2"] + initial_regs = [0] * 32 + initial_regs[1] = 0x833652d96c7c0058 + initial_regs[2] = 0x1c27ecff8a086c1a + self.run_tst_program(Program(lst), initial_regs) + lst = [f"extsb 3, 1"] + initial_regs = [0] * 32 + initial_regs[1] = 0x7f9497aaff900ea0 + self.run_tst_program(Program(lst), initial_regs) + lst = [f"add. 3, 1, 2"] + initial_regs = [0] * 32 + initial_regs[1] = 0xc523e996a8ff6215 + initial_regs[2] = 0xe1e5b9cc9864c4a8 + self.run_tst_program(Program(lst), initial_regs) + lst = [f"add 3, 1, 2"] + initial_regs = [0] * 32 + initial_regs[1] = 0x2e08ae202742baf8 + initial_regs[2] = 0x86c43ece9efe5baa + self.run_tst_program(Program(lst), initial_regs) def test_rand(self): - insns = ["and", "or", "xor"] + insns = ["add", "add.", "subf"] for i in range(40): choice = random.choice(insns) lst = [f"{choice} 3, 1, 2"] initial_regs = [0] * 32 - initial_regs[1] = random.randint(0, (1 << 64)-1) - initial_regs[2] = random.randint(0, (1 << 64)-1) + initial_regs[1] = random.randint(0, (1<<64)-1) + initial_regs[2] = random.randint(0, (1<<64)-1) self.run_tst_program(Program(lst), initial_regs) - def test_rand_imm_logical(self): - insns = ["andi.", "andis.", "ori", "oris", "xori", "xoris"] + def test_rand_imm(self): + insns = ["addi", "addis", "subfic"] for i in range(10): choice = random.choice(insns) - imm = random.randint(0, (1 << 16)-1) + imm = random.randint(-(1<<15), (1<<15)-1) lst = [f"{choice} 3, 1, {imm}"] print(lst) initial_regs = [0] * 32 - initial_regs[1] = random.randint(0, (1 << 64)-1) - self.run_tst_program(Program(lst), initial_regs) - - def test_cntz(self): - insns = ["cntlzd", "cnttzd", "cntlzw", "cnttzw"] - for i in range(100): - choice = random.choice(insns) - lst = [f"{choice} 3, 1"] - print(lst) - initial_regs = [0] * 32 - initial_regs[1] = random.randint(0, (1 << 64)-1) + initial_regs[1] = random.randint(0, (1<<64)-1) self.run_tst_program(Program(lst), initial_regs) - def test_parity(self): - insns = ["prtyw", "prtyd"] + def test_0_adde(self): + lst = ["adde. 5, 6, 7"] for i in range(10): - choice = random.choice(insns) - lst = [f"{choice} 3, 1"] - print(lst) initial_regs = [0] * 32 - initial_regs[1] = random.randint(0, (1 << 64)-1) - self.run_tst_program(Program(lst), initial_regs) + initial_regs[6] = random.randint(0, (1<<64)-1) + initial_regs[7] = random.randint(0, (1<<64)-1) + initial_sprs = {} + xer = SelectableInt(0, 64) + xer[XER_bits['CA']] = 1 + initial_sprs[special_sprs['XER']] = xer + self.run_tst_program(Program(lst), initial_regs, initial_sprs) + + def test_cmp(self): + lst = ["subf. 1, 6, 7", + "cmp cr2, 1, 6, 7"] + initial_regs = [0] * 32 + initial_regs[6] = 0x10 + initial_regs[7] = 0x05 + self.run_tst_program(Program(lst), initial_regs, {}) - def test_popcnt(self): - insns = ["popcntb", "popcntw", "popcntd"] + def test_extsb(self): + insns = ["extsb", "extsh", "extsw"] for i in range(10): choice = random.choice(insns) lst = [f"{choice} 3, 1"] print(lst) initial_regs = [0] * 32 - initial_regs[1] = random.randint(0, (1 << 64)-1) + initial_regs[1] = random.randint(0, (1<<64)-1) self.run_tst_program(Program(lst), initial_regs) - def test_popcnt_edge(self): - insns = ["popcntb", "popcntw", "popcntd"] - for choice in insns: - lst = [f"{choice} 3, 1"] - initial_regs = [0] * 32 - initial_regs[1] = -1 - self.run_tst_program(Program(lst), initial_regs) - - def test_cmpb(self): - lst = ["cmpb 3, 1, 2"] - initial_regs = [0] * 32 - initial_regs[1] = 0xdeadbeefcafec0de - initial_regs[2] = 0xd0adb0000afec1de - self.run_tst_program(Program(lst), initial_regs) - - def test_bpermd(self): - lst = ["bpermd 3, 1, 2"] + def test_cmpeqb(self): + lst = ["cmpeqb cr1, 1, 2"] for i in range(20): initial_regs = [0] * 32 - initial_regs[1] = 1<