sort out hacking of PowerDecoder to suit extra.csv
[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)
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 = {'unit': "NONE", 'internal op': "OP_ILLEGAL",
28 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
29 'ldst len': 'NONE',
30 'rc' : 'NONE', 'cry in' : 'ZERO'}
31 res = [self.function_unit.eq(Function[row['unit']]),
32 self.internal_op.eq(InternalOp[row['internal op']]),
33 self.in1_sel.eq(In1Sel[row['in1']]),
34 self.in2_sel.eq(In2Sel[row['in2']]),
35 self.in3_sel.eq(In3Sel[row['in3']]),
36 self.out_sel.eq(OutSel[row['out']]),
37 self.ldst_len.eq(LdstLen[row['ldst len']]),
38 self.rc_sel.eq(RC[row['rc']]),
39 self.cry_in.eq(CryIn[row['cry in']]),
40 ]
41 for bit in single_bit_flags:
42 sig = getattr(self, get_signal_name(bit))
43 res.append(sig.eq(int(row.get(bit, 0))))
44 return res
45
46 def ports(self):
47 regular = [self.function_unit,
48 self.in1_sel,
49 self.in2_sel,
50 self.in3_sel,
51 self.out_sel,
52 self.ldst_len,
53 self.rc_sel,
54 self.internal_op]
55 single_bit_ports = [getattr(self, get_signal_name(x))
56 for x in single_bit_flags]
57 return regular + single_bit_ports
58
59
60 class PowerDecoder(Elaboratable):
61 """PowerDecoder - decodes an incoming opcode into the type of operation
62 """
63
64 def __init__(self, width, csvname, opint=True):
65 self.opint = opint # true if the opcode needs to be converted to int
66 self.opcodes = get_csv(csvname)
67 self.opcode_in = Signal(width, reset_less=True)
68
69 self.op = PowerOp()
70
71 def elaborate(self, platform):
72 m = Module()
73 comb = m.d.comb
74
75 with m.Switch(self.opcode_in):
76 for row in self.opcodes:
77 opcode = row['opcode']
78 if self.opint:
79 opcode = int(opcode, 0)
80 if not row['unit']:
81 continue
82 print ("opcode", opcode)
83 with m.Case(opcode):
84 comb += self.op._eq(row)
85 with m.Default():
86 comb += self.op._eq(None)
87 return m
88
89 def ports(self):
90 return [self.opcode_in] + self.op.ports()
91