add another LD/ST example to qemu-sim test,
[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_2_load_store(self):
154 lst = ["addi 1, 0, 0x1004",
155 "addi 2, 0, 0x1008",
156 "addi 3, 0, 0x00ee",
157 "stb 3, 1(2)",
158 "lbz 4, 1(2)",
159 ]
160 initial_regs = [0] * 32
161 initial_regs[1] = 0x1004
162 initial_regs[2] = 0x1008
163 initial_regs[3] = 0x00ee
164 initial_mem = {0x1000: (0x5432123412345678, 8),
165 0x1008: (0xabcdef0187654321, 8),
166 0x1020: (0x1828384822324252, 8),
167 }
168 with Program(lst) as program:
169 self.run_tst_program(program, [3,4], initial_mem)
170
171 def _tst3_load_store(self):
172 lst = ["addi 1, 0, 0x1004",
173 "addi 2, 0, 0x1002",
174 "addi 3, 0, 0x15eb",
175 "sth 4, 0(2)",
176 "lhz 4, 0(2)"]
177 initial_regs = [0] * 32
178 initial_regs[1] = 0x1004
179 initial_regs[2] = 0x1002
180 initial_regs[3] = 0x15eb
181 initial_mem = {0x1000: (0x5432123412345678, 8),
182 0x1008: (0xabcdef0187654321, 8),
183 0x1020: (0x1828384822324252, 8),
184 }
185 with Program(lst) as program:
186 self.run_tst_program(program, [1,2,3,4], initial_mem)
187
188 def run_tst_program(self, prog, reglist, initial_mem=None):
189 import sys
190 simulator = self.run_tst(prog, initial_mem=initial_mem)
191 prog.reset()
192 with run_program(prog, initial_mem) as q:
193 self.qemu_register_compare(simulator, q, reglist)
194 self.qemu_mem_compare(simulator, q, reglist)
195 print(simulator.gpr.dump())
196
197 def qemu_mem_compare(self, sim, qemu, check=True):
198 if False: # disable convenient large interesting debugging memory dump
199 addr = 0x0
200 qmemdump = qemu.get_mem(addr, 2048)
201 for i in range(len(qmemdump)):
202 s = hex(int(qmemdump[i]))
203 print ("qemu mem %06x %s" % (addr+i*8, s))
204 for k, v in sim.mem.mem.items():
205 qmemdump = qemu.get_mem(k*8, 8)
206 s = hex(int(qmemdump[0]))[2:]
207 print ("qemu mem %06x %16s" % (k*8, s))
208 for k, v in sim.mem.mem.items():
209 print ("sim mem %06x %016x" % (k*8, v))
210 if not check:
211 return
212 for k, v in sim.mem.mem.items():
213 qmemdump = qemu.get_mem(k*8, 1)
214 self.assertEqual(int(qmemdump[0]), v)
215
216 def qemu_register_compare(self, sim, qemu, regs):
217 qpc, qxer, qcr = qemu.get_pc(), qemu.get_xer(), qemu.get_cr()
218 sim_cr = sim.cr.get_range().value
219 sim_pc = sim.pc.CIA.value
220 sim_xer = sim.spr['XER'].value
221 print("qemu pc", hex(qpc))
222 print("qemu cr", hex(qcr))
223 print("qemu xer", bin(qxer))
224 print("sim pc", hex(sim.pc.CIA.value))
225 print("sim cr", hex(sim_cr))
226 print("sim xer", hex(sim_xer))
227 self.assertEqual(qcr, sim_cr)
228 for reg in regs:
229 qemu_val = qemu.get_register(reg)
230 sim_val = sim.gpr(reg).value
231 self.assertEqual(qemu_val, sim_val)
232
233
234 if __name__ == "__main__":
235 unittest.main()