debugging termination (OP_ATTN)
[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 soc.decoder.isa.caller import special_sprs
13 from soc.decoder.power_decoder import create_pdecode
14 from soc.decoder.power_decoder2 import PowerDecode2
15 from soc.decoder.isa.all import ISA
16 from soc.decoder.power_enums import Function, XER_bits
17 from soc.config.test.test_loadstore import TestMemPspec
18
19 from soc.simple.core import NonProductionCore
20 from soc.experiment.compalu_multi import find_ok # hack
21
22 from soc.fu.compunits.test.test_compunit import (setup_test_memory,
23 check_sim_memory)
24
25 # test with ALU data and Logical data
26 from soc.fu.alu.test.test_pipe_caller import ALUTestCase
27 from soc.fu.logical.test.test_pipe_caller import LogicalTestCase
28 from soc.fu.shift_rot.test.test_pipe_caller import ShiftRotTestCase
29 from soc.fu.cr.test.test_pipe_caller import CRTestCase
30 from soc.fu.branch.test.test_pipe_caller import BranchTestCase
31 from soc.fu.ldst.test.test_pipe_caller import LDSTTestCase
32
33
34 def setup_regs(core, test):
35
36 # set up INT regfile, "direct" write (bypass rd/write ports)
37 intregs = core.regs.int
38 for i in range(32):
39 yield intregs.regs[i].reg.eq(test.regs[i])
40
41 # set up CR regfile, "direct" write across all CRs
42 cr = test.cr
43 crregs = core.regs.cr
44 #cr = int('{:32b}'.format(cr)[::-1], 2)
45 print ("cr reg", hex(cr))
46 for i in range(8):
47 #j = 7-i
48 cri = (cr>>(i*4)) & 0xf
49 #cri = int('{:04b}'.format(cri)[::-1], 2)
50 print ("cr reg", hex(cri), i,
51 crregs.regs[i].reg.shape())
52 yield crregs.regs[i].reg.eq(cri)
53
54 # set up XER. "direct" write (bypass rd/write ports)
55 xregs = core.regs.xer
56 print ("sprs", test.sprs)
57 if special_sprs['XER'] in test.sprs:
58 xer = test.sprs[special_sprs['XER']]
59 sobit = xer[XER_bits['SO']].value
60 yield xregs.regs[xregs.SO].reg.eq(sobit)
61 cabit = xer[XER_bits['CA']].value
62 ca32bit = xer[XER_bits['CA32']].value
63 yield xregs.regs[xregs.CA].reg.eq(Cat(cabit, ca32bit))
64 ovbit = xer[XER_bits['OV']].value
65 ov32bit = xer[XER_bits['OV32']].value
66 yield xregs.regs[xregs.OV].reg.eq(Cat(ovbit, ov32bit))
67 else:
68 yield xregs.regs[xregs.SO].reg.eq(0)
69 yield xregs.regs[xregs.OV].reg.eq(0)
70 yield xregs.regs[xregs.CA].reg.eq(0)
71
72 # XER
73 pdecode2 = core.pdecode2
74 so = yield xregs.regs[xregs.SO].reg
75 ov = yield xregs.regs[xregs.OV].reg
76 ca = yield xregs.regs[xregs.CA].reg
77 oe = yield pdecode2.e.do.oe.oe
78 oe_ok = yield pdecode2.e.do.oe.oe_ok
79
80 print ("before: so/ov-32/ca-32", so, bin(ov), bin(ca))
81 print ("oe:", oe, oe_ok)
82
83
84 def check_regs(dut, sim, core, test, code):
85 # int regs
86 intregs = []
87 for i in range(32):
88 rval = yield core.regs.int.regs[i].reg
89 intregs.append(rval)
90 print ("int regs", list(map(hex, intregs)))
91 for i in range(32):
92 simregval = sim.gpr[i].asint()
93 dut.assertEqual(simregval, intregs[i],
94 "int reg %d not equal %s" % (i, repr(code)))
95
96 # CRs
97 crregs = []
98 for i in range(8):
99 rval = yield core.regs.cr.regs[i].reg
100 crregs.append(rval)
101 print ("cr regs", list(map(hex, crregs)))
102 for i in range(8):
103 rval = crregs[i]
104 cri = sim.crl[7-i].get_range().value
105 print ("cr reg", i, hex(cri), i, hex(rval))
106 # XXX https://bugs.libre-soc.org/show_bug.cgi?id=363
107 dut.assertEqual(cri, rval,
108 "cr reg %d not equal %s" % (i, repr(code)))
109
110 # XER
111 xregs = core.regs.xer
112 so = yield xregs.regs[xregs.SO].reg
113 ov = yield xregs.regs[xregs.OV].reg
114 ca = yield xregs.regs[xregs.CA].reg
115
116 print ("sim SO", sim.spr['XER'][XER_bits['SO']])
117 e_so = sim.spr['XER'][XER_bits['SO']].value
118 e_ov = sim.spr['XER'][XER_bits['OV']].value
119 e_ov32 = sim.spr['XER'][XER_bits['OV32']].value
120 e_ca = sim.spr['XER'][XER_bits['CA']].value
121 e_ca32 = sim.spr['XER'][XER_bits['CA32']].value
122
123 e_ov = e_ov | (e_ov32<<1)
124 e_ca = e_ca | (e_ca32<<1)
125
126 print ("after: so/ov-32/ca-32", so, bin(ov), bin(ca))
127 dut.assertEqual(e_so, so, "so mismatch %s" % (repr(code)))
128 dut.assertEqual(e_ov, ov, "ov mismatch %s" % (repr(code)))
129 dut.assertEqual(e_ca, ca, "ca mismatch %s" % (repr(code)))
130
131
132 def wait_for_busy_hi(cu):
133 while True:
134 busy_o = yield cu.busy_o
135 terminated_o = yield cu.core_terminated_o
136 if busy_o or terminated_o:
137 print("busy/terminated:", busy_o, terminated_o)
138 break
139 print("!busy",)
140 yield
141
142 def set_issue(core, dec2, sim):
143 yield core.issue_i.eq(1)
144 yield
145 yield core.issue_i.eq(0)
146 yield from wait_for_busy_hi(core)
147
148
149 def wait_for_busy_clear(cu):
150 while True:
151 busy_o = yield cu.busy_o
152 terminated_o = yield cu.core_terminated_o
153 if not busy_o or terminated_o:
154 print("busy/terminated:", busy_o, terminated_o)
155 break
156 print("busy",)
157 yield
158
159
160 class TestRunner(FHDLTestCase):
161 def __init__(self, tst_data):
162 super().__init__("run_all")
163 self.test_data = tst_data
164
165 def run_all(self):
166 m = Module()
167 comb = m.d.comb
168 instruction = Signal(32)
169 ivalid_i = Signal()
170
171 pspec = TestMemPspec(ldst_ifacetype='testpi',
172 imem_ifacetype='',
173 addr_wid=48,
174 mask_wid=8,
175 reg_wid=64)
176
177 m.submodules.core = core = NonProductionCore(pspec)
178 pdecode2 = core.pdecode2
179 l0 = core.l0
180
181 comb += core.raw_opcode_i.eq(instruction)
182 comb += core.ivalid_i.eq(ivalid_i)
183
184 # temporary hack: says "go" immediately for both address gen and ST
185 ldst = core.fus.fus['ldst0']
186 m.d.comb += ldst.ad.go.eq(ldst.ad.rel) # link addr-go direct to rel
187 m.d.comb += ldst.st.go.eq(ldst.st.rel) # link store-go direct to rel
188
189 # nmigen Simulation
190 sim = Simulator(m)
191 sim.add_clock(1e-6)
192
193 def process():
194 yield core.issue_i.eq(0)
195 yield
196
197 for test in self.test_data:
198 print(test.name)
199 program = test.program
200 self.subTest(test.name)
201 sim = ISA(pdecode2, test.regs, test.sprs, test.cr, test.mem,
202 test.msr)
203 gen = program.generate_instructions()
204 instructions = list(zip(gen, program.assembly.splitlines()))
205
206 yield from setup_test_memory(l0, sim)
207 yield from setup_regs(core, test)
208
209 index = sim.pc.CIA.value//4
210 while index < len(instructions):
211 ins, code = instructions[index]
212
213 print("instruction: 0x{:X}".format(ins & 0xffffffff))
214 print(code)
215
216 # ask the decoder to decode this binary data (endian'd)
217 yield core.bigendian_i.eq(0) # little / big?
218 yield instruction.eq(ins) # raw binary instr.
219 yield ivalid_i.eq(1)
220 yield Settle()
221 #fn_unit = yield pdecode2.e.fn_unit
222 #fuval = self.funit.value
223 #self.assertEqual(fn_unit & fuval, fuval)
224
225 # set operand and get inputs
226 yield from set_issue(core, pdecode2, sim)
227 yield Settle()
228
229 yield from wait_for_busy_clear(core)
230 yield ivalid_i.eq(0)
231 yield
232
233 print ("sim", code)
234 # call simulated operation
235 opname = code.split(' ')[0]
236 yield from sim.call(opname)
237 index = sim.pc.CIA.value//4
238
239 # register check
240 yield from check_regs(self, sim, core, test, code)
241
242 # Memory check
243 yield from check_sim_memory(self, l0, sim, code)
244
245 sim.add_sync_process(process)
246 with sim.write_vcd("core_simulator.vcd", "core_simulator.gtkw",
247 traces=[]):
248 sim.run()
249
250
251 if __name__ == "__main__":
252 unittest.main(exit=False)
253 suite = unittest.TestSuite()
254 suite.addTest(TestRunner(LDSTTestCase.test_data))
255 suite.addTest(TestRunner(CRTestCase.test_data))
256 suite.addTest(TestRunner(ShiftRotTestCase.test_data))
257 suite.addTest(TestRunner(LogicalTestCase.test_data))
258 suite.addTest(TestRunner(ALUTestCase.test_data))
259 suite.addTest(TestRunner(BranchTestCase.test_data))
260
261 runner = unittest.TextTestRunner()
262 runner.run(suite)
263