fix qemu trap test
[soc.git] / src / soc / simulator / test_sim.py
1 from nmigen import Module, Signal
2 from nmigen.back.pysim import Simulator, Delay, Settle
3 from nmigen.test.utils import FHDLTestCase
4 import unittest
5 from soc.decoder.power_decoder import (create_pdecode)
6 from soc.decoder.power_enums import (Function, InternalOp,
7 In1Sel, In2Sel, In3Sel,
8 OutSel, RC, LdstLen, CryIn,
9 single_bit_flags, Form, SPR,
10 get_signal_name, get_csv)
11 from soc.decoder.power_decoder2 import (PowerDecode2)
12 from soc.simulator.program import Program
13 from soc.simulator.qemu import run_program
14 from soc.decoder.isa.all import ISA
15 from soc.fu.test.common import TestCase
16
17
18 class Register:
19 def __init__(self, num):
20 self.num = num
21
22
23 class GeneralTestCases(FHDLTestCase):
24 test_data = []
25
26 def __init__(self, name="general"):
27 super().__init__(name)
28 self.test_name = name
29
30 @unittest.skip("disable")
31 def test_0_cmp(self):
32 lst = ["addi 6, 0, 0x10",
33 "addi 7, 0, 0x05",
34 "subf. 1, 6, 7",
35 "cmp cr2, 1, 6, 7",
36 ]
37 with Program(lst) as program:
38 self.run_tst_program(program, [1])
39
40 @unittest.skip("disable")
41 def test_example(self):
42 lst = ["addi 1, 0, 0x5678",
43 "addi 2, 0, 0x1234",
44 "add 3, 1, 2",
45 "and 4, 1, 2"]
46 with Program(lst) as program:
47 self.run_tst_program(program, [1, 2, 3, 4])
48
49 @unittest.skip("disable")
50 def test_ldst(self):
51 lst = ["addi 1, 0, 0x5678",
52 "addi 2, 0, 0x1234",
53 "stw 1, 0(2)",
54 "lwz 3, 0(2)"
55 ]
56 initial_mem = {0x1230: (0x5432123412345678, 8),
57 0x1238: (0xabcdef0187654321, 8),
58 }
59 with Program(lst) as program:
60 self.run_tst_program(program,
61 [1, 2, 3],
62 initial_mem)
63
64 @unittest.skip("disable")
65 def test_ld_rev_ext(self):
66 lst = ["addi 1, 0, 0x5678",
67 "addi 2, 0, 0x1234",
68 "addi 4, 0, 0x40",
69 "stw 1, 0x40(2)",
70 "lwbrx 3, 4, 2"]
71 with Program(lst) as program:
72 self.run_tst_program(program, [1, 2, 3])
73
74 @unittest.skip("disable")
75 def test_st_rev_ext(self):
76 lst = ["addi 1, 0, 0x5678",
77 "addi 2, 0, 0x1234",
78 "addi 4, 0, 0x40",
79 "stwbrx 1, 4, 2",
80 "lwzx 3, 4, 2"]
81 with Program(lst) as program:
82 self.run_tst_program(program, [1, 2, 3])
83
84 @unittest.skip("disable")
85 def test_ldst_extended(self):
86 lst = ["addi 1, 0, 0x5678",
87 "addi 2, 0, 0x1234",
88 "addi 4, 0, 0x40",
89 "stw 1, 0x40(2)",
90 "lwzx 3, 4, 2"]
91 with Program(lst) as program:
92 self.run_tst_program(program, [1, 2, 3])
93
94 @unittest.skip("disable")
95 def test_0_ldst_widths(self):
96 lst = ["addis 1, 0, 0xdead",
97 "ori 1, 1, 0xbeef",
98 "addi 2, 0, 0x1000",
99 "std 1, 0(2)",
100 "lbz 1, 5(2)",
101 "lhz 3, 4(2)",
102 "lwz 4, 4(2)",
103 "addi 5, 0, 0x12",
104 "stb 5, 5(2)",
105 "ld 5, 0(2)"]
106 with Program(lst) as program:
107 self.run_tst_program(program, [1, 2, 3, 4, 5])
108
109 @unittest.skip("disable")
110 def test_sub(self):
111 lst = ["addi 1, 0, 0x1234",
112 "addi 2, 0, 0x5678",
113 "subf 3, 1, 2",
114 "subfic 4, 1, 0x1337",
115 "neg 5, 1"]
116 with Program(lst) as program:
117 self.run_tst_program(program, [1, 2, 3, 4, 5])
118
119 @unittest.skip("disable")
120 def test_add_with_carry(self):
121 lst = ["addi 1, 0, 5",
122 "neg 1, 1",
123 "addi 2, 0, 7",
124 "neg 2, 2",
125 "addc 3, 2, 1",
126 "addi 3, 3, 1"
127 ]
128 with Program(lst) as program:
129 self.run_tst_program(program, [1, 2, 3])
130
131 @unittest.skip("disable")
132 def test_addis(self):
133 lst = ["addi 1, 0, 0x0FFF",
134 "addis 1, 1, 0x0F"
135 ]
136 with Program(lst) as program:
137 self.run_tst_program(program, [1])
138
139 @unittest.skip("broken")
140 def test_mulli(self):
141 lst = ["addi 1, 0, 3",
142 "mulli 1, 1, 2"
143 ]
144 with Program(lst) as program:
145 self.run_tst_program(program, [1])
146
147 @unittest.skip("disable")
148 def test_2_load_store(self):
149 lst = ["addi 1, 0, 0x1004",
150 "addi 2, 0, 0x1008",
151 "addi 3, 0, 0x00ee",
152 "stb 3, 1(2)",
153 "lbz 4, 1(2)",
154 ]
155 initial_regs = [0] * 32
156 initial_regs[1] = 0x1004
157 initial_regs[2] = 0x1008
158 initial_regs[3] = 0x00ee
159 initial_mem = {0x1000: (0x5432123412345678, 8),
160 0x1008: (0xabcdef0187654321, 8),
161 0x1020: (0x1828384822324252, 8),
162 }
163 with Program(lst) as program:
164 self.run_tst_program(program, [3,4], initial_mem)
165
166 @unittest.skip("disable")
167 def test_3_load_store(self):
168 lst = ["addi 1, 0, 0x1004",
169 "addi 2, 0, 0x1002",
170 "addi 3, 0, 0x15eb",
171 "sth 4, 0(2)",
172 "lhz 4, 0(2)"]
173 initial_regs = [0] * 32
174 initial_regs[1] = 0x1004
175 initial_regs[2] = 0x1002
176 initial_regs[3] = 0x15eb
177 initial_mem = {0x1000: (0x5432123412345678, 8),
178 0x1008: (0xabcdef0187654321, 8),
179 0x1020: (0x1828384822324252, 8),
180 }
181 with Program(lst) as program:
182 self.run_tst_program(program, [1,2,3,4], initial_mem)
183
184 def test_loop(self):
185 """in godbolt.org:
186 register unsigned long i asm ("r12");
187 void square(void) {
188 i = 5;
189 do {
190 i = i - 1;
191 } while (i != 0);
192 }
193 """
194 lst = ["addi 9, 0, 0x10", # i = 16
195 "addi 9,9,-1", # i = i - 1
196 "cmpi 0,1,9,12", # compare 9 to value 0, store in CR2
197 "bc 4,0,-8" # branch if CR2 "test was != 0"
198 ]
199 with Program(lst) as program:
200 self.run_tst_program(program, [9], initial_mem={})
201
202 def run_tst_program(self, prog, initial_regs=None, initial_sprs=None,
203 initial_mem=None):
204 initial_regs = [0] * 32
205 tc = TestCase(prog, self.test_name, initial_regs, initial_sprs, 0,
206 initial_mem, 0)
207 self.test_data.append(tc)
208
209
210 class DecoderBase:
211
212 def run_tst(self, generator, initial_mem=None, initial_pc=0):
213 m = Module()
214 comb = m.d.comb
215
216 gen = list(generator.generate_instructions())
217 insn_code = generator.assembly.splitlines()
218 instructions = list(zip(gen, insn_code))
219
220 pdecode = create_pdecode()
221 m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
222
223 # place program at requested address
224 gen = (initial_pc, gen)
225
226 simulator = ISA(pdecode2, [0] * 32, {}, 0, initial_mem, 0,
227 initial_insns=gen, respect_pc=True,
228 disassembly=insn_code,
229 initial_pc=initial_pc)
230
231 sim = Simulator(m)
232
233 def process():
234 while True:
235 try:
236 yield from simulator.setup_one()
237 except KeyError: # indicates instruction not in imem: stop
238 break
239 yield Settle()
240 yield from simulator.execute_one()
241 yield Settle()
242
243
244 sim.add_process(process)
245 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
246 traces=[]):
247 sim.run()
248
249 return simulator
250
251 def run_tst_program(self, prog, reglist, initial_mem=None):
252 import sys
253 simulator = self.run_tst(prog, initial_mem=initial_mem,
254 initial_pc=0x20000000)
255 prog.reset()
256 with run_program(prog, initial_mem) as q:
257 self.qemu_register_compare(simulator, q, reglist)
258 self.qemu_mem_compare(simulator, q, reglist)
259 print(simulator.gpr.dump())
260
261 def qemu_mem_compare(self, sim, qemu, check=True):
262 if False: # disable convenient large interesting debugging memory dump
263 addr = 0x0
264 qmemdump = qemu.get_mem(addr, 2048)
265 for i in range(len(qmemdump)):
266 s = hex(int(qmemdump[i]))
267 print ("qemu mem %06x %s" % (addr+i*8, s))
268 for k, v in sim.mem.mem.items():
269 qmemdump = qemu.get_mem(k*8, 8)
270 s = hex(int(qmemdump[0]))[2:]
271 print ("qemu mem %06x %16s" % (k*8, s))
272 for k, v in sim.mem.mem.items():
273 print ("sim mem %06x %016x" % (k*8, v))
274 if not check:
275 return
276 for k, v in sim.mem.mem.items():
277 qmemdump = qemu.get_mem(k*8, 1)
278 self.assertEqual(int(qmemdump[0]), v)
279
280 def qemu_register_compare(self, sim, qemu, regs):
281 qpc, qxer, qcr = qemu.get_pc(), qemu.get_xer(), qemu.get_cr()
282 sim_cr = sim.cr.get_range().value
283 sim_pc = sim.pc.CIA.value
284 sim_xer = sim.spr['XER'].value
285 print("qemu pc", hex(qpc))
286 print("qemu cr", hex(qcr))
287 print("qemu xer", bin(qxer))
288 print("sim nia", hex(sim.pc.NIA.value))
289 print("sim pc", hex(sim.pc.CIA.value))
290 print("sim cr", hex(sim_cr))
291 print("sim xer", hex(sim_xer))
292 self.assertEqual(qcr, sim_cr)
293 self.assertEqual(qpc, sim_pc)
294 for reg in regs:
295 qemu_val = qemu.get_register(reg)
296 sim_val = sim.gpr(reg).value
297 self.assertEqual(qemu_val, sim_val)
298
299
300 class DecoderTestCase(DecoderBase, GeneralTestCases):
301 pass
302
303
304 if __name__ == "__main__":
305 unittest.main()