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
,
8 """PowerOp: spec for execution. op type (ADD etc.) reg specs etc.
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
))
25 def _eq(self
, row
=None):
27 row
= {'unit': "NONE", 'internal op': "OP_ILLEGAL",
28 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': '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']]),
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))))
46 def eq(self
, otherop
):
47 res
= [self
.function_unit
.eq(otherop
.function_unit
),
48 self
.internal_op
.eq(otherop
.internal_op
),
49 self
.in1_sel
.eq(otherop
.in1_sel
),
50 self
.in2_sel
.eq(otherop
.in2_sel
),
51 self
.in3_sel
.eq(otherop
.in3_sel
),
52 self
.out_sel
.eq(otherop
.out_sel
),
53 self
.rc_sel
.eq(otherop
.rc_sel
),
54 self
.ldst_len
.eq(otherop
.ldst_len
),
55 self
.cry_in
.eq(otherop
.cry_in
)]
56 for bit
in single_bit_flags
:
57 sig
= getattr(self
, get_signal_name(bit
))
58 res
.append(sig
.eq(getattr(otherop
, get_signal_name(bit
))))
62 regular
= [self
.function_unit
,
70 single_bit_ports
= [getattr(self
, get_signal_name(x
))
71 for x
in single_bit_flags
]
72 return regular
+ single_bit_ports
75 class PowerDecoder(Elaboratable
):
76 """PowerDecoder - decodes an incoming opcode into the type of operation
79 def __init__(self
, width
, opcodes
, opint
=True, 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)
86 if suffix
[1] - suffix
[0] >= width
:
90 def suffix_mask(self
):
91 return ((1 << self
.suffix
[1]) - 1) - ((1 << self
.suffix
[0]) - 1)
93 def divide_opcodes(self
):
95 mask
= self
.suffix_mask()
96 for row
in self
.opcodes
:
97 opcode
= row
['opcode']
99 opcode
= int(opcode
, 0)
100 key
= opcode
& mask
>> (self
.suffix
[0])
101 opcode
= opcode
>> self
.suffix
[1]
102 if key
not in divided
:
106 divided
[key
].append(r
)
109 def elaborate(self
, platform
):
114 opcodes
= self
.divide_opcodes()
115 opc_in
= Signal(self
.suffix
[1] - self
.suffix
[0], reset_less
=True)
116 comb
+= opc_in
.eq(self
.opcode_in
[self
.suffix
[0]:self
.suffix
[1]])
117 with m
.Switch(opc_in
):
118 for key
, row
in opcodes
.items():
119 subdecoder
= PowerDecoder(width
=self
.width
- opc_in
.width
,
123 setattr(m
.submodules
, "dec%d" % key
, subdecoder
)
124 comb
+= subdecoder
.opcode_in
.eq(self
.opcode_in
[self
.suffix
[1]:])
126 comb
+= self
.op
.eq(subdecoder
.op
)
129 with m
.Switch(self
.opcode_in
):
130 for row
in self
.opcodes
:
131 opcode
= row
['opcode']
133 opcode
= int(opcode
, 0)
137 comb
+= self
.op
._eq
(row
)
139 comb
+= self
.op
._eq
(None)
143 return [self
.opcode_in
] + self
.op
.ports()
147 # pminor = (0, 6, [(19, "minor_19", (1,11)), # pass to 'splitter' function
148 # (30, "minor_30", (1,4)),
149 # (31, "minor_31", (1,11)), # pass to 'splitter' function
150 # (58, "minor_58", (0,1)),
151 # (62, "minor_62", (0,1)),
154 # pdecode = PowerDecoder(6, "major", subcoders = pminor)