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 @unittest.skip("disable")
53 def test_0_litex_bios_ctr_loop(self
):
55 32a4: ff ff 63 38 addi r3,r3,-1
56 32a8: 20 00 63 78 clrldi r3,r3,32
57 32ac: 01 00 23 39 addi r9,r3,1
58 32b0: a6 03 29 7d mtctr r9
60 32b8: fc ff 00 42 bdnz 32b4 <cdelay+0x10>
63 notes on converting pseudo-assembler to actual:
65 * bdnz target (equivalent to: bc 16,0,target)
66 * Clear left immediate clrldi ra,rs,n (n < 64) rldicl ra,rs,0,n
67 * CTR mtctr Rx mtspr 9,Rx
71 @unittest.skip("disable")
72 def test_0_litex_bios_cmp(self
):
73 """litex bios cmp test
75 lst
= [ "addis 26, 0, 21845",
85 with
Program(lst
, bigendian
) as program
:
86 self
.run_tst_program(program
, [5,6,7,26], initial_mem
={})
88 @unittest.skip("disable")
89 def test_0_litex_bios_r1(self
):
90 """litex bios IMM64 macro test
92 lst
= [ "addis 1,0,0",
98 with
Program(lst
, bigendian
) as program
:
99 self
.run_tst_program(program
, [1], initial_mem
={})
101 @unittest.skip("disable")
102 def test_0_litex_trampoline(self
):
103 lst
= ["tdi 0,0,0x48",
113 with
Program(lst
, bigendian
) as program
:
114 self
.run_tst_program(program
, [], initial_mem
={})
116 @unittest.skip("disable")
117 def test_0_cmp(self
):
118 lst
= ["addi 6, 0, 0x10",
123 with
Program(lst
, bigendian
) as program
:
124 self
.run_tst_program(program
, [1])
126 @unittest.skip("disable")
127 def test_example(self
):
128 lst
= ["addi 1, 0, 0x5678",
132 with
Program(lst
, bigendian
) as program
:
133 self
.run_tst_program(program
, [1, 2, 3, 4])
135 @unittest.skip("disable")
137 lst
= ["addi 1, 0, 0x5678",
142 initial_mem
= {0x1230: (0x5432123412345678, 8),
143 0x1238: (0xabcdef0187654321, 8),
145 with
Program(lst
, bigendian
) as program
:
146 self
.run_tst_program(program
,
150 @unittest.skip("disable")
151 def test_ldst_update(self
):
152 lst
= ["addi 1, 0, 0x5678",
157 initial_mem
= {0x1230: (0x5432123412345678, 8),
158 0x1238: (0xabcdef0187654321, 8),
160 with
Program(lst
, bigendian
) as program
:
161 self
.run_tst_program(program
,
165 @unittest.skip("disable")
166 def test_ld_rev_ext(self
):
167 lst
= ["addi 1, 0, 0x5678",
172 with
Program(lst
, bigendian
) as program
:
173 self
.run_tst_program(program
, [1, 2, 3])
175 @unittest.skip("disable")
176 def test_st_rev_ext(self
):
177 lst
= ["addi 1, 0, 0x5678",
182 with
Program(lst
, bigendian
) as program
:
183 self
.run_tst_program(program
, [1, 2, 3])
185 @unittest.skip("disable")
186 def test_ldst_extended(self
):
187 lst
= ["addi 1, 0, 0x5678",
192 with
Program(lst
, bigendian
) as program
:
193 self
.run_tst_program(program
, [1, 2, 3])
195 @unittest.skip("disable")
196 def test_0_ldst_widths(self
):
197 lst
= ["addis 1, 0, 0xdead",
207 with
Program(lst
, bigendian
) as program
:
208 self
.run_tst_program(program
, [1, 2, 3, 4, 5])
210 @unittest.skip("disable")
212 lst
= ["addi 1, 0, 0x1234",
215 "subfic 4, 1, 0x1337",
217 with
Program(lst
, bigendian
) as program
:
218 self
.run_tst_program(program
, [1, 2, 3, 4, 5])
220 @unittest.skip("disable")
221 def test_add_with_carry(self
):
222 lst
= ["addi 1, 0, 5",
229 with
Program(lst
, bigendian
) as program
:
230 self
.run_tst_program(program
, [1, 2, 3])
232 @unittest.skip("disable")
233 def test_addis(self
):
234 lst
= ["addi 1, 0, 0x0FFF",
237 with
Program(lst
, bigendian
) as program
:
238 self
.run_tst_program(program
, [1])
240 @unittest.skip("broken")
241 def test_mulli(self
):
242 lst
= ["addi 1, 0, 3",
245 with
Program(lst
, bigendian
) as program
:
246 self
.run_tst_program(program
, [1])
248 #@unittest.skip("disable")
249 def test_crxor(self
):
250 lst
= ["addi 1, 0, 0x1004",
253 "mtcrf 0b1111111, 3",
257 initial_regs
= [0] * 32
258 initial_regs
[1] = 0x1004
259 initial_regs
[2] = 0x1008
260 initial_regs
[3] = 0x01ee
261 with
Program(lst
, bigendian
) as program
:
262 self
.run_tst_program(program
, [3, 4])
264 #@unittest.skip("disable")
265 def test_crxor_2(self
):
266 lst
= ["addi 1, 0, 0x1004",
269 "mtcrf 0b1111111, 3",
273 initial_regs
= [0] * 32
274 initial_regs
[1] = 0x1004
275 initial_regs
[2] = 0x1008
276 initial_regs
[3] = 0x01ee
277 with
Program(lst
, bigendian
) as program
:
278 self
.run_tst_program(program
, [3, 4])
280 #@unittest.skip("disable")
281 def test_crnand(self
):
282 lst
= ["addi 1, 0, 0x1004",
285 "mtcrf 0b1111111, 3",
289 initial_regs
= [0] * 32
290 initial_regs
[1] = 0x1004
291 initial_regs
[2] = 0x1008
292 initial_regs
[3] = 0x01ee
293 with
Program(lst
, bigendian
) as program
:
294 self
.run_tst_program(program
, [3, 4])
296 #@unittest.skip("disable")
297 def test_crnand_2(self
):
298 lst
= ["addi 1, 0, 0x1004",
301 "mtcrf 0b1111111, 3",
305 initial_regs
= [0] * 32
306 initial_regs
[1] = 0x1004
307 initial_regs
[2] = 0x1008
308 initial_regs
[3] = 0x01ee
309 with
Program(lst
, bigendian
) as program
:
310 self
.run_tst_program(program
, [3, 4])
312 @unittest.skip("disable")
313 def test_isel_1(self
):
314 lst
= ["addi 1, 0, 0x1004",
317 "mtcrf 0b1111111, 3",
320 initial_regs
= [0] * 32
321 initial_regs
[1] = 0x1004
322 initial_regs
[2] = 0x1008
323 initial_regs
[3] = 0x00ee
324 with
Program(lst
, bigendian
) as program
:
325 self
.run_tst_program(program
, [3, 4])
327 #@unittest.skip("disable")
328 def test_isel_2(self
):
329 lst
= ["addi 1, 0, 0x1004",
332 "mtcrf 0b1111111, 3",
335 initial_regs
= [0] * 32
336 initial_regs
[1] = 0x1004
337 initial_regs
[2] = 0x1008
338 initial_regs
[3] = 0x00ee
339 with
Program(lst
, bigendian
) as program
:
340 self
.run_tst_program(program
, [3, 4])
342 @unittest.skip("disable")
343 def test_isel_3(self
):
344 lst
= ["addi 1, 0, 0x1004",
347 "mtcrf 0b1111111, 3",
350 initial_regs
= [0] * 32
351 initial_regs
[1] = 0x1004
352 initial_regs
[2] = 0x1008
353 initial_regs
[3] = 0x00ee
354 with
Program(lst
, bigendian
) as program
:
355 self
.run_tst_program(program
, [3, 4])
357 @unittest.skip("disable")
358 def test_2_load_store(self
):
359 lst
= ["addi 1, 0, 0x1004",
365 initial_regs
= [0] * 32
366 initial_regs
[1] = 0x1004
367 initial_regs
[2] = 0x1008
368 initial_regs
[3] = 0x00ee
369 initial_mem
= {0x1000: (0x5432123412345678, 8),
370 0x1008: (0xabcdef0187654321, 8),
371 0x1020: (0x1828384822324252, 8),
373 with
Program(lst
, bigendian
) as program
:
374 self
.run_tst_program(program
, [3, 4], initial_mem
)
376 @unittest.skip("disable")
377 def test_3_load_store(self
):
378 lst
= ["addi 1, 0, 0x1004",
383 initial_regs
= [0] * 32
384 initial_regs
[1] = 0x1004
385 initial_regs
[2] = 0x1002
386 initial_regs
[3] = 0x15eb
387 initial_mem
= {0x1000: (0x5432123412345678, 8),
388 0x1008: (0xabcdef0187654321, 8),
389 0x1020: (0x1828384822324252, 8),
391 with
Program(lst
, bigendian
) as program
:
392 self
.run_tst_program(program
, [1, 2, 3, 4], initial_mem
)
394 @unittest.skip("disable")
396 lst
= ["addi 1, 0, 0x1004",
397 "ori 0,0,0", # "preferred" form of nop
400 initial_regs
= [0] * 32
401 with
Program(lst
, bigendian
) as program
:
402 self
.run_tst_program(program
, [1, 3])
404 @unittest.skip("disable")
405 def test_zero_illegal(self
):
406 lst
= bytes([0x10,0x00,0x20,0x39,
409 disassembly
= ["addi 9, 0, 0x10",
412 initial_regs
= [0] * 32
413 with
Program(lst
, bigendian
) as program
:
414 program
.assembly
= '\n'.join(disassembly
) + '\n' # XXX HACK!
415 self
.run_tst_program(program
, [1, 3])
420 register unsigned long i asm ("r9");
428 lst
= ["addi 9, 0, 0x10", # i = 16
429 "addi 9,9,-1", # i = i - 1
430 "cmpi 2,1,9,12", # compare 9 to value 12, store in CR2
431 "bc 4,10,-8" # branch if CR2 "test was != 12"
433 with
Program(lst
, bigendian
) as program
:
434 self
.run_tst_program(program
, [9], initial_mem
={})
436 @unittest.skip("disable")
437 def test_30_addis(self
):
438 lst
= [ # "addi 0, 0, 5",
441 with
Program(lst
, bigendian
) as program
:
442 self
.run_tst_program(program
, [12])
444 @unittest.skip("disable")
445 def test_31_addis(self
):
446 """tests for zero not in register zero
448 lst
= [ "rldicr 0, 0, 32, 31",
453 "rldicr 1, 1, 32, 31",
458 with
Program(lst
, bigendian
) as program
:
459 self
.run_tst_program(program
, [0, 1, 2])
461 def run_tst_program(self
, prog
, initial_regs
=None, initial_sprs
=None,
463 initial_regs
= [0] * 32
464 tc
= TestCase(prog
, self
.test_name
, initial_regs
, initial_sprs
, 0,
466 self
.test_data
.append(tc
)
471 def run_tst(self
, generator
, initial_mem
=None, initial_pc
=0):
475 gen
= list(generator
.generate_instructions())
476 insn_code
= generator
.assembly
.splitlines()
477 instructions
= list(zip(gen
, insn_code
))
479 pdecode
= create_pdecode()
480 m
.submodules
.pdecode2
= pdecode2
= PowerDecode2(pdecode
)
482 # place program at requested address
483 gen
= (initial_pc
, gen
)
485 simulator
= ISA(pdecode2
, [0] * 32, {}, 0, initial_mem
, 0,
486 initial_insns
=gen
, respect_pc
=True,
487 disassembly
=insn_code
,
488 initial_pc
=initial_pc
,
494 # yield pdecode2.dec.bigendian.eq(bigendian)
499 yield from simulator
.setup_one()
500 except KeyError: # indicates instruction not in imem: stop
503 yield from simulator
.execute_one()
506 sim
.add_process(process
)
507 with sim
.write_vcd("pdecode_simulator.vcd"):
512 def run_tst_program(self
, prog
, reglist
, initial_mem
=None,
513 extra_break_addr
=None):
515 simulator
= self
.run_tst(prog
, initial_mem
=initial_mem
,
516 initial_pc
=0x20000000)
518 with
run_program(prog
, initial_mem
, extra_break_addr
,
519 bigendian
=bigendian
) as q
:
520 self
.qemu_register_compare(simulator
, q
, reglist
)
521 self
.qemu_mem_compare(simulator
, q
, True)
522 print(simulator
.gpr
.dump())
524 def qemu_mem_compare(self
, sim
, qemu
, check
=True):
525 if False: # disable convenient large interesting debugging memory dump
527 qmemdump
= qemu
.get_mem(addr
, 2048)
528 for i
in range(len(qmemdump
)):
529 s
= hex(int(qmemdump
[i
]))
530 print("qemu mem %06x %s" % (addr
+i
*8, s
))
531 for k
, v
in sim
.mem
.mem
.items():
532 qmemdump
= qemu
.get_mem(k
*8, 8)
533 s
= hex(int(qmemdump
[0]))[2:]
534 print("qemu mem %06x %16s" % (k
*8, s
))
535 for k
, v
in sim
.mem
.mem
.items():
536 print("sim mem %06x %016x" % (k
*8, v
))
539 for k
, v
in sim
.mem
.mem
.items():
540 qmemdump
= qemu
.get_mem(k
*8, 1)
541 self
.assertEqual(int(qmemdump
[0]), v
)
543 def qemu_register_compare(self
, sim
, qemu
, regs
):
544 qpc
, qxer
, qcr
= qemu
.get_pc(), qemu
.get_xer(), qemu
.get_cr()
545 sim_cr
= sim
.cr
.value
546 sim_pc
= sim
.pc
.CIA
.value
547 sim_xer
= sim
.spr
['XER'].value
548 print("qemu pc", hex(qpc
))
549 print("qemu cr", hex(qcr
))
550 print("qemu xer", bin(qxer
))
551 print("sim nia", hex(sim
.pc
.NIA
.value
))
552 print("sim pc", hex(sim
.pc
.CIA
.value
))
553 print("sim cr", hex(sim_cr
))
554 print("sim xer", hex(sim_xer
))
555 self
.assertEqual(qpc
, sim_pc
)
557 qemu_val
= qemu
.get_register(reg
)
558 sim_val
= sim
.gpr(reg
).value
559 self
.assertEqual(qemu_val
, sim_val
,
560 "expect %x got %x" % (qemu_val
, sim_val
))
561 self
.assertEqual(qcr
, sim_cr
)
564 class DecoderTestCase(DecoderBase
, GeneralTestCases
):
568 if __name__
== "__main__":