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_ld_rev_ext(self
):
116 lst
= ["addi 1, 0, 0x5678",
121 with
Program(lst
, bigendian
) as program
:
122 self
.run_tst_program(program
, [1, 2, 3])
124 @unittest.skip("disable")
125 def test_st_rev_ext(self
):
126 lst
= ["addi 1, 0, 0x5678",
131 with
Program(lst
, bigendian
) as program
:
132 self
.run_tst_program(program
, [1, 2, 3])
134 @unittest.skip("disable")
135 def test_ldst_extended(self
):
136 lst
= ["addi 1, 0, 0x5678",
141 with
Program(lst
, bigendian
) as program
:
142 self
.run_tst_program(program
, [1, 2, 3])
144 @unittest.skip("disable")
145 def test_0_ldst_widths(self
):
146 lst
= ["addis 1, 0, 0xdead",
156 with
Program(lst
, bigendian
) as program
:
157 self
.run_tst_program(program
, [1, 2, 3, 4, 5])
159 @unittest.skip("disable")
161 lst
= ["addi 1, 0, 0x1234",
164 "subfic 4, 1, 0x1337",
166 with
Program(lst
, bigendian
) as program
:
167 self
.run_tst_program(program
, [1, 2, 3, 4, 5])
169 #@unittest.skip("disable")
170 def test_add_with_carry(self
):
171 lst
= ["addi 1, 0, 5",
178 with
Program(lst
, bigendian
) as program
:
179 self
.run_tst_program(program
, [1, 2, 3])
181 @unittest.skip("disable")
182 def test_addis(self
):
183 lst
= ["addi 1, 0, 0x0FFF",
186 with
Program(lst
, bigendian
) as program
:
187 self
.run_tst_program(program
, [1])
189 @unittest.skip("broken")
190 def test_mulli(self
):
191 lst
= ["addi 1, 0, 3",
194 with
Program(lst
, bigendian
) as program
:
195 self
.run_tst_program(program
, [1])
197 @unittest.skip("disable")
198 def test_2_load_store(self
):
199 lst
= ["addi 1, 0, 0x1004",
205 initial_regs
= [0] * 32
206 initial_regs
[1] = 0x1004
207 initial_regs
[2] = 0x1008
208 initial_regs
[3] = 0x00ee
209 initial_mem
= {0x1000: (0x5432123412345678, 8),
210 0x1008: (0xabcdef0187654321, 8),
211 0x1020: (0x1828384822324252, 8),
213 with
Program(lst
, bigendian
) as program
:
214 self
.run_tst_program(program
, [3, 4], initial_mem
)
216 @unittest.skip("disable")
217 def test_3_load_store(self
):
218 lst
= ["addi 1, 0, 0x1004",
223 initial_regs
= [0] * 32
224 initial_regs
[1] = 0x1004
225 initial_regs
[2] = 0x1002
226 initial_regs
[3] = 0x15eb
227 initial_mem
= {0x1000: (0x5432123412345678, 8),
228 0x1008: (0xabcdef0187654321, 8),
229 0x1020: (0x1828384822324252, 8),
231 with
Program(lst
, bigendian
) as program
:
232 self
.run_tst_program(program
, [1, 2, 3, 4], initial_mem
)
234 @unittest.skip("disable")
236 lst
= ["addi 1, 0, 0x1004",
237 "ori 0,0,0", # "preferred" form of nop
240 initial_regs
= [0] * 32
241 with
Program(lst
, bigendian
) as program
:
242 self
.run_tst_program(program
, [1, 3])
244 @unittest.skip("disable")
245 def test_zero_illegal(self
):
246 lst
= bytes([0x10,0x00,0x20,0x39,
249 disassembly
= ["addi 9, 0, 0x10",
252 initial_regs
= [0] * 32
253 with
Program(lst
, bigendian
) as program
:
254 program
.assembly
= '\n'.join(disassembly
) + '\n' # XXX HACK!
255 self
.run_tst_program(program
, [1, 3])
259 register unsigned long i asm ("r12");
267 lst
= ["addi 9, 0, 0x10", # i = 16
268 "addi 9,9,-1", # i = i - 1
269 "cmpi 0,1,9,12", # compare 9 to value 0, store in CR2
270 "bc 4,0,-8" # branch if CR2 "test was != 0"
272 with
Program(lst
, bigendian
) as program
:
273 self
.run_tst_program(program
, [9], initial_mem
={})
275 def test_30_addis(self
):
276 lst
= [ # "addi 0, 0, 5",
279 with
Program(lst
, bigendian
) as program
:
280 self
.run_tst_program(program
, [12])
282 def run_tst_program(self
, prog
, initial_regs
=None, initial_sprs
=None,
284 initial_regs
= [0] * 32
285 tc
= TestCase(prog
, self
.test_name
, initial_regs
, initial_sprs
, 0,
287 self
.test_data
.append(tc
)
292 def run_tst(self
, generator
, initial_mem
=None, initial_pc
=0):
296 gen
= list(generator
.generate_instructions())
297 insn_code
= generator
.assembly
.splitlines()
298 instructions
= list(zip(gen
, insn_code
))
300 pdecode
= create_pdecode()
301 m
.submodules
.pdecode2
= pdecode2
= PowerDecode2(pdecode
)
303 # place program at requested address
304 gen
= (initial_pc
, gen
)
306 simulator
= ISA(pdecode2
, [0] * 32, {}, 0, initial_mem
, 0,
307 initial_insns
=gen
, respect_pc
=True,
308 disassembly
=insn_code
,
309 initial_pc
=initial_pc
,
315 # yield pdecode2.dec.bigendian.eq(bigendian)
320 yield from simulator
.setup_one()
321 except KeyError: # indicates instruction not in imem: stop
324 yield from simulator
.execute_one()
327 sim
.add_process(process
)
328 with sim
.write_vcd("pdecode_simulator.vcd"):
333 def run_tst_program(self
, prog
, reglist
, initial_mem
=None,
334 extra_break_addr
=None):
336 simulator
= self
.run_tst(prog
, initial_mem
=initial_mem
,
337 initial_pc
=0x20000000)
339 with
run_program(prog
, initial_mem
, extra_break_addr
,
340 bigendian
=bigendian
) as q
:
341 self
.qemu_register_compare(simulator
, q
, reglist
)
342 self
.qemu_mem_compare(simulator
, q
, True)
343 print(simulator
.gpr
.dump())
345 def qemu_mem_compare(self
, sim
, qemu
, check
=True):
346 if False: # disable convenient large interesting debugging memory dump
348 qmemdump
= qemu
.get_mem(addr
, 2048)
349 for i
in range(len(qmemdump
)):
350 s
= hex(int(qmemdump
[i
]))
351 print("qemu mem %06x %s" % (addr
+i
*8, s
))
352 for k
, v
in sim
.mem
.mem
.items():
353 qmemdump
= qemu
.get_mem(k
*8, 8)
354 s
= hex(int(qmemdump
[0]))[2:]
355 print("qemu mem %06x %16s" % (k
*8, s
))
356 for k
, v
in sim
.mem
.mem
.items():
357 print("sim mem %06x %016x" % (k
*8, v
))
360 for k
, v
in sim
.mem
.mem
.items():
361 qmemdump
= qemu
.get_mem(k
*8, 1)
362 self
.assertEqual(int(qmemdump
[0]), v
)
364 def qemu_register_compare(self
, sim
, qemu
, regs
):
365 qpc
, qxer
, qcr
= qemu
.get_pc(), qemu
.get_xer(), qemu
.get_cr()
366 sim_cr
= sim
.cr
.get_range().value
367 sim_pc
= sim
.pc
.CIA
.value
368 sim_xer
= sim
.spr
['XER'].value
369 print("qemu pc", hex(qpc
))
370 print("qemu cr", hex(qcr
))
371 print("qemu xer", bin(qxer
))
372 print("sim nia", hex(sim
.pc
.NIA
.value
))
373 print("sim pc", hex(sim
.pc
.CIA
.value
))
374 print("sim cr", hex(sim_cr
))
375 print("sim xer", hex(sim_xer
))
376 self
.assertEqual(qpc
, sim_pc
)
378 qemu_val
= qemu
.get_register(reg
)
379 sim_val
= sim
.gpr(reg
).value
380 self
.assertEqual(qemu_val
, sim_val
,
381 "expect %x got %x" % (qemu_val
, sim_val
))
382 self
.assertEqual(qcr
, sim_cr
)
385 class DecoderTestCase(DecoderBase
, GeneralTestCases
):
389 if __name__
== "__main__":