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 if initial_sprs
is None:
24 instruction
= Signal(32)
26 pdecode
= create_pdecode()
28 gen
= list(generator
.generate_instructions())
29 insncode
= generator
.assembly
.splitlines()
30 instructions
= list(zip(gen
, insncode
))
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
,
39 comb
+= pdecode2
.dec
.raw_opcode_in
.eq(instruction
)
45 yield pdecode2
.dec
.bigendian
.eq(0) # little / big?
46 pc
= simulator
.pc
.CIA
.value
48 while index
< len(instructions
):
51 yield from simulator
.setup_one()
52 except KeyError: # indicates instruction not in imem: stop
56 ins
, code
= instructions
[index
]
57 print(" 0x{:X}".format(ins
& 0xffffffff))
58 opname
= code
.split(' ')[0]
61 # ask the decoder to decode this binary data (endian'd)
62 yield from simulator
.execute_one()
63 pc
= simulator
.pc
.CIA
.value
66 sim
.add_process(process
)
67 with sim
.write_vcd("simulator.vcd", "simulator.gtkw",
73 class DecoderTestCase(FHDLTestCase
):
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))
85 lst
= ["addi 3, 0, 0x1234",
88 with
Program(lst
, bigendian
=False) as program
:
89 sim
= self
.run_tst_program(program
)
91 self
.assertEqual(sim
.gpr(1), SelectableInt(0x5555, 64))
93 def test_load_store(self
):
94 lst
= ["addi 1, 0, 0x0010",
98 with
Program(lst
, bigendian
=False) as program
:
99 sim
= self
.run_tst_program(program
)
101 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1234, 64))
103 @unittest.skip("broken")
104 def test_addpcis(self
):
105 lst
= ["addpcis 1, 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))
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))
126 def test_branch_link(self
):
132 with
Program(lst
, bigendian
=False) as program
:
133 sim
= self
.run_tst_program(program
)
134 self
.assertEqual(sim
.spr
['LR'], SelectableInt(0x4, 64))
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))
148 def test_branch_cond(self
):
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
)
159 self
.assertEqual(sim
.gpr(2), SelectableInt(0, 64))
161 self
.assertEqual(sim
.gpr(2), SelectableInt(0x1234, 64))
163 def test_branch_loop(self
):
164 lst
= ["addi 1, 0, 0",
168 "cmpi cr0, 1, 1, 10",
170 with
Program(lst
, bigendian
=False) as program
:
171 sim
= self
.run_tst_program(program
)
173 self
.assertEqual(sim
.gpr(2), SelectableInt(0x37, 64))
175 def test_branch_loop_ctr(self
):
176 lst
= ["addi 1, 0, 0",
178 "mtspr 9, 2", # set ctr to 7
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
)
184 self
.assertEqual(sim
.gpr(1), SelectableInt(0x23, 64))
188 def test_add_compare(self
):
189 lst
= ["addis 1, 0, 0xffff",
190 "addis 2, 0, 0xffff",
193 with
Program(lst
, bigendian
=False) as program
:
194 sim
= self
.run_tst_program(program
)
196 self
.assertEqual(sim
.gpr(3), SelectableInt(0x80000000, 64))
199 lst
= ["addis 1, 0, 0xffff",
200 "addis 2, 0, 0xffff",
203 with
Program(lst
, bigendian
=False) as program
:
204 sim
= self
.run_tst_program(program
)
205 self
.assertEqual(sim
.gpr(3), SelectableInt(0x200000, 64))
208 lst
= ["slw 1, 3, 2"]
209 initial_regs
= [0] * 32
210 initial_regs
[3] = 0xdeadbeefcafebabe
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))
217 lst
= ["srw 1, 3, 2"]
218 initial_regs
= [0] * 32
219 initial_regs
[3] = 0xdeadbeefcafebabe
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))
225 def test_rlwinm(self
):
226 lst
= ["rlwinm 3, 1, 5, 20, 6"]
227 initial_regs
= [0] * 32
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))
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))
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))
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))
258 def test_popcnt(self
):
259 lst
= ["popcntb 2, 1",
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))
274 def test_cntlz(self
):
275 lst
= ["cntlzd 2, 1",
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))
285 def test_cmpeqb(self
):
286 lst
= ["cmpeqb cr0, 2, 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
,
296 self
.assertEqual(sim
.crl
[1].get_range().value
,
301 def test_mtcrf(self
):
303 # 0x76540000 gives expected (3+4) (2+4) (1+4) (0+4) for
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
)),
310 with
Program(lst
, bigendian
=False) as program
:
311 sim
= self
.run_tst_program(program
)
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
])
318 self
.assertEqual(sim
.cr
, SelectableInt(expected
<< ((7-i
)*4), 32))
320 def run_tst_program(self
, prog
, initial_regs
=[0] * 32):
321 simulator
= run_tst(prog
, initial_regs
)
326 if __name__
== "__main__":