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