test case for FSMMMUStage
[soc.git] / src / soc / fu / mmu / test / test_pipe_caller.py
1 from nmigen import Module, Signal
2
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
6
7 from nmigen.cli import rtlil
8 import unittest
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
18
19
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
26 import random
27
28
29 #incomplete test - not working yet
30 class MMUTestCase(TestAccumulatorBase):
31
32 def case_1_mmu(self):
33 # test case for MTSPR, MFSPR, DCBZ and TLBIE.
34 lst = ["mfspr 1, 26", # SRR0
35 "mfspr 2, 27", # SRR1
36 "mfspr 3, 8", # LR
37 "mfspr 4, 1", ] # XER
38 initial_regs = [0] * 32
39 initial_sprs = {'SRR0': 0x12345678, 'SRR1': 0x5678, 'LR': 0x1234,
40 'XER': 0xe00c0000}
41 self.add_case(Program(lst, bigendian),
42 initial_regs, initial_sprs)
43
44 #def case_ilang(self):
45 # pspec = SPRPipeSpec(id_wid=2)
46 # alu = SPRBasePipe(pspec)
47 # vl = rtlil.convert(alu, ports=alu.ports())
48 # with open("trap_pipeline.il", "w") as f:
49 # f.write(vl)
50
51
52 class TestRunner(unittest.TestCase):
53 def __init__(self, test_data):
54 super().__init__("run_all")
55 self.test_data = test_data
56
57 def execute(self, alu, instruction, pdecode2, test):
58 program = test.program
59 sim = ISA(pdecode2, test.regs, test.sprs, test.cr,
60 test.mem, test.msr,
61 bigendian=bigendian)
62 gen = program.generate_instructions()
63 instructions = list(zip(gen, program.assembly.splitlines()))
64
65 pc = sim.pc.CIA.value
66 msr = sim.msr.value
67 index = pc//4
68 while index < len(instructions):
69 ins, code = instructions[index]
70
71 print("pc %08x instr: %08x" % (pc, ins & 0xffffffff))
72 print(code)
73
74 if 'XER' in sim.spr:
75 so = 1 if sim.spr['XER'][XER_bits['SO']] else 0
76 ov = 1 if sim.spr['XER'][XER_bits['OV']] else 0
77 ov32 = 1 if sim.spr['XER'][XER_bits['OV32']] else 0
78 print("before: so/ov/32", so, ov, ov32)
79
80 # ask the decoder to decode this binary data (endian'd)
81 yield pdecode2.dec.bigendian.eq(bigendian) # little / big?
82 yield pdecode2.state.msr.eq(msr) # set MSR in pdecode2
83 yield pdecode2.state.pc.eq(pc) # set PC in pdecode2
84 yield instruction.eq(ins) # raw binary instr.
85 yield Settle()
86
87 fast_in = yield pdecode2.e.read_fast1.data
88 spr_in = yield pdecode2.e.read_spr1.data
89 print("dec2 spr/fast in", fast_in, spr_in)
90
91 fast_out = yield pdecode2.e.write_fast1.data
92 spr_out = yield pdecode2.e.write_spr.data
93 print("dec2 spr/fast in", fast_out, spr_out)
94
95 fn_unit = yield pdecode2.e.do.fn_unit
96 self.assertEqual(fn_unit, Function.SPR.value)
97 #TODO
98 alu_o = yield from set_alu_inputs(alu, pdecode2, sim)
99 yield
100 opname = code.split(' ')[0]
101 yield from sim.call(opname)
102 pc = sim.pc.CIA.value
103 msr = sim.msr.value
104 index = pc//4
105 print("pc after %08x" % (pc))
106
107 vld = yield alu.n.valid_o
108 while not vld:
109 yield
110 vld = yield alu.n.valid_o
111 yield
112
113 yield from self.check_alu_outputs(alu, pdecode2, sim, code)
114
115 def run_all(self):
116 m = Module()
117 comb = m.d.comb
118 instruction = Signal(32)
119
120 pdecode = create_pdecode()
121
122 m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
123
124 pspec = MMUPipeSpec(id_wid=2)
125 m.submodules.fsm = fsm = FSMMMUStage(pspec)
126
127 #FIXME connect fsm inputs
128
129 comb += alu.p.data_i.ctx.op.eq_from_execute1(pdecode2.do)
130 comb += alu.p.valid_i.eq(1)
131 comb += alu.n.ready_i.eq(1)
132 comb += pdecode2.dec.raw_opcode_in.eq(instruction)
133 sim = Simulator(m)
134
135 sim.add_clock(1e-6)
136
137 def process():
138 for test in self.test_data:
139 print("test", test.name)
140 print("sprs", test.sprs)
141 program = test.program
142 with self.subTest(test.name):
143 yield from self.execute(alu, instruction, pdecode2, test)
144
145 sim.add_sync_process(process)
146 with sim.write_vcd("alu_simulator.vcd", "simulator.gtkw",
147 traces=[]):
148 sim.run()
149
150 def check_alu_outputs(self, alu, dec2, sim, code):
151
152 rc = yield dec2.e.do.rc.data
153 cridx_ok = yield dec2.e.write_cr.ok
154 cridx = yield dec2.e.write_cr.data
155
156 print("check extra output", repr(code), cridx_ok, cridx)
157 if rc:
158 self.assertEqual(cridx, 0, code)
159
160 sim_o = {}
161 res = {}
162
163 yield from ALUHelpers.get_int_o(res, alu, dec2)
164 yield from ALUHelpers.get_fast_spr1(res, alu, dec2)
165 yield from ALUHelpers.get_slow_spr1(res, alu, dec2)
166 yield from ALUHelpers.get_xer_ov(res, alu, dec2)
167 yield from ALUHelpers.get_xer_ca(res, alu, dec2)
168 yield from ALUHelpers.get_xer_so(res, alu, dec2)
169
170 print("output", res)
171
172 yield from ALUHelpers.get_sim_int_o(sim_o, sim, dec2)
173 yield from ALUHelpers.get_wr_sim_xer_so(sim_o, sim, alu, dec2)
174 yield from ALUHelpers.get_wr_sim_xer_ov(sim_o, sim, alu, dec2)
175 yield from ALUHelpers.get_wr_sim_xer_ca(sim_o, sim, dec2)
176 yield from ALUHelpers.get_wr_fast_spr1(sim_o, sim, dec2)
177 yield from ALUHelpers.get_wr_slow_spr1(sim_o, sim, dec2)
178
179 print("sim output", sim_o)
180
181 ALUHelpers.check_xer_ov(self, res, sim_o, code)
182 ALUHelpers.check_xer_ca(self, res, sim_o, code)
183 ALUHelpers.check_xer_so(self, res, sim_o, code)
184 ALUHelpers.check_int_o(self, res, sim_o, code)
185 ALUHelpers.check_fast_spr1(self, res, sim_o, code)
186 ALUHelpers.check_slow_spr1(self, res, sim_o, code)
187
188
189 if __name__ == "__main__":
190 unittest.main(exit=False)
191 suite = unittest.TestSuite()
192 suite.addTest(TestRunner(MMUTestCase().test_data))
193
194 runner = unittest.TextTestRunner()
195 runner.run(suite)