error in setting fast regs test values
[soc.git] / src / soc / simple / test / test_core.py
1 """simple core test
2
3 related bugs:
4
5 * https://bugs.libre-soc.org/show_bug.cgi?id=363
6 """
7 from nmigen import Module, Signal, Cat
8 from nmigen.back.pysim import Simulator, Delay, Settle
9 from nmutil.formaltest import FHDLTestCase
10 from nmigen.cli import rtlil
11 import unittest
12 from openpower.decoder.isa.caller import special_sprs
13 from openpower.decoder.power_decoder import create_pdecode
14 from openpower.decoder.power_decoder2 import PowerDecode2
15 from openpower.decoder.selectable_int import SelectableInt
16 from openpower.decoder.isa.all import ISA
17
18 # note that for testing using SPRfull should be ok here
19 from openpower.decoder.power_enums import SPRfull as SPR, spr_dict, Function, XER_bits
20 from soc.config.test.test_loadstore import TestMemPspec
21 from openpower.endian import bigendian
22
23 from soc.simple.core import NonProductionCore
24 from soc.experiment.compalu_multi import find_ok # hack
25
26 from soc.fu.compunits.test.test_compunit import (setup_test_memory,
27 check_sim_memory)
28
29 # test with ALU data and Logical data
30 from soc.fu.alu.test.test_pipe_caller import ALUTestCase
31 from soc.fu.logical.test.test_pipe_caller import LogicalTestCase
32 from soc.fu.shift_rot.test.test_pipe_caller import ShiftRotTestCase
33 from soc.fu.cr.test.test_pipe_caller import CRTestCase
34 from soc.fu.branch.test.test_pipe_caller import BranchTestCase
35 from soc.fu.ldst.test.test_pipe_caller import LDSTTestCase
36 from openpower.util import spr_to_fast_reg
37
38 mmu_sprs = ["PRTBL"]
39
40 def set_mmu_spr(name, i, val, core): #important keep pep8 formatting
41 fsm = core.fus.fus["mmu0"].alu
42 yield fsm.mmu.l_in.mtspr.eq(1)
43 yield fsm.mmu.l_in.sprn.eq(i)
44 yield fsm.mmu.l_in.rs.eq(val)
45 yield
46 yield fsm.mmu.l_in.mtspr.eq(0)
47 print("mmu_spr was updated")
48
49 def setup_regs(pdecode2, core, test):
50
51 # set up INT regfile, "direct" write (bypass rd/write ports)
52 intregs = core.regs.int
53 for i in range(32):
54 if intregs.unary:
55 yield intregs.regs[i].reg.eq(test.regs[i])
56 else:
57 yield intregs.memory._array[i].eq(test.regs[i])
58 yield Settle()
59
60 # set up CR regfile, "direct" write across all CRs
61 cr = test.cr
62 crregs = core.regs.cr
63 #cr = int('{:32b}'.format(cr)[::-1], 2)
64 print("setup cr reg", hex(cr))
65 for i in range(8):
66 #j = 7-i
67 cri = (cr >> (i*4)) & 0xf
68 #cri = int('{:04b}'.format(cri)[::-1], 2)
69 print("setup cr reg", hex(cri), i,
70 crregs.regs[i].reg.shape())
71 yield crregs.regs[i].reg.eq(cri)
72
73 # set up XER. "direct" write (bypass rd/write ports)
74 xregs = core.regs.xer
75 print("setup sprs", test.sprs)
76 xer = None
77 if 'XER' in test.sprs:
78 xer = test.sprs['XER']
79 if 1 in test.sprs:
80 xer = test.sprs[1]
81 if xer is not None:
82 if isinstance(xer, int):
83 xer = SelectableInt(xer, 64)
84 sobit = xer[XER_bits['SO']].value
85 yield xregs.regs[xregs.SO].reg.eq(sobit)
86 cabit = xer[XER_bits['CA']].value
87 ca32bit = xer[XER_bits['CA32']].value
88 yield xregs.regs[xregs.CA].reg.eq(Cat(cabit, ca32bit))
89 ovbit = xer[XER_bits['OV']].value
90 ov32bit = xer[XER_bits['OV32']].value
91 yield xregs.regs[xregs.OV].reg.eq(Cat(ovbit, ov32bit))
92 print("setting XER so %d ca %d ca32 %d ov %d ov32 %d" %
93 (sobit, cabit, ca32bit, ovbit, ov32bit))
94 else:
95 yield xregs.regs[xregs.SO].reg.eq(0)
96 yield xregs.regs[xregs.OV].reg.eq(0)
97 yield xregs.regs[xregs.CA].reg.eq(0)
98
99 # setting both fast and slow SPRs from test data
100
101 fregs = core.regs.fast
102 sregs = core.regs.spr
103 for sprname, val in test.sprs.items():
104 if isinstance(val, SelectableInt):
105 val = val.value
106 if isinstance(sprname, int):
107 sprname = spr_dict[sprname].SPR
108 if sprname == 'XER':
109 continue
110 fast = spr_to_fast_reg(sprname)
111 if fast is None:
112 # match behaviour of SPRMap in power_decoder2.py
113 for i, x in enumerate(SPR):
114 if sprname == x.name:
115 print("setting slow SPR %d (%s) to %x" %
116 (i, sprname, val))
117 if not sprname in mmu_sprs:
118 yield sregs.memory._array[i].eq(val)
119 else:
120 yield from set_mmu_spr(sprname, i, val, core)
121 else:
122 print("setting fast reg %d (%s) to %x" %
123 (fast, sprname, val))
124 if fregs.unary:
125 rval = core.regs.int.regs[fast].reg
126 else:
127 rval = core.regs.int.memory._array[fast]
128 yield rval.eq(val)
129
130 # allow changes to settle before reporting on XER
131 yield Settle()
132
133 # XER
134 so = yield xregs.regs[xregs.SO].reg
135 ov = yield xregs.regs[xregs.OV].reg
136 ca = yield xregs.regs[xregs.CA].reg
137 oe = yield pdecode2.e.do.oe.oe
138 oe_ok = yield pdecode2.e.do.oe.oe_ok
139
140 print("before: so/ov-32/ca-32", so, bin(ov), bin(ca))
141 print("oe:", oe, oe_ok)
142
143
144 def check_regs(dut, sim, core, test, code):
145 # int regs
146 intregs = []
147 for i in range(32):
148 if core.regs.int.unary:
149 rval = yield core.regs.int.regs[i].reg
150 else:
151 rval = yield core.regs.int.memory._array[i]
152 intregs.append(rval)
153 print("int regs", list(map(hex, intregs)))
154 for i in range(32):
155 simregval = sim.gpr[i].asint()
156 dut.assertEqual(simregval, intregs[i],
157 "int reg %d not equal %s" % (i, repr(code)))
158
159 # CRs
160 crregs = []
161 for i in range(8):
162 rval = yield core.regs.cr.regs[i].reg
163 crregs.append(rval)
164 print("cr regs", list(map(hex, crregs)))
165 for i in range(8):
166 rval = crregs[i]
167 cri = sim.crl[7-i].get_range().value
168 print("cr reg", i, hex(cri), i, hex(rval))
169 # XXX https://bugs.libre-soc.org/show_bug.cgi?id=363
170 dut.assertEqual(cri, rval,
171 "cr reg %d not equal %s" % (i, repr(code)))
172
173 # XER
174 xregs = core.regs.xer
175 so = yield xregs.regs[xregs.SO].reg
176 ov = yield xregs.regs[xregs.OV].reg
177 ca = yield xregs.regs[xregs.CA].reg
178
179 print("sim SO", sim.spr['XER'][XER_bits['SO']])
180 e_so = sim.spr['XER'][XER_bits['SO']].value
181 e_ov = sim.spr['XER'][XER_bits['OV']].value
182 e_ov32 = sim.spr['XER'][XER_bits['OV32']].value
183 e_ca = sim.spr['XER'][XER_bits['CA']].value
184 e_ca32 = sim.spr['XER'][XER_bits['CA32']].value
185
186 e_ov = e_ov | (e_ov32 << 1)
187 e_ca = e_ca | (e_ca32 << 1)
188
189 print("after: so/ov-32/ca-32", so, bin(ov), bin(ca))
190 dut.assertEqual(e_so, so, "so mismatch %s" % (repr(code)))
191 dut.assertEqual(e_ov, ov, "ov mismatch %s" % (repr(code)))
192 dut.assertEqual(e_ca, ca, "ca mismatch %s" % (repr(code)))
193
194 # Check the PC as well
195 state = core.regs.state
196 pc = yield state.r_ports['cia'].data_o
197 e_pc = sim.pc.CIA.value
198 dut.assertEqual(e_pc, pc)
199
200
201 def wait_for_busy_hi(cu):
202 while True:
203 busy_o = yield cu.busy_o
204 terminate_o = yield cu.core_terminate_o
205 if busy_o:
206 print("busy/terminate:", busy_o, terminate_o)
207 break
208 print("!busy", busy_o, terminate_o)
209 yield
210
211
212 def set_issue(core, dec2, sim):
213 yield core.issue_i.eq(1)
214 yield
215 yield core.issue_i.eq(0)
216 yield from wait_for_busy_hi(core)
217
218
219 def wait_for_busy_clear(cu):
220 while True:
221 busy_o = yield cu.busy_o
222 terminate_o = yield cu.core_terminate_o
223 if not busy_o:
224 print("busy/terminate:", busy_o, terminate_o)
225 break
226 print("busy",)
227 yield
228
229
230 class TestRunner(FHDLTestCase):
231 def __init__(self, tst_data):
232 super().__init__("run_all")
233 self.test_data = tst_data
234
235 def run_all(self):
236 m = Module()
237 comb = m.d.comb
238 instruction = Signal(32)
239 ivalid_i = Signal()
240
241 pspec = TestMemPspec(ldst_ifacetype='testpi',
242 imem_ifacetype='',
243 addr_wid=48,
244 mask_wid=8,
245 reg_wid=64)
246
247 m.submodules.core = core = NonProductionCore(pspec)
248 pdecode2 = core.pdecode2
249 l0 = core.l0
250
251 comb += core.raw_opcode_i.eq(instruction)
252 comb += core.ivalid_i.eq(ivalid_i)
253
254 # temporary hack: says "go" immediately for both address gen and ST
255 ldst = core.fus.fus['ldst0']
256 m.d.comb += ldst.ad.go.eq(ldst.ad.rel) # link addr-go direct to rel
257 m.d.comb += ldst.st.go.eq(ldst.st.rel) # link store-go direct to rel
258
259 # nmigen Simulation
260 sim = Simulator(m)
261 sim.add_clock(1e-6)
262
263 def process():
264 yield core.issue_i.eq(0)
265 yield
266
267 for test in self.test_data:
268 print(test.name)
269 program = test.program
270 self.subTest(test.name)
271 sim = ISA(pdecode2, test.regs, test.sprs, test.cr, test.mem,
272 test.msr,
273 bigendian=bigendian)
274 gen = program.generate_instructions()
275 instructions = list(zip(gen, program.assembly.splitlines()))
276
277 yield from setup_test_memory(l0, sim)
278 yield from setup_regs(core, test)
279
280 index = sim.pc.CIA.value//4
281 while index < len(instructions):
282 ins, code = instructions[index]
283
284 print("instruction: 0x{:X}".format(ins & 0xffffffff))
285 print(code)
286
287 # ask the decoder to decode this binary data (endian'd)
288 yield core.bigendian_i.eq(bigendian) # little / big?
289 yield instruction.eq(ins) # raw binary instr.
290 yield ivalid_i.eq(1)
291 yield Settle()
292 # fn_unit = yield pdecode2.e.fn_unit
293 #fuval = self.funit.value
294 #self.assertEqual(fn_unit & fuval, fuval)
295
296 # set operand and get inputs
297 yield from set_issue(core, pdecode2, sim)
298 yield Settle()
299
300 yield from wait_for_busy_clear(core)
301 yield ivalid_i.eq(0)
302 yield
303
304 print("sim", code)
305 # call simulated operation
306 opname = code.split(' ')[0]
307 yield from sim.call(opname)
308 index = sim.pc.CIA.value//4
309
310 # register check
311 yield from check_regs(self, sim, core, test, code)
312
313 # Memory check
314 yield from check_sim_memory(self, l0, sim, code)
315
316 sim.add_sync_process(process)
317 with sim.write_vcd("core_simulator.vcd", "core_simulator.gtkw",
318 traces=[]):
319 sim.run()
320
321
322 if __name__ == "__main__":
323 unittest.main(exit=False)
324 suite = unittest.TestSuite()
325 suite.addTest(TestRunner(LDSTTestCase().test_data))
326 suite.addTest(TestRunner(CRTestCase().test_data))
327 suite.addTest(TestRunner(ShiftRotTestCase().test_data))
328 suite.addTest(TestRunner(LogicalTestCase().test_data))
329 suite.addTest(TestRunner(ALUTestCase().test_data))
330 suite.addTest(TestRunner(BranchTestCase().test_data))
331
332 runner = unittest.TextTestRunner()
333 runner.run(suite)