1 from nmigen
import Module
, Elaboratable
, Signal
2 from power_enums
import (Function
, InternalOp
, In1Sel
, In2Sel
, In3Sel
,
3 OutSel
, RC
, LdstLen
, CryIn
, get_csv
)
6 # names of the fields in major.csv that don't correspond to an enum
7 single_bit_flags
= ['CR in', 'CR out', 'inv A', 'inv out',
8 'cry out', 'BR', 'sgn ext', 'upd', 'rsrv', '32b',
9 'sgn', 'lk', 'sgl pipe']
12 def get_signal_name(name
):
13 return name
.lower().replace(' ', '_')
18 major_opcodes
= get_csv("major.csv")
21 class PowerMajorDecoder(Elaboratable
):
23 self
.opcode_in
= Signal(6, reset_less
=True)
25 self
.function_unit
= Signal(Function
, reset_less
=True)
26 self
.internal_op
= Signal(InternalOp
, reset_less
=True)
27 self
.in1_sel
= Signal(In1Sel
, reset_less
=True)
28 self
.in2_sel
= Signal(In2Sel
, reset_less
=True)
29 self
.in3_sel
= Signal(In3Sel
, reset_less
=True)
30 self
.out_sel
= Signal(OutSel
, reset_less
=True)
31 self
.ldst_len
= Signal(LdstLen
, reset_less
=True)
32 self
.rc_sel
= Signal(RC
, reset_less
=True)
33 self
.cry_in
= Signal(CryIn
, reset_less
=True)
34 for bit
in single_bit_flags
:
35 name
= get_signal_name(bit
)
37 Signal(reset_less
=True, name
=name
))
39 def elaborate(self
, platform
):
43 with m
.Switch(self
.opcode_in
):
44 for row
in major_opcodes
:
45 opcode
= int(row
['opcode'])
47 comb
+= self
.function_unit
.eq(Function
[row
['unit']])
48 comb
+= self
.internal_op
.eq(InternalOp
[row
['internal op']])
49 comb
+= self
.in1_sel
.eq(In1Sel
[row
['in1']])
50 comb
+= self
.in2_sel
.eq(In2Sel
[row
['in2']])
51 comb
+= self
.in3_sel
.eq(In3Sel
[row
['in3']])
52 comb
+= self
.out_sel
.eq(OutSel
[row
['out']])
53 comb
+= self
.ldst_len
.eq(LdstLen
[row
['ldst len']])
54 comb
+= self
.rc_sel
.eq(RC
[row
['rc']])
55 comb
+= self
.cry_in
.eq(CryIn
[row
['cry in']])
56 for bit
in single_bit_flags
:
57 sig
= getattr(self
, get_signal_name(bit
))
58 comb
+= sig
.eq(int(row
[bit
]))
62 regular
=[self
.opcode_in
,
71 single_bit_ports
= [getattr(self
, get_signal_name(x
))
72 for x
in single_bit_flags
]
73 return regular
+ single_bit_ports