big rename, global/search/replace of ready_o with o_ready and the other
[soc.git] / src / soc / simple / test / test_runner.py
index b6be2f3a20581a2482e9beb80490153bdd97230c..1d792fe51b6094a4172deb35e05c8b39f3b599f9 100644 (file)
@@ -5,6 +5,7 @@ related bugs:
  * https://bugs.libre-soc.org/show_bug.cgi?id=363
 """
 from nmigen import Module, Signal, Cat, ClockSignal
+from nmigen.hdl.xfrm import ResetInserter
 
 # NOTE: to use cxxsim, export NMIGEN_SIM_MODE=cxxsim from the shell
 # Also, check out the cxxsim nmigen branch, and latest yosys from git
@@ -13,12 +14,12 @@ from nmutil.sim_tmp_alternative import Simulator, Settle
 from nmutil.formaltest import FHDLTestCase
 from nmutil.gtkw import write_gtkw
 from nmigen.cli import rtlil
-from soc.decoder.isa.caller import special_sprs, SVP64State
-from soc.decoder.isa.all import ISA
-from soc.config.endian import bigendian
+from openpower.decoder.isa.caller import special_sprs, SVP64State
+from openpower.decoder.isa.all import ISA
+from openpower.endian import bigendian
 
-from soc.decoder.power_decoder import create_pdecode
-from soc.decoder.power_decoder2 import PowerDecode2
+from openpower.decoder.power_decoder import create_pdecode
+from openpower.decoder.power_decoder2 import PowerDecode2
 from soc.regfile.regfiles import StateRegs
 
 from soc.simple.issuer import TestIssuerInternal
@@ -27,7 +28,7 @@ from soc.config.test.test_loadstore import TestMemPspec
 from soc.simple.test.test_core import (setup_regs, check_regs,
                                        wait_for_busy_clear,
                                        wait_for_busy_hi)
-from soc.fu.compunits.test.test_compunit import (setup_test_memory,
+from soc.fu.compunits.test.test_compunit import (setup_tst_memory,
                                                  check_sim_memory)
 from soc.debug.dmi import DBGCore, DBGCtrl, DBGStat
 from nmutil.util import wrap
@@ -133,10 +134,16 @@ class TestRunner(FHDLTestCase):
         m = Module()
         comb = m.d.comb
         pc_i = Signal(32)
-        svstate_i = Signal(32)
+        svstate_i = Signal(64)
 
-        pspec = TestMemPspec(ldst_ifacetype='test_bare_wb',
-                             imem_ifacetype='test_bare_wb',
+        if self.microwatt_mmu:
+            ldst_ifacetype = 'test_mmu_cache_wb'
+        else:
+            ldst_ifacetype = 'test_bare_wb'
+        imem_ifacetype = 'test_bare_wb'
+
+        pspec = TestMemPspec(ldst_ifacetype=ldst_ifacetype,
+                             imem_ifacetype=imem_ifacetype,
                              addr_wid=48,
                              mask_wid=8,
                              imem_reg_wid=64,
@@ -149,7 +156,12 @@ class TestRunner(FHDLTestCase):
                              svp64=self.svp64,
                              mmu=self.microwatt_mmu,
                              reg_wid=64)
-        m.submodules.issuer = issuer = TestIssuerInternal(pspec)
+        #hard_reset = Signal(reset_less=True)
+        issuer = TestIssuerInternal(pspec)
+        # use DMI RESET command instead, this does actually work though
+        #issuer = ResetInserter({'coresync': hard_reset,
+        #                        'sync': hard_reset})(issuer)
+        m.submodules.issuer = issuer
         imem = issuer.imem._get_memory()
         core = issuer.core
         dmi = issuer.dbg.dmi
@@ -157,9 +169,8 @@ class TestRunner(FHDLTestCase):
         l0 = core.l0
         regreduce_en = pspec.regreduce_en == True
 
-        # copy of the decoder for simulator
-        simdec = create_pdecode()
-        simdec2 = PowerDecode2(simdec, regreduce_en=regreduce_en)
+        #simdec = create_pdecode()
+        simdec2 = PowerDecode2(None, regreduce_en=regreduce_en)
         m.submodules.simdec2 = simdec2  # pain in the neck
 
         # run core clock at same rate as test clock
@@ -178,15 +189,11 @@ class TestRunner(FHDLTestCase):
             # start in stopped
             yield from set_dmi(dmi, DBGCore.CTRL, 1<<DBGCtrl.STOP)
             yield
-            yield
 
             # get each test, completely reset the core, and run it
 
             for test in self.test_data:
 
-                # pull a reset
-                # yield from set_dmi(dmi, DBGCore.CTRL, 1<<DBGCtrl.RESET)
-
                 # set up bigendian (TODO: don't do this, use MSR)
                 yield issuer.core_bigendian_i.eq(bigendian)
                 yield Settle()
@@ -198,110 +205,105 @@ class TestRunner(FHDLTestCase):
 
                 print(test.name)
                 program = test.program
-                self.subTest(test.name)
-                print("regs", test.regs)
-                print("sprs", test.sprs)
-                print("cr", test.cr)
-                print("mem", test.mem)
-                print("msr", test.msr)
-                print("assem", program.assembly)
-                gen = list(program.generate_instructions())
-                insncode = program.assembly.splitlines()
-                instructions = list(zip(gen, insncode))
-
-                # set up the Simulator (which must track TestIssuer exactly)
-                sim = ISA(simdec2, test.regs, test.sprs, test.cr, test.mem,
-                          test.msr,
-                          initial_insns=gen, respect_pc=True,
-                          disassembly=insncode,
-                          bigendian=bigendian,
-                          initial_svstate=test.svstate)
-
-                # establish the TestIssuer context (mem, regs etc)
-
-                pc = 0  # start address
-                counter = 0  # test to pause/start
-
-                yield from setup_i_memory(imem, pc, instructions)
-                yield from setup_test_memory(l0, sim)
-                yield from setup_regs(pdecode2, core, test)
-
-                # set PC and SVSTATE
-                yield pc_i.eq(pc)
-                yield issuer.pc_i.ok.eq(1)
-
-                initial_svstate = test.svstate
-                if isinstance(initial_svstate, int):
-                    initial_svstate = SVP64State(initial_svstate)
-                yield svstate_i.eq(initial_svstate.spr.value)
-                yield issuer.svstate_i.ok.eq(1)
-                yield
-
-                print("instructions", instructions)
-
-                # run the loop of the instructions on the current test
-                index = sim.pc.CIA.value//4
-                while index < len(instructions):
-                    ins, code = instructions[index]
-
-                    print("instruction: 0x{:X}".format(ins & 0xffffffff))
-                    print(index, code)
-
-                    if counter == 0:
-                        # start the core
-                        yield
-                        yield from set_dmi(dmi, DBGCore.CTRL, 1<<DBGCtrl.START)
-                        yield issuer.pc_i.ok.eq(0)  # no change PC after this
-                        yield issuer.svstate_i.ok.eq(0) # ditto
-                        yield
-                        yield
-
-                    counter = counter + 1
-
-                    # wait until executed
-                    # wait for insn_done high
-                    while not (yield issuer.insn_done):
-                        yield
-                    # wait for insn_done low
-                    while (yield issuer.insn_done):
-                        yield
-
-                    # set up simulated instruction (in simdec2)
-                    try:
-                        yield from sim.setup_one()
-                    except KeyError:  # indicates instruction not in imem: stop
-                        break
-                    yield Settle()
-
-                    # call simulated operation
-                    print("sim", code)
-                    yield from sim.execute_one()
-                    yield Settle()
-                    index = sim.pc.CIA.value//4
-
-                    terminated = yield issuer.dbg.terminated_o
-                    print("terminated", terminated)
-
-                    if index >= len(instructions):
-                        print ("index over, send dmi stop")
-                        # stop at end
-                        yield from set_dmi(dmi, DBGCore.CTRL, 1<<DBGCtrl.STOP)
-                        yield
-                        yield
-
-                    # wait one cycle for registers to settle
+                with self.subTest(test.name):
+                    print("regs", test.regs)
+                    print("sprs", test.sprs)
+                    print("cr", test.cr)
+                    print("mem", test.mem)
+                    print("msr", test.msr)
+                    print("assem", program.assembly)
+                    gen = list(program.generate_instructions())
+                    insncode = program.assembly.splitlines()
+                    instructions = list(zip(gen, insncode))
+
+                    # set up the Simulator (which must track TestIssuer exactly)
+                    sim = ISA(simdec2, test.regs, test.sprs, test.cr, test.mem,
+                              test.msr,
+                              initial_insns=gen, respect_pc=True,
+                              disassembly=insncode,
+                              bigendian=bigendian,
+                              initial_svstate=test.svstate)
+
+                    # establish the TestIssuer context (mem, regs etc)
+
+                    pc = 0  # start address
+                    counter = 0  # test to pause/start
+
+                    yield from setup_i_memory(imem, pc, instructions)
+                    yield from setup_tst_memory(l0, sim)
+                    yield from setup_regs(pdecode2, core, test)
+
+                    # set PC and SVSTATE
+                    yield pc_i.eq(pc)
+                    yield issuer.pc_i.ok.eq(1)
+
+                    initial_svstate = test.svstate
+                    if isinstance(initial_svstate, int):
+                        initial_svstate = SVP64State(initial_svstate)
+                    yield svstate_i.eq(initial_svstate.value)
+                    yield issuer.svstate_i.ok.eq(1)
                     yield
 
-                    # register check
-                    yield from check_regs(self, sim, core, test, code)
-
-                    # Memory check
-                    yield from check_sim_memory(self, l0, sim, code)
+                    print("instructions", instructions)
 
-                    terminated = yield issuer.dbg.terminated_o
-                    print("terminated(2)", terminated)
-                    if terminated:
-                        break
+                    # run the loop of the instructions on the current test
+                    index = sim.pc.CIA.value//4
+                    while index < len(instructions):
+                        ins, code = instructions[index]
+
+                        print("instruction: 0x{:X}".format(ins & 0xffffffff))
+                        print(index, code)
+
+                        if counter == 0:
+                            # start the core
+                            yield
+                            yield from set_dmi(dmi, DBGCore.CTRL,
+                                               1<<DBGCtrl.START)
+                            yield issuer.pc_i.ok.eq(0) # no change PC after this
+                            yield issuer.svstate_i.ok.eq(0) # ditto
+                            yield
+                            yield
+
+                        counter = counter + 1
+
+                        # wait until executed
+                        while not (yield issuer.insn_done):
+                            yield
+
+                        # set up simulated instruction (in simdec2)
+                        try:
+                            yield from sim.setup_one()
+                        except KeyError:  # instruction not in imem: stop
+                            break
+                        yield Settle()
+
+                        # call simulated operation
+                        print("sim", code)
+                        yield from sim.execute_one()
+                        yield Settle()
+                        index = sim.pc.CIA.value//4
+
+                        terminated = yield issuer.dbg.terminated_o
+                        print("terminated", terminated)
+
+                        if index >= len(instructions):
+                            print ("index over, send dmi stop")
+                            # stop at end
+                            yield from set_dmi(dmi, DBGCore.CTRL,
+                                               1<<DBGCtrl.STOP)
+                            yield
+                            yield
+
+                        # register check
+                        yield from check_regs(self, sim, core, test, code)
+
+                        # Memory check
+                        yield from check_sim_memory(self, l0, sim, code)
+
+                        terminated = yield issuer.dbg.terminated_o
+                        print("terminated(2)", terminated)
+                        if terminated:
+                            break
 
                 # stop at end
                 yield from set_dmi(dmi, DBGCore.CTRL, 1<<DBGCtrl.STOP)
@@ -324,6 +326,10 @@ class TestRunner(FHDLTestCase):
                     print("after test %s reg %2d value %x" %
                           (test.name, int_reg, value))
 
+                # pull a reset
+                yield from set_dmi(dmi, DBGCore.CTRL, 1<<DBGCtrl.RESET)
+                yield
+
         styles = {
             'dec': {'base': 'dec'},
             'bin': {'base': 'bin'},
@@ -333,16 +339,16 @@ class TestRunner(FHDLTestCase):
         traces = [
             'clk',
             ('state machines', 'closed', [
-                'fetch_pc_valid_i', 'fetch_pc_ready_o',
+                'fetch_pc_i_valid', 'fetch_pc_o_ready',
                 'fetch_fsm_state',
-                'fetch_insn_valid_o', 'fetch_insn_ready_i',
-                'pred_insn_valid_i', 'pred_insn_ready_o',
+                'fetch_insn_o_valid', 'fetch_insn_i_ready',
+                'pred_insn_i_valid', 'pred_insn_o_ready',
                 'fetch_predicate_state',
-                'pred_mask_valid_o', 'pred_mask_ready_i',
+                'pred_mask_o_valid', 'pred_mask_i_ready',
                 'issue_fsm_state',
-                'exec_insn_valid_i', 'exec_insn_ready_o',
+                'exec_insn_i_valid', 'exec_insn_o_ready',
                 'exec_fsm_state',
-                'exec_pc_valid_o', 'exec_pc_ready_i',
+                'exec_pc_o_valid', 'exec_pc_i_ready',
                 'insn_done', 'core_stop_o', 'pc_i_ok', 'pc_changed',
                 'is_last', 'dec2.no_out_vec']),
             {'comment': 'fetch and decode'},
@@ -406,9 +412,32 @@ class TestRunner(FHDLTestCase):
             'core.int.rp_src1.memory(7)[63:0]',
             'core.int.rp_src1.memory(9)[63:0]',
             'core.int.rp_src1.memory(10)[63:0]',
-            'core.int.rp_src1.memory(13)[63:0]',
+            'core.int.rp_src1.memory(13)[63:0]'
         ]
 
+        # PortInterface module path varies depending on MMU option
+        if self.microwatt_mmu:
+            pi_module = 'core.ldst0'
+        else:
+            pi_module = 'core.fus.ldst0'
+
+        traces += [('ld/st port interface', {'submodule': pi_module}, [
+            'oper_r__insn_type',
+            'ldst_port0_is_ld_i',
+            'ldst_port0_is_st_i',
+            'ldst_port0_busy_o',
+            'ldst_port0_addr_i[47:0]',
+            'ldst_port0_addr_i_ok',
+            'ldst_port0_addr_ok_o',
+            'ldst_port0_exc_happened',
+            'ldst_port0_st_data_i[63:0]',
+            'ldst_port0_st_data_i_ok',
+            'ldst_port0_ld_data_o[63:0]',
+            'ldst_port0_ld_data_o_ok',
+            'exc_o_happened',
+            'cancel'
+        ])]
+
         if self.microwatt_mmu:
             traces += [
                 {'comment': 'microwatt_mmu'},