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
)
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):
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']]),
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))))
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
))))
59 regular
= [self
.function_unit
,
67 single_bit_ports
= [getattr(self
, get_signal_name(x
))
68 for x
in single_bit_flags
]
69 return regular
+ single_bit_ports
72 class PowerDecoder(Elaboratable
):
73 """PowerDecoder - decodes an incoming opcode into the type of operation
76 def __init__(self
, width
, opcodes
, *,
77 bitsel
, subdecoders
=[],
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
is not None and suffix
[1] - suffix
[0] >= width
:
89 self
.subdecoders
= subdecoders
92 def suffix_mask(self
):
93 return ((1 << self
.suffix
[1]) - 1) - ((1 << self
.suffix
[0]) - 1)
95 def divide_opcodes(self
):
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
:
109 divided
[key
].append(r
)
112 def elaborate(self
, platform
):
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,
125 # suffix=self.suffix)
126 # setattr(m.submodules, "dec%d" % key, subdecoder)
127 # comb += subdecoder.opcode_in.eq(self.opcode_in[self.suffix[1]:])
129 # comb += self.op.eq(subdecoder.op)
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)
142 comb
+= self
.op
._eq
(row
)
144 comb
+= self
.op
._eq
(None)
149 return [self
.opcode_in
] + self
.op
.ports()
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)),
160 # pdecode = PowerDecoder(6, "major", subcoders = pminor)