Change decoder to take the bits to select of the opcode as parameter
[soc.git] / src / decoder / power_decoder.py
1 from nmigen import Module, Elaboratable, Signal
2 from power_enums import (Function, InternalOp, In1Sel, In2Sel, In3Sel,
3 OutSel, RC, LdstLen, CryIn, get_csv, single_bit_flags,
4 get_signal_name, default_values)
5
6
7 class PowerOp:
8 """PowerOp: spec for execution. op type (ADD etc.) reg specs etc.
9 """
10
11 def __init__(self):
12 self.function_unit = Signal(Function, reset_less=True)
13 self.internal_op = Signal(InternalOp, reset_less=True)
14 self.in1_sel = Signal(In1Sel, reset_less=True)
15 self.in2_sel = Signal(In2Sel, reset_less=True)
16 self.in3_sel = Signal(In3Sel, reset_less=True)
17 self.out_sel = Signal(OutSel, reset_less=True)
18 self.ldst_len = Signal(LdstLen, reset_less=True)
19 self.rc_sel = Signal(RC, reset_less=True)
20 self.cry_in = Signal(CryIn, reset_less=True)
21 for bit in single_bit_flags:
22 name = get_signal_name(bit)
23 setattr(self, name, Signal(reset_less=True, name=name))
24
25 def _eq(self, row=None):
26 if row is None:
27 row = default_values
28 res = [self.function_unit.eq(Function[row['unit']]),
29 self.internal_op.eq(InternalOp[row['internal op']]),
30 self.in1_sel.eq(In1Sel[row['in1']]),
31 self.in2_sel.eq(In2Sel[row['in2']]),
32 self.in3_sel.eq(In3Sel[row['in3']]),
33 self.out_sel.eq(OutSel[row['out']]),
34 self.ldst_len.eq(LdstLen[row['ldst len']]),
35 self.rc_sel.eq(RC[row['rc']]),
36 self.cry_in.eq(CryIn[row['cry in']]),
37 ]
38 for bit in single_bit_flags:
39 sig = getattr(self, get_signal_name(bit))
40 res.append(sig.eq(int(row.get(bit, 0))))
41 return res
42
43 def eq(self, otherop):
44 res = [self.function_unit.eq(otherop.function_unit),
45 self.internal_op.eq(otherop.internal_op),
46 self.in1_sel.eq(otherop.in1_sel),
47 self.in2_sel.eq(otherop.in2_sel),
48 self.in3_sel.eq(otherop.in3_sel),
49 self.out_sel.eq(otherop.out_sel),
50 self.rc_sel.eq(otherop.rc_sel),
51 self.ldst_len.eq(otherop.ldst_len),
52 self.cry_in.eq(otherop.cry_in)]
53 for bit in single_bit_flags:
54 sig = getattr(self, get_signal_name(bit))
55 res.append(sig.eq(getattr(otherop, get_signal_name(bit))))
56 return res
57
58 def ports(self):
59 regular = [self.function_unit,
60 self.in1_sel,
61 self.in2_sel,
62 self.in3_sel,
63 self.out_sel,
64 self.ldst_len,
65 self.rc_sel,
66 self.internal_op]
67 single_bit_ports = [getattr(self, get_signal_name(x))
68 for x in single_bit_flags]
69 return regular + single_bit_ports
70
71
72 class PowerDecoder(Elaboratable):
73 """PowerDecoder - decodes an incoming opcode into the type of operation
74 """
75
76 def __init__(self, width, opcodes, *,
77 bitsel, subdecoders=[],
78 opint=True,
79 suffix=None):
80 self.opint = opint # true if the opcode needs to be converted to int
81 self.opcodes = opcodes
82 self.opcode_in = Signal(width, reset_less=True)
83
84 self.op = PowerOp()
85 self.suffix = suffix
86 if suffix is not None and suffix[1] - suffix[0] >= width:
87 self.suffix = None
88 self.bitsel = bitsel
89 self.subdecoders = subdecoders
90 self.width = width
91
92 def suffix_mask(self):
93 return ((1 << self.suffix[1]) - 1) - ((1 << self.suffix[0]) - 1)
94
95 def divide_opcodes(self):
96 divided = {}
97 mask = self.suffix_mask()
98 print ("mask", hex(mask))
99 for row in self.opcodes:
100 opcode = row['opcode']
101 if self.opint and '-' not in opcode:
102 opcode = int(opcode, 0)
103 key = opcode & mask >> (self.suffix[0])
104 opcode = opcode >> self.suffix[1]
105 if key not in divided:
106 divided[key] = []
107 r = row.copy()
108 r['opcode'] = opcode
109 divided[key].append(r)
110 return divided
111
112 def elaborate(self, platform):
113 m = Module()
114 comb = m.d.comb
115
116 # if self.suffix:
117 # opcodes = self.divide_opcodes()
118 # opc_in = Signal(self.suffix[1] - self.suffix[0], reset_less=True)
119 # comb += opc_in.eq(self.opcode_in[self.suffix[0]:self.suffix[1]])
120 # with m.Switch(opc_in):
121 # for key, row in opcodes.items():
122 # subdecoder = PowerDecoder(width=self.width - opc_in.width,
123 # opcodes=row,
124 # opint=False,
125 # suffix=self.suffix)
126 # setattr(m.submodules, "dec%d" % key, subdecoder)
127 # comb += subdecoder.opcode_in.eq(self.opcode_in[self.suffix[1]:])
128 # with m.Case(key):
129 # comb += self.op.eq(subdecoder.op)
130
131 # else:
132 opcode = Signal(self.bitsel[1] - self.bitsel[0], reset_less=True)
133 comb += opcode.eq(self.opcode_in[self.bitsel[0]:self.bitsel[1]])
134 with m.Switch(opcode):
135 for row in self.opcodes:
136 opcode = row['opcode']
137 if self.opint and '-' not in opcode:
138 opcode = int(opcode, 0)
139 if not row['unit']:
140 continue
141 with m.Case(opcode):
142 comb += self.op._eq(row)
143 with m.Default():
144 comb += self.op._eq(None)
145 return m
146
147
148 def ports(self):
149 return [self.opcode_in] + self.op.ports()
150
151 # how about this?
152 # if False:
153 # pminor = (0, 6, [(19, "minor_19", (1,11)), # pass to 'splitter' function
154 # (30, "minor_30", (1,4)),
155 # (31, "minor_31", (1,11)), # pass to 'splitter' function
156 # (58, "minor_58", (0,1)),
157 # (62, "minor_62", (0,1)),
158 # ]
159
160 # pdecode = PowerDecoder(6, "major", subcoders = pminor)