Allow the formal engine to perform a same-cycle result in the ALU
[soc.git] / src / soc / fu / mmu / test / test_non_production_core.py
1 from nmigen import Module, Signal
2
3 from nmutil.sim_tmp_alternative import Simulator, Settle
4
5 from nmigen.cli import rtlil
6 import unittest
7 from openpower.decoder.isa.caller import ISACaller, special_sprs
8 from openpower.decoder.power_decoder import (create_pdecode)
9 from openpower.decoder.power_decoder2 import (PowerDecode2)
10 from openpower.decoder.power_enums import (XER_bits, Function, MicrOp, CryIn)
11 from openpower.decoder.selectable_int import SelectableInt
12 from openpower.simulator.program import Program
13 from openpower.decoder.isa.all import ISA
14 from openpower.endian import bigendian
15 from openpower.consts import MSR
16
17
18 from openpower.test.common import (
19 TestAccumulatorBase, skip_case, TestCase, ALUHelpers)
20 import random
21
22 from soc.fu.div.test.helper import (log_rand, get_cu_inputs,
23 set_alu_inputs, DivTestHelper)
24
25 from soc.simple.core import NonProductionCore
26 from soc.config.test.test_loadstore import TestMemPspec
27 from soc.simple.test.test_core import (setup_regs, check_regs,
28 wait_for_busy_clear,
29 wait_for_busy_hi)
30
31 debughang = 2
32
33
34 class MMUTestCase(TestAccumulatorBase):
35 # MMU handles MTSPR, MFSPR, DCBZ and TLBIE.
36 # other instructions here -> must be load/store
37
38 def case_mfspr_after_invalid_load(self):
39 lst = [ # TODO -- set SPR on both sinulator and port interface
40 "mfspr 1, 18", # DSISR to reg 1
41 "mfspr 2, 19", # DAR to reg 2
42 # TODO -- verify returned sprvals
43 ]
44
45 initial_regs = [0] * 32
46
47 # THOSE are currently broken -- initial_sprs = {'DSISR': 0x12345678, 'DAR': 0x87654321}
48 initial_sprs = {}
49 self.add_case(Program(lst, bigendian),
50 initial_regs, initial_sprs)
51
52 # def case_ilang(self):
53 # pspec = SPRPipeSpec(id_wid=2, parent_pspec=None)
54 # alu = SPRBasePipe(pspec)
55 # vl = rtlil.convert(alu, ports=alu.ports())
56 # with open("trap_pipeline.il", "w") as f:
57 # f.write(vl)
58
59
60 class TestRunner(unittest.TestCase):
61 def __init__(self, test_data):
62 super().__init__("run_all")
63 self.test_data = test_data
64
65 def execute(self, core, instruction, pdecode2, test):
66 program = test.program
67 sim = ISA(pdecode2, test.regs, test.sprs, test.cr,
68 test.mem, test.msr,
69 bigendian=bigendian)
70 gen = program.generate_instructions()
71 instructions = list(zip(gen, program.assembly.splitlines()))
72
73 pc = sim.pc.CIA.value
74 msr = sim.msr.value
75 index = pc//4
76 while index < len(instructions):
77 ins, code = instructions[index]
78
79 print("pc %08x instr: %08x" % (pc, ins & 0xffffffff))
80 print(code)
81
82 if 'XER' in sim.spr:
83 so = 1 if sim.spr['XER'][XER_bits['SO']] else 0
84 ov = 1 if sim.spr['XER'][XER_bits['OV']] else 0
85 ov32 = 1 if sim.spr['XER'][XER_bits['OV32']] else 0
86 print("before: so/ov/32", so, ov, ov32)
87
88 # ask the decoder to decode this binary data (endian'd)
89 yield pdecode2.dec.bigendian.eq(bigendian) # little / big?
90 yield pdecode2.state.msr.eq(msr) # set MSR in pdecode2
91 yield pdecode2.state.pc.eq(pc) # set PC in pdecode2
92 yield instruction.eq(ins) # raw binary instr.
93 yield Settle()
94
95 yield from setup_regs(pdecode2, core, test)
96
97 opname = code.split(' ')[0]
98 yield from sim.call(opname)
99 pc = sim.pc.CIA.value
100 msr = sim.msr.value
101 index = pc//4
102 print("pc after %08x" % (pc))
103
104 fsm = core.fus.fus["mmu0"].alu
105
106 vld = yield fsm.n.o_valid
107 while not vld:
108 yield
109 if debughang:
110 print("not valid -- hang")
111 vld = yield fsm.n.o_valid
112 if debughang == 2:
113 vld = 1
114 yield
115
116 def run_all(self):
117 m = Module()
118 comb = m.d.comb
119 instruction = Signal(32)
120
121 pdecode = create_pdecode()
122
123 m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
124
125 pspec = TestMemPspec(ldst_ifacetype='testpi',
126 imem_ifacetype='',
127 addr_wid=48,
128 mask_wid=8,
129 reg_wid=64)
130
131 m.submodules.core = core = NonProductionCore(pspec
132 # XXX NO absolutely do not do this.
133 # all options must go into the pspec
134 # , microwatt_mmu=True
135 )
136
137 comb += pdecode2.dec.raw_opcode_in.eq(instruction)
138 sim = Simulator(m)
139
140 sim.add_clock(1e-6)
141
142 def process():
143 for test in self.test_data:
144 print("test", test.name)
145 print("sprs", test.sprs)
146 program = test.program
147 with self.subTest(test.name):
148 yield from self.execute(core, instruction, pdecode2, test)
149
150 sim.add_sync_process(process)
151 with sim.write_vcd("mmu_ldst_simulator.vcd", "mmu_ldst_simulator.gtkw",
152 traces=[]):
153 sim.run()
154
155
156 if __name__ == "__main__":
157 unittest.main(exit=False)
158 suite = unittest.TestSuite()
159 suite.addTest(TestRunner(MMUTestCase().test_data))
160
161 runner = unittest.TextTestRunner()
162 runner.run(suite)