1 from nmigen
import Module
, Signal
2 from nmigen
.back
.pysim
import Simulator
, Delay
, Settle
3 from nmutil
.formaltest
import FHDLTestCase
5 from openpower
.decoder
.isa
.caller
import ISACaller
6 from openpower
.decoder
.power_decoder
import create_pdecode
7 from openpower
.decoder
.power_decoder2
import (PowerDecode2
)
8 from openpower
.simulator
.program
import Program
9 from openpower
.decoder
.isa
.caller
import ISACaller
, inject
10 from openpower
.decoder
.selectable_int
import SelectableInt
11 from openpower
.decoder
.orderedset
import OrderedSet
12 from openpower
.decoder
.isa
.all
import ISA
13 from nmutil
.formaltest
import FHDLTestCase
17 def __init__(self
, num
):
21 class ISATestRunner(FHDLTestCase
):
22 def __init__(self
, tst_data
, include_fp
=True):
23 super().__init
__("run_all")
24 self
.test_data
= tst_data
25 self
.include_fp
= include_fp
30 instruction
= Signal(32)
32 pdecode
= create_pdecode(include_fp
=self
.include_fp
)
33 m
.submodules
.pdecode2
= pdecode2
= PowerDecode2(pdecode
)
35 comb
+= pdecode2
.dec
.raw_opcode_in
.eq(instruction
)
40 for test
in self
.test_data
:
42 with self
.subTest(test
.name
):
43 generator
= test
.program
45 gen
= list(generator
.generate_instructions())
46 insncode
= generator
.assembly
.splitlines()
47 instructions
= list(zip(gen
, insncode
))
49 simulator
= ISA(pdecode2
, test
.initial_regs
,
52 initial_insns
=gen
, respect_pc
=True,
53 initial_svstate
=test
.svstate
,
55 fpregfile
=test
.initial_fprs
,
65 yield pdecode2
.dec
.bigendian
.eq(0) # little / big?
66 pc
= simulator
.pc
.CIA
.value
68 while index
< len(instructions
):
71 yield from simulator
.setup_one()
72 except KeyError: # instruction not in imem: stop
76 ins
, code
= instructions
[index
]
77 print(" 0x{:X}".format(ins
& 0xffffffff))
78 opname
= code
.split(' ')[0]
81 # ask the decoder to decode this binary data (endian'd)
82 yield from simulator
.execute_one()
83 pc
= simulator
.pc
.CIA
.value
86 # run simulator multiple times, using the same PowerDecoder2,
87 # with multiple sub-tests
88 sim
.add_process(process
)
89 with sim
.write_vcd("simulator.vcd", "simulator.gtkw",
95 def run_tst(generator
, initial_regs
, initial_sprs
=None, svstate
=0, mmu
=False,
96 initial_cr
=0, mem
=None,
98 if initial_sprs
is None:
102 instruction
= Signal(32)
104 pdecode
= create_pdecode(include_fp
=initial_fprs
is not None)
106 gen
= list(generator
.generate_instructions())
107 insncode
= generator
.assembly
.splitlines()
108 instructions
= list(zip(gen
, insncode
))
110 m
.submodules
.pdecode2
= pdecode2
= PowerDecode2(pdecode
)
111 simulator
= ISA(pdecode2
, initial_regs
, initial_sprs
, initial_cr
,
112 initial_insns
=gen
, respect_pc
=True,
113 initial_svstate
=svstate
,
115 fpregfile
=initial_fprs
,
116 disassembly
=insncode
,
119 comb
+= pdecode2
.dec
.raw_opcode_in
.eq(instruction
)
129 yield pdecode2
.dec
.bigendian
.eq(0) # little / big?
130 pc
= simulator
.pc
.CIA
.value
132 while index
< len(instructions
):
133 print("instr pc", pc
)
135 yield from simulator
.setup_one()
136 except KeyError: # indicates instruction not in imem: stop
140 ins
, code
= instructions
[index
]
141 print(" 0x{:X}".format(ins
& 0xffffffff))
142 opname
= code
.split(' ')[0]
145 # ask the decoder to decode this binary data (endian'd)
146 yield from simulator
.execute_one()
147 pc
= simulator
.pc
.CIA
.value
150 sim
.add_process(process
)
151 with sim
.write_vcd("simulator.vcd", "simulator.gtkw",
157 class DecoderTestCase(FHDLTestCase
):
160 lst
= ["add 1, 3, 2"]
161 initial_regs
= [0] * 32
162 initial_regs
[3] = 0x1234
163 initial_regs
[2] = 0x4321
164 with
Program(lst
, bigendian
=False) as program
:
165 sim
= self
.run_tst_program(program
, initial_regs
)
166 self
.assertEqual(sim
.gpr(1), SelectableInt(0x5555, 64))
169 lst
= ["addi 3, 0, 0x1234",
172 with
Program(lst
, bigendian
=False) as program
:
173 sim
= self
.run_tst_program(program
)
175 self
.assertEqual(sim
.gpr(1), SelectableInt(0x5555, 64))
177 def test_load_store(self
):
178 lst
= ["addi 1, 0, 0x0010",
182 with
Program(lst
, bigendian
=False) as program
:
183 sim
= self
.run_tst_program(program
)
185 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1234, 64))
187 @unittest.skip("broken")
188 def test_addpcis(self
):
189 lst
= ["addpcis 1, 0x1",
192 with
Program(lst
, bigendian
=False) as program
:
193 sim
= self
.run_tst_program(program
)
194 self
.assertEqual(sim
.gpr(1), SelectableInt(0x10004, 64))
195 self
.assertEqual(sim
.gpr(2), SelectableInt(0x10008, 64))
196 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1000c, 64))
198 def test_branch(self
):
199 lst
= ["ba 0xc", # branch to line 4
200 "addi 1, 0, 0x1234", # Should never execute
201 "ba 0x1000", # exit the program
202 "addi 2, 0, 0x1234", # line 4
203 "ba 0x8"] # branch to line 3
204 with
Program(lst
, bigendian
=False) as program
:
205 sim
= self
.run_tst_program(program
)
206 self
.assertEqual(sim
.pc
.CIA
, SelectableInt(0x1000, 64))
207 self
.assertEqual(sim
.gpr(1), SelectableInt(0x0, 64))
208 self
.assertEqual(sim
.gpr(2), SelectableInt(0x1234, 64))
210 def test_branch_link(self
):
216 with
Program(lst
, bigendian
=False) as program
:
217 sim
= self
.run_tst_program(program
)
218 self
.assertEqual(sim
.spr
['LR'], SelectableInt(0x4, 64))
220 def test_branch_ctr(self
):
221 lst
= ["addi 1, 0, 0x10", # target of jump
222 "mtspr 9, 1", # mtctr 1
223 "bcctr 20, 0, 0", # bctr
224 "addi 2, 0, 0x1", # should never execute
225 "addi 1, 0, 0x1234"] # target of ctr
226 with
Program(lst
, bigendian
=False) as program
:
227 sim
= self
.run_tst_program(program
)
228 self
.assertEqual(sim
.spr
['CTR'], SelectableInt(0x10, 64))
229 self
.assertEqual(sim
.gpr(1), SelectableInt(0x1234, 64))
230 self
.assertEqual(sim
.gpr(2), SelectableInt(0, 64))
232 def test_branch_cond(self
):
234 lst
= [f
"addi 1, 0, {i}", # set r1 to i
235 "cmpi cr0, 1, 1, 10", # compare r1 with 10 and store to cr0
236 "bc 12, 2, 0x8", # beq 0x8 -
237 # branch if r1 equals 10 to the nop below
238 "addi 2, 0, 0x1234", # if r1 == 10 this shouldn't execute
239 "or 0, 0, 0"] # branch target
240 with
Program(lst
, bigendian
=False) as program
:
241 sim
= self
.run_tst_program(program
)
243 self
.assertEqual(sim
.gpr(2), SelectableInt(0, 64))
245 self
.assertEqual(sim
.gpr(2), SelectableInt(0x1234, 64))
247 def test_branch_loop(self
):
248 lst
= ["addi 1, 0, 0",
252 "cmpi cr0, 1, 1, 10",
254 with
Program(lst
, bigendian
=False) as program
:
255 sim
= self
.run_tst_program(program
)
257 self
.assertEqual(sim
.gpr(2), SelectableInt(0x37, 64))
259 def test_branch_loop_ctr(self
):
260 lst
= ["addi 1, 0, 0",
262 "mtspr 9, 2", # set ctr to 7
264 "bc 16, 0, -0x4"] # bdnz to the addi above
265 with
Program(lst
, bigendian
=False) as program
:
266 sim
= self
.run_tst_program(program
)
268 self
.assertEqual(sim
.gpr(1), SelectableInt(0x23, 64))
272 def test_add_compare(self
):
273 lst
= ["addis 1, 0, 0xffff",
274 "addis 2, 0, 0xffff",
277 with
Program(lst
, bigendian
=False) as program
:
278 sim
= self
.run_tst_program(program
)
280 self
.assertEqual(sim
.gpr(3), SelectableInt(0x80000000, 64))
283 lst
= ["addis 1, 0, 0xffff",
284 "addis 2, 0, 0xffff",
287 with
Program(lst
, bigendian
=False) as program
:
288 sim
= self
.run_tst_program(program
)
289 self
.assertEqual(sim
.gpr(3), SelectableInt(0x200000, 64))
292 lst
= ["slw 1, 3, 2"]
293 initial_regs
= [0] * 32
294 initial_regs
[3] = 0xdeadbeefcafebabe
296 with
Program(lst
, bigendian
=False) as program
:
297 sim
= self
.run_tst_program(program
, initial_regs
)
298 self
.assertEqual(sim
.gpr(1), SelectableInt(0x5fd757c0, 64))
301 lst
= ["srw 1, 3, 2"]
302 initial_regs
= [0] * 32
303 initial_regs
[3] = 0xdeadbeefcafebabe
305 with
Program(lst
, bigendian
=False) as program
:
306 sim
= self
.run_tst_program(program
, initial_regs
)
307 self
.assertEqual(sim
.gpr(1), SelectableInt(0x657f5d5, 64))
309 def test_rlwinm(self
):
310 lst
= ["rlwinm 3, 1, 5, 20, 6"]
311 initial_regs
= [0] * 32
313 with
Program(lst
, bigendian
=False) as program
:
314 sim
= self
.run_tst_program(program
, initial_regs
)
315 self
.assertEqual(sim
.gpr(3), SelectableInt(0xfffffffffe000fff, 64))
317 def test_rlwimi(self
):
318 lst
= ["rlwimi 3, 1, 5, 20, 6"]
319 initial_regs
= [0] * 32
320 initial_regs
[1] = 0xffffffffdeadbeef
321 initial_regs
[3] = 0x12345678
322 with
Program(lst
, bigendian
=False) as program
:
323 sim
= self
.run_tst_program(program
, initial_regs
)
324 self
.assertEqual(sim
.gpr(3), SelectableInt(0xd5b7ddfbd4345dfb, 64))
326 def test_rldic(self
):
327 lst
= ["rldic 3, 1, 5, 20"]
328 initial_regs
= [0] * 32
329 initial_regs
[1] = 0xdeadbeefcafec0de
330 with
Program(lst
, bigendian
=False) as program
:
331 sim
= self
.run_tst_program(program
, initial_regs
)
332 self
.assertEqual(sim
.gpr(3), SelectableInt(0xdf95fd81bc0, 64))
336 initial_regs
= [0] * 32
337 initial_regs
[1] = 0xdeadbeeecaffc0de
338 with
Program(lst
, bigendian
=False) as program
:
339 sim
= self
.run_tst_program(program
, initial_regs
)
340 self
.assertEqual(sim
.gpr(2), SelectableInt(0x100000001, 64))
342 def test_popcnt(self
):
343 lst
= ["popcntb 2, 1",
347 initial_regs
= [0] * 32
348 initial_regs
[1] = 0xdeadbeefcafec0de
349 with
Program(lst
, bigendian
=False) as program
:
350 sim
= self
.run_tst_program(program
, initial_regs
)
351 self
.assertEqual(sim
.gpr(2),
352 SelectableInt(0x605060704070206, 64))
353 self
.assertEqual(sim
.gpr(3),
354 SelectableInt(0x1800000013, 64))
355 self
.assertEqual(sim
.gpr(4),
356 SelectableInt(0x2b, 64))
358 def test_cntlz(self
):
359 lst
= ["cntlzd 2, 1",
361 initial_regs
= [0] * 32
362 initial_regs
[1] = 0x0000beeecaffc0de
363 initial_regs
[3] = 0x0000000000ffc0de
364 with
Program(lst
, bigendian
=False) as program
:
365 sim
= self
.run_tst_program(program
, initial_regs
)
366 self
.assertEqual(sim
.gpr(2), SelectableInt(16, 64))
367 self
.assertEqual(sim
.gpr(4), SelectableInt(8, 64))
369 def test_cmpeqb(self
):
370 lst
= ["cmpeqb cr0, 2, 1",
372 initial_regs
= [0] * 32
373 initial_regs
[1] = 0x0102030405060708
374 initial_regs
[2] = 0x04
375 initial_regs
[3] = 0x10
376 with
Program(lst
, bigendian
=False) as program
:
377 sim
= self
.run_tst_program(program
, initial_regs
)
378 self
.assertEqual(sim
.crl
[0].get_range().value
,
380 self
.assertEqual(sim
.crl
[1].get_range().value
,
385 def test_mtcrf(self
):
387 # 0x76540000 gives expected (3+4) (2+4) (1+4) (0+4) for
389 # The positions of the CR fields have been verified using
390 # QEMU and 'cmp crx, a, b' instructions
391 lst
= ["addis 1, 0, 0x7654",
392 "mtcrf %d, 1" % (1 << (7-i
)),
394 with
Program(lst
, bigendian
=False) as program
:
395 sim
= self
.run_tst_program(program
)
398 # check CR[0]/1/2/3 as well
399 print("cr%d" % i
, sim
.crl
[i
].asint(True))
400 self
.assertTrue(SelectableInt(expected
, 4) == sim
.crl
[i
])
402 self
.assertEqual(sim
.cr
, SelectableInt(expected
<< ((7-i
)*4), 64))
404 def run_tst_program(self
, prog
, initial_regs
=[0] * 32):
405 simulator
= run_tst(prog
, initial_regs
)
410 if __name__
== "__main__":