Reorder the register reads so the field in read_reg2 is last
[soc.git] / src / soc / alu / test / test_pipe_caller.py
1 from nmigen import Module, Signal
2 from nmigen.back.pysim import Simulator, Delay, Settle
3 from nmigen.test.utils import FHDLTestCase
4 from nmigen.cli import rtlil
5 import unittest
6 from soc.decoder.isa.caller import ISACaller
7 from soc.decoder.power_decoder import (create_pdecode)
8 from soc.decoder.power_decoder2 import (PowerDecode2)
9 from soc.decoder.selectable_int import SelectableInt
10 from soc.simulator.program import Program
11 from soc.decoder.isa.all import ISA
12
13
14 from soc.alu.pipeline import ALUBasePipe
15 from soc.alu.alu_input_record import CompALUOpSubset
16 from soc.alu.pipe_data import ALUPipeSpec
17 import random
18
19 def get_rec_width(rec):
20 recwidth = 0
21 # Setup random inputs for dut.op
22 for p in rec.ports():
23 width = p.width
24 recwidth += width
25 return recwidth
26
27 def set_alu_inputs(alu, dec2, sim):
28 inputs = []
29 reg1_ok = yield dec2.e.read_reg1.ok
30 if reg1_ok:
31 reg1_sel = yield dec2.e.read_reg1.data
32 inputs.append(sim.gpr(reg1_sel).value)
33 reg3_ok = yield dec2.e.read_reg3.ok
34 if reg3_ok:
35 reg3_sel = yield dec2.e.read_reg3.data
36 inputs.append(sim.gpr(reg3_sel).value)
37 reg2_ok = yield dec2.e.read_reg2.ok
38 if reg2_ok:
39 reg2_sel = yield dec2.e.read_reg2.data
40 inputs.append(sim.gpr(reg2_sel).value)
41
42 print(inputs)
43
44 if len(inputs) == 0:
45 yield alu.p.data_i.a.eq(0)
46 yield alu.p.data_i.b.eq(0)
47 if len(inputs) == 1:
48 yield alu.p.data_i.a.eq(inputs[0])
49 yield alu.p.data_i.b.eq(0)
50 if len(inputs) == 2:
51 yield alu.p.data_i.a.eq(inputs[0])
52 yield alu.p.data_i.b.eq(inputs[1])
53
54
55
56 class ALUTestCase(FHDLTestCase):
57 def run_tst(self, program, initial_regs):
58 m = Module()
59 comb = m.d.comb
60 instruction = Signal(32)
61
62 pdecode = create_pdecode()
63
64 m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
65
66 rec = CompALUOpSubset()
67
68 pspec = ALUPipeSpec(id_wid=2, op_wid=get_rec_width(rec))
69 m.submodules.alu = alu = ALUBasePipe(pspec)
70
71 comb += alu.p.data_i.ctx.op.eq_from_execute1(pdecode2.e)
72 comb += alu.p.valid_i.eq(1)
73 comb += alu.n.ready_i.eq(1)
74 simulator = ISA(pdecode2, initial_regs)
75 comb += pdecode2.dec.raw_opcode_in.eq(instruction)
76 sim = Simulator(m)
77 gen = program.generate_instructions()
78
79 sim.add_clock(1e-6)
80 def process():
81 instructions = list(zip(gen, program.assembly.splitlines()))
82
83 index = simulator.pc.CIA.value//4
84 while index < len(instructions):
85 ins, code = instructions[index]
86
87 print("0x{:X}".format(ins & 0xffffffff))
88 print(code)
89
90 # ask the decoder to decode this binary data (endian'd)
91 yield pdecode2.dec.bigendian.eq(0) # little / big?
92 yield instruction.eq(ins) # raw binary instr.
93 yield Settle()
94 yield from set_alu_inputs(alu, pdecode2, simulator)
95 yield
96 opname = code.split(' ')[0]
97 yield from simulator.call(opname)
98 index = simulator.pc.CIA.value//4
99
100 vld = yield alu.n.valid_o
101 while not vld:
102 yield
103 vld = yield alu.n.valid_o
104 yield
105 alu_out = yield alu.n.data_o.o
106 print(f"expected {simulator.gpr(3).value:x}, actual: {alu_out:x}")
107 self.assertEqual(simulator.gpr(3).value, alu_out)
108
109 sim.add_sync_process(process)
110 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
111 traces=[]):
112 sim.run()
113 return simulator
114
115 def run_tst_program(self, prog, initial_regs=[0] * 32):
116 simulator = self.run_tst(prog, initial_regs)
117 simulator.gpr.dump()
118 return simulator
119
120 def test_rand(self):
121 insns = ["add", "add.", "and", "or", "xor", "subf"]
122 for i in range(40):
123 choice = random.choice(insns)
124 lst = [f"{choice} 3, 1, 2"]
125 initial_regs = [0] * 32
126 initial_regs[1] = random.randint(0, (1<<64)-1)
127 initial_regs[2] = random.randint(0, (1<<64)-1)
128 with Program(lst) as program:
129 sim = self.run_tst_program(program, initial_regs)
130
131 def test_rand_imm(self):
132 insns = ["addi", "addis", "subfic"]
133 for i in range(10):
134 choice = random.choice(insns)
135 imm = random.randint(-(1<<15), (1<<15)-1)
136 lst = [f"{choice} 3, 1, {imm}"]
137 print(lst)
138 initial_regs = [0] * 32
139 initial_regs[1] = random.randint(0, (1<<64)-1)
140 with Program(lst) as program:
141 sim = self.run_tst_program(program, initial_regs)
142
143 def test_rand_imm_logical(self):
144 insns = ["andi.", "andis.", "ori", "oris", "xori", "xoris"]
145 for i in range(10):
146 choice = random.choice(insns)
147 imm = random.randint(0, (1<<16)-1)
148 lst = [f"{choice} 3, 1, {imm}"]
149 print(lst)
150 initial_regs = [0] * 32
151 initial_regs[1] = random.randint(0, (1<<64)-1)
152 with Program(lst) as program:
153 sim = self.run_tst_program(program, initial_regs)
154
155 unittest.skip("broken")
156 def test_shift(self):
157 insns = ["slw", "sld", "srw", "srd", "sraw", "srad"]
158 for i in range(20):
159 choice = random.choice(insns)
160 lst = [f"{choice} 3, 1, 2"]
161 initial_regs = [0] * 32
162 initial_regs[1] = random.randint(0, (1<<64)-1)
163 initial_regs[2] = random.randint(0, 63)
164 print(initial_regs[1], initial_regs[2])
165 with Program(lst) as program:
166 sim = self.run_tst_program(program, initial_regs)
167
168 unittest.skip("broken")
169 def test_shift_imm(self):
170 lst = ["sradi 3, 1, 5"]
171 initial_regs = [0] * 32
172 initial_regs[1] = random.randint(0, (1<<64)-1)
173 with Program(lst) as program:
174 sim = self.run_tst_program(program, initial_regs)
175
176 @unittest.skip("broken")
177 def test_shift_arith(self):
178 lst = ["sraw 3, 1, 2"]
179 initial_regs = [0] * 32
180 initial_regs[1] = random.randint(0, (1<<64)-1)
181 initial_regs[2] = random.randint(0, 63)
182 print(initial_regs[1], initial_regs[2])
183 with Program(lst) as program:
184 sim = self.run_tst_program(program, initial_regs)
185
186 @unittest.skip("broken")
187 def test_rlwinm(self):
188 for i in range(10):
189 mb = random.randint(0,31)
190 me = random.randint(0,31)
191 sh = random.randint(0,31)
192 lst = [f"rlwinm 3, 1, {mb}, {me}, {sh}"]
193 initial_regs = [0] * 32
194 initial_regs[1] = random.randint(0, (1<<64)-1)
195 with Program(lst) as program:
196 sim = self.run_tst_program(program, initial_regs)
197
198 @unittest.skip("broken")
199 def test_rlwimi(self):
200 lst = ["rlwinm 3, 1, 5, 20, 6",
201 "rlwimi 3, 1, 5, 20, 6"]
202 initial_regs = [0] * 32
203 initial_regs[1] = random.randint(0, (1<<64)-1)
204 initial_regs[3] = random.randint(0, (1<<64)-1)
205 with Program(lst) as program:
206 sim = self.run_tst_program(program, initial_regs)
207
208 @unittest.skip("broken")
209 def test_rlwnm(self):
210 lst = ["rlwnm 3, 1, 2, 20, 6"]
211 initial_regs = [0] * 32
212 initial_regs[1] = random.randint(0, (1<<64)-1)
213 initial_regs[2] = random.randint(0, 63)
214 with Program(lst) as program:
215 sim = self.run_tst_program(program, initial_regs)
216
217 def test_add(self):
218 lst = ["add 3, 1, 2"]
219 initial_regs = [0] * 32
220 initial_regs[1] = random.randint(0, (1<<64)-1)
221 initial_regs[2] = random.randint(0, 63)
222 with Program(lst) as program:
223 sim = self.run_tst_program(program, initial_regs)
224
225 def test_ilang(self):
226 rec = CompALUOpSubset()
227
228 pspec = ALUPipeSpec(id_wid=2, op_wid=get_rec_width(rec))
229 alu = ALUBasePipe(pspec)
230 vl = rtlil.convert(alu, ports=[])
231 with open("pipeline.il", "w") as f:
232 f.write(vl)
233
234 if __name__ == "__main__":
235 unittest.main()