0b701ae85b0ddcc550cf8f1dfe1a68a4c086d4cf
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 Function
12 from openpower
.simulator
.program
import Program
13 from openpower
.decoder
.isa
.all
import ISA
14 from soc
.regfile
.regfiles
import FastRegs
15 from openpower
.endian
import bigendian
17 from openpower
.test
.common
import ALUHelpers
18 from soc
.fu
.branch
.pipeline
import BranchBasePipe
19 from soc
.fu
.branch
.pipe_data
import BranchPipeSpec
22 from openpower
.test
.branch
.branch_cases
import BranchTestCase
25 def get_rec_width(rec
):
27 # Setup random inputs for dut.op
34 def get_cu_inputs(dec2
, sim
):
35 """naming (res) must conform to BranchFunctionUnit input regspec
40 #res['cia'] = sim.pc.CIA.value
42 yield from ALUHelpers
.get_sim_fast_spr1(res
, sim
, dec2
)
43 yield from ALUHelpers
.get_sim_fast_spr2(res
, sim
, dec2
)
44 yield from ALUHelpers
.get_sim_cr_a(res
, sim
, dec2
)
46 print("get inputs", res
)
50 class BranchAllCases(BranchTestCase
):
53 pspec
= BranchPipeSpec(id_wid
=2)
54 alu
= BranchBasePipe(pspec
)
55 vl
= rtlil
.convert(alu
, ports
=alu
.ports())
56 with
open("branch_pipeline.il", "w") as f
:
60 class TestRunner(unittest
.TestCase
):
62 test_data
= BranchAllCases().test_data
65 instruction
= Signal(32)
68 opkls
= BranchPipeSpec
.opsubsetkls
70 m
.submodules
.pdecode2
= pdecode2
= PowerDecode2(None, opkls
, fn_name
)
71 pdecode
= pdecode2
.dec
73 pspec
= BranchPipeSpec(id_wid
=2)
74 m
.submodules
.branch
= branch
= BranchBasePipe(pspec
)
76 comb
+= branch
.p
.i_data
.ctx
.op
.eq_from_execute1(pdecode2
.do
)
77 comb
+= branch
.p
.i_valid
.eq(1)
78 comb
+= branch
.n
.i_ready
.eq(1)
79 comb
+= pdecode2
.dec
.raw_opcode_in
.eq(instruction
)
85 for test
in test_data
:
87 program
= test
.program
88 with self
.subTest(test
.name
):
89 simulator
= ISA(pdecode2
, test
.regs
, test
.sprs
, test
.cr
,
93 simulator
.set_pc(initial_cia
)
94 gen
= program
.generate_instructions()
96 zip(gen
, program
.assembly
.splitlines()))
98 pc
= simulator
.pc
.CIA
.value
99 msr
= simulator
.msr
.value
100 index
= (pc
- initial_cia
)//4
101 while index
< len(instructions
) and index
>= 0:
103 ins
, code
= instructions
[index
]
105 print("0x{:X}".format(ins
& 0xffffffff))
108 # ask the decoder to decode this binary data (endian'd)
110 yield pdecode2
.dec
.bigendian
.eq(bigendian
)
111 yield pdecode2
.state
.msr
.eq(msr
) # set MSR in pdecode2
112 yield pdecode2
.state
.pc
.eq(pc
) # set PC in pdecode2
113 yield instruction
.eq(ins
) # raw binary instr.
114 # note, here, the op will need further decoding in order
115 # to set the correct SPRs on SPR1/2/3. op_bc* require
116 # spr1 to be set to CTR, op_bctar require spr2 to be
117 # set to TAR, op_bclr* require spr2 to be set to LR.
118 # if op_sc*, op_rf* and op_hrfid are to be added here
119 # then additional op-decoding is required, accordingly
121 lk
= yield pdecode2
.e
.do
.lk
123 yield from self
.set_inputs(branch
, pdecode2
, simulator
)
124 fn_unit
= yield pdecode2
.e
.do
.fn_unit
125 self
.assertEqual(fn_unit
, Function
.BRANCH
.value
, code
)
128 opname
= code
.split(' ')[0]
129 prev_nia
= simulator
.pc
.NIA
.value
130 yield from simulator
.call(opname
)
131 pc
= simulator
.pc
.CIA
.value
132 msr
= simulator
.msr
.value
133 index
= (pc
- initial_cia
)//4
135 yield from self
.assert_outputs(branch
, pdecode2
,
139 sim
.add_sync_process(process
)
140 with sim
.write_vcd("branch_simulator.vcd"):
143 def assert_outputs(self
, branch
, dec2
, sim
, prev_nia
, code
):
144 branch_taken
= yield branch
.n
.o_data
.nia
.ok
145 sim_branch_taken
= prev_nia
!= sim
.pc
.CIA
146 self
.assertEqual(branch_taken
, sim_branch_taken
, code
)
148 branch_addr
= yield branch
.n
.o_data
.nia
.data
149 print(f
"real: {branch_addr:x}, sim: {sim.pc.CIA.value:x}")
150 self
.assertEqual(branch_addr
, sim
.pc
.CIA
.value
, code
)
152 # TODO: check write_fast1 as well (should contain CTR)
154 # TODO: this should be checking write_fast2
155 lk
= yield dec2
.e
.do
.lk
156 branch_lk
= yield branch
.n
.o_data
.lr
.ok
157 self
.assertEqual(lk
, branch_lk
, code
)
159 branch_lr
= yield branch
.n
.o_data
.lr
.data
160 self
.assertEqual(sim
.spr
['LR'], branch_lr
, code
)
162 def set_inputs(self
, branch
, dec2
, sim
):
163 print(f
"cr0: {sim.crl[0].get_range()}")
165 inp
= yield from get_cu_inputs(dec2
, sim
)
167 yield from ALUHelpers
.set_fast_spr1(branch
, dec2
, inp
)
168 yield from ALUHelpers
.set_fast_spr2(branch
, dec2
, inp
)
169 yield from ALUHelpers
.set_cr_a(branch
, dec2
, inp
)
172 if __name__
== "__main__":