6e3ccdd25bbdd7f326ab1150a24e933525b30647
[soc.git] / src / soc / decoder / isa / test_caller.py
1 from nmigen import Module, Signal
2 from nmigen.back.pysim import Simulator, Delay
3 from nmigen.test.utils import FHDLTestCase
4 import unittest
5 from soc.decoder.isa.caller import ISACaller
6 from soc.decoder.power_decoder import (create_pdecode)
7 from soc.decoder.power_decoder2 import (PowerDecode2)
8 from soc.simulator.program import Program
9 from soc.decoder.isa.caller import ISACaller, inject
10 from soc.decoder.selectable_int import SelectableInt
11 from soc.decoder.orderedset import OrderedSet
12 from soc.decoder.isa.all import ISA
13
14
15 class Register:
16 def __init__(self, num):
17 self.num = num
18
19
20 class DecoderTestCase(FHDLTestCase):
21
22 def run_tst(self, generator, initial_regs):
23 m = Module()
24 comb = m.d.comb
25 instruction = Signal(32)
26
27 pdecode = create_pdecode()
28
29 m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
30 simulator = ISA(pdecode2, initial_regs)
31 comb += pdecode2.dec.raw_opcode_in.eq(instruction)
32 sim = Simulator(m)
33 gen = generator.generate_instructions()
34
35 def process():
36 instructions = list(zip(gen, generator.assembly.splitlines()))
37
38 index = simulator.pc.CIA.value//4
39 while index < len(instructions):
40 ins, code = instructions[index]
41
42 print("0x{:X}".format(ins & 0xffffffff))
43 print(code)
44
45 # ask the decoder to decode this binary data (endian'd)
46 yield pdecode2.dec.bigendian.eq(0) # little / big?
47 yield instruction.eq(ins) # raw binary instr.
48 yield Delay(1e-6)
49 opname = code.split(' ')[0]
50 yield from simulator.call(opname)
51 index = simulator.pc.CIA.value//4
52
53 sim.add_process(process)
54 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
55 traces=[]):
56 sim.run()
57 return simulator
58
59 def test_add(self):
60 lst = ["add 1, 3, 2"]
61 initial_regs = [0] * 32
62 initial_regs[3] = 0x1234
63 initial_regs[2] = 0x4321
64 with Program(lst) as program:
65 sim = self.run_tst_program(program, initial_regs)
66 self.assertEqual(sim.gpr(1), SelectableInt(0x5555, 64))
67
68 def test_addi(self):
69 lst = ["addi 3, 0, 0x1234",
70 "addi 2, 0, 0x4321",
71 "add 1, 3, 2"]
72 with Program(lst) as program:
73 sim = self.run_tst_program(program)
74 print(sim.gpr(1))
75 self.assertEqual(sim.gpr(1), SelectableInt(0x5555, 64))
76
77 def test_load_store(self):
78 lst = ["addi 1, 0, 0x0010",
79 "addi 2, 0, 0x1234",
80 "stw 2, 0(1)",
81 "lwz 3, 0(1)"]
82 with Program(lst) as program:
83 sim = self.run_tst_program(program)
84 print(sim.gpr(1))
85 self.assertEqual(sim.gpr(3), SelectableInt(0x1234, 64))
86
87 def test_addpcis(self):
88 lst = ["addpcis 1, 0x1",
89 "addpcis 2, 0x1",
90 "addpcis 3, 0x1"]
91 with Program(lst) as program:
92 sim = self.run_tst_program(program)
93 self.assertEqual(sim.gpr(1), SelectableInt(0x10004, 64))
94 self.assertEqual(sim.gpr(2), SelectableInt(0x10008, 64))
95 self.assertEqual(sim.gpr(3), SelectableInt(0x1000c, 64))
96
97 def test_branch(self):
98 lst = ["ba 0xc", # branch to line 4
99 "addi 1, 0, 0x1234", # Should never execute
100 "ba 0x1000", # exit the program
101 "addi 2, 0, 0x1234", # line 4
102 "ba 0x8"] # branch to line 3
103 with Program(lst) as program:
104 sim = self.run_tst_program(program)
105 self.assertEqual(sim.pc.CIA, SelectableInt(0x1000, 64))
106 self.assertEqual(sim.gpr(1), SelectableInt(0x0, 64))
107 self.assertEqual(sim.gpr(2), SelectableInt(0x1234, 64))
108
109 def test_branch_link(self):
110 lst = ["bl 0xc",
111 "addi 2, 1, 0x1234",
112 "ba 0x1000",
113 "addi 1, 0, 0x1234",
114 "bclr 20, 0, 0"]
115 with Program(lst) as program:
116 sim = self.run_tst_program(program)
117 self.assertEqual(sim.spr['LR'], SelectableInt(0x4, 64))
118
119 def test_branch_ctr(self):
120 lst = ["addi 1, 0, 0x10", # target of jump
121 "mtspr 9, 1", # mtctr 1
122 "bcctr 20, 0, 0", # bctr
123 "addi 2, 0, 0x1", # should never execute
124 "addi 1, 0, 0x1234"] # target of ctr
125 with Program(lst) as program:
126 sim = self.run_tst_program(program)
127 self.assertEqual(sim.spr['CTR'], SelectableInt(0x10, 64))
128 self.assertEqual(sim.gpr(1), SelectableInt(0x1234, 64))
129 self.assertEqual(sim.gpr(2), SelectableInt(0, 64))
130
131 def test_add_compare(self):
132 lst = ["addis 1, 0, 0xffff",
133 "addis 2, 0, 0xffff",
134 "add. 1, 1, 2",
135 "mfcr 3"]
136 with Program(lst) as program:
137 sim = self.run_tst_program(program)
138 # Verified with QEMU
139 self.assertEqual(sim.gpr(3), SelectableInt(0x80000000, 64))
140
141 def test_cmp(self):
142 lst = ["addis 1, 0, 0xffff",
143 "addis 2, 0, 0xffff",
144 "cmp cr0, 0, 1, 2",
145 "mfcr 3"]
146 with Program(lst) as program:
147 sim = self.run_tst_program(program)
148 self.assertEqual(sim.gpr(3), SelectableInt(0x20000000, 64))
149
150 def test_mtcrf(self):
151 for i in range(4):
152 # 0x76540000 gives expected (3+4) (2+4) (1+4) (0+4) for
153 # i=0, 1, 2, 3
154 # The positions of the CR fields have been verified using
155 # QEMU and 'cmp crx, a, b' instructions
156 lst = ["addis 1, 0, 0x7654",
157 "mtcrf %d, 1" % (1 << (7-i)),
158 ]
159 with Program(lst) as program:
160 sim = self.run_tst_program(program)
161 print("cr", sim.cr)
162 expected = (7-i)
163 # check CR itself
164 self.assertEqual(sim.cr, SelectableInt(expected << ((7-i)*4), 32))
165 # check CR[0]/1/2/3 as well
166 print("cr%d", sim.crl[i])
167 self.assertTrue(SelectableInt(expected, 4) == sim.crl[i])
168
169 def run_tst_program(self, prog, initial_regs=[0] * 32):
170 simulator = self.run_tst(prog, initial_regs)
171 simulator.gpr.dump()
172 return simulator
173
174
175 if __name__ == "__main__":
176 unittest.main()