From: Luke Kenneth Casson Leighton Date: Sun, 26 Jul 2020 10:05:34 +0000 (+0100) Subject: again, move large heavily-indented code-block in div test_pipe_caller X-Git-Tag: semi_working_ecp5~535 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b991cf1aacecb0a8310abe344bedf3cea25cdce5;p=soc.git again, move large heavily-indented code-block in div test_pipe_caller --- diff --git a/src/soc/fu/div/test/runner.py b/src/soc/fu/div/test/runner.py index 3d66de5e..04f837b6 100644 --- a/src/soc/fu/div/test/runner.py +++ b/src/soc/fu/div/test/runner.py @@ -115,6 +115,102 @@ class DivRunner(unittest.TestCase): def test_write_ilang(self): self.write_ilang(self.div_pipe_kind) + def execute(self, alu, instruction, pdecode2, test): + prog = test.program + isa_sim = ISA(pdecode2, test.regs, test.sprs, test.cr, + test.mem, test.msr, + bigendian=bigendian) + gen = prog.generate_instructions() + instructions = list(zip(gen, prog.assembly.splitlines())) + yield Delay(0.1e-6) + + index = isa_sim.pc.CIA.value//4 + while index < len(instructions): + ins, code = instructions[index] + + print("instruction: 0x{:X}".format(ins & 0xffffffff)) + print(code) + spr = isa_sim.spr + if 'XER' in spr: + so = 1 if spr['XER'][XER_bits['SO']] else 0 + ov = 1 if spr['XER'][XER_bits['OV']] else 0 + ov32 = 1 if spr['XER'][XER_bits['OV32']] else 0 + xer_zero = not (so or ov or ov32) + print("before: so/ov/32", so, ov, ov32) + else: + xer_zero = True + + # ask the decoder to decode this binary data (endian'd) + # little / big? + yield pdecode2.dec.bigendian.eq(bigendian) + yield instruction.eq(ins) # raw binary instr. + yield Delay(0.1e-6) + fn_unit = yield pdecode2.e.do.fn_unit + self.assertEqual(fn_unit, Function.DIV.value) + pia_inputs = yield from set_alu_inputs(alu, pdecode2, + isa_sim) + + # set valid for one cycle, propagate through pipeline.. + # note that it is critically important to do this + # for DIV otherwise it starts trying to produce + # multiple results. + yield alu.p.valid_i.eq(1) + yield + yield alu.p.valid_i.eq(0) + + opname = code.split(' ')[0] + if xer_zero: + fnname = opname.replace(".", "_") + print(f"{fnname}({pia_inputs})") + pia_res = getattr( + pia, opname.replace(".", "_"))(pia_inputs) + print(f"-> {pia_res}") + else: + pia_res = None + + yield from isa_sim.call(opname) + index = isa_sim.pc.CIA.value//4 + + vld = yield alu.n.valid_o + while not vld: + yield + yield Delay(0.1e-6) + vld = yield alu.n.valid_o + # bug #425 investigation + do = alu.pipe_end.div_out + ctx_op = do.i.ctx.op + is_32bit = yield ctx_op.is_32bit + is_signed = yield ctx_op.is_signed + quotient_root = yield do.i.core.quotient_root + quotient_65 = yield do.quotient_65 + dive_abs_ov32 = yield do.i.dive_abs_ov32 + div_by_zero = yield do.i.div_by_zero + quotient_neg = yield do.quotient_neg + print("32bit", hex(is_32bit)) + print("signed", hex(is_signed)) + print("quotient_root", hex(quotient_root)) + print("quotient_65", hex(quotient_65)) + print("div_by_zero", hex(div_by_zero)) + print("dive_abs_ov32", hex(dive_abs_ov32)) + print("quotient_neg", hex(quotient_neg)) + print("") + yield + + yield Delay(0.1e-6) + # XXX sim._state is an internal variable + # and timeline does not exist + # AttributeError: '_SimulatorState' object + # has no attribute 'timeline' + # TODO: raise bugreport with whitequark + # requesting a public API to access this "officially" + # XXX print("time:", sim._state.timeline.now) + msg = "%s: %s" % (self.div_pipe_kind.name, code) + msg += " %s" % (repr(prog.assembly)) + msg += " %s" % (repr(test.regs)) + yield from self.check_alu_outputs(alu, pdecode2, + isa_sim, msg, + pia_res) + def run_all(self): # *sigh* this is a mess. unit test gets added by code-walking # (unittest module) and picked up with a test name. @@ -145,101 +241,8 @@ class DivRunner(unittest.TestCase): def process(): for test in self.test_data: print(test.name) - prog = test.program with self.subTest(test.name): - isa_sim = ISA(pdecode2, test.regs, test.sprs, test.cr, - test.mem, test.msr, - bigendian=bigendian) - gen = prog.generate_instructions() - instructions = list(zip(gen, prog.assembly.splitlines())) - yield Delay(0.1e-6) - - index = isa_sim.pc.CIA.value//4 - while index < len(instructions): - ins, code = instructions[index] - - print("instruction: 0x{:X}".format(ins & 0xffffffff)) - print(code) - spr = isa_sim.spr - if 'XER' in spr: - so = 1 if spr['XER'][XER_bits['SO']] else 0 - ov = 1 if spr['XER'][XER_bits['OV']] else 0 - ov32 = 1 if spr['XER'][XER_bits['OV32']] else 0 - xer_zero = not (so or ov or ov32) - print("before: so/ov/32", so, ov, ov32) - else: - xer_zero = True - - # ask the decoder to decode this binary data (endian'd) - # little / big? - yield pdecode2.dec.bigendian.eq(bigendian) - yield instruction.eq(ins) # raw binary instr. - yield Delay(0.1e-6) - fn_unit = yield pdecode2.e.do.fn_unit - self.assertEqual(fn_unit, Function.DIV.value) - pia_inputs = yield from set_alu_inputs(alu, pdecode2, - isa_sim) - - # set valid for one cycle, propagate through pipeline.. - # note that it is critically important to do this - # for DIV otherwise it starts trying to produce - # multiple results. - yield alu.p.valid_i.eq(1) - yield - yield alu.p.valid_i.eq(0) - - opname = code.split(' ')[0] - if xer_zero: - fnname = opname.replace(".", "_") - print(f"{fnname}({pia_inputs})") - pia_res = getattr( - pia, opname.replace(".", "_"))(pia_inputs) - print(f"-> {pia_res}") - else: - pia_res = None - - yield from isa_sim.call(opname) - index = isa_sim.pc.CIA.value//4 - - vld = yield alu.n.valid_o - while not vld: - yield - yield Delay(0.1e-6) - vld = yield alu.n.valid_o - # bug #425 investigation - do = alu.pipe_end.div_out - ctx_op = do.i.ctx.op - is_32bit = yield ctx_op.is_32bit - is_signed = yield ctx_op.is_signed - quotient_root = yield do.i.core.quotient_root - quotient_65 = yield do.quotient_65 - dive_abs_ov32 = yield do.i.dive_abs_ov32 - div_by_zero = yield do.i.div_by_zero - quotient_neg = yield do.quotient_neg - print("32bit", hex(is_32bit)) - print("signed", hex(is_signed)) - print("quotient_root", hex(quotient_root)) - print("quotient_65", hex(quotient_65)) - print("div_by_zero", hex(div_by_zero)) - print("dive_abs_ov32", hex(dive_abs_ov32)) - print("quotient_neg", hex(quotient_neg)) - print("") - yield - - yield Delay(0.1e-6) - # XXX sim._state is an internal variable - # and timeline does not exist - # AttributeError: '_SimulatorState' object - # has no attribute 'timeline' - # TODO: raise bugreport with whitequark - # requesting a public API to access this "officially" - # XXX print("time:", sim._state.timeline.now) - msg = "%s: %s" % (self.div_pipe_kind.name, code) - msg += " %s" % (repr(prog.assembly)) - msg += " %s" % (repr(test.regs)) - yield from self.check_alu_outputs(alu, pdecode2, - isa_sim, msg, - pia_res) + yield from self.execute(alu, instruction, pdecode2, test) sim.add_sync_process(process) with sim.write_vcd(f"div_simulator_{self.div_pipe_kind.name}.vcd"):