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
, Delay
, Settle
6 # to be renamed for a c-based module.
7 from openpower
.decoder
.test
.pysim
import PySimEngine
9 from nmutil
.formaltest
import FHDLTestCase
10 from nmigen
.cli
import rtlil
14 from openpower
.decoder
.power_decoder
import (create_pdecode
)
15 from openpower
.decoder
.power_enums
import (Function
, MicrOp
,
16 In1Sel
, In2Sel
, In3Sel
,
18 OutSel
, RCOE
, LdstLen
, CryIn
,
20 get_signal_name
, get_csv
)
23 class DecoderTestCase(FHDLTestCase
):
25 def run_tst(self
, bitsel
, csvname
, minor
=None, suffix
=None, opint
=True):
29 function_unit
= Signal(Function
)
30 internal_op
= Signal(MicrOp
)
31 in1_sel
= Signal(In1Sel
)
32 in2_sel
= Signal(In2Sel
)
33 in3_sel
= Signal(In3Sel
)
34 out_sel
= Signal(OutSel
)
35 cr_in
= Signal(CRInSel
)
36 cr_out
= Signal(CROutSel
)
38 ldst_len
= Signal(LdstLen
)
39 cry_in
= Signal(CryIn
)
41 comb
+= bigendian
.eq(0)
43 # opcodes = get_csv(csvname)
44 m
.submodules
.dut
= dut
= create_pdecode()
45 comb
+= [dut
.raw_opcode_in
.eq(opcode
),
46 dut
.bigendian
.eq(bigendian
),
47 function_unit
.eq(dut
.op
.function_unit
),
48 in1_sel
.eq(dut
.op
.in1_sel
),
49 in2_sel
.eq(dut
.op
.in2_sel
),
50 in3_sel
.eq(dut
.op
.in3_sel
),
51 out_sel
.eq(dut
.op
.out_sel
),
52 cr_in
.eq(dut
.op
.cr_in
),
53 cr_out
.eq(dut
.op
.cr_out
),
54 rc_sel
.eq(dut
.op
.rc_sel
),
55 ldst_len
.eq(dut
.op
.ldst_len
),
56 cry_in
.eq(dut
.op
.cry_in
),
57 internal_op
.eq(dut
.op
.internal_op
)]
60 # Use the below line instead to run the work-in-progress C simulator.
61 sim
= Simulator(m
, engine
=PySimEngine
)
62 # for test purposes repeat the simulation to get performance stats
65 opcodes
= get_csv(csvname
)
68 tic
= time
.perf_counter()
69 for i
in range(repeat_times
):
73 # skip "conditions" for now
74 if (row
['CONDITIONS'] and
75 row
['CONDITIONS'] in ['SVP64BREV']):
78 if not opint
: # HACK: convert 001---10 to 0b00100010
79 op
= "0b" + op
.replace('-', '0')
80 print("opint", opint
, row
['opcode'], op
)
83 yield opcode
[bitsel
[0]:bitsel
[1]].eq(int(op
, 0))
87 yield opcode
[minorbits
[0]:minorbits
[1]].eq(minor
[0])
89 # OR 0, 0, 0 ; 0x60000000 is decoded as a NOP
90 # If we're testing the OR instruction, make sure
91 # that the instruction is not 0x60000000
93 yield opcode
[24:25].eq(0b11)
97 signals
= [(function_unit
, Function
, 'unit'),
98 (internal_op
, MicrOp
, 'internal op'),
99 (in1_sel
, In1Sel
, 'in1'),
100 (in2_sel
, In2Sel
, 'in2'),
101 (in3_sel
, In3Sel
, 'in3'),
102 (out_sel
, OutSel
, 'out'),
103 (cr_in
, CRInSel
, 'CR in'),
104 (cr_out
, CROutSel
, 'CR out'),
105 (rc_sel
, RCOE
, 'rc'),
106 (cry_in
, CryIn
, 'cry in'),
107 (ldst_len
, LdstLen
, 'ldst len')]
108 for sig
, enm
, name
in signals
:
110 expected
= enm
[row
[name
]]
111 msg
= f
"{sig.name} == {enm(result)}, expected: {expected}"
112 msg
+= "- op: %x, opcode %s" % (opint
, row
['opcode'])
114 self
.assertEqual(enm(result
), expected
, msg
)
115 for bit
in single_bit_flags
:
116 sig
= getattr(dut
.op
, get_signal_name(bit
))
118 expected
= int(row
[bit
])
119 msg
= f
"{sig.name} == {result}, expected: {expected}"
120 self
.assertEqual(expected
, result
, msg
)
121 ticend
= time
.perf_counter()
122 print ("time taken:", ticend
- tic
)
124 sim
.add_process(process
)
125 prefix
= os
.path
.splitext(csvname
)[0]
126 with sim
.write_vcd("%s.vcd" % prefix
, "%s.gtkw" % prefix
, traces
=[
127 opcode
, function_unit
, internal_op
,
131 def generate_ilang(self
):
132 conditions
= {'SVP64BREV': Signal(name
="svp64brev", reset_less
=True),
133 'SVP64FFT': Signal(name
="svp64fft", reset_less
=True),
135 pdecode
= create_pdecode(conditions
=conditions
)
136 vl
= rtlil
.convert(pdecode
, ports
=pdecode
.ports())
137 with
open("decoder.il", "w") as f
:
140 def test_major(self
):
141 self
.run_tst((26, 32), "major.csv")
142 self
.generate_ilang()
144 def test_minor_19(self
):
145 self
.run_tst((1, 11), "minor_19.csv", minor
=(19, (26, 32)),
148 # def test_minor_19_00000(self):
149 # self.run_tst((1, 11), "minor_19_00000.csv")
151 # FIXME: ValueError: invalid literal for int() with base 0: '010-'
152 @unittest.expectedFailure
153 def test_minor_30(self
):
154 self
.run_tst((1, 5), "minor_30.csv", minor
=(30, (26, 32)))
156 def test_minor_31(self
):
157 self
.run_tst((1, 11), "minor_31.csv", minor
=(31, (26, 32)))
159 def test_minor_58(self
):
160 self
.run_tst((0, 2), "minor_58.csv", minor
=(58, (26, 32)))
162 def test_minor_62(self
):
163 self
.run_tst((0, 2), "minor_62.csv", minor
=(62, (26, 32)))
165 # #def test_minor_31_prefix(self):
166 # # self.run_tst(10, "minor_31.csv", suffix=(5, 10))
168 # def test_extra(self):
169 # self.run_tst(32, "extra.csv", opint=False)
170 # self.generate_ilang(32, "extra.csv", opint=False)
173 if __name__
== "__main__":