re-add unit tests back in
[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
18
19 from soc.simple.core import NonProductionCore
20 from soc.experiment.compalu_multi import find_ok # hack
21
22 # test with ALU data and Logical data
23 from soc.fu.alu.test.test_pipe_caller import ALUTestCase
24 from soc.fu.logical.test.test_pipe_caller import LogicalTestCase
25 from soc.fu.shift_rot.test.test_pipe_caller import ShiftRotTestCase
26 from soc.fu.cr.test.test_pipe_caller import CRTestCase
27 from soc.fu.branch.test.test_pipe_caller import BranchTestCase
28
29
30 def set_issue(core, dec2, sim):
31 yield core.issue_i.eq(1)
32 yield
33 yield core.issue_i.eq(0)
34 while True:
35 busy_o = yield core.busy_o
36 if busy_o:
37 break
38 print("!busy",)
39 yield
40
41
42 def wait_for_busy_clear(cu):
43 while True:
44 busy_o = yield cu.busy_o
45 if not busy_o:
46 break
47 print("busy",)
48 yield
49
50
51 class TestRunner(FHDLTestCase):
52 def __init__(self, tst_data):
53 super().__init__("run_all")
54 self.test_data = tst_data
55
56 def run_all(self):
57 m = Module()
58 comb = m.d.comb
59 instruction = Signal(32)
60 ivalid_i = Signal()
61
62 m.submodules.core = core = NonProductionCore()
63 pdecode = core.pdecode
64 pdecode2 = core.pdecode2
65
66 comb += pdecode2.dec.raw_opcode_in.eq(instruction)
67 comb += core.ivalid_i.eq(ivalid_i)
68 sim = Simulator(m)
69
70 sim.add_clock(1e-6)
71
72 def process():
73 yield core.issue_i.eq(0)
74 yield
75
76 for test in self.test_data:
77 print(test.name)
78 program = test.program
79 self.subTest(test.name)
80 sim = ISA(pdecode2, test.regs, test.sprs, test.cr, test.mem,
81 test.msr)
82 gen = program.generate_instructions()
83 instructions = list(zip(gen, program.assembly.splitlines()))
84
85 # set up INT regfile, "direct" write (bypass rd/write ports)
86 for i in range(32):
87 yield core.regs.int.regs[i].reg.eq(test.regs[i])
88
89 # set up CR regfile, "direct" write across all CRs
90 cr = test.cr
91 #cr = int('{:32b}'.format(cr)[::-1], 2)
92 print ("cr reg", hex(cr))
93 for i in range(8):
94 #j = 7-i
95 cri = (cr>>(i*4)) & 0xf
96 #cri = int('{:04b}'.format(cri)[::-1], 2)
97 print ("cr reg", hex(cri), i,
98 core.regs.cr.regs[i].reg.shape())
99 yield core.regs.cr.regs[i].reg.eq(cri)
100
101 # set up XER. "direct" write (bypass rd/write ports)
102 xregs = core.regs.xer
103 print ("sprs", test.sprs)
104 if special_sprs['XER'] in test.sprs:
105 xer = test.sprs[special_sprs['XER']]
106 sobit = xer[XER_bits['SO']].value
107 yield xregs.regs[xregs.SO].reg.eq(sobit)
108 cabit = xer[XER_bits['CA']].value
109 ca32bit = xer[XER_bits['CA32']].value
110 yield xregs.regs[xregs.CA].reg.eq(Cat(cabit, ca32bit))
111 ovbit = xer[XER_bits['OV']].value
112 ov32bit = xer[XER_bits['OV32']].value
113 yield xregs.regs[xregs.OV].reg.eq(Cat(ovbit, ov32bit))
114 else:
115 yield xregs.regs[xregs.SO].reg.eq(0)
116 yield xregs.regs[xregs.OV].reg.eq(0)
117 yield xregs.regs[xregs.CA].reg.eq(0)
118
119 index = sim.pc.CIA.value//4
120 while index < len(instructions):
121 ins, code = instructions[index]
122
123 print("instruction: 0x{:X}".format(ins & 0xffffffff))
124 print(code)
125
126 # ask the decoder to decode this binary data (endian'd)
127 yield pdecode2.dec.bigendian.eq(0) # little / big?
128 yield instruction.eq(ins) # raw binary instr.
129 yield ivalid_i.eq(1)
130 yield Settle()
131 #fn_unit = yield pdecode2.e.fn_unit
132 #fuval = self.funit.value
133 #self.assertEqual(fn_unit & fuval, fuval)
134
135 # XER
136 so = yield xregs.regs[xregs.SO].reg
137 ov = yield xregs.regs[xregs.OV].reg
138 ca = yield xregs.regs[xregs.CA].reg
139 oe = yield pdecode2.e.oe.oe
140 oe_ok = yield pdecode2.e.oe.oe_ok
141
142 print ("before: so/ov-32/ca-32", so, bin(ov), bin(ca))
143 print ("oe:", oe, oe_ok)
144
145 # set operand and get inputs
146 yield from set_issue(core, pdecode2, sim)
147 yield Settle()
148
149 yield from wait_for_busy_clear(core)
150 yield ivalid_i.eq(0)
151 yield
152
153 print ("sim", code)
154 # call simulated operation
155 opname = code.split(' ')[0]
156 yield from sim.call(opname)
157 index = sim.pc.CIA.value//4
158
159 # int regs
160 intregs = []
161 for i in range(32):
162 rval = yield core.regs.int.regs[i].reg
163 intregs.append(rval)
164 print ("int regs", list(map(hex, intregs)))
165 for i in range(32):
166 simregval = sim.gpr[i].asint()
167 self.assertEqual(simregval, intregs[i],
168 "int reg %d not equal %s" % (i, repr(code)))
169
170 # CRs
171 crregs = []
172 for i in range(8):
173 rval = yield core.regs.cr.regs[i].reg
174 crregs.append(rval)
175 print ("cr regs", list(map(hex, crregs)))
176 print ("sim cr reg", hex(cr))
177 for i in range(8):
178 rval = crregs[i]
179 cri = sim.crl[7-i].get_range().value
180 print ("cr reg", i, hex(cri), i, hex(rval))
181 # XXX https://bugs.libre-soc.org/show_bug.cgi?id=363
182 self.assertEqual(cri, rval,
183 "cr reg %d not equal %s" % (i, repr(code)))
184
185 # XER
186 so = yield xregs.regs[xregs.SO].reg
187 ov = yield xregs.regs[xregs.OV].reg
188 ca = yield xregs.regs[xregs.CA].reg
189
190 print ("sim SO", sim.spr['XER'][XER_bits['SO']])
191 e_so = sim.spr['XER'][XER_bits['SO']].value
192 e_ov = sim.spr['XER'][XER_bits['OV']].value
193 e_ov32 = sim.spr['XER'][XER_bits['OV32']].value
194 e_ca = sim.spr['XER'][XER_bits['CA']].value
195 e_ca32 = sim.spr['XER'][XER_bits['CA32']].value
196
197 e_ov = e_ov | (e_ov32<<1)
198 e_ca = e_ca | (e_ca32<<1)
199
200 print ("after: so/ov-32/ca-32", so, bin(ov), bin(ca))
201 self.assertEqual(e_so, so, "so mismatch %s" % (repr(code)))
202 self.assertEqual(e_ov, ov, "ov mismatch %s" % (repr(code)))
203 self.assertEqual(e_ca, ca, "ca mismatch %s" % (repr(code)))
204
205 sim.add_sync_process(process)
206 with sim.write_vcd("core_simulator.vcd", "core_simulator.gtkw",
207 traces=[]):
208 sim.run()
209
210
211 if __name__ == "__main__":
212 unittest.main(exit=False)
213 suite = unittest.TestSuite()
214 suite.addTest(TestRunner(CRTestCase.test_data))
215 suite.addTest(TestRunner(ShiftRotTestCase.test_data))
216 suite.addTest(TestRunner(LogicalTestCase.test_data))
217 suite.addTest(TestRunner(ALUTestCase.test_data))
218 suite.addTest(TestRunner(BranchTestCase.test_data))
219
220 runner = unittest.TextTestRunner()
221 runner.run(suite)
222