Allow the formal engine to perform a same-cycle result in the ALU
[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 def run_all(self):
82 m = Module()
83 comb = m.d.comb
84 instruction = Signal(32)
85
86 pdecode = create_pdecode()
87
88 m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
89
90 pspec = TrapPipeSpec(id_wid=2, parent_pspec=None)
91 m.submodules.alu = alu = TrapBasePipe(pspec)
92
93 comb += alu.p.i_data.ctx.op.eq_from_execute1(pdecode2.do)
94 comb += alu.p.i_valid.eq(1)
95 comb += alu.n.i_ready.eq(1)
96 comb += pdecode2.dec.raw_opcode_in.eq(instruction)
97 sim = Simulator(m)
98
99 sim.add_clock(1e-6)
100
101 def process():
102 for test in self.test_data:
103 print(test.name)
104 program = test.program
105 with self.subTest(test.name):
106 sim = ISA(pdecode2, test.regs, test.sprs, test.cr,
107 test.mem, test.msr,
108 bigendian=bigendian)
109 gen = program.generate_instructions()
110 instructions = list(
111 zip(gen, program.assembly.splitlines()))
112
113 msr = sim.msr.value
114 pc = sim.pc.CIA.value
115 print("starting msr, pc %08x, %08x" % (msr, pc))
116 index = pc//4
117 while index < len(instructions):
118 ins, code = instructions[index]
119
120 print("pc %08x msr %08x instr: %08x" % (pc, msr, ins))
121 print(code)
122 if 'XER' in sim.spr:
123 so = 1 if sim.spr['XER'][XER_bits['SO']] else 0
124 ov = 1 if sim.spr['XER'][XER_bits['OV']] else 0
125 ov32 = 1 if sim.spr['XER'][XER_bits['OV32']] else 0
126 print("before: so/ov/32", so, ov, ov32)
127
128 # ask the decoder to decode this binary data (endian'd)
129 yield pdecode2.dec.bigendian.eq(bigendian) # l/big?
130 yield pdecode2.state.msr.eq(msr) # set MSR in pdecode2
131 yield pdecode2.state.pc.eq(pc) # set CIA in pdecode2
132 yield instruction.eq(ins) # raw binary instr.
133 yield Settle()
134 fn_unit = yield pdecode2.e.do.fn_unit
135 self.assertEqual(fn_unit, Function.TRAP.value)
136 alu_o = yield from set_alu_inputs(alu, pdecode2, sim)
137 yield
138 opname = code.split(' ')[0]
139 yield from sim.call(opname)
140 pc = sim.pc.CIA.value
141 index = pc//4
142 print("pc after %08x" % (pc))
143 msr = sim.msr.value
144 print("msr after %08x" % (msr))
145
146 vld = yield alu.n.o_valid
147 while not vld:
148 yield
149 vld = yield alu.n.o_valid
150 yield
151
152 yield from self.check_alu_outputs(alu, pdecode2,
153 sim, code)
154
155 sim.add_sync_process(process)
156 with sim.write_vcd("alu_simulator.vcd", "simulator.gtkw",
157 traces=[]):
158 sim.run()
159
160 def check_alu_outputs(self, alu, dec2, sim, code):
161
162 rc = yield dec2.e.do.rc.data
163 cridx_ok = yield dec2.e.write_cr.ok
164 cridx = yield dec2.e.write_cr.data
165
166 print("check extra output", repr(code), cridx_ok, cridx)
167 if rc:
168 self.assertEqual(cridx, 0, code)
169
170 sim_o = {}
171 res = {}
172
173 yield from ALUHelpers.get_int_o(res, alu, dec2)
174 yield from ALUHelpers.get_fast_spr1(res, alu, dec2)
175 yield from ALUHelpers.get_fast_spr2(res, alu, dec2)
176 yield from ALUHelpers.get_fast_spr3(res, alu, dec2)
177 yield from ALUHelpers.get_nia(res, alu, dec2)
178 yield from ALUHelpers.get_msr(res, alu, dec2)
179
180 print("output", res)
181
182 yield from ALUHelpers.get_sim_int_o(sim_o, sim, dec2)
183 yield from ALUHelpers.get_wr_fast_spr1(sim_o, sim, dec2)
184 yield from ALUHelpers.get_wr_fast_spr2(sim_o, sim, dec2)
185 yield from ALUHelpers.get_wr_fast_spr3(sim_o, sim, dec2)
186 ALUHelpers.get_sim_nia(sim_o, sim, dec2)
187 ALUHelpers.get_sim_msr(sim_o, sim, dec2)
188
189 print("sim output", sim_o)
190
191 ALUHelpers.check_int_o(self, res, sim_o, code)
192 ALUHelpers.check_fast_spr1(self, res, sim_o, code)
193 ALUHelpers.check_fast_spr2(self, res, sim_o, code)
194 ALUHelpers.check_fast_spr3(self, res, sim_o, code)
195 ALUHelpers.check_nia(self, res, sim_o, code)
196 ALUHelpers.check_msr(self, res, sim_o, code)
197
198
199 if __name__ == "__main__":
200 unittest.main(exit=False)
201 suite = unittest.TestSuite()
202 suite.addTest(TestRunner(TrapTestCase().test_data))
203 suite.addTest(TestRunner(TrapIlangCase().test_data))
204
205 runner = unittest.TextTestRunner()
206 runner.run(suite)