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