sigh. weirdness involving bit-inversion, inconsistency on mfcr and isel
[soc.git] / src / soc / simple / test / test_core.py
1 from nmigen import Module, Signal, Cat
2 from nmigen.back.pysim import Simulator, Delay, Settle
3 from nmutil.formaltest import FHDLTestCase
4 from nmigen.cli import rtlil
5 import unittest
6 from soc.decoder.isa.caller import special_sprs
7 from soc.decoder.power_decoder import create_pdecode
8 from soc.decoder.power_decoder2 import PowerDecode2
9 from soc.decoder.isa.all import ISA
10 from soc.decoder.power_enums import Function, XER_bits
11
12
13 from soc.simple.core import NonProductionCore
14 from soc.experiment.compalu_multi import find_ok # hack
15
16 # test with ALU data and Logical data
17 from soc.fu.alu.test.test_pipe_caller import ALUTestCase
18 from soc.fu.logical.test.test_pipe_caller import LogicalTestCase
19 from soc.fu.shift_rot.test.test_pipe_caller import ShiftRotTestCase
20 from soc.fu.cr.test.test_pipe_caller import CRTestCase
21
22
23 def set_cu_input(cu, idx, data):
24 rdop = cu.get_in_name(idx)
25 yield cu.src_i[idx].eq(data)
26 while True:
27 rd_rel_o = yield cu.rd.rel[idx]
28 print ("rd_rel %d wait HI" % idx, rd_rel_o, rdop, hex(data))
29 if rd_rel_o:
30 break
31 yield
32 yield cu.rd.go[idx].eq(1)
33 while True:
34 yield
35 rd_rel_o = yield cu.rd.rel[idx]
36 if rd_rel_o:
37 break
38 print ("rd_rel %d wait HI" % idx, rd_rel_o)
39 yield
40 yield cu.rd.go[idx].eq(0)
41 yield cu.src_i[idx].eq(0)
42
43
44 def get_cu_output(cu, idx, code):
45 wrmask = yield cu.wrmask
46 wrop = cu.get_out_name(idx)
47 wrok = cu.get_out(idx)
48 fname = find_ok(wrok.fields)
49 wrok = yield getattr(wrok, fname)
50 print ("wr_rel mask", repr(code), idx, wrop, bin(wrmask), fname, wrok)
51 assert wrmask & (1<<idx), \
52 "get_cu_output '%s': mask bit %d not set\n" \
53 "write-operand '%s' Data.ok likely not set (%s)" \
54 % (code, idx, wrop, hex(wrok))
55 while True:
56 wr_relall_o = yield cu.wr.rel
57 wr_rel_o = yield cu.wr.rel[idx]
58 print ("wr_rel %d wait" % idx, hex(wr_relall_o), wr_rel_o)
59 if wr_rel_o:
60 break
61 yield
62 yield cu.wr.go[idx].eq(1)
63 yield Settle()
64 result = yield cu.dest[idx]
65 yield
66 yield cu.wr.go[idx].eq(0)
67 print ("result", repr(code), idx, wrop, wrok, hex(result))
68 return result
69
70
71 def set_cu_inputs(cu, inp):
72 for idx, data in inp.items():
73 yield from set_cu_input(cu, idx, data)
74
75
76 def set_issue(core, dec2, sim):
77 yield core.issue_i.eq(1)
78 yield
79 yield core.issue_i.eq(0)
80 while True:
81 busy_o = yield core.busy_o
82 if busy_o:
83 break
84 print("!busy",)
85 yield
86
87
88 def wait_for_busy_clear(cu):
89 while True:
90 busy_o = yield cu.busy_o
91 if not busy_o:
92 break
93 print("busy",)
94 yield
95
96
97 def get_cu_outputs(cu, code):
98 res = {}
99 for i in range(cu.n_dst):
100 wr_rel_o = yield cu.wr.rel[i]
101 if wr_rel_o:
102 result = yield from get_cu_output(cu, i, code)
103 wrop = cu.get_out_name(i)
104 print ("output", i, wrop, hex(result))
105 res[wrop] = result
106 return res
107
108
109 def get_inp_indexed(cu, inp):
110 res = {}
111 for i in range(cu.n_src):
112 wrop = cu.get_in_name(i)
113 if wrop in inp:
114 res[i] = inp[wrop]
115 return res
116
117
118 class TestRunner(FHDLTestCase):
119 def __init__(self, tst_data):
120 super().__init__("run_all")
121 self.test_data = tst_data
122
123 def run_all(self):
124 m = Module()
125 comb = m.d.comb
126 instruction = Signal(32)
127 ivalid_i = Signal()
128
129 m.submodules.core = core = NonProductionCore()
130 pdecode = core.pdecode
131 pdecode2 = core.pdecode2
132
133 comb += pdecode2.dec.raw_opcode_in.eq(instruction)
134 comb += core.ivalid_i.eq(ivalid_i)
135 sim = Simulator(m)
136
137 sim.add_clock(1e-6)
138
139 def process():
140 yield core.issue_i.eq(0)
141 yield
142
143 for test in self.test_data:
144 print(test.name)
145 program = test.program
146 self.subTest(test.name)
147 sim = ISA(pdecode2, test.regs, test.sprs, test.cr)
148 gen = program.generate_instructions()
149 instructions = list(zip(gen, program.assembly.splitlines()))
150
151 # set up INT regfile, "direct" write (bypass rd/write ports)
152 for i in range(32):
153 yield core.regs.int.regs[i].reg.eq(test.regs[i])
154
155 # set up CR regfile, "direct" write across all CRs
156 cr = test.cr
157 # sigh. Because POWER
158 cr = int('{:032b}'.format(test.cr)[::-1], 2)
159 print ("cr reg", hex(cr))
160 for i in range(8):
161 j = i
162 cri = (cr>>(j*4)) & 0xf
163 # sigh. Because POWER
164 cri = int('{:04b}'.format(cri)[::-1], 2)
165 print ("cr reg", hex(cri), i,
166 core.regs.cr.regs[i].reg.shape())
167 yield core.regs.cr.regs[i].reg.eq(cri)
168
169 # set up XER. "direct" write (bypass rd/write ports)
170 xregs = core.regs.xer
171 print ("sprs", test.sprs)
172 if special_sprs['XER'] in test.sprs:
173 xer = test.sprs[special_sprs['XER']]
174 sobit = xer[XER_bits['SO']].asint()
175 yield xregs.regs[xregs.SO].reg.eq(sobit)
176 cabit = xer[XER_bits['CA']].asint()
177 ca32bit = xer[XER_bits['CA32']].asint()
178 yield xregs.regs[xregs.CA].reg.eq(Cat(cabit, ca32bit))
179 ovbit = xer[XER_bits['OV']].asint()
180 ov32bit = xer[XER_bits['OV32']].asint()
181 yield xregs.regs[xregs.OV].reg.eq(Cat(ovbit, ov32bit))
182 else:
183 yield xregs.regs[xregs.SO].reg.eq(0)
184 yield xregs.regs[xregs.OV].reg.eq(0)
185 yield xregs.regs[xregs.CA].reg.eq(0)
186
187 index = sim.pc.CIA.value//4
188 while index < len(instructions):
189 ins, code = instructions[index]
190
191 print("0x{:X}".format(ins & 0xffffffff))
192 print(code)
193
194 # ask the decoder to decode this binary data (endian'd)
195 yield pdecode2.dec.bigendian.eq(0) # little / big?
196 yield instruction.eq(ins) # raw binary instr.
197 yield ivalid_i.eq(1)
198 yield Settle()
199 #fn_unit = yield pdecode2.e.fn_unit
200 #fuval = self.funit.value
201 #self.assertEqual(fn_unit & fuval, fuval)
202
203 # set operand and get inputs
204 yield from set_issue(core, pdecode2, sim)
205 yield Settle()
206
207 yield from wait_for_busy_clear(core)
208 yield ivalid_i.eq(0)
209 yield
210
211 print ("sim", code)
212 # call simulated operation
213 opname = code.split(' ')[0]
214 yield from sim.call(opname)
215 index = sim.pc.CIA.value//4
216
217 # int regs
218 intregs = []
219 for i in range(32):
220 rval = yield core.regs.int.regs[i].reg
221 intregs.append(rval)
222 print ("int regs", list(map(hex, intregs)))
223 for i in range(32):
224 simregval = sim.gpr[i].asint()
225 self.assertEqual(simregval, intregs[i],
226 "int reg %d not equal %s" % (i, repr(code)))
227
228 sim.add_sync_process(process)
229 with sim.write_vcd("core_simulator.vcd", "core_simulator.gtkw",
230 traces=[]):
231 sim.run()
232
233
234 if __name__ == "__main__":
235 unittest.main(exit=False)
236 suite = unittest.TestSuite()
237 suite.addTest(TestRunner(CRTestCase.test_data))
238 #suite.addTest(TestRunner(ShiftRotTestCase.test_data))
239 #suite.addTest(TestRunner(LogicalTestCase.test_data))
240 #suite.addTest(TestRunner(ALUTestCase.test_data))
241
242 runner = unittest.TextTestRunner()
243 runner.run(suite)
244