1 from nmigen
import Module
, Signal
2 from nmigen
.back
.pysim
import Simulator
, Delay
, Settle
3 from nmigen
.test
.utils
import FHDLTestCase
5 from soc
.decoder
.power_decoder
import (create_pdecode
)
6 from soc
.decoder
.power_enums
import (Function
, InternalOp
,
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
18 class AttnTestCase(FHDLTestCase
):
21 def __init__(self
, name
="general"):
22 super().__init
__(name
)
25 def test_0_attn(self
):
26 """simple test of attn. program is 4 long: should halt at 2nd op
28 lst
= ["addi 6, 0, 0x10",
33 with
Program(lst
) as program
:
34 self
.run_tst_program(program
, [1])
36 def run_tst_program(self
, prog
, initial_regs
=None, initial_sprs
=None,
38 initial_regs
= [0] * 32
39 tc
= TestCase(prog
, self
.test_name
, initial_regs
, initial_sprs
, 0,
41 self
.test_data
.append(tc
)
44 class GeneralTestCases(FHDLTestCase
):
47 def __init__(self
, name
="general"):
48 super().__init
__(name
)
51 @unittest.skip("disable")
53 lst
= ["addi 6, 0, 0x10",
58 with
Program(lst
) as program
:
59 self
.run_tst_program(program
, [1])
61 @unittest.skip("disable")
62 def test_example(self
):
63 lst
= ["addi 1, 0, 0x5678",
67 with
Program(lst
) as program
:
68 self
.run_tst_program(program
, [1, 2, 3, 4])
70 @unittest.skip("disable")
72 lst
= ["addi 1, 0, 0x5678",
77 initial_mem
= {0x1230: (0x5432123412345678, 8),
78 0x1238: (0xabcdef0187654321, 8),
80 with
Program(lst
) as program
:
81 self
.run_tst_program(program
,
85 @unittest.skip("disable")
86 def test_ld_rev_ext(self
):
87 lst
= ["addi 1, 0, 0x5678",
92 with
Program(lst
) as program
:
93 self
.run_tst_program(program
, [1, 2, 3])
95 @unittest.skip("disable")
96 def test_st_rev_ext(self
):
97 lst
= ["addi 1, 0, 0x5678",
102 with
Program(lst
) as program
:
103 self
.run_tst_program(program
, [1, 2, 3])
105 @unittest.skip("disable")
106 def test_ldst_extended(self
):
107 lst
= ["addi 1, 0, 0x5678",
112 with
Program(lst
) as program
:
113 self
.run_tst_program(program
, [1, 2, 3])
115 @unittest.skip("disable")
116 def test_0_ldst_widths(self
):
117 lst
= ["addis 1, 0, 0xdead",
127 with
Program(lst
) as program
:
128 self
.run_tst_program(program
, [1, 2, 3, 4, 5])
130 @unittest.skip("disable")
132 lst
= ["addi 1, 0, 0x1234",
135 "subfic 4, 1, 0x1337",
137 with
Program(lst
) as program
:
138 self
.run_tst_program(program
, [1, 2, 3, 4, 5])
140 @unittest.skip("disable")
141 def test_add_with_carry(self
):
142 lst
= ["addi 1, 0, 5",
149 with
Program(lst
) as program
:
150 self
.run_tst_program(program
, [1, 2, 3])
152 @unittest.skip("disable")
153 def test_addis(self
):
154 lst
= ["addi 1, 0, 0x0FFF",
157 with
Program(lst
) as program
:
158 self
.run_tst_program(program
, [1])
160 @unittest.skip("broken")
161 def test_mulli(self
):
162 lst
= ["addi 1, 0, 3",
165 with
Program(lst
) as program
:
166 self
.run_tst_program(program
, [1])
168 @unittest.skip("disable")
169 def test_2_load_store(self
):
170 lst
= ["addi 1, 0, 0x1004",
176 initial_regs
= [0] * 32
177 initial_regs
[1] = 0x1004
178 initial_regs
[2] = 0x1008
179 initial_regs
[3] = 0x00ee
180 initial_mem
= {0x1000: (0x5432123412345678, 8),
181 0x1008: (0xabcdef0187654321, 8),
182 0x1020: (0x1828384822324252, 8),
184 with
Program(lst
) as program
:
185 self
.run_tst_program(program
, [3,4], initial_mem
)
187 @unittest.skip("disable")
188 def test_3_load_store(self
):
189 lst
= ["addi 1, 0, 0x1004",
194 initial_regs
= [0] * 32
195 initial_regs
[1] = 0x1004
196 initial_regs
[2] = 0x1002
197 initial_regs
[3] = 0x15eb
198 initial_mem
= {0x1000: (0x5432123412345678, 8),
199 0x1008: (0xabcdef0187654321, 8),
200 0x1020: (0x1828384822324252, 8),
202 with
Program(lst
) as program
:
203 self
.run_tst_program(program
, [1,2,3,4], initial_mem
)
207 register unsigned long i asm ("r12");
215 lst
= ["addi 9, 0, 0x10", # i = 16
216 "addi 9,9,-1", # i = i - 1
217 "cmpi 0,1,9,12", # compare 9 to value 0, store in CR2
218 "bc 4,0,-8" # branch if CR2 "test was != 0"
220 with
Program(lst
) as program
:
221 self
.run_tst_program(program
, [9], initial_mem
={})
223 def test_30_addis(self
):
224 lst
= [#"addi 0, 0, 5",
227 with
Program(lst
) as program
:
228 self
.run_tst_program(program
, [0, 12])
230 def run_tst_program(self
, prog
, initial_regs
=None, initial_sprs
=None,
232 initial_regs
= [0] * 32
233 tc
= TestCase(prog
, self
.test_name
, initial_regs
, initial_sprs
, 0,
235 self
.test_data
.append(tc
)
240 def run_tst(self
, generator
, initial_mem
=None, initial_pc
=0):
244 gen
= list(generator
.generate_instructions())
245 insn_code
= generator
.assembly
.splitlines()
246 instructions
= list(zip(gen
, insn_code
))
248 pdecode
= create_pdecode()
249 m
.submodules
.pdecode2
= pdecode2
= PowerDecode2(pdecode
)
251 # place program at requested address
252 gen
= (initial_pc
, gen
)
254 simulator
= ISA(pdecode2
, [0] * 32, {}, 0, initial_mem
, 0,
255 initial_insns
=gen
, respect_pc
=True,
256 disassembly
=insn_code
,
257 initial_pc
=initial_pc
)
262 yield pdecode2
.dec
.bigendian
.eq(1)
267 yield from simulator
.setup_one()
268 except KeyError: # indicates instruction not in imem: stop
271 yield from simulator
.execute_one()
275 sim
.add_process(process
)
276 with sim
.write_vcd("simulator.vcd", "simulator.gtkw",
282 def run_tst_program(self
, prog
, reglist
, initial_mem
=None,
283 extra_break_addr
=None):
285 simulator
= self
.run_tst(prog
, initial_mem
=initial_mem
,
286 initial_pc
=0x20000000)
288 with
run_program(prog
, initial_mem
, extra_break_addr
) as q
:
289 self
.qemu_register_compare(simulator
, q
, reglist
)
290 self
.qemu_mem_compare(simulator
, q
, True)
291 print(simulator
.gpr
.dump())
293 def qemu_mem_compare(self
, sim
, qemu
, check
=True):
294 if False: # disable convenient large interesting debugging memory dump
296 qmemdump
= qemu
.get_mem(addr
, 2048)
297 for i
in range(len(qmemdump
)):
298 s
= hex(int(qmemdump
[i
]))
299 print ("qemu mem %06x %s" % (addr
+i
*8, s
))
300 for k
, v
in sim
.mem
.mem
.items():
301 qmemdump
= qemu
.get_mem(k
*8, 8)
302 s
= hex(int(qmemdump
[0]))[2:]
303 print ("qemu mem %06x %16s" % (k
*8, s
))
304 for k
, v
in sim
.mem
.mem
.items():
305 print ("sim mem %06x %016x" % (k
*8, v
))
308 for k
, v
in sim
.mem
.mem
.items():
309 qmemdump
= qemu
.get_mem(k
*8, 1)
310 self
.assertEqual(int(qmemdump
[0]), v
)
312 def qemu_register_compare(self
, sim
, qemu
, regs
):
313 qpc
, qxer
, qcr
= qemu
.get_pc(), qemu
.get_xer(), qemu
.get_cr()
314 sim_cr
= sim
.cr
.get_range().value
315 sim_pc
= sim
.pc
.CIA
.value
316 sim_xer
= sim
.spr
['XER'].value
317 print("qemu pc", hex(qpc
))
318 print("qemu cr", hex(qcr
))
319 print("qemu xer", bin(qxer
))
320 print("sim nia", hex(sim
.pc
.NIA
.value
))
321 print("sim pc", hex(sim
.pc
.CIA
.value
))
322 print("sim cr", hex(sim_cr
))
323 print("sim xer", hex(sim_xer
))
324 self
.assertEqual(qpc
, sim_pc
)
326 qemu_val
= qemu
.get_register(reg
)
327 sim_val
= sim
.gpr(reg
).value
328 self
.assertEqual(qemu_val
, sim_val
,
329 "expect %x got %x" % (qemu_val
, sim_val
))
330 self
.assertEqual(qcr
, sim_cr
)
333 class DecoderTestCase(DecoderBase
, GeneralTestCases
):
337 if __name__
== "__main__":