first cut at qemu memory dump and compare
[soc.git] / src / soc / simulator / test_sim.py
1 from nmigen import Module, Signal
2 from nmigen.back.pysim import Simulator, Delay, Settle
3 from nmigen.test.utils import FHDLTestCase
4 import unittest
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
16
17 class Register:
18 def __init__(self, num):
19 self.num = num
20
21
22 class DecoderTestCase(FHDLTestCase):
23
24 def run_tst(self, generator):
25 m = Module()
26 comb = m.d.comb
27 instruction = Signal(32)
28
29 pdecode = create_pdecode()
30
31 m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
32
33 simulator = ISA(pdecode2, [0] * 32, {}, 0, {}, 0)
34 comb += pdecode2.dec.raw_opcode_in.eq(instruction)
35 comb += pdecode2.dec.bigendian.eq(0)
36 gen = generator.generate_instructions()
37 instructions = list(zip(gen, generator.assembly.splitlines()))
38
39 sim = Simulator(m)
40 def process():
41
42 index = simulator.pc.CIA.value//4
43 while index < len(instructions):
44 ins, code = instructions[index]
45
46 print("0x{:X}".format(ins & 0xffffffff))
47 print(code)
48
49 yield instruction.eq(ins)
50 yield Delay(1e-6)
51
52 opname = code.split(' ')[0]
53 yield from simulator.call(opname)
54 index = simulator.pc.CIA.value//4
55
56
57 sim.add_process(process)
58 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
59 traces=[]):
60 sim.run()
61
62 return simulator
63
64 def test_0_cmp(self):
65 lst = ["addi 6, 0, 0x10",
66 "addi 7, 0, 0x05",
67 "subf. 1, 6, 7",
68 "cmp cr2, 1, 6, 7",
69 ]
70 with Program(lst) as program:
71 self.run_tst_program(program, [1])
72
73 def test_example(self):
74 lst = ["addi 1, 0, 0x1234",
75 "addi 2, 0, 0x5678",
76 "add 3, 1, 2",
77 "and 4, 1, 2"]
78 with Program(lst) as program:
79 self.run_tst_program(program, [1, 2, 3, 4])
80
81 def test_ldst(self):
82 lst = ["addi 1, 0, 0x1234",
83 "addi 2, 0, 0x5678",
84 "stw 1, 0(2)",
85 "lwz 3, 0(2)"]
86 with Program(lst) as program:
87 self.run_tst_program(program, [1, 2, 3])
88
89 def test_ldst_extended(self):
90 lst = ["addi 1, 0, 0x1234",
91 "addi 2, 0, 0x5678",
92 "addi 4, 0, 0x40",
93 "stw 1, 0x40(2)",
94 "lwzx 3, 4, 2"]
95 with Program(lst) as program:
96 self.run_tst_program(program, [1, 2, 3])
97
98 def test_0_ldst_widths(self):
99 lst = ["addis 1, 0, 0xdead",
100 "ori 1, 1, 0xbeef",
101 "addi 2, 0, 0x1000",
102 "std 1, 0(2)",
103 "lbz 1, 5(2)",
104 "lhz 3, 4(2)",
105 "lwz 4, 4(2)",
106 "addi 5, 0, 0x12",
107 "stb 5, 5(2)",
108 "ld 5, 0(2)"]
109 with Program(lst) as program:
110 self.run_tst_program(program, [1, 2, 3, 4, 5])
111
112 def test_sub(self):
113 lst = ["addi 1, 0, 0x1234",
114 "addi 2, 0, 0x5678",
115 "subf 3, 1, 2",
116 "subfic 4, 1, 0x1337",
117 "neg 5, 1"]
118 with Program(lst) as program:
119 self.run_tst_program(program, [1, 2, 3, 4, 5])
120
121 def test_add_with_carry(self):
122 lst = ["addi 1, 0, 5",
123 "neg 1, 1",
124 "addi 2, 0, 7",
125 "neg 2, 2",
126 "addc 3, 2, 1",
127 "addi 3, 3, 1"
128 ]
129 with Program(lst) as program:
130 self.run_tst_program(program, [1, 2, 3])
131
132 def test_addis(self):
133 lst = ["addi 1, 0, 0x0FFF",
134 "addis 1, 1, 0x0F"
135 ]
136 with Program(lst) as program:
137 self.run_tst_program(program, [1])
138
139 @unittest.skip("broken")
140 def test_mulli(self):
141 lst = ["addi 1, 0, 3",
142 "mulli 1, 1, 2"
143 ]
144 with Program(lst) as program:
145 self.run_tst_program(program, [1])
146
147 def run_tst_program(self, prog, reglist):
148 import sys
149 simulator = self.run_tst(prog)
150 prog.reset()
151 with run_program(prog) as q:
152 self.qemu_register_compare(simulator, q, reglist)
153 self.qemu_mem_compare(simulator, q, reglist)
154 print(simulator.gpr.dump())
155
156 def qemu_mem_compare(self, sim, qemu, regs):
157 addr = 0x1000
158 qmemdump = qemu.get_mem(addr, 16)
159 for i in range(len(qmemdump)):
160 s = hex(int(qmemdump[i]))
161 print ("qemu mem %06x %s" % (addr+i*8, s))
162 for k, v in sim.mem.mem.items():
163 print ("sim %06x %016x" % (k, v))
164 for k, v in sim.mem.mem.items():
165 self.assertEqual(int(qmemdump[(k-0x200)//8]), v) # magic constant??
166
167 def qemu_register_compare(self, sim, qemu, regs):
168 qpc, qxer, qcr = qemu.get_pc(), qemu.get_xer(), qemu.get_cr()
169 sim_cr = sim.cr.get_range().value
170 sim_pc = sim.pc.CIA.value
171 sim_xer = sim.spr['XER'].value
172 print("qemu pc", hex(qpc))
173 print("qemu cr", hex(qcr))
174 print("qemu xer", bin(qxer))
175 print("sim pc", hex(sim.pc.CIA.value))
176 print("sim cr", hex(sim_cr))
177 print("sim xer", hex(sim_xer))
178 self.assertEqual(qcr, sim_cr)
179 for reg in regs:
180 qemu_val = qemu.get_register(reg)
181 sim_val = sim.gpr(reg).value
182 self.assertEqual(qemu_val, sim_val)
183
184
185 if __name__ == "__main__":
186 unittest.main()