Add support for hierarchical decoding
[soc.git] / src / decoder / test / test_power_decoder.py
1 from nmigen import Module, Signal
2 from nmigen.back.pysim import Simulator, Delay
3 from nmigen.test.utils import FHDLTestCase
4 from nmigen.cli import rtlil
5 import sys
6 import os
7 import unittest
8 sys.path.append("../")
9 from power_decoder import (PowerDecoder)
10 from power_enums import (Function, InternalOp, In1Sel, In2Sel, In3Sel,
11 OutSel, RC, LdstLen, CryIn, single_bit_flags,
12 get_signal_name, get_csv)
13
14
15 class DecoderTestCase(FHDLTestCase):
16 def run_test(self, width, csvname, suffix=None, opint=True):
17 m = Module()
18 comb = m.d.comb
19 opcode = Signal(width)
20 function_unit = Signal(Function)
21 internal_op = Signal(InternalOp)
22 in1_sel = Signal(In1Sel)
23 in2_sel = Signal(In2Sel)
24 in3_sel = Signal(In3Sel)
25 out_sel = Signal(OutSel)
26 rc_sel = Signal(RC)
27 ldst_len = Signal(LdstLen)
28 cry_in = Signal(CryIn)
29
30 opcodes = get_csv(csvname)
31 m.submodules.dut = dut = PowerDecoder(width, opcodes, opint, suffix=suffix)
32 comb += [dut.opcode_in.eq(opcode),
33 function_unit.eq(dut.op.function_unit),
34 in1_sel.eq(dut.op.in1_sel),
35 in2_sel.eq(dut.op.in2_sel),
36 in3_sel.eq(dut.op.in3_sel),
37 out_sel.eq(dut.op.out_sel),
38 rc_sel.eq(dut.op.rc_sel),
39 ldst_len.eq(dut.op.ldst_len),
40 cry_in.eq(dut.op.cry_in),
41 internal_op.eq(dut.op.internal_op)]
42
43 sim = Simulator(m)
44
45 def process():
46 for row in dut.opcodes:
47 if not row['unit']:
48 continue
49 op = row['opcode']
50 if not opint: # HACK: convert 001---10 to 0b00100010
51 op = "0b" + op.replace('-', '0')
52 print ("opint", opint, row['opcode'], op)
53 yield opcode.eq(int(op, 0))
54 yield Delay(1e-6)
55 signals = [(function_unit, Function, 'unit'),
56 (internal_op, InternalOp, 'internal op'),
57 (in1_sel, In1Sel, 'in1'),
58 (in2_sel, In2Sel, 'in2'),
59 (in3_sel, In3Sel, 'in3'),
60 (out_sel, OutSel, 'out'),
61 (rc_sel, RC, 'rc'),
62 (cry_in, CryIn, 'cry in'),
63 (ldst_len, LdstLen, 'ldst len')]
64 for sig, enm, name in signals:
65 result = yield sig
66 expected = enm[row[name]]
67 msg = f"{sig.name} == {enm(result)}, expected: {expected}"
68 self.assertEqual(enm(result), expected, msg)
69 for bit in single_bit_flags:
70 sig = getattr(dut.op, get_signal_name(bit))
71 result = yield sig
72 expected = int(row[bit])
73 msg = f"{sig.name} == {result}, expected: {expected}"
74 self.assertEqual(expected, result, msg)
75 sim.add_process(process)
76 with sim.write_vcd("test.vcd", "test.gtkw", traces=[
77 opcode, function_unit, internal_op,
78 in1_sel, in2_sel]):
79 sim.run()
80
81 def generate_ilang(self, width, csvname, opint=True, suffix=None):
82 prefix = os.path.splitext(csvname)[0]
83 dut = PowerDecoder(width, get_csv(csvname), opint, suffix=suffix)
84 vl = rtlil.convert(dut, ports=dut.ports())
85 with open("%s_decoder.il" % prefix, "w") as f:
86 f.write(vl)
87
88 def test_major(self):
89 self.run_test(6, "major.csv")
90 self.generate_ilang(6, "major.csv")
91
92 # def test_minor_19(self):
93 # self.run_test(3, "minor_19.csv")
94 # self.generate_ilang(3, "minor_19.csv")
95
96 def test_minor_30(self):
97 self.run_test(4, "minor_30.csv")
98 self.generate_ilang(4, "minor_30.csv")
99
100 def test_minor_31(self):
101 self.run_test(10, "minor_31.csv", suffix=(0, 5))
102 self.generate_ilang(10, "minor_31.csv", suffix=(0, 5))
103
104 def test_extra(self):
105 self.run_test(32, "extra.csv", False)
106 self.generate_ilang(32, "extra.csv", False)
107
108 if __name__ == "__main__":
109 unittest.main()