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
16 def __init__(self
, num
):
19 def run_tst(generator
, initial_regs
, initial_sprs
=None, svstate
=0, mmu
=False,
20 initial_cr
=0, mem
=None,
22 if initial_sprs
is None:
26 instruction
= Signal(32)
28 pdecode
= create_pdecode(include_fp
=initial_fprs
is not None)
30 gen
= list(generator
.generate_instructions())
31 insncode
= generator
.assembly
.splitlines()
32 instructions
= list(zip(gen
, insncode
))
34 m
.submodules
.pdecode2
= pdecode2
= PowerDecode2(pdecode
)
35 simulator
= ISA(pdecode2
, initial_regs
, initial_sprs
, initial_cr
,
36 initial_insns
=gen
, respect_pc
=True,
37 initial_svstate
=svstate
,
39 fpregfile
=initial_fprs
,
43 comb
+= pdecode2
.dec
.raw_opcode_in
.eq(instruction
)
53 yield pdecode2
.dec
.bigendian
.eq(0) # little / big?
54 pc
= simulator
.pc
.CIA
.value
56 while index
< len(instructions
):
59 yield from simulator
.setup_one()
60 except KeyError: # indicates instruction not in imem: stop
64 ins
, code
= instructions
[index
]
65 print(" 0x{:X}".format(ins
& 0xffffffff))
66 opname
= code
.split(' ')[0]
69 # ask the decoder to decode this binary data (endian'd)
70 yield from simulator
.execute_one()
71 pc
= simulator
.pc
.CIA
.value
74 sim
.add_process(process
)
75 with sim
.write_vcd("simulator.vcd", "simulator.gtkw",
81 class DecoderTestCase(FHDLTestCase
):
85 initial_regs
= [0] * 32
86 initial_regs
[3] = 0x1234
87 initial_regs
[2] = 0x4321
88 with
Program(lst
, bigendian
=False) as program
:
89 sim
= self
.run_tst_program(program
, initial_regs
)
90 self
.assertEqual(sim
.gpr(1), SelectableInt(0x5555, 64))
93 lst
= ["addi 3, 0, 0x1234",
96 with
Program(lst
, bigendian
=False) as program
:
97 sim
= self
.run_tst_program(program
)
99 self
.assertEqual(sim
.gpr(1), SelectableInt(0x5555, 64))
101 def test_load_store(self
):
102 lst
= ["addi 1, 0, 0x0010",
106 with
Program(lst
, bigendian
=False) as program
:
107 sim
= self
.run_tst_program(program
)
109 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1234, 64))
111 @unittest.skip("broken")
112 def test_addpcis(self
):
113 lst
= ["addpcis 1, 0x1",
116 with
Program(lst
, bigendian
=False) as program
:
117 sim
= self
.run_tst_program(program
)
118 self
.assertEqual(sim
.gpr(1), SelectableInt(0x10004, 64))
119 self
.assertEqual(sim
.gpr(2), SelectableInt(0x10008, 64))
120 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1000c, 64))
122 def test_branch(self
):
123 lst
= ["ba 0xc", # branch to line 4
124 "addi 1, 0, 0x1234", # Should never execute
125 "ba 0x1000", # exit the program
126 "addi 2, 0, 0x1234", # line 4
127 "ba 0x8"] # branch to line 3
128 with
Program(lst
, bigendian
=False) as program
:
129 sim
= self
.run_tst_program(program
)
130 self
.assertEqual(sim
.pc
.CIA
, SelectableInt(0x1000, 64))
131 self
.assertEqual(sim
.gpr(1), SelectableInt(0x0, 64))
132 self
.assertEqual(sim
.gpr(2), SelectableInt(0x1234, 64))
134 def test_branch_link(self
):
140 with
Program(lst
, bigendian
=False) as program
:
141 sim
= self
.run_tst_program(program
)
142 self
.assertEqual(sim
.spr
['LR'], SelectableInt(0x4, 64))
144 def test_branch_ctr(self
):
145 lst
= ["addi 1, 0, 0x10", # target of jump
146 "mtspr 9, 1", # mtctr 1
147 "bcctr 20, 0, 0", # bctr
148 "addi 2, 0, 0x1", # should never execute
149 "addi 1, 0, 0x1234"] # target of ctr
150 with
Program(lst
, bigendian
=False) as program
:
151 sim
= self
.run_tst_program(program
)
152 self
.assertEqual(sim
.spr
['CTR'], SelectableInt(0x10, 64))
153 self
.assertEqual(sim
.gpr(1), SelectableInt(0x1234, 64))
154 self
.assertEqual(sim
.gpr(2), SelectableInt(0, 64))
156 def test_branch_cond(self
):
158 lst
= [f
"addi 1, 0, {i}", # set r1 to i
159 "cmpi cr0, 1, 1, 10", # compare r1 with 10 and store to cr0
160 "bc 12, 2, 0x8", # beq 0x8 -
161 # branch if r1 equals 10 to the nop below
162 "addi 2, 0, 0x1234", # if r1 == 10 this shouldn't execute
163 "or 0, 0, 0"] # branch target
164 with
Program(lst
, bigendian
=False) as program
:
165 sim
= self
.run_tst_program(program
)
167 self
.assertEqual(sim
.gpr(2), SelectableInt(0, 64))
169 self
.assertEqual(sim
.gpr(2), SelectableInt(0x1234, 64))
171 def test_branch_loop(self
):
172 lst
= ["addi 1, 0, 0",
176 "cmpi cr0, 1, 1, 10",
178 with
Program(lst
, bigendian
=False) as program
:
179 sim
= self
.run_tst_program(program
)
181 self
.assertEqual(sim
.gpr(2), SelectableInt(0x37, 64))
183 def test_branch_loop_ctr(self
):
184 lst
= ["addi 1, 0, 0",
186 "mtspr 9, 2", # set ctr to 7
188 "bc 16, 0, -0x4"] # bdnz to the addi above
189 with
Program(lst
, bigendian
=False) as program
:
190 sim
= self
.run_tst_program(program
)
192 self
.assertEqual(sim
.gpr(1), SelectableInt(0x23, 64))
196 def test_add_compare(self
):
197 lst
= ["addis 1, 0, 0xffff",
198 "addis 2, 0, 0xffff",
201 with
Program(lst
, bigendian
=False) as program
:
202 sim
= self
.run_tst_program(program
)
204 self
.assertEqual(sim
.gpr(3), SelectableInt(0x80000000, 64))
207 lst
= ["addis 1, 0, 0xffff",
208 "addis 2, 0, 0xffff",
211 with
Program(lst
, bigendian
=False) as program
:
212 sim
= self
.run_tst_program(program
)
213 self
.assertEqual(sim
.gpr(3), SelectableInt(0x200000, 64))
216 lst
= ["slw 1, 3, 2"]
217 initial_regs
= [0] * 32
218 initial_regs
[3] = 0xdeadbeefcafebabe
220 with
Program(lst
, bigendian
=False) as program
:
221 sim
= self
.run_tst_program(program
, initial_regs
)
222 self
.assertEqual(sim
.gpr(1), SelectableInt(0x5fd757c0, 64))
225 lst
= ["srw 1, 3, 2"]
226 initial_regs
= [0] * 32
227 initial_regs
[3] = 0xdeadbeefcafebabe
229 with
Program(lst
, bigendian
=False) as program
:
230 sim
= self
.run_tst_program(program
, initial_regs
)
231 self
.assertEqual(sim
.gpr(1), SelectableInt(0x657f5d5, 64))
233 def test_rlwinm(self
):
234 lst
= ["rlwinm 3, 1, 5, 20, 6"]
235 initial_regs
= [0] * 32
237 with
Program(lst
, bigendian
=False) as program
:
238 sim
= self
.run_tst_program(program
, initial_regs
)
239 self
.assertEqual(sim
.gpr(3), SelectableInt(0xfffffffffe000fff, 64))
241 def test_rlwimi(self
):
242 lst
= ["rlwimi 3, 1, 5, 20, 6"]
243 initial_regs
= [0] * 32
244 initial_regs
[1] = 0xffffffffdeadbeef
245 initial_regs
[3] = 0x12345678
246 with
Program(lst
, bigendian
=False) as program
:
247 sim
= self
.run_tst_program(program
, initial_regs
)
248 self
.assertEqual(sim
.gpr(3), SelectableInt(0xd5b7ddfbd4345dfb, 64))
250 def test_rldic(self
):
251 lst
= ["rldic 3, 1, 5, 20"]
252 initial_regs
= [0] * 32
253 initial_regs
[1] = 0xdeadbeefcafec0de
254 with
Program(lst
, bigendian
=False) as program
:
255 sim
= self
.run_tst_program(program
, initial_regs
)
256 self
.assertEqual(sim
.gpr(3), SelectableInt(0xdf95fd81bc0, 64))
260 initial_regs
= [0] * 32
261 initial_regs
[1] = 0xdeadbeeecaffc0de
262 with
Program(lst
, bigendian
=False) as program
:
263 sim
= self
.run_tst_program(program
, initial_regs
)
264 self
.assertEqual(sim
.gpr(2), SelectableInt(0x100000001, 64))
266 def test_popcnt(self
):
267 lst
= ["popcntb 2, 1",
271 initial_regs
= [0] * 32
272 initial_regs
[1] = 0xdeadbeefcafec0de
273 with
Program(lst
, bigendian
=False) as program
:
274 sim
= self
.run_tst_program(program
, initial_regs
)
275 self
.assertEqual(sim
.gpr(2),
276 SelectableInt(0x605060704070206, 64))
277 self
.assertEqual(sim
.gpr(3),
278 SelectableInt(0x1800000013, 64))
279 self
.assertEqual(sim
.gpr(4),
280 SelectableInt(0x2b, 64))
282 def test_cntlz(self
):
283 lst
= ["cntlzd 2, 1",
285 initial_regs
= [0] * 32
286 initial_regs
[1] = 0x0000beeecaffc0de
287 initial_regs
[3] = 0x0000000000ffc0de
288 with
Program(lst
, bigendian
=False) as program
:
289 sim
= self
.run_tst_program(program
, initial_regs
)
290 self
.assertEqual(sim
.gpr(2), SelectableInt(16, 64))
291 self
.assertEqual(sim
.gpr(4), SelectableInt(8, 64))
293 def test_cmpeqb(self
):
294 lst
= ["cmpeqb cr0, 2, 1",
296 initial_regs
= [0] * 32
297 initial_regs
[1] = 0x0102030405060708
298 initial_regs
[2] = 0x04
299 initial_regs
[3] = 0x10
300 with
Program(lst
, bigendian
=False) as program
:
301 sim
= self
.run_tst_program(program
, initial_regs
)
302 self
.assertEqual(sim
.crl
[0].get_range().value
,
304 self
.assertEqual(sim
.crl
[1].get_range().value
,
309 def test_mtcrf(self
):
311 # 0x76540000 gives expected (3+4) (2+4) (1+4) (0+4) for
313 # The positions of the CR fields have been verified using
314 # QEMU and 'cmp crx, a, b' instructions
315 lst
= ["addis 1, 0, 0x7654",
316 "mtcrf %d, 1" % (1 << (7-i
)),
318 with
Program(lst
, bigendian
=False) as program
:
319 sim
= self
.run_tst_program(program
)
322 # check CR[0]/1/2/3 as well
323 print("cr%d" % i
, sim
.crl
[i
].asint(True))
324 self
.assertTrue(SelectableInt(expected
, 4) == sim
.crl
[i
])
326 self
.assertEqual(sim
.cr
, SelectableInt(expected
<< ((7-i
)*4), 64))
328 def run_tst_program(self
, prog
, initial_regs
=[0] * 32):
329 simulator
= run_tst(prog
, initial_regs
)
334 if __name__
== "__main__":