a2699a9185c2f9841dfb59b2c0170c479b3ed05d
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 from collections
import namedtuple
7 Subdecoder
= namedtuple("Subdecoder", ["pattern", "csv", "opint", "bitsel"])
11 """PowerOp: spec for execution. op type (ADD etc.) reg specs etc.
15 self
.function_unit
= Signal(Function
, reset_less
=True)
16 self
.internal_op
= Signal(InternalOp
, reset_less
=True)
17 self
.in1_sel
= Signal(In1Sel
, reset_less
=True)
18 self
.in2_sel
= Signal(In2Sel
, reset_less
=True)
19 self
.in3_sel
= Signal(In3Sel
, reset_less
=True)
20 self
.out_sel
= Signal(OutSel
, reset_less
=True)
21 self
.ldst_len
= Signal(LdstLen
, reset_less
=True)
22 self
.rc_sel
= Signal(RC
, reset_less
=True)
23 self
.cry_in
= Signal(CryIn
, reset_less
=True)
24 for bit
in single_bit_flags
:
25 name
= get_signal_name(bit
)
26 setattr(self
, name
, Signal(reset_less
=True, name
=name
))
28 def _eq(self
, row
=None):
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
, *,
80 bitsel
, subdecoders
=[],
83 self
.opint
= opint
# true if the opcode needs to be converted to int
84 self
.opcodes
= opcodes
85 self
.opcode_in
= Signal(width
, reset_less
=True)
89 if suffix
is not None and suffix
[1] - suffix
[0] >= width
:
92 self
.subdecoders
= subdecoders
95 def suffix_mask(self
):
96 return ((1 << self
.suffix
[1]) - 1) - ((1 << self
.suffix
[0]) - 1)
98 def divide_opcodes(self
):
100 mask
= self
.suffix_mask()
101 print ("mask", hex(mask
))
102 for row
in self
.opcodes
:
103 opcode
= row
['opcode']
104 if self
.opint
and '-' not in opcode
:
105 opcode
= int(opcode
, 0)
106 key
= opcode
& mask
>> (self
.suffix
[0])
107 opcode
= opcode
>> self
.suffix
[1]
108 if key
not in divided
:
112 divided
[key
].append(r
)
115 def elaborate(self
, platform
):
120 # opcodes = self.divide_opcodes()
121 # opc_in = Signal(self.suffix[1] - self.suffix[0], reset_less=True)
122 # comb += opc_in.eq(self.opcode_in[self.suffix[0]:self.suffix[1]])
123 # with m.Switch(opc_in):
124 # for key, row in opcodes.items():
125 # subdecoder = PowerDecoder(width=self.width - opc_in.width,
128 # suffix=self.suffix)
129 # setattr(m.submodules, "dec%d" % key, subdecoder)
130 # comb += subdecoder.opcode_in.eq(self.opcode_in[self.suffix[1]:])
132 # comb += self.op.eq(subdecoder.op)
135 opcode_switch
= Signal(self
.bitsel
[1] - self
.bitsel
[0], reset_less
=True)
136 comb
+= opcode_switch
.eq(self
.opcode_in
[self
.bitsel
[0]:self
.bitsel
[1]])
137 with m
.Switch(opcode_switch
):
138 self
.handle_subdecoders(m
)
139 for row
in self
.opcodes
:
140 opcode
= row
['opcode']
141 if self
.opint
and '-' not in opcode
:
142 opcode
= int(opcode
, 0)
146 comb
+= self
.op
._eq
(row
)
148 comb
+= self
.op
._eq
(None)
151 def handle_subdecoders(self
, m
):
152 for dec
in self
.subdecoders
:
153 subdecoder
= PowerDecoder(width
=self
.width
,
158 setattr(m
.submodules
, "dec%d" % dec
.pattern
, subdecoder
)
159 m
.d
.comb
+= subdecoder
.opcode_in
.eq(self
.opcode_in
)
160 with m
.Case(dec
.pattern
):
161 m
.d
.comb
+= self
.op
.eq(subdecoder
.op
)
164 return [self
.opcode_in
] + self
.op
.ports()
168 Subdecoder(pattern
=19, csv
=get_csv("minor_19.csv"),
169 opint
=True, bitsel
=(1, 11)),
170 Subdecoder(pattern
=30, csv
=get_csv("minor_30.csv"),
171 opint
=True, bitsel
=(1, 5)),
172 Subdecoder(pattern
=31, csv
=get_csv("minor_31.csv"),
173 opint
=True, bitsel
=(1, 11)),
174 Subdecoder(pattern
=58, csv
=get_csv("minor_58.csv"),
175 opint
=True, bitsel
=(0, 2)),
176 Subdecoder(pattern
=62, csv
=get_csv("minor_62.csv"),
177 opint
=True, bitsel
=(0, 2)),
180 opcodes
= get_csv("major.csv")
181 pdecode
= PowerDecoder(32, opcodes
, bitsel
=(26, 32), subdecoders
=pminor
)