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