add in memory setup/check but disable LDST Unit Tests in core.py
[soc.git] / src / soc / simple / test / test_core.py
index 82d6d52bf6807633220909309dcc0a9a16d54367..8b633c7be402cadbafd5cace07767268ef3eae0d 100644 (file)
@@ -1,3 +1,9 @@
+"""simple core test
+
+related bugs:
+
+ * https://bugs.libre-soc.org/show_bug.cgi?id=363
+"""
 from nmigen import Module, Signal, Cat
 from nmigen.back.pysim import Simulator, Delay, Settle
 from nmutil.formaltest import FHDLTestCase
 from nmigen import Module, Signal, Cat
 from nmigen.back.pysim import Simulator, Delay, Settle
 from nmutil.formaltest import FHDLTestCase
@@ -13,63 +19,16 @@ from soc.decoder.power_enums import Function, XER_bits
 from soc.simple.core import NonProductionCore
 from soc.experiment.compalu_multi import find_ok # hack
 
 from soc.simple.core import NonProductionCore
 from soc.experiment.compalu_multi import find_ok # hack
 
+from soc.fu.compunits.test.test_compunit import (setup_test_memory,
+                                                 check_sim_memory)
+
 # test with ALU data and Logical data
 # test with ALU data and Logical data
-from soc.fu.alu.test.test_pipe_caller import TestCase, ALUTestCase
+from soc.fu.alu.test.test_pipe_caller import ALUTestCase
 from soc.fu.logical.test.test_pipe_caller import LogicalTestCase
 from soc.fu.shift_rot.test.test_pipe_caller import ShiftRotTestCase
 from soc.fu.logical.test.test_pipe_caller import LogicalTestCase
 from soc.fu.shift_rot.test.test_pipe_caller import ShiftRotTestCase
-
-
-def set_cu_input(cu, idx, data):
-    rdop = cu.get_in_name(idx)
-    yield cu.src_i[idx].eq(data)
-    while True:
-        rd_rel_o = yield cu.rd.rel[idx]
-        print ("rd_rel %d wait HI" % idx, rd_rel_o, rdop, hex(data))
-        if rd_rel_o:
-            break
-        yield
-    yield cu.rd.go[idx].eq(1)
-    while True:
-        yield
-        rd_rel_o = yield cu.rd.rel[idx]
-        if rd_rel_o:
-            break
-        print ("rd_rel %d wait HI" % idx, rd_rel_o)
-        yield
-    yield cu.rd.go[idx].eq(0)
-    yield cu.src_i[idx].eq(0)
-
-
-def get_cu_output(cu, idx, code):
-    wrmask = yield cu.wrmask
-    wrop = cu.get_out_name(idx)
-    wrok = cu.get_out(idx)
-    fname = find_ok(wrok.fields)
-    wrok = yield getattr(wrok, fname)
-    print ("wr_rel mask", repr(code), idx, wrop, bin(wrmask), fname, wrok)
-    assert wrmask & (1<<idx), \
-            "get_cu_output '%s': mask bit %d not set\n" \
-            "write-operand '%s' Data.ok likely not set (%s)" \
-            % (code, idx, wrop, hex(wrok))
-    while True:
-        wr_relall_o = yield cu.wr.rel
-        wr_rel_o = yield cu.wr.rel[idx]
-        print ("wr_rel %d wait" % idx, hex(wr_relall_o), wr_rel_o)
-        if wr_rel_o:
-            break
-        yield
-    yield cu.wr.go[idx].eq(1)
-    yield Settle()
-    result = yield cu.dest[idx]
-    yield
-    yield cu.wr.go[idx].eq(0)
-    print ("result", repr(code), idx, wrop, wrok, hex(result))
-    return result
-
-
-def set_cu_inputs(cu, inp):
-    for idx, data in inp.items():
-        yield from set_cu_input(cu, idx, data)
+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
 
 
 def set_issue(core, dec2, sim):
 
 
 def set_issue(core, dec2, sim):
@@ -93,27 +52,6 @@ def wait_for_busy_clear(cu):
         yield
 
 
         yield
 
 
-def get_cu_outputs(cu, code):
-    res = {}
-    for i in range(cu.n_dst):
-        wr_rel_o = yield cu.wr.rel[i]
-        if wr_rel_o:
-            result = yield from get_cu_output(cu, i, code)
-            wrop = cu.get_out_name(i)
-            print ("output", i, wrop, hex(result))
-            res[wrop] = result
-    return res
-
-
-def get_inp_indexed(cu, inp):
-    res = {}
-    for i in range(cu.n_src):
-        wrop = cu.get_in_name(i)
-        if wrop in inp:
-            res[i] = inp[wrop]
-    return res
-
-
 class TestRunner(FHDLTestCase):
     def __init__(self, tst_data):
         super().__init__("run_all")
 class TestRunner(FHDLTestCase):
     def __init__(self, tst_data):
         super().__init__("run_all")
@@ -128,11 +66,17 @@ class TestRunner(FHDLTestCase):
         m.submodules.core = core = NonProductionCore()
         pdecode = core.pdecode
         pdecode2 = core.pdecode2
         m.submodules.core = core = NonProductionCore()
         pdecode = core.pdecode
         pdecode2 = core.pdecode2
+        l0 = core.l0
 
         comb += pdecode2.dec.raw_opcode_in.eq(instruction)
         comb += core.ivalid_i.eq(ivalid_i)
         sim = Simulator(m)
 
 
         comb += pdecode2.dec.raw_opcode_in.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
+
         sim.add_clock(1e-6)
 
         def process():
         sim.add_clock(1e-6)
 
         def process():
@@ -143,26 +87,41 @@ class TestRunner(FHDLTestCase):
                 print(test.name)
                 program = test.program
                 self.subTest(test.name)
                 print(test.name)
                 program = test.program
                 self.subTest(test.name)
-                sim = ISA(pdecode2, test.regs, test.sprs, 0)
+                sim = ISA(pdecode2, test.regs, test.sprs, test.cr, test.mem,
+                          test.msr)
                 gen = program.generate_instructions()
                 instructions = list(zip(gen, program.assembly.splitlines()))
 
                 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 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']]
                 # 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']].asint()
+                    sobit = xer[XER_bits['SO']].value
                     yield xregs.regs[xregs.SO].reg.eq(sobit)
                     yield xregs.regs[xregs.SO].reg.eq(sobit)
-                    cabit = xer[XER_bits['CA']].asint()
-                    ca32bit = xer[XER_bits['CA32']].asint()
+                    cabit = xer[XER_bits['CA']].value
+                    ca32bit = xer[XER_bits['CA32']].value
                     yield xregs.regs[xregs.CA].reg.eq(Cat(cabit, ca32bit))
                     yield xregs.regs[xregs.CA].reg.eq(Cat(cabit, ca32bit))
-                    ovbit = xer[XER_bits['OV']].asint()
-                    ov32bit = xer[XER_bits['OV32']].asint()
+                    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(Cat(ovbit, ov32bit))
                 else:
                     yield xregs.regs[xregs.SO].reg.eq(0)
@@ -173,7 +132,7 @@ class TestRunner(FHDLTestCase):
                 while index < len(instructions):
                     ins, code = instructions[index]
 
                 while index < len(instructions):
                     ins, code = instructions[index]
 
-                    print("0x{:X}".format(ins & 0xffffffff))
+                    print("instruction: 0x{:X}".format(ins & 0xffffffff))
                     print(code)
 
                     # ask the decoder to decode this binary data (endian'd)
                     print(code)
 
                     # ask the decoder to decode this binary data (endian'd)
@@ -185,6 +144,16 @@ class TestRunner(FHDLTestCase):
                     #fuval = self.funit.value
                     #self.assertEqual(fn_unit & fuval, fuval)
 
                     #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()
                     # set operand and get inputs
                     yield from set_issue(core, pdecode2, sim)
                     yield Settle()
@@ -210,6 +179,44 @@ class TestRunner(FHDLTestCase):
                         self.assertEqual(simregval, intregs[i],
                             "int reg %d not equal %s" % (i, repr(code)))
 
                         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)))
+
+                    # 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=[]):
         sim.add_sync_process(process)
         with sim.write_vcd("core_simulator.vcd", "core_simulator.gtkw",
                             traces=[]):
@@ -219,9 +226,12 @@ class TestRunner(FHDLTestCase):
 if __name__ == "__main__":
     unittest.main(exit=False)
     suite = unittest.TestSuite()
 if __name__ == "__main__":
     unittest.main(exit=False)
     suite = unittest.TestSuite()
+    #suite.addTest(TestRunner(LDSTTestCase.test_data))
+    suite.addTest(TestRunner(CRTestCase.test_data))
     suite.addTest(TestRunner(ShiftRotTestCase.test_data))
     suite.addTest(TestRunner(LogicalTestCase.test_data))
     suite.addTest(TestRunner(ALUTestCase.test_data))
     suite.addTest(TestRunner(ShiftRotTestCase.test_data))
     suite.addTest(TestRunner(LogicalTestCase.test_data))
     suite.addTest(TestRunner(ALUTestCase.test_data))
+    suite.addTest(TestRunner(BranchTestCase.test_data))
 
     runner = unittest.TextTestRunner()
     runner.run(suite)
 
     runner = unittest.TextTestRunner()
     runner.run(suite)