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 soc
.decoder
.isa
.caller
import ISACaller
, special_sprs
10 from soc
.decoder
.power_decoder
import (create_pdecode
)
11 from soc
.decoder
.power_decoder2
import (PowerDecode2
)
12 from soc
.decoder
.power_enums
import (XER_bits
, Function
, MicrOp
, CryIn
)
13 from soc
.decoder
.selectable_int
import SelectableInt
14 from soc
.simulator
.program
import Program
15 from soc
.decoder
.isa
.all
import ISA
16 from soc
.config
.endian
import bigendian
17 from soc
.consts
import MSR
20 from soc
.fu
.test
.common
import (
21 TestAccumulatorBase
, skip_case
, TestCase
, ALUHelpers
)
22 #from soc.fu.spr.pipeline import SPRBasePipe
23 #from soc.fu.spr.pipe_data import SPRPipeSpec
24 #from soc.fu.mmu.fsm import FSMMMUStage
25 #from soc.fu.mmu.pipe_data import MMUPipeSpec
28 from soc
.fu
.div
.test
.helper
import (log_rand
, get_cu_inputs
,
29 set_alu_inputs
, DivTestHelper
)
31 from soc
.simple
.core
import NonProductionCore
32 from soc
.config
.test
.test_loadstore
import TestMemPspec
33 from soc
.simple
.test
.test_core
import (setup_regs
, check_regs
,
37 import power_instruction_analyzer
as pia
41 def set_fsm_inputs_do_not_use(alu
, dec2
, sim
):
42 # TODO: see https://bugs.libre-soc.org/show_bug.cgi?id=305#c43
43 # detect the immediate here (with m.If(self.i.ctx.op.imm_data.imm_ok))
44 # and place it into data_i.b
47 inp
= yield from get_cu_inputs(dec2
, sim
)
48 # set int registers a and b
49 yield from ALUHelpers
.set_int_ra(alu
, dec2
, inp
)
50 yield from ALUHelpers
.set_int_rb(alu
, dec2
, inp
)
51 # TODO set spr register
52 # yield from ALUHelpers.set_spr_spr1(alu, dec2, inp)
59 print("xer_so::::::::::::::::::::::::::::::::::::::::::::::::")
62 overflow
= pia
.OverflowFlags(so
=bool(so
),
70 return pia
.InstructionInput(ra
=a
, rb
=b
, overflow
=overflow
)
72 class MMUTestCase(TestAccumulatorBase
):
73 # MMU handles MTSPR, MFSPR, DCBZ and TLBIE.
74 # other instructions here -> must be load/store
76 #before running the test case: set DISR and DAR
78 def case_mfspr_after_invalid_load(self
):
79 lst
= [ # TODO -- set SPR on both sinulator and port interface
80 "mfspr 1, 18", # DSISR to reg 1
81 "mfspr 2, 19", # DAR to reg 2
82 # TODO -- verify returned sprvals
85 initial_regs
= [0] * 32
87 initial_sprs
= {'DSISR': 0x12345678, 'DAR': 0x87654321}
88 self
.add_case(Program(lst
, bigendian
),
89 initial_regs
, initial_sprs
)
91 #def case_ilang(self):
92 # pspec = SPRPipeSpec(id_wid=2)
93 # alu = SPRBasePipe(pspec)
94 # vl = rtlil.convert(alu, ports=alu.ports())
95 # with open("trap_pipeline.il", "w") as f:
99 class TestRunner(unittest
.TestCase
):
100 def __init__(self
, test_data
):
101 super().__init
__("run_all")
102 self
.test_data
= test_data
104 def check_fsm_outputs_delete_me(self
, alu
, dec2
, sim
, code
, pia_res
):
106 rc
= yield dec2
.e
.do
.rc
.data
107 cridx_ok
= yield dec2
.e
.write_cr
.ok
108 cridx
= yield dec2
.e
.write_cr
.data
110 print("check extra output", repr(code
), cridx_ok
, cridx
)
112 self
.assertEqual(cridx
, 0, code
)
117 #MMUOutputData does not have xer
119 yield from ALUHelpers
.get_cr_a(res
, alu
, dec2
)
120 #yield from ALUHelpers.get_xer_ov(res, alu, dec2)
121 yield from ALUHelpers
.get_int_o(res
, alu
, dec2
)
122 #yield from ALUHelpers.get_xer_so(res, alu, dec2)
125 print("res output", res
)
127 yield from ALUHelpers
.get_sim_int_o(sim_o
, sim
, dec2
)
128 yield from ALUHelpers
.get_wr_sim_cr_a(sim_o
, sim
, dec2
)
129 #yield from ALUHelpers.get_sim_xer_ov(sim_o, sim, dec2)
130 #yield from ALUHelpers.get_sim_xer_so(sim_o, sim, dec2)
132 print("sim output", sim_o
)
134 print("power-instruction-analyzer result:")
136 #if pia_res is not None:
137 # with self.subTest(check="pia", sim_o=sim_o, pia_res=str(pia_res)):
138 # pia_o = pia_res_to_output(pia_res)
139 # ALUHelpers.check_int_o(self, res, pia_o, code)
140 # ALUHelpers.check_cr_a(self, res, pia_o, code)
141 # #ALUHelpers.check_xer_ov(self, res, pia_o, code)
142 # #ALUHelpers.check_xer_so(self, res, pia_o, code)
144 with self
.subTest(check
="sim", sim_o
=sim_o
, pia_res
=str(pia_res
)):
145 #ALUHelpers.check_int_o(self, res, sim_o, code) # mmu is not an alu
146 ALUHelpers
.check_cr_a(self
, res
, sim_o
, code
)
147 #ALUHelpers.check_xer_ov(self, res, sim_o, code)
148 #ALUHelpers.check_xer_so(self, res, sim_o, code)
150 #oe = yield dec2.e.do.oe.oe
151 #oe_ok = yield dec2.e.do.oe.ok
152 #print("oe, oe_ok", oe, oe_ok)
153 #if not oe or not oe_ok:
154 # # if OE not enabled, XER SO and OV must not be activated
155 # so_ok = yield alu.n.data_o.xer_so.ok
156 # ov_ok = yield alu.n.data_o.xer_ov.ok
157 # print("so, ov", so_ok, ov_ok)
158 # self.assertEqual(ov_ok, False, code)
159 # self.assertEqual(so_ok, False, code)
161 def execute(self
, core
, instruction
, pdecode2
, test
):
162 program
= test
.program
163 sim
= ISA(pdecode2
, test
.regs
, test
.sprs
, test
.cr
,
166 gen
= program
.generate_instructions()
167 instructions
= list(zip(gen
, program
.assembly
.splitlines()))
169 pc
= sim
.pc
.CIA
.value
172 while index
< len(instructions
):
173 ins
, code
= instructions
[index
]
175 print("pc %08x instr: %08x" % (pc
, ins
& 0xffffffff))
179 so
= 1 if sim
.spr
['XER'][XER_bits
['SO']] else 0
180 ov
= 1 if sim
.spr
['XER'][XER_bits
['OV']] else 0
181 ov32
= 1 if sim
.spr
['XER'][XER_bits
['OV32']] else 0
182 print("before: so/ov/32", so
, ov
, ov32
)
184 # ask the decoder to decode this binary data (endian'd)
185 yield pdecode2
.dec
.bigendian
.eq(bigendian
) # little / big?
186 yield pdecode2
.state
.msr
.eq(msr
) # set MSR in pdecode2
187 yield pdecode2
.state
.pc
.eq(pc
) # set PC in pdecode2
188 yield instruction
.eq(ins
) # raw binary instr.
192 yield from setup_regs(pdecode2
, core
, test
)
194 ##fast_in = yield pdecode2.e.read_fast1.data
195 ##spr_in = yield pdecode2.e.read_spr1.data
196 ##print("dec2 spr/fast in", fast_in, spr_in)
198 ##fast_out = yield pdecode2.e.write_fast1.data
199 ##spr_out = yield pdecode2.e.write_spr.data
200 ##print("dec2 spr/fast in", fast_out, spr_out)
202 ##fn_unit = yield pdecode2.e.do.fn_unit
203 ##pia_res = yield from set_fsm_inputs(fsm, pdecode2, sim)
205 opname
= code
.split(' ')[0]
206 yield from sim
.call(opname
)
207 pc
= sim
.pc
.CIA
.value
210 print("pc after %08x" % (pc
))
212 vld
= yield fsm
.n
.valid_o
#fsm
215 if debughang
: print("not valid -- hang")
216 vld
= yield fsm
.n
.valid_o
217 if debughang
==2: vld
=1
223 instruction
= Signal(32)
225 pdecode
= create_pdecode()
227 m
.submodules
.pdecode2
= pdecode2
= PowerDecode2(pdecode
)
229 pspec
= TestMemPspec(ldst_ifacetype
='testpi',
235 m
.submodules
.core
= core
= NonProductionCore(pspec
)
237 # TODO connect pdecode2 to core
239 # TODO connect outputs of power decoder
240 #comb += fsm.p.data_i.ctx.op.eq_from_execute1(pdecode2.do)
241 #comb += fsm.p.valid_i.eq(1)
242 #comb += fsm.n.ready_i.eq(1)
244 #use this instead# yield from setup_regs(pdecode2, core, test)
246 comb
+= pdecode2
.dec
.raw_opcode_in
.eq(instruction
)
252 for test
in self
.test_data
:
253 print("test", test
.name
)
254 print("sprs", test
.sprs
)
255 program
= test
.program
256 with self
.subTest(test
.name
):
257 yield from self
.execute(core
, instruction
, pdecode2
, test
)
259 sim
.add_sync_process(process
)
260 with sim
.write_vcd("alu_simulator.vcd", "simulator.gtkw",
264 if __name__
== "__main__":
265 unittest
.main(exit
=False)
266 suite
= unittest
.TestSuite()
267 suite
.addTest(TestRunner(MMUTestCase().test_data
))
269 runner
= unittest
.TextTestRunner()