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 import power_instruction_analyzer
as pia
35 def set_fsm_inputs(alu
, dec2
, sim
):
36 # TODO: see https://bugs.libre-soc.org/show_bug.cgi?id=305#c43
37 # detect the immediate here (with m.If(self.i.ctx.op.imm_data.imm_ok))
38 # and place it into data_i.b
41 inp
= yield from get_cu_inputs(dec2
, sim
)
42 # set int registers a and b
43 yield from ALUHelpers
.set_int_ra(alu
, dec2
, inp
)
44 yield from ALUHelpers
.set_int_rb(alu
, dec2
, inp
)
45 # TODO set spr register
46 # yield from ALUHelpers.set_spr_spr1(alu, dec2, inp)
53 print("xer_so::::::::::::::::::::::::::::::::::::::::::::::::")
56 overflow
= pia
.OverflowFlags(so
=bool(so
),
64 return pia
.InstructionInput(ra
=a
, rb
=b
, overflow
=overflow
)
67 def check_fsm_outputs(fsm
, pdecode2
, sim
, code
):
68 # check that MMUOutputData is correct
71 #incomplete test - connect fsm inputs first
72 class MMUTestCase(TestAccumulatorBase
):
75 # test case for MTSPR, MFSPR, DCBZ and TLBIE.
76 #lst = ["dcbz 2,3"] not yet implemented
77 lst
= ["mtspr 18, 1", # DSISR
83 initial_regs
= [0] * 32
84 initial_regs
[1] = 0xBADCAB1E
85 initial_regs
[2] = 0xDEADC0DE
86 initial_sprs
= {'SRR0': 0x12345678, 'SRR1': 0x5678, 'LR': 0x1234,
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 execute(self
, fsm
, instruction
, pdecode2
, test
):
105 program
= test
.program
106 sim
= ISA(pdecode2
, test
.regs
, test
.sprs
, test
.cr
,
109 gen
= program
.generate_instructions()
110 instructions
= list(zip(gen
, program
.assembly
.splitlines()))
112 pc
= sim
.pc
.CIA
.value
115 while index
< len(instructions
):
116 ins
, code
= instructions
[index
]
118 print("pc %08x instr: %08x" % (pc
, ins
& 0xffffffff))
122 so
= 1 if sim
.spr
['XER'][XER_bits
['SO']] else 0
123 ov
= 1 if sim
.spr
['XER'][XER_bits
['OV']] else 0
124 ov32
= 1 if sim
.spr
['XER'][XER_bits
['OV32']] else 0
125 print("before: so/ov/32", so
, ov
, ov32
)
127 # ask the decoder to decode this binary data (endian'd)
128 yield pdecode2
.dec
.bigendian
.eq(bigendian
) # little / big?
129 yield pdecode2
.state
.msr
.eq(msr
) # set MSR in pdecode2
130 yield pdecode2
.state
.pc
.eq(pc
) # set PC in pdecode2
131 yield instruction
.eq(ins
) # raw binary instr.
134 fast_in
= yield pdecode2
.e
.read_fast1
.data
135 spr_in
= yield pdecode2
.e
.read_spr1
.data
136 print("dec2 spr/fast in", fast_in
, spr_in
)
138 fast_out
= yield pdecode2
.e
.write_fast1
.data
139 spr_out
= yield pdecode2
.e
.write_spr
.data
140 print("dec2 spr/fast in", fast_out
, spr_out
)
142 fn_unit
= yield pdecode2
.e
.do
.fn_unit
143 #FIXME this fails -- self.assertEqual(fn_unit, Function.SPR.value)
144 fsm_o_unused
= yield from set_fsm_inputs(fsm
, pdecode2
, sim
)
146 opname
= code
.split(' ')[0]
147 yield from sim
.call(opname
)
148 pc
= sim
.pc
.CIA
.value
151 print("pc after %08x" % (pc
))
153 vld
= yield fsm
.n
.valid_o
#fsm
156 if debughang
: print("not valid -- hang")
157 vld
= yield fsm
.n
.valid_o
158 if debughang
==2: vld
=1
161 #TODO: yield from self.check_fsm_outputs(fsm, pdecode2, sim, code)
166 instruction
= Signal(32)
168 pdecode
= create_pdecode()
170 m
.submodules
.pdecode2
= pdecode2
= PowerDecode2(pdecode
)
172 pspec
= MMUPipeSpec(id_wid
=2)
173 m
.submodules
.fsm
= fsm
= FSMMMUStage(pspec
)
175 #FIXME connect fsm inputs
177 comb
+= fsm
.p
.data_i
.ctx
.op
.eq_from_execute1(pdecode2
.do
)
178 comb
+= fsm
.p
.valid_i
.eq(1)
179 comb
+= fsm
.n
.ready_i
.eq(1)
180 comb
+= pdecode2
.dec
.raw_opcode_in
.eq(instruction
)
186 for test
in self
.test_data
:
187 print("test", test
.name
)
188 print("sprs", test
.sprs
)
189 program
= test
.program
190 with self
.subTest(test
.name
):
191 yield from self
.execute(fsm
, instruction
, pdecode2
, test
)
193 sim
.add_sync_process(process
)
194 with sim
.write_vcd("alu_simulator.vcd", "simulator.gtkw",
198 if __name__
== "__main__":
199 unittest
.main(exit
=False)
200 suite
= unittest
.TestSuite()
201 suite
.addTest(TestRunner(MMUTestCase().test_data
))
203 runner
= unittest
.TextTestRunner()