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
.power_decoder
import (create_pdecode
)
6 from soc
.decoder
.power_enums
import (Function
, MicrOp
,
7 In1Sel
, In2Sel
, In3Sel
,
8 OutSel
, RC
, LdstLen
, CryIn
,
9 single_bit_flags
, Form
, SPR
,
10 get_signal_name
, get_csv
)
11 from soc
.decoder
.power_decoder2
import (PowerDecode2
)
12 from soc
.simulator
.program
import Program
13 from soc
.simulator
.qemu
import run_program
14 from soc
.decoder
.isa
.all
import ISA
15 from soc
.fu
.test
.common
import TestCase
16 from soc
.config
.endian
import bigendian
19 class AttnTestCase(FHDLTestCase
):
22 def __init__(self
, name
="general"):
23 super().__init
__(name
)
26 def test_0_attn(self
):
27 """simple test of attn. program is 4 long: should halt at 2nd op
29 lst
= ["addi 6, 0, 0x10",
34 with
Program(lst
, bigendian
) as program
:
35 self
.run_tst_program(program
, [1])
37 def run_tst_program(self
, prog
, initial_regs
=None, initial_sprs
=None,
39 initial_regs
= [0] * 32
40 tc
= TestCase(prog
, self
.test_name
, initial_regs
, initial_sprs
, 0,
42 self
.test_data
.append(tc
)
45 class GeneralTestCases(FHDLTestCase
):
48 def __init__(self
, name
="general"):
49 super().__init
__(name
)
52 def test_0_litex_bios_ctr_loop(self
):
54 32a4: ff ff 63 38 addi r3,r3,-1
55 32a8: 20 00 63 78 clrldi r3,r3,32
56 32ac: 01 00 23 39 addi r9,r3,1
57 32b0: a6 03 29 7d mtctr r9
59 32b8: fc ff 00 42 bdnz 32b4 <cdelay+0x10>
62 notes on converting pseudo-assembler to actual:
64 * bdnz target (equivalent to: bc 16,0,target)
65 * Clear left immediate clrldi ra,rs,n (n < 64) rldicl ra,rs,0,n
66 * CTR mtctr Rx mtspr 9,Rx
70 def test_0_litex_bios_cmp(self
):
71 """litex bios cmp test
73 lst
= [ "addis 26, 0, 21845",
83 with
Program(lst
, bigendian
) as program
:
84 self
.run_tst_program(program
, [5,6,7,26], initial_mem
={})
86 @unittest.skip("disable")
87 def test_0_litex_bios_r1(self
):
88 """litex bios IMM64 macro test
90 lst
= [ "addis 1,0,0",
96 with
Program(lst
, bigendian
) as program
:
97 self
.run_tst_program(program
, [1], initial_mem
={})
99 @unittest.skip("disable")
100 def test_0_litex_trampoline(self
):
101 lst
= ["tdi 0,0,0x48",
111 with
Program(lst
, bigendian
) as program
:
112 self
.run_tst_program(program
, [], initial_mem
={})
114 @unittest.skip("disable")
115 def test_0_cmp(self
):
116 lst
= ["addi 6, 0, 0x10",
121 with
Program(lst
, bigendian
) as program
:
122 self
.run_tst_program(program
, [1])
124 @unittest.skip("disable")
125 def test_example(self
):
126 lst
= ["addi 1, 0, 0x5678",
130 with
Program(lst
, bigendian
) as program
:
131 self
.run_tst_program(program
, [1, 2, 3, 4])
133 @unittest.skip("disable")
135 lst
= ["addi 1, 0, 0x5678",
140 initial_mem
= {0x1230: (0x5432123412345678, 8),
141 0x1238: (0xabcdef0187654321, 8),
143 with
Program(lst
, bigendian
) as program
:
144 self
.run_tst_program(program
,
148 #@unittest.skip("disable")
149 def test_ldst_update(self
):
150 lst
= ["addi 1, 0, 0x5678",
155 initial_mem
= {0x1230: (0x5432123412345678, 8),
156 0x1238: (0xabcdef0187654321, 8),
158 with
Program(lst
, bigendian
) as program
:
159 self
.run_tst_program(program
,
163 @unittest.skip("disable")
164 def test_ld_rev_ext(self
):
165 lst
= ["addi 1, 0, 0x5678",
170 with
Program(lst
, bigendian
) as program
:
171 self
.run_tst_program(program
, [1, 2, 3])
173 #@unittest.skip("disable")
174 def test_st_rev_ext(self
):
175 lst
= ["addi 1, 0, 0x5678",
180 with
Program(lst
, bigendian
) as program
:
181 self
.run_tst_program(program
, [1, 2, 3])
183 @unittest.skip("disable")
184 def test_ldst_extended(self
):
185 lst
= ["addi 1, 0, 0x5678",
190 with
Program(lst
, bigendian
) as program
:
191 self
.run_tst_program(program
, [1, 2, 3])
193 @unittest.skip("disable")
194 def test_0_ldst_widths(self
):
195 lst
= ["addis 1, 0, 0xdead",
205 with
Program(lst
, bigendian
) as program
:
206 self
.run_tst_program(program
, [1, 2, 3, 4, 5])
208 @unittest.skip("disable")
210 lst
= ["addi 1, 0, 0x1234",
213 "subfic 4, 1, 0x1337",
215 with
Program(lst
, bigendian
) as program
:
216 self
.run_tst_program(program
, [1, 2, 3, 4, 5])
218 @unittest.skip("disable")
219 def test_add_with_carry(self
):
220 lst
= ["addi 1, 0, 5",
227 with
Program(lst
, bigendian
) as program
:
228 self
.run_tst_program(program
, [1, 2, 3])
230 @unittest.skip("disable")
231 def test_addis(self
):
232 lst
= ["addi 1, 0, 0x0FFF",
235 with
Program(lst
, bigendian
) as program
:
236 self
.run_tst_program(program
, [1])
238 @unittest.skip("broken")
239 def test_mulli(self
):
240 lst
= ["addi 1, 0, 3",
243 with
Program(lst
, bigendian
) as program
:
244 self
.run_tst_program(program
, [1])
246 @unittest.skip("disable")
247 def test_2_load_store(self
):
248 lst
= ["addi 1, 0, 0x1004",
254 initial_regs
= [0] * 32
255 initial_regs
[1] = 0x1004
256 initial_regs
[2] = 0x1008
257 initial_regs
[3] = 0x00ee
258 initial_mem
= {0x1000: (0x5432123412345678, 8),
259 0x1008: (0xabcdef0187654321, 8),
260 0x1020: (0x1828384822324252, 8),
262 with
Program(lst
, bigendian
) as program
:
263 self
.run_tst_program(program
, [3, 4], initial_mem
)
265 @unittest.skip("disable")
266 def test_3_load_store(self
):
267 lst
= ["addi 1, 0, 0x1004",
272 initial_regs
= [0] * 32
273 initial_regs
[1] = 0x1004
274 initial_regs
[2] = 0x1002
275 initial_regs
[3] = 0x15eb
276 initial_mem
= {0x1000: (0x5432123412345678, 8),
277 0x1008: (0xabcdef0187654321, 8),
278 0x1020: (0x1828384822324252, 8),
280 with
Program(lst
, bigendian
) as program
:
281 self
.run_tst_program(program
, [1, 2, 3, 4], initial_mem
)
283 @unittest.skip("disable")
285 lst
= ["addi 1, 0, 0x1004",
286 "ori 0,0,0", # "preferred" form of nop
289 initial_regs
= [0] * 32
290 with
Program(lst
, bigendian
) as program
:
291 self
.run_tst_program(program
, [1, 3])
293 @unittest.skip("disable")
294 def test_zero_illegal(self
):
295 lst
= bytes([0x10,0x00,0x20,0x39,
298 disassembly
= ["addi 9, 0, 0x10",
301 initial_regs
= [0] * 32
302 with
Program(lst
, bigendian
) as program
:
303 program
.assembly
= '\n'.join(disassembly
) + '\n' # XXX HACK!
304 self
.run_tst_program(program
, [1, 3])
306 @unittest.skip("disable")
309 register unsigned long i asm ("r12");
317 lst
= ["addi 9, 0, 0x10", # i = 16
318 "addi 9,9,-1", # i = i - 1
319 "cmpi 0,1,9,12", # compare 9 to value 0, store in CR2
320 "bc 4,0,-8" # branch if CR2 "test was != 0"
322 with
Program(lst
, bigendian
) as program
:
323 self
.run_tst_program(program
, [9], initial_mem
={})
325 @unittest.skip("disable")
326 def test_30_addis(self
):
327 lst
= [ # "addi 0, 0, 5",
330 with
Program(lst
, bigendian
) as program
:
331 self
.run_tst_program(program
, [12])
333 #@unittest.skip("disable")
334 def test_31_addis(self
):
335 """tests for zero not in register zero
337 lst
= [ "rldicr 0, 0, 32, 31",
342 "rldicr 1, 1, 32, 31",
347 with
Program(lst
, bigendian
) as program
:
348 self
.run_tst_program(program
, [0, 1, 2])
350 def run_tst_program(self
, prog
, initial_regs
=None, initial_sprs
=None,
352 initial_regs
= [0] * 32
353 tc
= TestCase(prog
, self
.test_name
, initial_regs
, initial_sprs
, 0,
355 self
.test_data
.append(tc
)
360 def run_tst(self
, generator
, initial_mem
=None, initial_pc
=0):
364 gen
= list(generator
.generate_instructions())
365 insn_code
= generator
.assembly
.splitlines()
366 instructions
= list(zip(gen
, insn_code
))
368 pdecode
= create_pdecode()
369 m
.submodules
.pdecode2
= pdecode2
= PowerDecode2(pdecode
)
371 # place program at requested address
372 gen
= (initial_pc
, gen
)
374 simulator
= ISA(pdecode2
, [0] * 32, {}, 0, initial_mem
, 0,
375 initial_insns
=gen
, respect_pc
=True,
376 disassembly
=insn_code
,
377 initial_pc
=initial_pc
,
383 # yield pdecode2.dec.bigendian.eq(bigendian)
388 yield from simulator
.setup_one()
389 except KeyError: # indicates instruction not in imem: stop
392 yield from simulator
.execute_one()
395 sim
.add_process(process
)
396 with sim
.write_vcd("pdecode_simulator.vcd"):
401 def run_tst_program(self
, prog
, reglist
, initial_mem
=None,
402 extra_break_addr
=None):
404 simulator
= self
.run_tst(prog
, initial_mem
=initial_mem
,
405 initial_pc
=0x20000000)
407 with
run_program(prog
, initial_mem
, extra_break_addr
,
408 bigendian
=bigendian
) as q
:
409 self
.qemu_register_compare(simulator
, q
, reglist
)
410 self
.qemu_mem_compare(simulator
, q
, True)
411 print(simulator
.gpr
.dump())
413 def qemu_mem_compare(self
, sim
, qemu
, check
=True):
414 if False: # disable convenient large interesting debugging memory dump
416 qmemdump
= qemu
.get_mem(addr
, 2048)
417 for i
in range(len(qmemdump
)):
418 s
= hex(int(qmemdump
[i
]))
419 print("qemu mem %06x %s" % (addr
+i
*8, s
))
420 for k
, v
in sim
.mem
.mem
.items():
421 qmemdump
= qemu
.get_mem(k
*8, 8)
422 s
= hex(int(qmemdump
[0]))[2:]
423 print("qemu mem %06x %16s" % (k
*8, s
))
424 for k
, v
in sim
.mem
.mem
.items():
425 print("sim mem %06x %016x" % (k
*8, v
))
428 for k
, v
in sim
.mem
.mem
.items():
429 qmemdump
= qemu
.get_mem(k
*8, 1)
430 self
.assertEqual(int(qmemdump
[0]), v
)
432 def qemu_register_compare(self
, sim
, qemu
, regs
):
433 qpc
, qxer
, qcr
= qemu
.get_pc(), qemu
.get_xer(), qemu
.get_cr()
434 sim_cr
= sim
.cr
.get_range().value
435 sim_pc
= sim
.pc
.CIA
.value
436 sim_xer
= sim
.spr
['XER'].value
437 print("qemu pc", hex(qpc
))
438 print("qemu cr", hex(qcr
))
439 print("qemu xer", bin(qxer
))
440 print("sim nia", hex(sim
.pc
.NIA
.value
))
441 print("sim pc", hex(sim
.pc
.CIA
.value
))
442 print("sim cr", hex(sim_cr
))
443 print("sim xer", hex(sim_xer
))
444 self
.assertEqual(qpc
, sim_pc
)
446 qemu_val
= qemu
.get_register(reg
)
447 sim_val
= sim
.gpr(reg
).value
448 self
.assertEqual(qemu_val
, sim_val
,
449 "expect %x got %x" % (qemu_val
, sim_val
))
450 self
.assertEqual(qcr
, sim_cr
)
453 class DecoderTestCase(DecoderBase
, GeneralTestCases
):
457 if __name__
== "__main__":