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_r1(self
):
54 """litex bios IMM64 macro test
56 lst
= [ "addis 1,0,0",
62 with
Program(lst
, bigendian
) as program
:
63 self
.run_tst_program(program
, [1], initial_mem
={})
65 @unittest.skip("disable")
66 def test_0_litex_trampoline(self
):
67 lst
= ["tdi 0,0,0x48",
77 with
Program(lst
, bigendian
) as program
:
78 self
.run_tst_program(program
, [], initial_mem
={})
80 @unittest.skip("disable")
82 lst
= ["addi 6, 0, 0x10",
87 with
Program(lst
, bigendian
) as program
:
88 self
.run_tst_program(program
, [1])
90 @unittest.skip("disable")
91 def test_example(self
):
92 lst
= ["addi 1, 0, 0x5678",
96 with
Program(lst
, bigendian
) as program
:
97 self
.run_tst_program(program
, [1, 2, 3, 4])
99 #@unittest.skip("disable")
101 lst
= ["addi 1, 0, 0x5678",
106 initial_mem
= {0x1230: (0x5432123412345678, 8),
107 0x1238: (0xabcdef0187654321, 8),
109 with
Program(lst
, bigendian
) as program
:
110 self
.run_tst_program(program
,
114 #@unittest.skip("disable")
115 def test_ldst_update(self
):
116 lst
= ["addi 1, 0, 0x5678",
121 initial_mem
= {0x1230: (0x5432123412345678, 8),
122 0x1238: (0xabcdef0187654321, 8),
124 with
Program(lst
, bigendian
) as program
:
125 self
.run_tst_program(program
,
129 @unittest.skip("disable")
130 def test_ld_rev_ext(self
):
131 lst
= ["addi 1, 0, 0x5678",
136 with
Program(lst
, bigendian
) as program
:
137 self
.run_tst_program(program
, [1, 2, 3])
139 @unittest.skip("disable")
140 def test_st_rev_ext(self
):
141 lst
= ["addi 1, 0, 0x5678",
146 with
Program(lst
, bigendian
) as program
:
147 self
.run_tst_program(program
, [1, 2, 3])
149 #@unittest.skip("disable")
150 def test_ldst_extended(self
):
151 lst
= ["addi 1, 0, 0x5678",
156 with
Program(lst
, bigendian
) as program
:
157 self
.run_tst_program(program
, [1, 2, 3])
159 @unittest.skip("disable")
160 def test_0_ldst_widths(self
):
161 lst
= ["addis 1, 0, 0xdead",
171 with
Program(lst
, bigendian
) as program
:
172 self
.run_tst_program(program
, [1, 2, 3, 4, 5])
174 @unittest.skip("disable")
176 lst
= ["addi 1, 0, 0x1234",
179 "subfic 4, 1, 0x1337",
181 with
Program(lst
, bigendian
) as program
:
182 self
.run_tst_program(program
, [1, 2, 3, 4, 5])
184 #@unittest.skip("disable")
185 def test_add_with_carry(self
):
186 lst
= ["addi 1, 0, 5",
193 with
Program(lst
, bigendian
) as program
:
194 self
.run_tst_program(program
, [1, 2, 3])
196 @unittest.skip("disable")
197 def test_addis(self
):
198 lst
= ["addi 1, 0, 0x0FFF",
201 with
Program(lst
, bigendian
) as program
:
202 self
.run_tst_program(program
, [1])
204 @unittest.skip("broken")
205 def test_mulli(self
):
206 lst
= ["addi 1, 0, 3",
209 with
Program(lst
, bigendian
) as program
:
210 self
.run_tst_program(program
, [1])
212 @unittest.skip("disable")
213 def test_2_load_store(self
):
214 lst
= ["addi 1, 0, 0x1004",
220 initial_regs
= [0] * 32
221 initial_regs
[1] = 0x1004
222 initial_regs
[2] = 0x1008
223 initial_regs
[3] = 0x00ee
224 initial_mem
= {0x1000: (0x5432123412345678, 8),
225 0x1008: (0xabcdef0187654321, 8),
226 0x1020: (0x1828384822324252, 8),
228 with
Program(lst
, bigendian
) as program
:
229 self
.run_tst_program(program
, [3, 4], initial_mem
)
231 @unittest.skip("disable")
232 def test_3_load_store(self
):
233 lst
= ["addi 1, 0, 0x1004",
238 initial_regs
= [0] * 32
239 initial_regs
[1] = 0x1004
240 initial_regs
[2] = 0x1002
241 initial_regs
[3] = 0x15eb
242 initial_mem
= {0x1000: (0x5432123412345678, 8),
243 0x1008: (0xabcdef0187654321, 8),
244 0x1020: (0x1828384822324252, 8),
246 with
Program(lst
, bigendian
) as program
:
247 self
.run_tst_program(program
, [1, 2, 3, 4], initial_mem
)
249 @unittest.skip("disable")
251 lst
= ["addi 1, 0, 0x1004",
252 "ori 0,0,0", # "preferred" form of nop
255 initial_regs
= [0] * 32
256 with
Program(lst
, bigendian
) as program
:
257 self
.run_tst_program(program
, [1, 3])
259 @unittest.skip("disable")
260 def test_zero_illegal(self
):
261 lst
= bytes([0x10,0x00,0x20,0x39,
264 disassembly
= ["addi 9, 0, 0x10",
267 initial_regs
= [0] * 32
268 with
Program(lst
, bigendian
) as program
:
269 program
.assembly
= '\n'.join(disassembly
) + '\n' # XXX HACK!
270 self
.run_tst_program(program
, [1, 3])
272 @unittest.skip("disable")
275 register unsigned long i asm ("r12");
283 lst
= ["addi 9, 0, 0x10", # i = 16
284 "addi 9,9,-1", # i = i - 1
285 "cmpi 0,1,9,12", # compare 9 to value 0, store in CR2
286 "bc 4,0,-8" # branch if CR2 "test was != 0"
288 with
Program(lst
, bigendian
) as program
:
289 self
.run_tst_program(program
, [9], initial_mem
={})
291 @unittest.skip("disable")
292 def test_30_addis(self
):
293 lst
= [ # "addi 0, 0, 5",
296 with
Program(lst
, bigendian
) as program
:
297 self
.run_tst_program(program
, [12])
299 def run_tst_program(self
, prog
, initial_regs
=None, initial_sprs
=None,
301 initial_regs
= [0] * 32
302 tc
= TestCase(prog
, self
.test_name
, initial_regs
, initial_sprs
, 0,
304 self
.test_data
.append(tc
)
309 def run_tst(self
, generator
, initial_mem
=None, initial_pc
=0):
313 gen
= list(generator
.generate_instructions())
314 insn_code
= generator
.assembly
.splitlines()
315 instructions
= list(zip(gen
, insn_code
))
317 pdecode
= create_pdecode()
318 m
.submodules
.pdecode2
= pdecode2
= PowerDecode2(pdecode
)
320 # place program at requested address
321 gen
= (initial_pc
, gen
)
323 simulator
= ISA(pdecode2
, [0] * 32, {}, 0, initial_mem
, 0,
324 initial_insns
=gen
, respect_pc
=True,
325 disassembly
=insn_code
,
326 initial_pc
=initial_pc
,
332 # yield pdecode2.dec.bigendian.eq(bigendian)
337 yield from simulator
.setup_one()
338 except KeyError: # indicates instruction not in imem: stop
341 yield from simulator
.execute_one()
344 sim
.add_process(process
)
345 with sim
.write_vcd("pdecode_simulator.vcd"):
350 def run_tst_program(self
, prog
, reglist
, initial_mem
=None,
351 extra_break_addr
=None):
353 simulator
= self
.run_tst(prog
, initial_mem
=initial_mem
,
354 initial_pc
=0x20000000)
356 with
run_program(prog
, initial_mem
, extra_break_addr
,
357 bigendian
=bigendian
) as q
:
358 self
.qemu_register_compare(simulator
, q
, reglist
)
359 self
.qemu_mem_compare(simulator
, q
, True)
360 print(simulator
.gpr
.dump())
362 def qemu_mem_compare(self
, sim
, qemu
, check
=True):
363 if False: # disable convenient large interesting debugging memory dump
365 qmemdump
= qemu
.get_mem(addr
, 2048)
366 for i
in range(len(qmemdump
)):
367 s
= hex(int(qmemdump
[i
]))
368 print("qemu mem %06x %s" % (addr
+i
*8, s
))
369 for k
, v
in sim
.mem
.mem
.items():
370 qmemdump
= qemu
.get_mem(k
*8, 8)
371 s
= hex(int(qmemdump
[0]))[2:]
372 print("qemu mem %06x %16s" % (k
*8, s
))
373 for k
, v
in sim
.mem
.mem
.items():
374 print("sim mem %06x %016x" % (k
*8, v
))
377 for k
, v
in sim
.mem
.mem
.items():
378 qmemdump
= qemu
.get_mem(k
*8, 1)
379 self
.assertEqual(int(qmemdump
[0]), v
)
381 def qemu_register_compare(self
, sim
, qemu
, regs
):
382 qpc
, qxer
, qcr
= qemu
.get_pc(), qemu
.get_xer(), qemu
.get_cr()
383 sim_cr
= sim
.cr
.get_range().value
384 sim_pc
= sim
.pc
.CIA
.value
385 sim_xer
= sim
.spr
['XER'].value
386 print("qemu pc", hex(qpc
))
387 print("qemu cr", hex(qcr
))
388 print("qemu xer", bin(qxer
))
389 print("sim nia", hex(sim
.pc
.NIA
.value
))
390 print("sim pc", hex(sim
.pc
.CIA
.value
))
391 print("sim cr", hex(sim_cr
))
392 print("sim xer", hex(sim_xer
))
393 self
.assertEqual(qpc
, sim_pc
)
395 qemu_val
= qemu
.get_register(reg
)
396 sim_val
= sim
.gpr(reg
).value
397 self
.assertEqual(qemu_val
, sim_val
,
398 "expect %x got %x" % (qemu_val
, sim_val
))
399 self
.assertEqual(qcr
, sim_cr
)
402 class DecoderTestCase(DecoderBase
, GeneralTestCases
):
406 if __name__
== "__main__":