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
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
14 from soc
.alu
.pipeline
import ALUBasePipe
15 from soc
.alu
.alu_input_record
import CompALUOpSubset
16 from soc
.alu
.pipe_data
import ALUPipeSpec
19 def get_rec_width(rec
):
21 # Setup random inputs for dut.op
27 def set_alu_inputs(alu
, dec2
, sim
):
29 reg1_ok
= yield dec2
.e
.read_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
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
39 reg2_sel
= yield dec2
.e
.read_reg2
.data
40 inputs
.append(sim
.gpr(reg2_sel
).value
)
45 yield alu
.p
.data_i
.a
.eq(0)
46 yield alu
.p
.data_i
.b
.eq(0)
48 yield alu
.p
.data_i
.a
.eq(inputs
[0])
49 yield alu
.p
.data_i
.b
.eq(0)
51 yield alu
.p
.data_i
.a
.eq(inputs
[0])
52 yield alu
.p
.data_i
.b
.eq(inputs
[1])
56 class ALUTestCase(FHDLTestCase
):
57 def run_tst(self
, program
, initial_regs
):
60 instruction
= Signal(32)
62 pdecode
= create_pdecode()
64 m
.submodules
.pdecode2
= pdecode2
= PowerDecode2(pdecode
)
66 rec
= CompALUOpSubset()
68 pspec
= ALUPipeSpec(id_wid
=2, op_wid
=get_rec_width(rec
))
69 m
.submodules
.alu
= alu
= ALUBasePipe(pspec
)
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
)
77 gen
= program
.generate_instructions()
81 instructions
= list(zip(gen
, program
.assembly
.splitlines()))
83 index
= simulator
.pc
.CIA
.value
//4
84 while index
< len(instructions
):
85 ins
, code
= instructions
[index
]
87 print("0x{:X}".format(ins
& 0xffffffff))
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.
94 yield from set_alu_inputs(alu
, pdecode2
, simulator
)
96 opname
= code
.split(' ')[0]
97 yield from simulator
.call(opname
)
98 index
= simulator
.pc
.CIA
.value
//4
100 vld
= yield alu
.n
.valid_o
103 vld
= yield alu
.n
.valid_o
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
)
109 sim
.add_sync_process(process
)
110 with sim
.write_vcd("simulator.vcd", "simulator.gtkw",
115 def run_tst_program(self
, prog
, initial_regs
=[0] * 32):
116 simulator
= self
.run_tst(prog
, initial_regs
)
121 insns
= ["add", "add.", "and", "or", "xor", "subf"]
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
)
131 def test_rand_imm(self
):
132 insns
= ["addi", "addis", "subfic"]
134 choice
= random
.choice(insns
)
135 imm
= random
.randint(-(1<<15), (1<<15)-1)
136 lst
= [f
"{choice} 3, 1, {imm}"]
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
)
143 def test_rand_imm_logical(self
):
144 insns
= ["andi.", "andis.", "ori", "oris", "xori", "xoris"]
146 choice
= random
.choice(insns
)
147 imm
= random
.randint(0, (1<<16)-1)
148 lst
= [f
"{choice} 3, 1, {imm}"]
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
)
155 unittest
.skip("broken")
156 def test_shift(self
):
157 insns
= ["slw", "sld", "srw", "srd", "sraw", "srad"]
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
)
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
)
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
)
186 @unittest.skip("broken")
187 def test_rlwinm(self
):
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
)
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
)
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
)
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
)
225 def test_ilang(self
):
226 rec
= CompALUOpSubset()
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
:
234 if __name__
== "__main__":