make tests pass again
[openpower-isa.git] / src / openpower / decoder / test / test_power_decoder.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, Delay, Settle
6 # to be renamed for a c-based module.
7 from openpower.decoder.test.pysim import PySimEngine
8
9 from nmutil.formaltest import FHDLTestCase
10 from nmigen.cli import rtlil
11 import os
12 import time
13 import unittest
14 from openpower.decoder.power_decoder import (create_pdecode)
15 from openpower.decoder.power_enums import (Function, MicrOp,
16 In1Sel, In2Sel, In3Sel,
17 CRInSel, CROutSel,
18 OutSel, RCOE, LdstLen, CryIn,
19 single_bit_flags,
20 get_signal_name, get_csv)
21
22
23 class DecoderTestCase(FHDLTestCase):
24
25 def run_tst(self, bitsel, csvname, minor=None, suffix=None, opint=True):
26 m = Module()
27 comb = m.d.comb
28 opcode = Signal(32)
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)
37 rc_sel = Signal(RCOE)
38 ldst_len = Signal(LdstLen)
39 cry_in = Signal(CryIn)
40 bigendian = Signal()
41 comb += bigendian.eq(0)
42
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)]
58
59 #sim = Simulator(m)
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
63 repeat_times = 10
64
65 opcodes = get_csv(csvname)
66
67 def process():
68 tic = time.perf_counter()
69 for i in range(repeat_times):
70 for row in opcodes:
71 if not row['unit']:
72 continue
73 # skip "conditions" for now
74 if (row['CONDITIONS'] and
75 row['CONDITIONS'] in ['SVP64BREV']):
76 continue
77 op = row['opcode']
78 if not opint: # HACK: convert 001---10 to 0b00100010
79 op = "0b" + op.replace('-', '0')
80 print("opint", opint, row['opcode'], op)
81 print(row)
82 yield opcode.eq(0)
83 yield opcode[bitsel[0]:bitsel[1]].eq(int(op, 0))
84 if minor:
85 print(minor)
86 minorbits = minor[1]
87 yield opcode[minorbits[0]:minorbits[1]].eq(minor[0])
88 else:
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
92 if int(op, 0) == 24:
93 yield opcode[24:25].eq(0b11)
94
95 yield Delay(1e-6)
96 yield Settle()
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:
109 result = yield sig
110 expected = enm[row[name]]
111 msg = f"{sig.name} == {enm(result)}, expected: {expected}"
112 msg += "- op: %x, opcode %s" % (opint, row['opcode'])
113 print (msg)
114 self.assertEqual(enm(result), expected, msg)
115 for bit in single_bit_flags:
116 sig = getattr(dut.op, get_signal_name(bit))
117 result = yield sig
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)
123
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,
128 in1_sel, in2_sel]):
129 sim.run()
130
131 def generate_ilang(self):
132 conditions = {'SVP64BREV': Signal(name="svp64brev", reset_less=True),
133 'SVP64FFT': Signal(name="svp64fft", reset_less=True),
134 }
135 pdecode = create_pdecode(conditions=conditions)
136 vl = rtlil.convert(pdecode, ports=pdecode.ports())
137 with open("decoder.il", "w") as f:
138 f.write(vl)
139
140 def test_major(self):
141 self.run_tst((26, 32), "major.csv")
142 self.generate_ilang()
143
144 def test_minor_19(self):
145 self.run_tst((1, 11), "minor_19.csv", minor=(19, (26, 32)),
146 suffix=(0, 5))
147
148 # def test_minor_19_00000(self):
149 # self.run_tst((1, 11), "minor_19_00000.csv")
150
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)))
155
156 def test_minor_31(self):
157 self.run_tst((1, 11), "minor_31.csv", minor=(31, (26, 32)))
158
159 def test_minor_58(self):
160 self.run_tst((0, 2), "minor_58.csv", minor=(58, (26, 32)))
161
162 def test_minor_62(self):
163 self.run_tst((0, 2), "minor_62.csv", minor=(62, (26, 32)))
164
165 # #def test_minor_31_prefix(self):
166 # # self.run_tst(10, "minor_31.csv", suffix=(5, 10))
167
168 # def test_extra(self):
169 # self.run_tst(32, "extra.csv", opint=False)
170 # self.generate_ilang(32, "extra.csv", opint=False)
171
172
173 if __name__ == "__main__":
174 unittest.main()