8b16c24923d6f31c3b87a71e06b51c3c3aaf734d
[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 test_ld_rev_ext(self):
96 lst = ["addi 1, 0, 0x5678",
97 "addi 2, 0, 0x1234",
98 "addi 4, 0, 0x40",
99 "stw 1, 0x40(2)",
100 "lwbrx 3, 4, 2"]
101 with Program(lst) as program:
102 self.run_tst_program(program, [1, 2, 3])
103
104 def test_st_rev_ext(self):
105 lst = ["addi 1, 0, 0x5678",
106 "addi 2, 0, 0x1234",
107 "addi 4, 0, 0x40",
108 "stwbrx 1, 4, 2",
109 "lwzx 3, 4, 2"]
110 with Program(lst) as program:
111 self.run_tst_program(program, [1, 2, 3])
112
113 def test_ldst_extended(self):
114 lst = ["addi 1, 0, 0x5678",
115 "addi 2, 0, 0x1234",
116 "addi 4, 0, 0x40",
117 "stw 1, 0x40(2)",
118 "lwzx 3, 4, 2"]
119 with Program(lst) as program:
120 self.run_tst_program(program, [1, 2, 3])
121
122 def _tst0_ldst_widths(self):
123 lst = ["addis 1, 0, 0xdead",
124 "ori 1, 1, 0xbeef",
125 "addi 2, 0, 0x1000",
126 "std 1, 0(2)",
127 "lbz 1, 5(2)",
128 "lhz 3, 4(2)",
129 "lwz 4, 4(2)",
130 "addi 5, 0, 0x12",
131 "stb 5, 5(2)",
132 "ld 5, 0(2)"]
133 with Program(lst) as program:
134 self.run_tst_program(program, [1, 2, 3, 4, 5])
135
136 def _tstsub(self):
137 lst = ["addi 1, 0, 0x1234",
138 "addi 2, 0, 0x5678",
139 "subf 3, 1, 2",
140 "subfic 4, 1, 0x1337",
141 "neg 5, 1"]
142 with Program(lst) as program:
143 self.run_tst_program(program, [1, 2, 3, 4, 5])
144
145 def _tstadd_with_carry(self):
146 lst = ["addi 1, 0, 5",
147 "neg 1, 1",
148 "addi 2, 0, 7",
149 "neg 2, 2",
150 "addc 3, 2, 1",
151 "addi 3, 3, 1"
152 ]
153 with Program(lst) as program:
154 self.run_tst_program(program, [1, 2, 3])
155
156 def _tstaddis(self):
157 lst = ["addi 1, 0, 0x0FFF",
158 "addis 1, 1, 0x0F"
159 ]
160 with Program(lst) as program:
161 self.run_tst_program(program, [1])
162
163 @unittest.skip("broken")
164 def _tstmulli(self):
165 lst = ["addi 1, 0, 3",
166 "mulli 1, 1, 2"
167 ]
168 with Program(lst) as program:
169 self.run_tst_program(program, [1])
170
171 def tst_2_load_store(self):
172 lst = ["addi 1, 0, 0x1004",
173 "addi 2, 0, 0x1008",
174 "addi 3, 0, 0x00ee",
175 "stb 3, 1(2)",
176 "lbz 4, 1(2)",
177 ]
178 initial_regs = [0] * 32
179 initial_regs[1] = 0x1004
180 initial_regs[2] = 0x1008
181 initial_regs[3] = 0x00ee
182 initial_mem = {0x1000: (0x5432123412345678, 8),
183 0x1008: (0xabcdef0187654321, 8),
184 0x1020: (0x1828384822324252, 8),
185 }
186 with Program(lst) as program:
187 self.run_tst_program(program, [3,4], initial_mem)
188
189 def _tst3_load_store(self):
190 lst = ["addi 1, 0, 0x1004",
191 "addi 2, 0, 0x1002",
192 "addi 3, 0, 0x15eb",
193 "sth 4, 0(2)",
194 "lhz 4, 0(2)"]
195 initial_regs = [0] * 32
196 initial_regs[1] = 0x1004
197 initial_regs[2] = 0x1002
198 initial_regs[3] = 0x15eb
199 initial_mem = {0x1000: (0x5432123412345678, 8),
200 0x1008: (0xabcdef0187654321, 8),
201 0x1020: (0x1828384822324252, 8),
202 }
203 with Program(lst) as program:
204 self.run_tst_program(program, [1,2,3,4], initial_mem)
205
206 def run_tst_program(self, prog, reglist, initial_mem=None):
207 import sys
208 simulator = self.run_tst(prog, initial_mem=initial_mem)
209 prog.reset()
210 with run_program(prog, initial_mem) as q:
211 self.qemu_register_compare(simulator, q, reglist)
212 self.qemu_mem_compare(simulator, q, reglist)
213 print(simulator.gpr.dump())
214
215 def qemu_mem_compare(self, sim, qemu, check=True):
216 if False: # disable convenient large interesting debugging memory dump
217 addr = 0x0
218 qmemdump = qemu.get_mem(addr, 2048)
219 for i in range(len(qmemdump)):
220 s = hex(int(qmemdump[i]))
221 print ("qemu mem %06x %s" % (addr+i*8, s))
222 for k, v in sim.mem.mem.items():
223 qmemdump = qemu.get_mem(k*8, 8)
224 s = hex(int(qmemdump[0]))[2:]
225 print ("qemu mem %06x %16s" % (k*8, s))
226 for k, v in sim.mem.mem.items():
227 print ("sim mem %06x %016x" % (k*8, v))
228 if not check:
229 return
230 for k, v in sim.mem.mem.items():
231 qmemdump = qemu.get_mem(k*8, 1)
232 self.assertEqual(int(qmemdump[0]), v)
233
234 def qemu_register_compare(self, sim, qemu, regs):
235 qpc, qxer, qcr = qemu.get_pc(), qemu.get_xer(), qemu.get_cr()
236 sim_cr = sim.cr.get_range().value
237 sim_pc = sim.pc.CIA.value
238 sim_xer = sim.spr['XER'].value
239 print("qemu pc", hex(qpc))
240 print("qemu cr", hex(qcr))
241 print("qemu xer", bin(qxer))
242 print("sim pc", hex(sim.pc.CIA.value))
243 print("sim cr", hex(sim_cr))
244 print("sim xer", hex(sim_xer))
245 self.assertEqual(qcr, sim_cr)
246 for reg in regs:
247 qemu_val = qemu.get_register(reg)
248 sim_val = sim.gpr(reg).value
249 self.assertEqual(qemu_val, sim_val)
250
251
252 if __name__ == "__main__":
253 unittest.main()