1 from nmigen
import Module
, Signal
2 from nmigen
.back
.pysim
import Simulator
, Delay
, Settle
3 from nmutil
.formaltest
import FHDLTestCase
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
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):
21 if initial_sprs
is None:
25 instruction
= Signal(32)
27 pdecode
= create_pdecode()
29 gen
= list(generator
.generate_instructions())
30 insncode
= generator
.assembly
.splitlines()
31 instructions
= list(zip(gen
, insncode
))
33 m
.submodules
.pdecode2
= pdecode2
= PowerDecode2(pdecode
)
34 simulator
= ISA(pdecode2
, initial_regs
, initial_sprs
, initial_cr
,
35 initial_insns
=gen
, respect_pc
=True,
36 initial_svstate
=svstate
,
41 comb
+= pdecode2
.dec
.raw_opcode_in
.eq(instruction
)
47 yield pdecode2
.dec
.bigendian
.eq(0) # little / big?
48 pc
= simulator
.pc
.CIA
.value
50 while index
< len(instructions
):
53 yield from simulator
.setup_one()
54 except KeyError: # indicates instruction not in imem: stop
58 ins
, code
= instructions
[index
]
59 print(" 0x{:X}".format(ins
& 0xffffffff))
60 opname
= code
.split(' ')[0]
63 # ask the decoder to decode this binary data (endian'd)
64 yield from simulator
.execute_one()
65 pc
= simulator
.pc
.CIA
.value
68 sim
.add_process(process
)
69 with sim
.write_vcd("simulator.vcd", "simulator.gtkw",
75 class DecoderTestCase(FHDLTestCase
):
79 initial_regs
= [0] * 32
80 initial_regs
[3] = 0x1234
81 initial_regs
[2] = 0x4321
82 with
Program(lst
, bigendian
=False) as program
:
83 sim
= self
.run_tst_program(program
, initial_regs
)
84 self
.assertEqual(sim
.gpr(1), SelectableInt(0x5555, 64))
87 lst
= ["addi 3, 0, 0x1234",
90 with
Program(lst
, bigendian
=False) as program
:
91 sim
= self
.run_tst_program(program
)
93 self
.assertEqual(sim
.gpr(1), SelectableInt(0x5555, 64))
95 def test_load_store(self
):
96 lst
= ["addi 1, 0, 0x0010",
100 with
Program(lst
, bigendian
=False) as program
:
101 sim
= self
.run_tst_program(program
)
103 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1234, 64))
105 @unittest.skip("broken")
106 def test_addpcis(self
):
107 lst
= ["addpcis 1, 0x1",
110 with
Program(lst
, bigendian
=False) as program
:
111 sim
= self
.run_tst_program(program
)
112 self
.assertEqual(sim
.gpr(1), SelectableInt(0x10004, 64))
113 self
.assertEqual(sim
.gpr(2), SelectableInt(0x10008, 64))
114 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1000c, 64))
116 def test_branch(self
):
117 lst
= ["ba 0xc", # branch to line 4
118 "addi 1, 0, 0x1234", # Should never execute
119 "ba 0x1000", # exit the program
120 "addi 2, 0, 0x1234", # line 4
121 "ba 0x8"] # branch to line 3
122 with
Program(lst
, bigendian
=False) as program
:
123 sim
= self
.run_tst_program(program
)
124 self
.assertEqual(sim
.pc
.CIA
, SelectableInt(0x1000, 64))
125 self
.assertEqual(sim
.gpr(1), SelectableInt(0x0, 64))
126 self
.assertEqual(sim
.gpr(2), SelectableInt(0x1234, 64))
128 def test_branch_link(self
):
134 with
Program(lst
, bigendian
=False) as program
:
135 sim
= self
.run_tst_program(program
)
136 self
.assertEqual(sim
.spr
['LR'], SelectableInt(0x4, 64))
138 def test_branch_ctr(self
):
139 lst
= ["addi 1, 0, 0x10", # target of jump
140 "mtspr 9, 1", # mtctr 1
141 "bcctr 20, 0, 0", # bctr
142 "addi 2, 0, 0x1", # should never execute
143 "addi 1, 0, 0x1234"] # target of ctr
144 with
Program(lst
, bigendian
=False) as program
:
145 sim
= self
.run_tst_program(program
)
146 self
.assertEqual(sim
.spr
['CTR'], SelectableInt(0x10, 64))
147 self
.assertEqual(sim
.gpr(1), SelectableInt(0x1234, 64))
148 self
.assertEqual(sim
.gpr(2), SelectableInt(0, 64))
150 def test_branch_cond(self
):
152 lst
= [f
"addi 1, 0, {i}", # set r1 to i
153 "cmpi cr0, 1, 1, 10", # compare r1 with 10 and store to cr0
154 "bc 12, 2, 0x8", # beq 0x8 -
155 # branch if r1 equals 10 to the nop below
156 "addi 2, 0, 0x1234", # if r1 == 10 this shouldn't execute
157 "or 0, 0, 0"] # branch target
158 with
Program(lst
, bigendian
=False) as program
:
159 sim
= self
.run_tst_program(program
)
161 self
.assertEqual(sim
.gpr(2), SelectableInt(0, 64))
163 self
.assertEqual(sim
.gpr(2), SelectableInt(0x1234, 64))
165 def test_branch_loop(self
):
166 lst
= ["addi 1, 0, 0",
170 "cmpi cr0, 1, 1, 10",
172 with
Program(lst
, bigendian
=False) as program
:
173 sim
= self
.run_tst_program(program
)
175 self
.assertEqual(sim
.gpr(2), SelectableInt(0x37, 64))
177 def test_branch_loop_ctr(self
):
178 lst
= ["addi 1, 0, 0",
180 "mtspr 9, 2", # set ctr to 7
182 "bc 16, 0, -0x4"] # bdnz to the addi above
183 with
Program(lst
, bigendian
=False) as program
:
184 sim
= self
.run_tst_program(program
)
186 self
.assertEqual(sim
.gpr(1), SelectableInt(0x23, 64))
190 def test_add_compare(self
):
191 lst
= ["addis 1, 0, 0xffff",
192 "addis 2, 0, 0xffff",
195 with
Program(lst
, bigendian
=False) as program
:
196 sim
= self
.run_tst_program(program
)
198 self
.assertEqual(sim
.gpr(3), SelectableInt(0x80000000, 64))
201 lst
= ["addis 1, 0, 0xffff",
202 "addis 2, 0, 0xffff",
205 with
Program(lst
, bigendian
=False) as program
:
206 sim
= self
.run_tst_program(program
)
207 self
.assertEqual(sim
.gpr(3), SelectableInt(0x200000, 64))
210 lst
= ["slw 1, 3, 2"]
211 initial_regs
= [0] * 32
212 initial_regs
[3] = 0xdeadbeefcafebabe
214 with
Program(lst
, bigendian
=False) as program
:
215 sim
= self
.run_tst_program(program
, initial_regs
)
216 self
.assertEqual(sim
.gpr(1), SelectableInt(0x5fd757c0, 64))
219 lst
= ["srw 1, 3, 2"]
220 initial_regs
= [0] * 32
221 initial_regs
[3] = 0xdeadbeefcafebabe
223 with
Program(lst
, bigendian
=False) as program
:
224 sim
= self
.run_tst_program(program
, initial_regs
)
225 self
.assertEqual(sim
.gpr(1), SelectableInt(0x657f5d5, 64))
227 def test_rlwinm(self
):
228 lst
= ["rlwinm 3, 1, 5, 20, 6"]
229 initial_regs
= [0] * 32
231 with
Program(lst
, bigendian
=False) as program
:
232 sim
= self
.run_tst_program(program
, initial_regs
)
233 self
.assertEqual(sim
.gpr(3), SelectableInt(0xfffffffffe000fff, 64))
235 def test_rlwimi(self
):
236 lst
= ["rlwimi 3, 1, 5, 20, 6"]
237 initial_regs
= [0] * 32
238 initial_regs
[1] = 0xffffffffdeadbeef
239 initial_regs
[3] = 0x12345678
240 with
Program(lst
, bigendian
=False) as program
:
241 sim
= self
.run_tst_program(program
, initial_regs
)
242 self
.assertEqual(sim
.gpr(3), SelectableInt(0xd5b7ddfbd4345dfb, 64))
244 def test_rldic(self
):
245 lst
= ["rldic 3, 1, 5, 20"]
246 initial_regs
= [0] * 32
247 initial_regs
[1] = 0xdeadbeefcafec0de
248 with
Program(lst
, bigendian
=False) as program
:
249 sim
= self
.run_tst_program(program
, initial_regs
)
250 self
.assertEqual(sim
.gpr(3), SelectableInt(0xdf95fd81bc0, 64))
254 initial_regs
= [0] * 32
255 initial_regs
[1] = 0xdeadbeeecaffc0de
256 with
Program(lst
, bigendian
=False) as program
:
257 sim
= self
.run_tst_program(program
, initial_regs
)
258 self
.assertEqual(sim
.gpr(2), SelectableInt(0x100000001, 64))
260 def test_popcnt(self
):
261 lst
= ["popcntb 2, 1",
265 initial_regs
= [0] * 32
266 initial_regs
[1] = 0xdeadbeefcafec0de
267 with
Program(lst
, bigendian
=False) as program
:
268 sim
= self
.run_tst_program(program
, initial_regs
)
269 self
.assertEqual(sim
.gpr(2),
270 SelectableInt(0x605060704070206, 64))
271 self
.assertEqual(sim
.gpr(3),
272 SelectableInt(0x1800000013, 64))
273 self
.assertEqual(sim
.gpr(4),
274 SelectableInt(0x2b, 64))
276 def test_cntlz(self
):
277 lst
= ["cntlzd 2, 1",
279 initial_regs
= [0] * 32
280 initial_regs
[1] = 0x0000beeecaffc0de
281 initial_regs
[3] = 0x0000000000ffc0de
282 with
Program(lst
, bigendian
=False) as program
:
283 sim
= self
.run_tst_program(program
, initial_regs
)
284 self
.assertEqual(sim
.gpr(2), SelectableInt(16, 64))
285 self
.assertEqual(sim
.gpr(4), SelectableInt(8, 64))
287 def test_cmpeqb(self
):
288 lst
= ["cmpeqb cr0, 2, 1",
290 initial_regs
= [0] * 32
291 initial_regs
[1] = 0x0102030405060708
292 initial_regs
[2] = 0x04
293 initial_regs
[3] = 0x10
294 with
Program(lst
, bigendian
=False) as program
:
295 sim
= self
.run_tst_program(program
, initial_regs
)
296 self
.assertEqual(sim
.crl
[0].get_range().value
,
298 self
.assertEqual(sim
.crl
[1].get_range().value
,
303 def test_mtcrf(self
):
305 # 0x76540000 gives expected (3+4) (2+4) (1+4) (0+4) for
307 # The positions of the CR fields have been verified using
308 # QEMU and 'cmp crx, a, b' instructions
309 lst
= ["addis 1, 0, 0x7654",
310 "mtcrf %d, 1" % (1 << (7-i
)),
312 with
Program(lst
, bigendian
=False) as program
:
313 sim
= self
.run_tst_program(program
)
316 # check CR[0]/1/2/3 as well
317 print("cr%d", sim
.crl
[i
])
318 self
.assertTrue(SelectableInt(expected
, 4) == sim
.crl
[i
])
320 self
.assertEqual(sim
.cr
, SelectableInt(expected
<< ((7-i
)*4), 32))
322 def run_tst_program(self
, prog
, initial_regs
=[0] * 32):
323 simulator
= run_tst(prog
, initial_regs
)
328 if __name__
== "__main__":