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