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