add sv.divmod2du test, inverse of the sv.madded
[openpower-isa.git] / src / openpower / test / runner.py
index 839709f7823623be236c50f504532d58407f291e..cf9b28b3615bae44be508337fc6e3adfe0e92beb 100644 (file)
@@ -18,7 +18,7 @@ related bugs:
 from unittest.mock import Mock
 from nmigen import Module, ClockSignal
 from copy import copy, deepcopy
-from pprint import pprint
+from pprint import pformat
 
 # NOTE: to use cxxsim, export NMIGEN_SIM_MODE=cxxsim from the shell
 # Also, check out the cxxsim nmigen branch, and latest yosys from git
@@ -35,6 +35,7 @@ from nmutil.util import wrap
 from openpower.test.wb_get import wb_get
 import openpower.test.wb_get as wbget
 from openpower.test.state import TestState, StateRunner, ExpectedState
+from openpower.util import log, LogKind
 
 
 class SimRunner(StateRunner):
@@ -47,8 +48,10 @@ class SimRunner(StateRunner):
         self.dut = dut
 
         self.mmu = pspec.mmu == True
+        fp_en = pspec.fp_en == True
         regreduce_en = pspec.regreduce_en == True
-        self.simdec2 = simdec2 = PowerDecode2(None, regreduce_en=regreduce_en)
+        self.simdec2 = simdec2 = PowerDecode2(
+            None, regreduce_en=regreduce_en, fp_en=fp_en)
         m.submodules.simdec2 = simdec2  # pain in the neck
 
     def prepare_for_test(self, test):
@@ -70,15 +73,22 @@ class SimRunner(StateRunner):
                   disassembly=insncode,
                   bigendian=bigendian,
                   initial_svstate=test.svstate,
-                  mmu=self.mmu)
+                  mmu=self.mmu,
+                  fpregfile=test.fpregs)
 
         # 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("sim instr: 0x{:X}".format(ins & 0xffffffff))
-            print(index, code)
+            # extra new-line so it's easier to visually separate each
+            # instruction in output
+            log(f"\n0x{sim.pc.CIA.value:04X}: {ins % (1 << 32):08X} {code}",
+                kind=LogKind.InstrInOuts)
+
+            log("sim instr: 0x{:X} pc=0x{:X}".format(ins & 0xffffffff,
+                                                     sim.pc.CIA.value))
+            log(index, code)
 
             # set up simulated instruction (in simdec2)
             try:
@@ -88,7 +98,7 @@ class SimRunner(StateRunner):
             yield Settle()
 
             # call simulated operation
-            print("sim", code)
+            log("sim", code)
             yield from sim.execute_one()
             yield Settle()
             index = sim.pc.CIA.value//4
@@ -97,6 +107,8 @@ class SimRunner(StateRunner):
             state = yield from TestState("sim", sim, dut, code)
             sim_states.append(state)
 
+        log(f"final pc: 0x{sim.pc.CIA.value:X}", kind=LogKind.InstrInOuts)
+
         if self.dut.allow_overlap:
             # get last state, at end of run
             state = yield from TestState("sim", sim, dut, code)
@@ -118,7 +130,7 @@ class TestRunnerBase(FHDLTestCase):
 
     def __init__(self, tst_data, microwatt_mmu=False, rom=None,
                  svp64=True, run_hdl=None, run_sim=True,
-                 allow_overlap=False, inorder=False):
+                 allow_overlap=False, inorder=False, fp=False):
         super().__init__("run_all")
         self.test_data = tst_data
         self.microwatt_mmu = microwatt_mmu
@@ -128,6 +140,7 @@ class TestRunnerBase(FHDLTestCase):
         self.inorder = inorder
         self.run_hdl = run_hdl
         self.run_sim = run_sim
+        self.fp = fp
 
     def run_all(self):
         m = Module()
@@ -161,7 +174,8 @@ class TestRunnerBase(FHDLTestCase):
                      allow_overlap=self.allow_overlap,
                      inorder=self.inorder,
                      mmu=self.microwatt_mmu,
-                     reg_wid=64)
+                     reg_wid=64,
+                     fp_en=self.fp)
 
         ###### SETUP PHASE #######
         # Determine the simulations needed and add to state_list
@@ -223,14 +237,43 @@ class TestRunnerBase(FHDLTestCase):
                     for runner in state_list:
                         yield from runner.prepare_for_test(test)
 
-                    print(test.name)
+                    log("running test: ", test.name, test.subtest_args,
+                        kind=LogKind.InstrInOuts)
                     program = test.program
-                    print("regs", test.regs)
-                    print("sprs", test.sprs)
-                    print("cr", test.cr)
-                    print("mem", test.mem)
-                    print("msr", test.msr)
-                    print("assem", program.assembly)
+
+                    def format_regs(regs):
+                        # type: (list[int]) -> str
+                        out = []
+                        for i, v in enumerate(regs):
+                            values = ""
+                            for sz in (32, 64):
+                                for signed in ("u", "i"):
+                                    value = v % (1 << sz)
+                                    if signed == "i" and \
+                                            value & (1 << (sz - 1)) != 0:
+                                        value -= 1 << sz
+                                    values += f" {signed}{sz}:{value}"
+                            out.append(f"r{i} = 0x{v:X} {values}")
+                        return "\n".join(out)
+                    log("regs:", format_regs(test.regs),
+                        kind=LogKind.InstrInOuts)
+                    log("sprs", test.sprs, kind=LogKind.InstrInOuts)
+                    log("cr", test.cr, kind=LogKind.InstrInOuts)
+                    log("mem", test.mem)
+                    log("msr", test.msr, kind=LogKind.InstrInOuts)
+
+                    def format_assembly(assembly):
+                        # type: (str) -> str
+                        pc = 0
+                        out = []
+                        for line in assembly.splitlines():
+                            out.append(f"pc=0x{pc:04X}: {line}")
+                            if not line.startswith(".set ") and \
+                                    line.partition('#')[0].strip() != "":
+                                pc += 4
+                        return "\n".join(out)
+                    log("assembly:\n" + format_assembly(program.assembly),
+                        kind=LogKind.InstrInOuts)
                     gen = list(program.generate_instructions())
                     insncode = program.assembly.splitlines()
                     instructions = list(zip(gen, insncode))
@@ -280,27 +323,28 @@ class TestRunnerBase(FHDLTestCase):
                         last_sim = None  # err what are you doing??
 
                     if self.run_hdl:
-                        print("hdl_states")
+                        log("hdl_states")
                         for state in hdl_states:
-                            print(state)
+                            log(state)
 
-                    if self.run_sim:
-                        print("sim_states")
-                        for state in sim_states:
-                            print(state)
+                    # FIXME: commented until SimState has a __repr__
+                    # if self.run_sim:
+                    #     log("sim_states")
+                    #     for state in sim_states:
+                    #         log(state)
 
                     # compare the states
                     if self.run_hdl and self.run_sim:
                         # if allow_overlap is enabled, because allow_overlap
                         # can commit out-of-order, only compare the last ones
                         if self.allow_overlap:
-                            print("allow_overlap: truncating %d %d "
-                                  "states to last" % (len(sim_states),
-                                                      len(hdl_states)))
+                            log("allow_overlap: truncating %d %d "
+                                "states to last" % (len(sim_states),
+                                                    len(hdl_states)))
                             sim_states = sim_states[-1:]
                             hdl_states = hdl_states[-1:]
                             sim_states[-1].dump_state_tofile()
-                            print("allow_overlap: last hdl_state")
+                            log("allow_overlap: last hdl_state")
                             hdl_states[-1].dump_state_tofile()
                         for simstate, hdlstate in zip(sim_states, hdl_states):
                             simstate.compare(hdlstate)     # register check
@@ -503,8 +547,8 @@ class TestRunnerBase(FHDLTestCase):
         # extra emulated process
         self.default_mem = {}
         if self.rom is not None:
-            print("TestRunner with MMU ROM")
-            pprint(self.rom)
+            log("TestRunner with MMU ROM")
+            log(pformat(self.rom))
             dcache = hdlrun.issuer.core.fus.fus["mmu0"].alu.dcache
             icache = hdlrun.issuer.core.fus.fus["mmu0"].alu.icache
             self.default_mem = deepcopy(self.rom)