1e28f9a1ebe1f4a33da2c47fa596b6c8d56e0564
[soc.git] / src / soc / fu / mmu / test / test_non_production_core.py
1 from nmigen import Module, Signal
2
3 # NOTE: to use cxxsim, export NMIGEN_SIM_MODE=cxxsim from the shell
4 # Also, check out the cxxsim nmigen branch, and latest yosys from git
5 from nmutil.sim_tmp_alternative import Simulator, Settle
6
7 from nmigen.cli import rtlil
8 import unittest
9 from soc.decoder.isa.caller import ISACaller, special_sprs
10 from soc.decoder.power_decoder import (create_pdecode)
11 from soc.decoder.power_decoder2 import (PowerDecode2)
12 from soc.decoder.power_enums import (XER_bits, Function, MicrOp, CryIn)
13 from soc.decoder.selectable_int import SelectableInt
14 from soc.simulator.program import Program
15 from soc.decoder.isa.all import ISA
16 from soc.config.endian import bigendian
17 from soc.consts import MSR
18
19
20 from soc.fu.test.common import (
21 TestAccumulatorBase, skip_case, TestCase, ALUHelpers)
22 #from soc.fu.spr.pipeline import SPRBasePipe
23 #from soc.fu.spr.pipe_data import SPRPipeSpec
24 #from soc.fu.mmu.fsm import FSMMMUStage
25 #from soc.fu.mmu.pipe_data import MMUPipeSpec
26 import random
27
28 from soc.fu.div.test.helper import (log_rand, get_cu_inputs,
29 set_alu_inputs, DivTestHelper)
30
31 from soc.simple.core import NonProductionCore
32 from soc.config.test.test_loadstore import TestMemPspec
33 from soc.simple.test.test_core import (setup_regs, check_regs,
34 wait_for_busy_clear,
35 wait_for_busy_hi)
36
37 import power_instruction_analyzer as pia
38
39 debughang = 2
40
41 def set_fsm_inputs_do_not_use(alu, dec2, sim):
42 # TODO: see https://bugs.libre-soc.org/show_bug.cgi?id=305#c43
43 # detect the immediate here (with m.If(self.i.ctx.op.imm_data.imm_ok))
44 # and place it into data_i.b
45
46 print("Error here")
47 inp = yield from get_cu_inputs(dec2, sim)
48 # set int registers a and b
49 yield from ALUHelpers.set_int_ra(alu, dec2, inp)
50 yield from ALUHelpers.set_int_rb(alu, dec2, inp)
51 # TODO set spr register
52 # yield from ALUHelpers.set_spr_spr1(alu, dec2, inp)
53
54 overflow = None
55 a=None
56 b=None
57 # TODO
58 if 'xer_so' in inp:
59 print("xer_so::::::::::::::::::::::::::::::::::::::::::::::::")
60 so = inp['xer_so']
61 print(so)
62 overflow = pia.OverflowFlags(so=bool(so),
63 ov=False,
64 ov32=False)
65 if 'ra' in inp:
66 a = inp['ra']
67 if 'rb' in inp:
68 b = inp['rb']
69 print(inp)
70 return pia.InstructionInput(ra=a, rb=b, overflow=overflow)
71
72 class MMUTestCase(TestAccumulatorBase):
73 # MMU handles MTSPR, MFSPR, DCBZ and TLBIE.
74 # other instructions here -> must be load/store
75
76 #before running the test case: set DISR and DAR
77
78 def case_mfspr_after_invalid_load(self):
79 lst = [ # TODO -- set SPR on both sinulator and port interface
80 "mfspr 1, 18", # DSISR to reg 1
81 "mfspr 2, 19", # DAR to reg 2
82 # TODO -- verify returned sprvals
83 ]
84
85 initial_regs = [0] * 32
86
87 #initial_sprs = {'DSISR': 0x12345678, 'DAR': 0x87654321}
88 initial_sprs = {}
89 self.add_case(Program(lst, bigendian),
90 initial_regs, initial_sprs)
91
92 #def case_ilang(self):
93 # pspec = SPRPipeSpec(id_wid=2)
94 # alu = SPRBasePipe(pspec)
95 # vl = rtlil.convert(alu, ports=alu.ports())
96 # with open("trap_pipeline.il", "w") as f:
97 # f.write(vl)
98
99
100 class TestRunner(unittest.TestCase):
101 def __init__(self, test_data):
102 super().__init__("run_all")
103 self.test_data = test_data
104
105 def check_fsm_outputs_delete_me(self, alu, dec2, sim, code, pia_res):
106
107 rc = yield dec2.e.do.rc.data
108 cridx_ok = yield dec2.e.write_cr.ok
109 cridx = yield dec2.e.write_cr.data
110
111 print("check extra output", repr(code), cridx_ok, cridx)
112 if rc:
113 self.assertEqual(cridx, 0, code)
114
115 sim_o = {}
116 res = {}
117
118 #MMUOutputData does not have xer
119
120 yield from ALUHelpers.get_cr_a(res, alu, dec2)
121 #yield from ALUHelpers.get_xer_ov(res, alu, dec2)
122 yield from ALUHelpers.get_int_o(res, alu, dec2)
123 #yield from ALUHelpers.get_xer_so(res, alu, dec2)
124
125
126 print("res output", res)
127
128 yield from ALUHelpers.get_sim_int_o(sim_o, sim, dec2)
129 yield from ALUHelpers.get_wr_sim_cr_a(sim_o, sim, dec2)
130 #yield from ALUHelpers.get_sim_xer_ov(sim_o, sim, dec2)
131 #yield from ALUHelpers.get_sim_xer_so(sim_o, sim, dec2)
132
133 print("sim output", sim_o)
134
135 print("power-instruction-analyzer result:")
136 print(pia_res)
137 #if pia_res is not None:
138 # with self.subTest(check="pia", sim_o=sim_o, pia_res=str(pia_res)):
139 # pia_o = pia_res_to_output(pia_res)
140 # ALUHelpers.check_int_o(self, res, pia_o, code)
141 # ALUHelpers.check_cr_a(self, res, pia_o, code)
142 # #ALUHelpers.check_xer_ov(self, res, pia_o, code)
143 # #ALUHelpers.check_xer_so(self, res, pia_o, code)
144
145 with self.subTest(check="sim", sim_o=sim_o, pia_res=str(pia_res)):
146 #ALUHelpers.check_int_o(self, res, sim_o, code) # mmu is not an alu
147 ALUHelpers.check_cr_a(self, res, sim_o, code)
148 #ALUHelpers.check_xer_ov(self, res, sim_o, code)
149 #ALUHelpers.check_xer_so(self, res, sim_o, code)
150
151 #oe = yield dec2.e.do.oe.oe
152 #oe_ok = yield dec2.e.do.oe.ok
153 #print("oe, oe_ok", oe, oe_ok)
154 #if not oe or not oe_ok:
155 # # if OE not enabled, XER SO and OV must not be activated
156 # so_ok = yield alu.n.data_o.xer_so.ok
157 # ov_ok = yield alu.n.data_o.xer_ov.ok
158 # print("so, ov", so_ok, ov_ok)
159 # self.assertEqual(ov_ok, False, code)
160 # self.assertEqual(so_ok, False, code)
161
162 def execute(self, core, instruction, pdecode2, test):
163 program = test.program
164 sim = ISA(pdecode2, test.regs, test.sprs, test.cr,
165 test.mem, test.msr,
166 bigendian=bigendian)
167 gen = program.generate_instructions()
168 instructions = list(zip(gen, program.assembly.splitlines()))
169
170 pc = sim.pc.CIA.value
171 msr = sim.msr.value
172 index = pc//4
173 while index < len(instructions):
174 ins, code = instructions[index]
175
176 print("pc %08x instr: %08x" % (pc, ins & 0xffffffff))
177 print(code)
178
179 if 'XER' in sim.spr:
180 so = 1 if sim.spr['XER'][XER_bits['SO']] else 0
181 ov = 1 if sim.spr['XER'][XER_bits['OV']] else 0
182 ov32 = 1 if sim.spr['XER'][XER_bits['OV32']] else 0
183 print("before: so/ov/32", so, ov, ov32)
184
185 # ask the decoder to decode this binary data (endian'd)
186 yield pdecode2.dec.bigendian.eq(bigendian) # little / big?
187 yield pdecode2.state.msr.eq(msr) # set MSR in pdecode2
188 yield pdecode2.state.pc.eq(pc) # set PC in pdecode2
189 yield instruction.eq(ins) # raw binary instr.
190 yield Settle()
191
192 #
193 yield from setup_regs(pdecode2, core, test)
194
195 ##fast_in = yield pdecode2.e.read_fast1.data
196 ##spr_in = yield pdecode2.e.read_spr1.data
197 ##print("dec2 spr/fast in", fast_in, spr_in)
198
199 ##fast_out = yield pdecode2.e.write_fast1.data
200 ##spr_out = yield pdecode2.e.write_spr.data
201 ##print("dec2 spr/fast in", fast_out, spr_out)
202
203 ##fn_unit = yield pdecode2.e.do.fn_unit
204 ##pia_res = yield from set_fsm_inputs(fsm, pdecode2, sim)
205 ##yield
206 opname = code.split(' ')[0]
207 yield from sim.call(opname)
208 pc = sim.pc.CIA.value
209 msr = sim.msr.value
210 index = pc//4
211 print("pc after %08x" % (pc))
212
213 fsm = core.fus.fus["mmu0"].alu
214
215 vld = yield fsm.n.valid_o #fsm
216 while not vld:
217 yield
218 if debughang: print("not valid -- hang")
219 vld = yield fsm.n.valid_o
220 if debughang==2: vld=1
221 yield
222
223 def run_all(self):
224 m = Module()
225 comb = m.d.comb
226 instruction = Signal(32)
227
228 pdecode = create_pdecode()
229
230 m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
231
232 pspec = TestMemPspec(ldst_ifacetype='testpi',
233 imem_ifacetype='',
234 addr_wid=48,
235 mask_wid=8,
236 reg_wid=64)
237
238 m.submodules.core = core = NonProductionCore(pspec,microwatt_mmu=True)
239
240 comb += pdecode2.dec.raw_opcode_in.eq(instruction)
241 sim = Simulator(m)
242
243 sim.add_clock(1e-6)
244
245 def process():
246 for test in self.test_data:
247 print("test", test.name)
248 print("sprs", test.sprs)
249 program = test.program
250 with self.subTest(test.name):
251 yield from self.execute(core, instruction, pdecode2, test)
252
253 sim.add_sync_process(process)
254 with sim.write_vcd("mmu_ldst_simulator.vcd", "mmu_ldst_simulator.gtkw",
255 traces=[]):
256 sim.run()
257
258 if __name__ == "__main__":
259 unittest.main(exit=False)
260 suite = unittest.TestSuite()
261 suite.addTest(TestRunner(MMUTestCase().test_data))
262
263 runner = unittest.TextTestRunner()
264 runner.run(suite)