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