reasonably certain that the careful and slow use of little-endian data read/write
[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, initial_mem=None):
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, initial_mem, 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 _tst0_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 _tstexample(self):
74 lst = ["addi 1, 0, 0x5678",
75 "addi 2, 0, 0x1234",
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 _tstldst(self):
82 lst = ["addi 1, 0, 0x5678",
83 "addi 2, 0, 0x1234",
84 "stw 1, 0(2)",
85 "lwz 3, 0(2)"
86 ]
87 initial_mem = {0x1230: (0x5432123412345678, 8),
88 0x1238: (0xabcdef0187654321, 8),
89 }
90 with Program(lst) as program:
91 self.run_tst_program(program,
92 [1, 2, 3],
93 initial_mem)
94
95 def _tstldst_extended(self):
96 lst = ["addi 1, 0, 0x5678",
97 "addi 2, 0, 0x1234",
98 "addi 4, 0, 0x40",
99 "stw 1, 0x40(2)",
100 "lwzx 3, 4, 2"]
101 with Program(lst) as program:
102 self.run_tst_program(program, [1, 2, 3])
103
104 def _tst0_ldst_widths(self):
105 lst = ["addis 1, 0, 0xdead",
106 "ori 1, 1, 0xbeef",
107 "addi 2, 0, 0x1000",
108 "std 1, 0(2)",
109 "lbz 1, 5(2)",
110 "lhz 3, 4(2)",
111 "lwz 4, 4(2)",
112 "addi 5, 0, 0x12",
113 "stb 5, 5(2)",
114 "ld 5, 0(2)"]
115 with Program(lst) as program:
116 self.run_tst_program(program, [1, 2, 3, 4, 5])
117
118 def _tstsub(self):
119 lst = ["addi 1, 0, 0x1234",
120 "addi 2, 0, 0x5678",
121 "subf 3, 1, 2",
122 "subfic 4, 1, 0x1337",
123 "neg 5, 1"]
124 with Program(lst) as program:
125 self.run_tst_program(program, [1, 2, 3, 4, 5])
126
127 def _tstadd_with_carry(self):
128 lst = ["addi 1, 0, 5",
129 "neg 1, 1",
130 "addi 2, 0, 7",
131 "neg 2, 2",
132 "addc 3, 2, 1",
133 "addi 3, 3, 1"
134 ]
135 with Program(lst) as program:
136 self.run_tst_program(program, [1, 2, 3])
137
138 def _tstaddis(self):
139 lst = ["addi 1, 0, 0x0FFF",
140 "addis 1, 1, 0x0F"
141 ]
142 with Program(lst) as program:
143 self.run_tst_program(program, [1])
144
145 @unittest.skip("broken")
146 def _tstmulli(self):
147 lst = ["addi 1, 0, 3",
148 "mulli 1, 1, 2"
149 ]
150 with Program(lst) as program:
151 self.run_tst_program(program, [1])
152
153 def test_3_load_store(self):
154 lst = ["addi 1, 0, 0x1004",
155 "addi 2, 0, 0x1002",
156 "addi 3, 0, 0x15eb",
157 "sth 4, 0(2)",
158 "lhz 4, 0(2)"]
159 initial_regs = [0] * 32
160 initial_regs[1] = 0x0004
161 initial_regs[2] = 0x0002
162 initial_regs[3] = 0x15eb
163 initial_mem = {0x1000: (0x5432123412345678, 8),
164 0x1008: (0xabcdef0187654321, 8),
165 0x1020: (0x1828384822324252, 8),
166 }
167 with Program(lst) as program:
168 self.run_tst_program(program, [1,2,3,4], initial_mem)
169
170 def run_tst_program(self, prog, reglist, initial_mem=None):
171 import sys
172 simulator = self.run_tst(prog, initial_mem=initial_mem)
173 prog.reset()
174 with run_program(prog, initial_mem) as q:
175 self.qemu_register_compare(simulator, q, reglist)
176 self.qemu_mem_compare(simulator, q, reglist)
177 print(simulator.gpr.dump())
178
179 def qemu_mem_compare(self, sim, qemu, check=True):
180 if False: # disable convenient large interesting debugging memory dump
181 addr = 0x0
182 qmemdump = qemu.get_mem(addr, 2048)
183 for i in range(len(qmemdump)):
184 s = hex(int(qmemdump[i]))
185 print ("qemu mem %06x %s" % (addr+i*8, s))
186 for k, v in sim.mem.mem.items():
187 qmemdump = qemu.get_mem(k*8, 8)
188 s = hex(int(qmemdump[0]))[2:]
189 print ("qemu mem %06x %16s" % (k*8, s))
190 for k, v in sim.mem.mem.items():
191 print ("sim mem %06x %016x" % (k*8, v))
192 if not check:
193 return
194 for k, v in sim.mem.mem.items():
195 qmemdump = qemu.get_mem(k*8, 1)
196 self.assertEqual(int(qmemdump[0]), v)
197
198 def qemu_register_compare(self, sim, qemu, regs):
199 qpc, qxer, qcr = qemu.get_pc(), qemu.get_xer(), qemu.get_cr()
200 sim_cr = sim.cr.get_range().value
201 sim_pc = sim.pc.CIA.value
202 sim_xer = sim.spr['XER'].value
203 print("qemu pc", hex(qpc))
204 print("qemu cr", hex(qcr))
205 print("qemu xer", bin(qxer))
206 print("sim pc", hex(sim.pc.CIA.value))
207 print("sim cr", hex(sim_cr))
208 print("sim xer", hex(sim_xer))
209 self.assertEqual(qcr, sim_cr)
210 for reg in regs:
211 qemu_val = qemu.get_register(reg)
212 sim_val = sim.gpr(reg).value
213 self.assertEqual(qemu_val, sim_val)
214
215
216 if __name__ == "__main__":
217 unittest.main()