unit test: pass bool mmu
[soc.git] / src / soc / decoder / isa / test_caller.py
1 from nmigen import Module, Signal
2 from nmigen.back.pysim import Simulator, Delay, Settle
3 from nmutil.formaltest import FHDLTestCase
4 import unittest
5 from soc.decoder.isa.caller import ISACaller
6 from soc.decoder.power_decoder import (create_pdecode)
7 from soc.decoder.power_decoder2 import (PowerDecode2)
8 from soc.simulator.program import Program
9 from soc.decoder.isa.caller import ISACaller, inject
10 from soc.decoder.selectable_int import SelectableInt
11 from soc.decoder.orderedset import OrderedSet
12 from soc.decoder.isa.all import ISA
13
14
15 class Register:
16 def __init__(self, num):
17 self.num = num
18
19 def run_tst(generator, initial_regs, initial_sprs=None, svstate=0, mmu=False):
20 if initial_sprs is None:
21 initial_sprs = {}
22 m = Module()
23 comb = m.d.comb
24 instruction = Signal(32)
25
26 pdecode = create_pdecode()
27
28 gen = list(generator.generate_instructions())
29 insncode = generator.assembly.splitlines()
30 instructions = list(zip(gen, insncode))
31
32 m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
33 simulator = ISA(pdecode2, initial_regs, initial_sprs, 0,
34 initial_insns=gen, respect_pc=True,
35 initial_svstate=svstate,
36 disassembly=insncode,
37 bigendian=0,
38 mmu=mmu)
39 comb += pdecode2.dec.raw_opcode_in.eq(instruction)
40 sim = Simulator(m)
41
42
43 def process():
44
45 yield pdecode2.dec.bigendian.eq(0) # little / big?
46 pc = simulator.pc.CIA.value
47 index = pc//4
48 while index < len(instructions):
49 print("instr pc", pc)
50 try:
51 yield from simulator.setup_one()
52 except KeyError: # indicates instruction not in imem: stop
53 break
54 yield Settle()
55
56 ins, code = instructions[index]
57 print(" 0x{:X}".format(ins & 0xffffffff))
58 opname = code.split(' ')[0]
59 print(code, opname)
60
61 # ask the decoder to decode this binary data (endian'd)
62 yield from simulator.execute_one()
63 pc = simulator.pc.CIA.value
64 index = pc//4
65
66 sim.add_process(process)
67 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
68 traces=[]):
69 sim.run()
70 return simulator
71
72
73 class DecoderTestCase(FHDLTestCase):
74
75 def test_add(self):
76 lst = ["add 1, 3, 2"]
77 initial_regs = [0] * 32
78 initial_regs[3] = 0x1234
79 initial_regs[2] = 0x4321
80 with Program(lst, bigendian=False) as program:
81 sim = self.run_tst_program(program, initial_regs)
82 self.assertEqual(sim.gpr(1), SelectableInt(0x5555, 64))
83
84 def test_addi(self):
85 lst = ["addi 3, 0, 0x1234",
86 "addi 2, 0, 0x4321",
87 "add 1, 3, 2"]
88 with Program(lst, bigendian=False) as program:
89 sim = self.run_tst_program(program)
90 print(sim.gpr(1))
91 self.assertEqual(sim.gpr(1), SelectableInt(0x5555, 64))
92
93 def test_load_store(self):
94 lst = ["addi 1, 0, 0x0010",
95 "addi 2, 0, 0x1234",
96 "stw 2, 0(1)",
97 "lwz 3, 0(1)"]
98 with Program(lst, bigendian=False) as program:
99 sim = self.run_tst_program(program)
100 print(sim.gpr(1))
101 self.assertEqual(sim.gpr(3), SelectableInt(0x1234, 64))
102
103 @unittest.skip("broken")
104 def test_addpcis(self):
105 lst = ["addpcis 1, 0x1",
106 "addpcis 2, 0x1",
107 "addpcis 3, 0x1"]
108 with Program(lst, bigendian=False) as program:
109 sim = self.run_tst_program(program)
110 self.assertEqual(sim.gpr(1), SelectableInt(0x10004, 64))
111 self.assertEqual(sim.gpr(2), SelectableInt(0x10008, 64))
112 self.assertEqual(sim.gpr(3), SelectableInt(0x1000c, 64))
113
114 def test_branch(self):
115 lst = ["ba 0xc", # branch to line 4
116 "addi 1, 0, 0x1234", # Should never execute
117 "ba 0x1000", # exit the program
118 "addi 2, 0, 0x1234", # line 4
119 "ba 0x8"] # branch to line 3
120 with Program(lst, bigendian=False) as program:
121 sim = self.run_tst_program(program)
122 self.assertEqual(sim.pc.CIA, SelectableInt(0x1000, 64))
123 self.assertEqual(sim.gpr(1), SelectableInt(0x0, 64))
124 self.assertEqual(sim.gpr(2), SelectableInt(0x1234, 64))
125
126 def test_branch_link(self):
127 lst = ["bl 0xc",
128 "addi 2, 1, 0x1234",
129 "ba 0x1000",
130 "addi 1, 0, 0x1234",
131 "bclr 20, 0, 0"]
132 with Program(lst, bigendian=False) as program:
133 sim = self.run_tst_program(program)
134 self.assertEqual(sim.spr['LR'], SelectableInt(0x4, 64))
135
136 def test_branch_ctr(self):
137 lst = ["addi 1, 0, 0x10", # target of jump
138 "mtspr 9, 1", # mtctr 1
139 "bcctr 20, 0, 0", # bctr
140 "addi 2, 0, 0x1", # should never execute
141 "addi 1, 0, 0x1234"] # target of ctr
142 with Program(lst, bigendian=False) as program:
143 sim = self.run_tst_program(program)
144 self.assertEqual(sim.spr['CTR'], SelectableInt(0x10, 64))
145 self.assertEqual(sim.gpr(1), SelectableInt(0x1234, 64))
146 self.assertEqual(sim.gpr(2), SelectableInt(0, 64))
147
148 def test_branch_cond(self):
149 for i in [0, 10]:
150 lst = [f"addi 1, 0, {i}", # set r1 to i
151 "cmpi cr0, 1, 1, 10", # compare r1 with 10 and store to cr0
152 "bc 12, 2, 0x8", # beq 0x8 -
153 # branch if r1 equals 10 to the nop below
154 "addi 2, 0, 0x1234", # if r1 == 10 this shouldn't execute
155 "or 0, 0, 0"] # branch target
156 with Program(lst, bigendian=False) as program:
157 sim = self.run_tst_program(program)
158 if i == 10:
159 self.assertEqual(sim.gpr(2), SelectableInt(0, 64))
160 else:
161 self.assertEqual(sim.gpr(2), SelectableInt(0x1234, 64))
162
163 def test_branch_loop(self):
164 lst = ["addi 1, 0, 0",
165 "addi 1, 0, 0",
166 "addi 1, 1, 1",
167 "add 2, 2, 1",
168 "cmpi cr0, 1, 1, 10",
169 "bc 12, 0, -0xc"]
170 with Program(lst, bigendian=False) as program:
171 sim = self.run_tst_program(program)
172 # Verified with qemu
173 self.assertEqual(sim.gpr(2), SelectableInt(0x37, 64))
174
175 def test_branch_loop_ctr(self):
176 lst = ["addi 1, 0, 0",
177 "addi 2, 0, 7",
178 "mtspr 9, 2", # set ctr to 7
179 "addi 1, 1, 5",
180 "bc 16, 0, -0x4"] # bdnz to the addi above
181 with Program(lst, bigendian=False) as program:
182 sim = self.run_tst_program(program)
183 # Verified with qemu
184 self.assertEqual(sim.gpr(1), SelectableInt(0x23, 64))
185
186
187
188 def test_add_compare(self):
189 lst = ["addis 1, 0, 0xffff",
190 "addis 2, 0, 0xffff",
191 "add. 1, 1, 2",
192 "mfcr 3"]
193 with Program(lst, bigendian=False) as program:
194 sim = self.run_tst_program(program)
195 # Verified with QEMU
196 self.assertEqual(sim.gpr(3), SelectableInt(0x80000000, 64))
197
198 def test_cmp(self):
199 lst = ["addis 1, 0, 0xffff",
200 "addis 2, 0, 0xffff",
201 "cmp cr2, 0, 1, 2",
202 "mfcr 3"]
203 with Program(lst, bigendian=False) as program:
204 sim = self.run_tst_program(program)
205 self.assertEqual(sim.gpr(3), SelectableInt(0x200000, 64))
206
207 def test_slw(self):
208 lst = ["slw 1, 3, 2"]
209 initial_regs = [0] * 32
210 initial_regs[3] = 0xdeadbeefcafebabe
211 initial_regs[2] = 5
212 with Program(lst, bigendian=False) as program:
213 sim = self.run_tst_program(program, initial_regs)
214 self.assertEqual(sim.gpr(1), SelectableInt(0x5fd757c0, 64))
215
216 def test_srw(self):
217 lst = ["srw 1, 3, 2"]
218 initial_regs = [0] * 32
219 initial_regs[3] = 0xdeadbeefcafebabe
220 initial_regs[2] = 5
221 with Program(lst, bigendian=False) as program:
222 sim = self.run_tst_program(program, initial_regs)
223 self.assertEqual(sim.gpr(1), SelectableInt(0x657f5d5, 64))
224
225 def test_rlwinm(self):
226 lst = ["rlwinm 3, 1, 5, 20, 6"]
227 initial_regs = [0] * 32
228 initial_regs[1] = -1
229 with Program(lst, bigendian=False) as program:
230 sim = self.run_tst_program(program, initial_regs)
231 self.assertEqual(sim.gpr(3), SelectableInt(0xfffffffffe000fff, 64))
232
233 def test_rlwimi(self):
234 lst = ["rlwimi 3, 1, 5, 20, 6"]
235 initial_regs = [0] * 32
236 initial_regs[1] = 0xffffffffdeadbeef
237 initial_regs[3] = 0x12345678
238 with Program(lst, bigendian=False) as program:
239 sim = self.run_tst_program(program, initial_regs)
240 self.assertEqual(sim.gpr(3), SelectableInt(0xd5b7ddfbd4345dfb, 64))
241
242 def test_rldic(self):
243 lst = ["rldic 3, 1, 5, 20"]
244 initial_regs = [0] * 32
245 initial_regs[1] = 0xdeadbeefcafec0de
246 with Program(lst, bigendian=False) as program:
247 sim = self.run_tst_program(program, initial_regs)
248 self.assertEqual(sim.gpr(3), SelectableInt(0xdf95fd81bc0, 64))
249
250 def test_prty(self):
251 lst = ["prtyw 2, 1"]
252 initial_regs = [0] * 32
253 initial_regs[1] = 0xdeadbeeecaffc0de
254 with Program(lst, bigendian=False) as program:
255 sim = self.run_tst_program(program, initial_regs)
256 self.assertEqual(sim.gpr(2), SelectableInt(0x100000001, 64))
257
258 def test_popcnt(self):
259 lst = ["popcntb 2, 1",
260 "popcntw 3, 1",
261 "popcntd 4, 1"
262 ]
263 initial_regs = [0] * 32
264 initial_regs[1] = 0xdeadbeefcafec0de
265 with Program(lst, bigendian=False) as program:
266 sim = self.run_tst_program(program, initial_regs)
267 self.assertEqual(sim.gpr(2),
268 SelectableInt(0x605060704070206, 64))
269 self.assertEqual(sim.gpr(3),
270 SelectableInt(0x1800000013, 64))
271 self.assertEqual(sim.gpr(4),
272 SelectableInt(0x2b, 64))
273
274 def test_cntlz(self):
275 lst = ["cntlzd 2, 1",
276 "cntlzw 4, 3"]
277 initial_regs = [0] * 32
278 initial_regs[1] = 0x0000beeecaffc0de
279 initial_regs[3] = 0x0000000000ffc0de
280 with Program(lst, bigendian=False) as program:
281 sim = self.run_tst_program(program, initial_regs)
282 self.assertEqual(sim.gpr(2), SelectableInt(16, 64))
283 self.assertEqual(sim.gpr(4), SelectableInt(8, 64))
284
285 def test_cmpeqb(self):
286 lst = ["cmpeqb cr0, 2, 1",
287 "cmpeqb cr1, 3, 1"]
288 initial_regs = [0] * 32
289 initial_regs[1] = 0x0102030405060708
290 initial_regs[2] = 0x04
291 initial_regs[3] = 0x10
292 with Program(lst, bigendian=False) as program:
293 sim = self.run_tst_program(program, initial_regs)
294 self.assertEqual(sim.crl[0].get_range().value,
295 SelectableInt(4, 4))
296 self.assertEqual(sim.crl[1].get_range().value,
297 SelectableInt(0, 4))
298
299
300
301 def test_mtcrf(self):
302 for i in range(4):
303 # 0x76540000 gives expected (3+4) (2+4) (1+4) (0+4) for
304 # i=0, 1, 2, 3
305 # The positions of the CR fields have been verified using
306 # QEMU and 'cmp crx, a, b' instructions
307 lst = ["addis 1, 0, 0x7654",
308 "mtcrf %d, 1" % (1 << (7-i)),
309 ]
310 with Program(lst, bigendian=False) as program:
311 sim = self.run_tst_program(program)
312 print("cr", sim.cr)
313 expected = (7-i)
314 # check CR[0]/1/2/3 as well
315 print("cr%d", sim.crl[i])
316 self.assertTrue(SelectableInt(expected, 4) == sim.crl[i])
317 # check CR itself
318 self.assertEqual(sim.cr, SelectableInt(expected << ((7-i)*4), 32))
319
320 def run_tst_program(self, prog, initial_regs=[0] * 32):
321 simulator = run_tst(prog, initial_regs)
322 simulator.gpr.dump()
323 return simulator
324
325
326 if __name__ == "__main__":
327 unittest.main()