8932c0bb30e2b6aed98118876c34b5316f432ade
[soc.git] / src / soc / fu / trap / test / test_pipe_caller.py
1 """trap pipeline tests
2
3 issues:
4 * https://bugs.libre-soc.org/show_bug.cgi?id=629
5 """
6
7 from nmigen import Module, Signal
8
9 # NOTE: to use cxxsim, export NMIGEN_SIM_MODE=cxxsim from the shell
10 # Also, check out the cxxsim nmigen branch, and latest yosys from git
11 from nmutil.sim_tmp_alternative import Simulator, Settle
12
13 from nmigen.cli import rtlil
14 import unittest
15 from openpower.decoder.power_decoder import (create_pdecode)
16 from openpower.decoder.power_decoder2 import (PowerDecode2)
17 from openpower.decoder.power_enums import XER_bits, Function
18 from openpower.decoder.selectable_int import SelectableInt
19 from openpower.decoder.isa.all import ISA
20 from openpower.endian import bigendian
21 from openpower.consts import MSR
22
23 from openpower.test.common import TestAccumulatorBase, ALUHelpers
24 from soc.fu.trap.pipeline import TrapBasePipe
25 from soc.fu.trap.pipe_data import TrapPipeSpec
26 import random
27
28 from openpower.test.trap.trap_cases import TrapTestCase
29
30
31 def get_cu_inputs(dec2, sim):
32 """naming (res) must conform to TrapFunctionUnit input regspec
33 """
34 res = {}
35
36 yield from ALUHelpers.get_sim_int_ra(res, sim, dec2) # RA
37 yield from ALUHelpers.get_sim_int_rb(res, sim, dec2) # RB
38 yield from ALUHelpers.get_sim_fast_spr1(res, sim, dec2) # SPR0
39 yield from ALUHelpers.get_sim_fast_spr2(res, sim, dec2) # SPR1
40 yield from ALUHelpers.get_sim_fast_spr3(res, sim, dec2) # SVSRR0
41 ALUHelpers.get_sim_cia(res, sim, dec2) # PC
42 ALUHelpers.get_sim_msr(res, sim, dec2) # MSR
43
44 print("alu get_cu_inputs", res)
45
46 return res
47
48
49 def set_alu_inputs(alu, dec2, sim):
50 # TODO: see https://bugs.libre-soc.org/show_bug.cgi?id=305#c43
51 # detect the immediate here (with m.If(self.i.ctx.op.imm_data.imm_ok))
52 # and place it into i_data.b
53
54 inp = yield from get_cu_inputs(dec2, sim)
55 yield from ALUHelpers.set_int_ra(alu, dec2, inp)
56 yield from ALUHelpers.set_int_rb(alu, dec2, inp)
57 yield from ALUHelpers.set_fast_spr1(alu, dec2, inp) # SPR0
58 yield from ALUHelpers.set_fast_spr2(alu, dec2, inp) # SPR1
59 yield from ALUHelpers.set_fast_spr3(alu, dec2, inp) # SVSRR0
60
61 # yield from ALUHelpers.set_cia(alu, dec2, inp)
62 # yield from ALUHelpers.set_msr(alu, dec2, inp)
63 return inp
64
65
66 class TrapIlangCase(TestAccumulatorBase):
67
68 def case_ilang(self):
69 pspec = TrapPipeSpec(id_wid=2, parent_pspec=None)
70 alu = TrapBasePipe(pspec)
71 vl = rtlil.convert(alu, ports=alu.ports())
72 with open("trap_pipeline.il", "w") as f:
73 f.write(vl)
74
75
76 class TestRunner(unittest.TestCase):
77 def __init__(self, test_data):
78 super().__init__("run_all")
79 self.test_data = test_data
80
81
82 def execute(self, alu, instruction, pdecode2, test):
83 program = test.program
84 sim = ISA(pdecode2, test.regs, test.sprs, test.cr,
85 test.mem, test.msr,
86 bigendian=bigendian)
87 gen = program.generate_instructions()
88 instructions = list(zip(gen, program.assembly.splitlines()))
89
90 msr = sim.msr.value
91 pc = sim.pc.CIA.value
92 print("starting msr, pc %08x, %08x" % (msr, pc))
93 index = pc//4
94 while index < len(instructions):
95 ins, code = instructions[index]
96
97 print("pc %08x msr %08x instr: %08x" % (pc, msr, ins))
98 print(code)
99 if 'XER' in sim.spr:
100 so = 1 if sim.spr['XER'][XER_bits['SO']] else 0
101 ov = 1 if sim.spr['XER'][XER_bits['OV']] else 0
102 ov32 = 1 if sim.spr['XER'][XER_bits['OV32']] else 0
103 print("before: so/ov/32", so, ov, ov32)
104
105 # ask the decoder to decode this binary data (endian'd)
106 yield pdecode2.dec.bigendian.eq(bigendian) # l/big?
107 yield pdecode2.state.msr.eq(msr) # set MSR in pdecode2
108 yield pdecode2.state.pc.eq(pc) # set CIA in pdecode2
109 yield instruction.eq(ins) # raw binary instr.
110 yield Settle()
111 fn_unit = yield pdecode2.e.do.fn_unit
112 asmcode = yield pdecode2.e.asmcode
113 dec_asmcode = yield pdecode2.dec.op.asmcode
114 print("asmcode", asmcode, dec_asmcode)
115 self.assertEqual(fn_unit, Function.TRAP.value)
116 alu_o = yield from set_alu_inputs(alu, pdecode2, sim)
117
118 # set valid for one cycle, propagate through pipeline...
119 yield alu.p.i_valid.eq(1)
120 yield
121 yield alu.p.i_valid.eq(0)
122
123 opname = code.split(' ')[0]
124 yield from sim.call(opname)
125 pc = sim.pc.CIA.value
126 index = pc//4
127 print("pc after %08x" % (pc))
128 msr = sim.msr.value
129 print("msr after %08x" % (msr))
130
131 vld = yield alu.n.o_valid
132 while not vld:
133 yield
134 vld = yield alu.n.o_valid
135 yield
136
137 yield from self.check_alu_outputs(alu, pdecode2, sim, code)
138 yield Settle()
139
140 def run_all(self):
141 m = Module()
142 comb = m.d.comb
143 instruction = Signal(32)
144
145 pdecode = create_pdecode()
146
147 m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
148
149 pspec = TrapPipeSpec(id_wid=2, parent_pspec=None)
150 m.submodules.alu = alu = TrapBasePipe(pspec)
151
152 comb += alu.p.i_data.ctx.op.eq_from_execute1(pdecode2.do)
153 comb += alu.n.i_ready.eq(1)
154 comb += pdecode2.dec.raw_opcode_in.eq(instruction)
155 sim = Simulator(m)
156
157 sim.add_clock(1e-6)
158
159 def process():
160 for test in self.test_data:
161 print(test.name)
162 program = test.program
163 with self.subTest(test.name):
164 yield from self.execute(alu, instruction, pdecode2, test)
165
166 sim.add_sync_process(process)
167 with sim.write_vcd("alu_simulator.vcd", "simulator.gtkw",
168 traces=[]):
169 sim.run()
170
171 def check_alu_outputs(self, alu, dec2, sim, code):
172
173 rc = yield dec2.e.do.rc.data
174 cridx_ok = yield dec2.e.write_cr.ok
175 cridx = yield dec2.e.write_cr.data
176
177 print("check extra output", repr(code), cridx_ok, cridx)
178 if rc:
179 self.assertEqual(cridx, 0, code)
180
181 sim_o = {}
182 res = {}
183
184 yield from ALUHelpers.get_int_o(res, alu, dec2)
185 yield from ALUHelpers.get_fast_spr1(res, alu, dec2)
186 yield from ALUHelpers.get_fast_spr2(res, alu, dec2)
187 yield from ALUHelpers.get_fast_spr3(res, alu, dec2)
188 yield from ALUHelpers.get_nia(res, alu, dec2)
189 yield from ALUHelpers.get_msr(res, alu, dec2)
190
191 print("output", res)
192
193 yield from ALUHelpers.get_sim_int_o(sim_o, sim, dec2)
194 yield from ALUHelpers.get_wr_fast_spr1(sim_o, sim, dec2)
195 yield from ALUHelpers.get_wr_fast_spr2(sim_o, sim, dec2)
196 yield from ALUHelpers.get_wr_fast_spr3(sim_o, sim, dec2)
197 ALUHelpers.get_sim_nia(sim_o, sim, dec2)
198 ALUHelpers.get_sim_msr(sim_o, sim, dec2)
199
200 print("sim output", sim_o)
201
202 ALUHelpers.check_int_o(self, res, sim_o, code)
203 ALUHelpers.check_fast_spr1(self, res, sim_o, code)
204 ALUHelpers.check_fast_spr2(self, res, sim_o, code)
205 ALUHelpers.check_fast_spr3(self, res, sim_o, code)
206 ALUHelpers.check_nia(self, res, sim_o, code)
207 ALUHelpers.check_msr(self, res, sim_o, code)
208
209
210 if __name__ == "__main__":
211 unittest.main(exit=False)
212 suite = unittest.TestSuite()
213 suite.addTest(TestRunner(TrapTestCase().test_data))
214 suite.addTest(TestRunner(TrapIlangCase().test_data))
215
216 runner = unittest.TextTestRunner()
217 runner.run(suite)