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
.decoder
.isa
.all
import ISA
13 from openpower
.endian
import bigendian
15 from openpower
.test
.common
import TestAccumulatorBase
, ALUHelpers
16 from openpower
.util
import mask_extend
17 from soc
.fu
.cr
.pipeline
import CRBasePipe
18 from soc
.fu
.cr
.pipe_data
import CRPipeSpec
21 from openpower
.test
.cr
.cr_cases
import CRTestCase
24 class CRIlangCase(TestAccumulatorBase
):
27 pspec
= CRPipeSpec(id_wid
=2, parent_pspec
=None)
28 alu
= CRBasePipe(pspec
)
29 vl
= rtlil
.convert(alu
, ports
=alu
.ports())
30 with
open("cr_pipeline.il", "w") as f
:
34 def get_cu_inputs(dec2
, sim
):
35 """naming (res) must conform to CRFunctionUnit input regspec
38 full_reg
= yield dec2
.dec_cr_in
.whole_reg
.data
39 full_reg_ok
= yield dec2
.dec_cr_in
.whole_reg
.ok
40 full_cr_mask
= mask_extend(full_reg
, 8, 4)
45 res
['full_cr'] = sim
.cr
.value
& full_cr_mask
47 yield from ALUHelpers
.get_sim_cr_a(res
, sim
, dec2
) # CR A
48 yield from ALUHelpers
.get_sim_cr_b(res
, sim
, dec2
) # CR B
49 yield from ALUHelpers
.get_sim_cr_c(res
, sim
, dec2
) # CR C
51 yield from ALUHelpers
.get_sim_int_ra(res
, sim
, dec2
) # RA
52 yield from ALUHelpers
.get_sim_int_rb(res
, sim
, dec2
) # RB
54 print("get inputs", res
)
58 class TestRunner(unittest
.TestCase
):
59 def __init__(self
, test_data
):
60 super().__init
__("run_all")
61 self
.test_data
= test_data
63 def set_inputs(self
, alu
, dec2
, simulator
):
64 inp
= yield from get_cu_inputs(dec2
, simulator
)
65 yield from ALUHelpers
.set_full_cr(alu
, dec2
, inp
)
66 yield from ALUHelpers
.set_cr_a(alu
, dec2
, inp
)
67 yield from ALUHelpers
.set_cr_b(alu
, dec2
, inp
)
68 yield from ALUHelpers
.set_cr_c(alu
, dec2
, inp
)
69 yield from ALUHelpers
.set_int_ra(alu
, dec2
, inp
)
70 yield from ALUHelpers
.set_int_rb(alu
, dec2
, inp
)
72 def assert_outputs(self
, alu
, dec2
, simulator
, code
):
73 whole_reg_ok
= yield dec2
.dec_cr_out
.whole_reg
.ok
74 whole_reg_data
= yield dec2
.dec_cr_out
.whole_reg
.data
75 full_cr_mask
= mask_extend(whole_reg_data
, 8, 4)
77 cr_en
= yield dec2
.e
.write_cr
.ok
79 full_cr
= yield alu
.n
.o_data
.full_cr
.data
& full_cr_mask
80 expected_cr
= simulator
.cr
.value
81 print("CR whole: expected %x, actual: %x mask: %x" %
82 (expected_cr
, full_cr
, full_cr_mask
))
83 # HACK: only look at the bits that we expected to change
84 self
.assertEqual(expected_cr
& full_cr_mask
, full_cr
, code
)
86 cr_sel
= yield dec2
.e
.write_cr
.data
87 expected_cr
= simulator
.cr
.value
88 print(f
"CR whole: {expected_cr:x}, sel {cr_sel}")
89 expected_cr
= simulator
.crl
[cr_sel
].get_range().value
90 real_cr
= yield alu
.n
.o_data
.cr
.data
91 print(f
"CR part: expected {expected_cr:x}, actual: {real_cr:x}")
92 self
.assertEqual(expected_cr
, real_cr
, code
)
93 alu_out
= yield alu
.n
.o_data
.o
.data
94 out_reg_valid
= yield dec2
.e
.write_reg
.ok
96 write_reg_idx
= yield dec2
.e
.write_reg
.data
97 expected
= simulator
.gpr(write_reg_idx
).value
98 print(f
"expected {expected:x}, actual: {alu_out:x}")
99 self
.assertEqual(expected
, alu_out
, code
)
101 def execute(self
, alu
, instruction
, pdecode2
, test
):
102 program
= test
.program
103 sim
= ISA(pdecode2
, test
.regs
, test
.sprs
, test
.cr
, test
.mem
,
106 gen
= program
.generate_instructions()
107 instructions
= list(zip(gen
, program
.assembly
.splitlines()))
109 index
= sim
.pc
.CIA
.value
//4
110 while index
< len(instructions
):
111 ins
, code
= instructions
[index
]
113 print("0x{:X}".format(ins
& 0xffffffff))
116 # ask the decoder to decode this binary data (endian'd)
117 yield pdecode2
.dec
.bigendian
.eq(bigendian
) # little / big?
118 yield instruction
.eq(ins
) # raw binary instr.
120 yield from self
.set_inputs(alu
, pdecode2
, sim
)
121 yield alu
.p
.i_valid
.eq(1)
122 fn_unit
= yield pdecode2
.e
.do
.fn_unit
123 self
.assertEqual(fn_unit
, Function
.CR
.value
, code
)
125 opname
= code
.split(' ')[0]
126 yield from sim
.call(opname
)
127 index
= sim
.pc
.CIA
.value
//4
129 vld
= yield alu
.n
.o_valid
132 vld
= yield alu
.n
.o_valid
134 yield from self
.assert_outputs(alu
, pdecode2
, sim
, code
)
139 instruction
= Signal(32)
142 opkls
= CRPipeSpec
.opsubsetkls
144 m
.submodules
.pdecode2
= pdecode2
= PowerDecode2(None, opkls
, fn_name
)
145 pdecode
= pdecode2
.dec
147 pspec
= CRPipeSpec(id_wid
=2, parent_pspec
=None)
148 m
.submodules
.alu
= alu
= CRBasePipe(pspec
)
150 comb
+= alu
.p
.i_data
.ctx
.op
.eq_from_execute1(pdecode2
.do
)
151 comb
+= alu
.n
.i_ready
.eq(1)
152 comb
+= pdecode2
.dec
.raw_opcode_in
.eq(instruction
)
158 for test
in self
.test_data
:
160 with self
.subTest(test
.name
):
161 yield from self
.execute(alu
, instruction
, pdecode2
, test
)
163 sim
.add_sync_process(process
)
164 with sim
.write_vcd("cr_simulator.vcd"):
168 if __name__
== "__main__":
169 unittest
.main(exit
=False)
170 suite
= unittest
.TestSuite()
171 suite
.addTest(TestRunner(CRTestCase().test_data
))
172 suite
.addTest(TestRunner(CRIlangCase().test_data
))
174 runner
= unittest
.TextTestRunner()