X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fsoc%2Fsimple%2Ftest%2Ftest_core.py;h=b2c219da2c1825498553c357ea1d75d85c31bdd0;hb=575802fa56d7175ebbdc16bb5c493b556dab9c74;hp=8b633c7be402cadbafd5cace07767268ef3eae0d;hpb=54a1dbf96e7092aebf59c76ec99aed678f861dae;p=soc.git diff --git a/src/soc/simple/test/test_core.py b/src/soc/simple/test/test_core.py index 8b633c7b..b2c219da 100644 --- a/src/soc/simple/test/test_core.py +++ b/src/soc/simple/test/test_core.py @@ -12,12 +12,14 @@ import unittest from soc.decoder.isa.caller import special_sprs from soc.decoder.power_decoder import create_pdecode from soc.decoder.power_decoder2 import PowerDecode2 +from soc.decoder.selectable_int import SelectableInt from soc.decoder.isa.all import ISA -from soc.decoder.power_enums import Function, XER_bits - +from soc.decoder.power_enums import SPR, spr_dict, Function, XER_bits +from soc.config.test.test_loadstore import TestMemPspec +from soc.config.endian import bigendian from soc.simple.core import NonProductionCore -from soc.experiment.compalu_multi import find_ok # hack +from soc.experiment.compalu_multi import find_ok # hack from soc.fu.compunits.test.test_compunit import (setup_test_memory, check_sim_memory) @@ -29,24 +31,166 @@ from soc.fu.shift_rot.test.test_pipe_caller import ShiftRotTestCase from soc.fu.cr.test.test_pipe_caller import CRTestCase from soc.fu.branch.test.test_pipe_caller import BranchTestCase from soc.fu.ldst.test.test_pipe_caller import LDSTTestCase +from soc.regfile.util import spr_to_fast_reg + + +def setup_regs(core, test): + + # set up INT regfile, "direct" write (bypass rd/write ports) + intregs = core.regs.int + for i in range(32): + yield intregs.regs[i].reg.eq(test.regs[i]) + + # set up CR regfile, "direct" write across all CRs + cr = test.cr + crregs = core.regs.cr + #cr = int('{:32b}'.format(cr)[::-1], 2) + print("cr reg", hex(cr)) + for i in range(8): + #j = 7-i + cri = (cr >> (i*4)) & 0xf + #cri = int('{:04b}'.format(cri)[::-1], 2) + print("cr reg", hex(cri), i, + crregs.regs[i].reg.shape()) + yield crregs.regs[i].reg.eq(cri) + + # set up XER. "direct" write (bypass rd/write ports) + xregs = core.regs.xer + print("sprs", test.sprs) + xer = None + if 'XER' in test.sprs: + xer = test.sprs['XER'] + if 1 in test.sprs: + xer = test.sprs[1] + if xer is not None: + if isinstance(xer, int): + xer = SelectableInt(xer, 64) + sobit = xer[XER_bits['SO']].value + yield xregs.regs[xregs.SO].reg.eq(sobit) + cabit = xer[XER_bits['CA']].value + ca32bit = xer[XER_bits['CA32']].value + yield xregs.regs[xregs.CA].reg.eq(Cat(cabit, ca32bit)) + ovbit = xer[XER_bits['OV']].value + ov32bit = xer[XER_bits['OV32']].value + yield xregs.regs[xregs.OV].reg.eq(Cat(ovbit, ov32bit)) + print("setting XER so %d ca %d ca32 %d ov %d ov32 %d" % + (sobit, cabit, ca32bit, ovbit, ov32bit)) + else: + yield xregs.regs[xregs.SO].reg.eq(0) + yield xregs.regs[xregs.OV].reg.eq(0) + yield xregs.regs[xregs.CA].reg.eq(0) + + # setting both fast and slow SPRs from test data + + fregs = core.regs.fast + sregs = core.regs.spr + for sprname, val in test.sprs.items(): + if isinstance(val, SelectableInt): + val = val.value + if isinstance(sprname, int): + sprname = spr_dict[sprname].SPR + if sprname == 'XER': + continue + fast = spr_to_fast_reg(sprname) + if fast is None: + # match behaviour of SPRMap in power_decoder2.py + for i, x in enumerate(SPR): + if sprname == x.name: + yield sregs[i].reg.eq(val) + print("setting slow SPR %d (%s) to %x" % + (i, sprname, val)) + else: + yield fregs.regs[fast].reg.eq(val) + print("setting fast reg %d (%s) to %x" % + (fast, sprname, val)) + + # allow changes to settle before reporting on XER + yield Settle() + + # XER + pdecode2 = core.pdecode2 + so = yield xregs.regs[xregs.SO].reg + ov = yield xregs.regs[xregs.OV].reg + ca = yield xregs.regs[xregs.CA].reg + oe = yield pdecode2.e.do.oe.oe + oe_ok = yield pdecode2.e.do.oe.oe_ok + + print("before: so/ov-32/ca-32", so, bin(ov), bin(ca)) + print("oe:", oe, oe_ok) + + +def check_regs(dut, sim, core, test, code): + # int regs + intregs = [] + for i in range(32): + rval = yield core.regs.int.regs[i].reg + intregs.append(rval) + print("int regs", list(map(hex, intregs))) + for i in range(32): + simregval = sim.gpr[i].asint() + dut.assertEqual(simregval, intregs[i], + "int reg %d not equal %s" % (i, repr(code))) + + # CRs + crregs = [] + for i in range(8): + rval = yield core.regs.cr.regs[i].reg + crregs.append(rval) + print("cr regs", list(map(hex, crregs))) + for i in range(8): + rval = crregs[i] + cri = sim.crl[7-i].get_range().value + print("cr reg", i, hex(cri), i, hex(rval)) + # XXX https://bugs.libre-soc.org/show_bug.cgi?id=363 + dut.assertEqual(cri, rval, + "cr reg %d not equal %s" % (i, repr(code))) + + # XER + xregs = core.regs.xer + so = yield xregs.regs[xregs.SO].reg + ov = yield xregs.regs[xregs.OV].reg + ca = yield xregs.regs[xregs.CA].reg + + print("sim SO", sim.spr['XER'][XER_bits['SO']]) + e_so = sim.spr['XER'][XER_bits['SO']].value + e_ov = sim.spr['XER'][XER_bits['OV']].value + e_ov32 = sim.spr['XER'][XER_bits['OV32']].value + e_ca = sim.spr['XER'][XER_bits['CA']].value + e_ca32 = sim.spr['XER'][XER_bits['CA32']].value + + e_ov = e_ov | (e_ov32 << 1) + e_ca = e_ca | (e_ca32 << 1) + + print("after: so/ov-32/ca-32", so, bin(ov), bin(ca)) + dut.assertEqual(e_so, so, "so mismatch %s" % (repr(code))) + dut.assertEqual(e_ov, ov, "ov mismatch %s" % (repr(code))) + dut.assertEqual(e_ca, ca, "ca mismatch %s" % (repr(code))) + + +def wait_for_busy_hi(cu): + while True: + busy_o = yield cu.busy_o + terminated_o = yield cu.core_terminated_o + if busy_o or terminated_o: + print("busy/terminated:", busy_o, terminated_o) + break + print("!busy", busy_o, terminated_o) + yield def set_issue(core, dec2, sim): yield core.issue_i.eq(1) yield yield core.issue_i.eq(0) - while True: - busy_o = yield core.busy_o - if busy_o: - break - print("!busy",) - yield + yield from wait_for_busy_hi(core) def wait_for_busy_clear(cu): while True: busy_o = yield cu.busy_o - if not busy_o: + terminated_o = yield cu.core_terminated_o + if not busy_o or terminated_o: + print("busy/terminated:", busy_o, terminated_o) break print("busy",) yield @@ -63,20 +207,26 @@ class TestRunner(FHDLTestCase): instruction = Signal(32) ivalid_i = Signal() - m.submodules.core = core = NonProductionCore() - pdecode = core.pdecode + pspec = TestMemPspec(ldst_ifacetype='testpi', + imem_ifacetype='', + addr_wid=48, + mask_wid=8, + reg_wid=64) + + m.submodules.core = core = NonProductionCore(pspec) pdecode2 = core.pdecode2 l0 = core.l0 - comb += pdecode2.dec.raw_opcode_in.eq(instruction) + comb += core.raw_opcode_i.eq(instruction) comb += core.ivalid_i.eq(ivalid_i) - sim = Simulator(m) # temporary hack: says "go" immediately for both address gen and ST ldst = core.fus.fus['ldst0'] - m.d.comb += ldst.ad.go.eq(ldst.ad.rel) # link addr-go direct to rel - m.d.comb += ldst.st.go.eq(ldst.st.rel) # link store-go direct to rel + m.d.comb += ldst.ad.go.eq(ldst.ad.rel) # link addr-go direct to rel + m.d.comb += ldst.st.go.eq(ldst.st.rel) # link store-go direct to rel + # nmigen Simulation + sim = Simulator(m) sim.add_clock(1e-6) def process(): @@ -88,45 +238,13 @@ class TestRunner(FHDLTestCase): program = test.program self.subTest(test.name) sim = ISA(pdecode2, test.regs, test.sprs, test.cr, test.mem, - test.msr) + test.msr, + bigendian=bigendian) gen = program.generate_instructions() instructions = list(zip(gen, program.assembly.splitlines())) yield from setup_test_memory(l0, sim) - - # set up INT regfile, "direct" write (bypass rd/write ports) - for i in range(32): - yield core.regs.int.regs[i].reg.eq(test.regs[i]) - - # set up CR regfile, "direct" write across all CRs - cr = test.cr - #cr = int('{:32b}'.format(cr)[::-1], 2) - print ("cr reg", hex(cr)) - for i in range(8): - #j = 7-i - cri = (cr>>(i*4)) & 0xf - #cri = int('{:04b}'.format(cri)[::-1], 2) - print ("cr reg", hex(cri), i, - core.regs.cr.regs[i].reg.shape()) - yield core.regs.cr.regs[i].reg.eq(cri) - - # set up XER. "direct" write (bypass rd/write ports) - xregs = core.regs.xer - print ("sprs", test.sprs) - if special_sprs['XER'] in test.sprs: - xer = test.sprs[special_sprs['XER']] - sobit = xer[XER_bits['SO']].value - yield xregs.regs[xregs.SO].reg.eq(sobit) - cabit = xer[XER_bits['CA']].value - ca32bit = xer[XER_bits['CA32']].value - yield xregs.regs[xregs.CA].reg.eq(Cat(cabit, ca32bit)) - ovbit = xer[XER_bits['OV']].value - ov32bit = xer[XER_bits['OV32']].value - yield xregs.regs[xregs.OV].reg.eq(Cat(ovbit, ov32bit)) - else: - yield xregs.regs[xregs.SO].reg.eq(0) - yield xregs.regs[xregs.OV].reg.eq(0) - yield xregs.regs[xregs.CA].reg.eq(0) + yield from setup_regs(core, test) index = sim.pc.CIA.value//4 while index < len(instructions): @@ -136,24 +254,14 @@ class TestRunner(FHDLTestCase): print(code) # ask the decoder to decode this binary data (endian'd) - yield pdecode2.dec.bigendian.eq(0) # little / big? + yield core.bigendian_i.eq(bigendian) # little / big? yield instruction.eq(ins) # raw binary instr. yield ivalid_i.eq(1) yield Settle() - #fn_unit = yield pdecode2.e.fn_unit + # fn_unit = yield pdecode2.e.fn_unit #fuval = self.funit.value #self.assertEqual(fn_unit & fuval, fuval) - # XER - so = yield xregs.regs[xregs.SO].reg - ov = yield xregs.regs[xregs.OV].reg - ca = yield xregs.regs[xregs.CA].reg - oe = yield pdecode2.e.oe.oe - oe_ok = yield pdecode2.e.oe.oe_ok - - print ("before: so/ov-32/ca-32", so, bin(ov), bin(ca)) - print ("oe:", oe, oe_ok) - # set operand and get inputs yield from set_issue(core, pdecode2, sim) yield Settle() @@ -162,71 +270,28 @@ class TestRunner(FHDLTestCase): yield ivalid_i.eq(0) yield - print ("sim", code) + print("sim", code) # call simulated operation opname = code.split(' ')[0] yield from sim.call(opname) index = sim.pc.CIA.value//4 - # int regs - intregs = [] - for i in range(32): - rval = yield core.regs.int.regs[i].reg - intregs.append(rval) - print ("int regs", list(map(hex, intregs))) - for i in range(32): - simregval = sim.gpr[i].asint() - self.assertEqual(simregval, intregs[i], - "int reg %d not equal %s" % (i, repr(code))) - - # CRs - crregs = [] - for i in range(8): - rval = yield core.regs.cr.regs[i].reg - crregs.append(rval) - print ("cr regs", list(map(hex, crregs))) - print ("sim cr reg", hex(cr)) - for i in range(8): - rval = crregs[i] - cri = sim.crl[7-i].get_range().value - print ("cr reg", i, hex(cri), i, hex(rval)) - # XXX https://bugs.libre-soc.org/show_bug.cgi?id=363 - self.assertEqual(cri, rval, - "cr reg %d not equal %s" % (i, repr(code))) - - # XER - so = yield xregs.regs[xregs.SO].reg - ov = yield xregs.regs[xregs.OV].reg - ca = yield xregs.regs[xregs.CA].reg - - print ("sim SO", sim.spr['XER'][XER_bits['SO']]) - e_so = sim.spr['XER'][XER_bits['SO']].value - e_ov = sim.spr['XER'][XER_bits['OV']].value - e_ov32 = sim.spr['XER'][XER_bits['OV32']].value - e_ca = sim.spr['XER'][XER_bits['CA']].value - e_ca32 = sim.spr['XER'][XER_bits['CA32']].value - - e_ov = e_ov | (e_ov32<<1) - e_ca = e_ca | (e_ca32<<1) - - print ("after: so/ov-32/ca-32", so, bin(ov), bin(ca)) - self.assertEqual(e_so, so, "so mismatch %s" % (repr(code))) - self.assertEqual(e_ov, ov, "ov mismatch %s" % (repr(code))) - self.assertEqual(e_ca, ca, "ca mismatch %s" % (repr(code))) + # register check + yield from check_regs(self, sim, core, test, code) # Memory check yield from check_sim_memory(self, l0, sim, code) sim.add_sync_process(process) with sim.write_vcd("core_simulator.vcd", "core_simulator.gtkw", - traces=[]): + traces=[]): sim.run() if __name__ == "__main__": unittest.main(exit=False) suite = unittest.TestSuite() - #suite.addTest(TestRunner(LDSTTestCase.test_data)) + suite.addTest(TestRunner(LDSTTestCase.test_data)) suite.addTest(TestRunner(CRTestCase.test_data)) suite.addTest(TestRunner(ShiftRotTestCase.test_data)) suite.addTest(TestRunner(LogicalTestCase.test_data)) @@ -235,4 +300,3 @@ if __name__ == "__main__": runner = unittest.TextTestRunner() runner.run(suite) -