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 data_i.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)
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)
91 m.submodules.alu = alu = TrapBasePipe(pspec)
92
93 comb += alu.p.data_i.ctx.op.eq_from_execute1(pdecode2.do)
94 comb += alu.p.valid_i.eq(1)
95 comb += alu.n.ready_i.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(zip(gen, program.assembly.splitlines()))
111
112 msr = sim.msr.value
113 pc = sim.pc.CIA.value
114 print("starting msr, pc %08x, %08x" % (msr, pc))
115 index = pc//4
116 while index < len(instructions):
117 ins, code = instructions[index]
118
119 print("pc %08x msr %08x instr: %08x" % (pc, msr, ins))
120 print(code)
121 if 'XER' in sim.spr:
122 so = 1 if sim.spr['XER'][XER_bits['SO']] else 0
123 ov = 1 if sim.spr['XER'][XER_bits['OV']] else 0
124 ov32 = 1 if sim.spr['XER'][XER_bits['OV32']] else 0
125 print("before: so/ov/32", so, ov, ov32)
126
127 # ask the decoder to decode this binary data (endian'd)
128 yield pdecode2.dec.bigendian.eq(bigendian) # l/big?
129 yield pdecode2.state.msr.eq(msr) # set MSR in pdecode2
130 yield pdecode2.state.pc.eq(pc) # set CIA in pdecode2
131 yield instruction.eq(ins) # raw binary instr.
132 yield Settle()
133 fn_unit = yield pdecode2.e.do.fn_unit
134 self.assertEqual(fn_unit, Function.TRAP.value)
135 alu_o = yield from set_alu_inputs(alu, pdecode2, sim)
136 yield
137 opname = code.split(' ')[0]
138 yield from sim.call(opname)
139 pc = sim.pc.CIA.value
140 index = pc//4
141 print("pc after %08x" % (pc))
142 msr = sim.msr.value
143 print("msr after %08x" % (msr))
144
145 vld = yield alu.n.valid_o
146 while not vld:
147 yield
148 vld = yield alu.n.valid_o
149 yield
150
151 yield from self.check_alu_outputs(alu, pdecode2,
152 sim, code)
153
154 sim.add_sync_process(process)
155 with sim.write_vcd("alu_simulator.vcd", "simulator.gtkw",
156 traces=[]):
157 sim.run()
158
159 def check_alu_outputs(self, alu, dec2, sim, code):
160
161 rc = yield dec2.e.do.rc.data
162 cridx_ok = yield dec2.e.write_cr.ok
163 cridx = yield dec2.e.write_cr.data
164
165 print("check extra output", repr(code), cridx_ok, cridx)
166 if rc:
167 self.assertEqual(cridx, 0, code)
168
169 sim_o = {}
170 res = {}
171
172 yield from ALUHelpers.get_int_o(res, alu, dec2)
173 yield from ALUHelpers.get_fast_spr1(res, alu, dec2)
174 yield from ALUHelpers.get_fast_spr2(res, alu, dec2)
175 yield from ALUHelpers.get_fast_spr3(res, alu, dec2)
176 yield from ALUHelpers.get_nia(res, alu, dec2)
177 yield from ALUHelpers.get_msr(res, alu, dec2)
178
179 print("output", res)
180
181 yield from ALUHelpers.get_sim_int_o(sim_o, sim, dec2)
182 yield from ALUHelpers.get_wr_fast_spr1(sim_o, sim, dec2)
183 yield from ALUHelpers.get_wr_fast_spr2(sim_o, sim, dec2)
184 yield from ALUHelpers.get_wr_fast_spr3(sim_o, sim, dec2)
185 ALUHelpers.get_sim_nia(sim_o, sim, dec2)
186 ALUHelpers.get_sim_msr(sim_o, sim, dec2)
187
188 print("sim output", sim_o)
189
190 ALUHelpers.check_int_o(self, res, sim_o, code)
191 ALUHelpers.check_fast_spr1(self, res, sim_o, code)
192 ALUHelpers.check_fast_spr2(self, res, sim_o, code)
193 ALUHelpers.check_fast_spr3(self, res, sim_o, code)
194 ALUHelpers.check_nia(self, res, sim_o, code)
195 ALUHelpers.check_msr(self, res, sim_o, code)
196
197
198 if __name__ == "__main__":
199 unittest.main(exit=False)
200 suite = unittest.TestSuite()
201 suite.addTest(TestRunner(TrapTestCase().test_data))
202 suite.addTest(TestRunner(TrapIlangCase().test_data))
203
204 runner = unittest.TextTestRunner()
205 runner.run(suite)