8dc13da5c78877a5a0530a6603a3f12483b40b01
1 from nmigen
import Module
, Signal
3 # NOTE: to use cxxsim, export NMIGEN_SIM_MODE=cxxsim from the shell
4 # Also, check out the cxxsim nmigen branch, and latest yosys from git
5 from nmutil
.sim_tmp_alternative
import Simulator
, Settle
7 from nmigen
.cli
import rtlil
9 from openpower
.decoder
.power_decoder
import (create_pdecode
)
10 from openpower
.decoder
.power_decoder2
import (PowerDecode2
)
11 from openpower
.decoder
.power_enums
import XER_bits
, Function
12 from openpower
.decoder
.selectable_int
import SelectableInt
13 from openpower
.simulator
.program
import Program
14 from openpower
.decoder
.isa
.all
import ISA
15 from openpower
.endian
import bigendian
16 from openpower
.consts
import MSR
18 from openpower
.test
.spr
.spr_cases
import SPRTestCase
21 from openpower
.test
.common
import (
22 TestAccumulatorBase
, skip_case
, TestCase
, ALUHelpers
)
23 from soc
.fu
.spr
.pipeline
import SPRBasePipe
24 from soc
.fu
.spr
.pipe_data
import SPRPipeSpec
28 def get_cu_inputs(dec2
, sim
):
29 """naming (res) must conform to SPRFunctionUnit input regspec
33 yield from ALUHelpers
.get_sim_int_ra(res
, sim
, dec2
) # RA
34 yield from ALUHelpers
.get_sim_int_rb(res
, sim
, dec2
) # RB
35 yield from ALUHelpers
.get_sim_slow_spr1(res
, sim
, dec2
) # FAST1
36 yield from ALUHelpers
.get_sim_fast_spr1(res
, sim
, dec2
) # FAST1
37 yield from ALUHelpers
.get_rd_sim_xer_ca(res
, sim
, dec2
) # XER.ca
38 yield from ALUHelpers
.get_sim_xer_ov(res
, sim
, dec2
) # XER.ov
39 yield from ALUHelpers
.get_sim_xer_so(res
, sim
, dec2
) # XER.so
41 print("spr get_cu_inputs", res
)
46 def set_alu_inputs(alu
, dec2
, sim
):
47 # TODO: see https://bugs.libre-soc.org/show_bug.cgi?id=305#c43
48 # detect the immediate here (with m.If(self.i.ctx.op.imm_data.imm_ok))
49 # and place it into data_i.b
51 inp
= yield from get_cu_inputs(dec2
, sim
)
52 yield from ALUHelpers
.set_int_ra(alu
, dec2
, inp
)
53 yield from ALUHelpers
.set_xer_ca(alu
, dec2
, inp
)
54 yield from ALUHelpers
.set_xer_ov(alu
, dec2
, inp
)
55 yield from ALUHelpers
.set_xer_so(alu
, dec2
, inp
)
57 yield from ALUHelpers
.set_fast_spr1(alu
, dec2
, inp
)
58 yield from ALUHelpers
.set_slow_spr1(alu
, dec2
, inp
)
62 class SPRIlangCase(TestAccumulatorBase
):
64 pspec
= SPRPipeSpec(id_wid
=2)
65 alu
= SPRBasePipe(pspec
)
66 vl
= rtlil
.convert(alu
, ports
=alu
.ports())
67 with
open("trap_pipeline.il", "w") as f
:
71 class TestRunner(unittest
.TestCase
):
72 def __init__(self
, test_data
):
73 super().__init
__("run_all")
74 self
.test_data
= test_data
76 def execute(self
, alu
, instruction
, pdecode2
, test
):
77 program
= test
.program
78 sim
= ISA(pdecode2
, test
.regs
, test
.sprs
, test
.cr
,
81 gen
= program
.generate_instructions()
82 instructions
= list(zip(gen
, program
.assembly
.splitlines()))
87 while index
< len(instructions
):
88 ins
, code
= instructions
[index
]
90 print("pc %08x instr: %08x" % (pc
, ins
& 0xffffffff))
94 so
= 1 if sim
.spr
['XER'][XER_bits
['SO']] else 0
95 ov
= 1 if sim
.spr
['XER'][XER_bits
['OV']] else 0
96 ov32
= 1 if sim
.spr
['XER'][XER_bits
['OV32']] else 0
97 print("before: so/ov/32", so
, ov
, ov32
)
99 # ask the decoder to decode this binary data (endian'd)
100 yield pdecode2
.dec
.bigendian
.eq(bigendian
) # little / big?
101 yield pdecode2
.state
.msr
.eq(msr
) # set MSR in pdecode2
102 yield pdecode2
.state
.pc
.eq(pc
) # set PC in pdecode2
103 yield instruction
.eq(ins
) # raw binary instr.
106 fast_in
= yield pdecode2
.e
.read_fast1
.data
107 spr_in
= yield pdecode2
.e
.read_spr1
.data
108 print("dec2 spr/fast in", fast_in
, spr_in
)
110 fast_out
= yield pdecode2
.e
.write_fast1
.data
111 spr_out
= yield pdecode2
.e
.write_spr
.data
112 print("dec2 spr/fast in", fast_out
, spr_out
)
114 fn_unit
= yield pdecode2
.e
.do
.fn_unit
115 self
.assertEqual(fn_unit
, Function
.SPR
.value
)
116 alu_o
= yield from set_alu_inputs(alu
, pdecode2
, sim
)
118 opname
= code
.split(' ')[0]
119 yield from sim
.call(opname
)
120 pc
= sim
.pc
.CIA
.value
123 print("pc after %08x" % (pc
))
125 vld
= yield alu
.n
.valid_o
128 vld
= yield alu
.n
.valid_o
131 yield from self
.check_alu_outputs(alu
, pdecode2
, sim
, code
)
136 instruction
= Signal(32)
138 pdecode
= create_pdecode()
140 m
.submodules
.pdecode2
= pdecode2
= PowerDecode2(pdecode
)
142 pspec
= SPRPipeSpec(id_wid
=2)
143 m
.submodules
.alu
= alu
= SPRBasePipe(pspec
)
145 comb
+= alu
.p
.data_i
.ctx
.op
.eq_from_execute1(pdecode2
.do
)
146 comb
+= alu
.p
.valid_i
.eq(1)
147 comb
+= alu
.n
.ready_i
.eq(1)
148 comb
+= pdecode2
.dec
.raw_opcode_in
.eq(instruction
)
154 for test
in self
.test_data
:
155 print("test", test
.name
)
156 print("sprs", test
.sprs
)
157 program
= test
.program
158 with self
.subTest(test
.name
):
159 yield from self
.execute(alu
, instruction
, pdecode2
, test
)
161 sim
.add_sync_process(process
)
162 with sim
.write_vcd("alu_simulator.vcd", "simulator.gtkw",
166 def check_alu_outputs(self
, alu
, dec2
, sim
, code
):
168 rc
= yield dec2
.e
.do
.rc
.data
169 cridx_ok
= yield dec2
.e
.write_cr
.ok
170 cridx
= yield dec2
.e
.write_cr
.data
172 print("check extra output", repr(code
), cridx_ok
, cridx
)
174 self
.assertEqual(cridx
, 0, code
)
179 yield from ALUHelpers
.get_int_o(res
, alu
, dec2
)
180 yield from ALUHelpers
.get_fast_spr1(res
, alu
, dec2
)
181 yield from ALUHelpers
.get_slow_spr1(res
, alu
, dec2
)
182 yield from ALUHelpers
.get_xer_ov(res
, alu
, dec2
)
183 yield from ALUHelpers
.get_xer_ca(res
, alu
, dec2
)
184 yield from ALUHelpers
.get_xer_so(res
, alu
, dec2
)
188 yield from ALUHelpers
.get_sim_int_o(sim_o
, sim
, dec2
)
189 yield from ALUHelpers
.get_wr_sim_xer_so(sim_o
, sim
, alu
, dec2
)
190 yield from ALUHelpers
.get_wr_sim_xer_ov(sim_o
, sim
, alu
, dec2
)
191 yield from ALUHelpers
.get_wr_sim_xer_ca(sim_o
, sim
, dec2
)
192 yield from ALUHelpers
.get_wr_fast_spr1(sim_o
, sim
, dec2
)
193 yield from ALUHelpers
.get_wr_slow_spr1(sim_o
, sim
, dec2
)
195 print("sim output", sim_o
)
197 ALUHelpers
.check_xer_ov(self
, res
, sim_o
, code
)
198 ALUHelpers
.check_xer_ca(self
, res
, sim_o
, code
)
199 ALUHelpers
.check_xer_so(self
, res
, sim_o
, code
)
200 ALUHelpers
.check_int_o(self
, res
, sim_o
, code
)
201 ALUHelpers
.check_fast_spr1(self
, res
, sim_o
, code
)
202 ALUHelpers
.check_slow_spr1(self
, res
, sim_o
, code
)
205 if __name__
== "__main__":
206 unittest
.main(exit
=False)
207 suite
= unittest
.TestSuite()
208 suite
.addTest(TestRunner(SPRTestCase().test_data
))
209 suite
.addTest(TestRunner(SPRIlangCase().test_data
))
211 runner
= unittest
.TextTestRunner()