2f1e52979d1b01b5eb1eadb79b3c6a116c274858
[soc.git] / src / decoder / power_major_decoder.py
1 from nmigen import Module, Elaboratable, Signal
2 import csv
3 import os
4 from enum import Enum, unique
5
6
7 @unique
8 class Function(Enum):
9 ALU = 0
10 LDST = 1
11
12
13 @unique
14 class InternalOp(Enum):
15 OP_ADD = 0
16 OP_AND = 1
17 OP_B = 2
18 OP_BC = 3
19 OP_CMP = 4
20 OP_LOAD = 5
21 OP_MUL_L64 = 6
22 OP_OR = 7
23 OP_RLC = 8
24 OP_STORE = 9
25 OP_TDI = 10
26 OP_XOR = 11
27
28
29 @unique
30 class In1Sel(Enum):
31 RA = 0
32 RA_OR_ZERO = 1
33 NONE = 2
34 SPR = 3
35
36
37 @unique
38 class In2Sel(Enum):
39 CONST_SI = 0
40 CONST_SI_HI = 1
41 CONST_UI = 2
42 CONST_UI_HI = 3
43 CONST_LI = 4
44 CONST_BD = 5
45 CONST_SH32 = 6
46 RB = 7
47
48
49 @unique
50 class In3Sel(Enum):
51 NONE = 0
52 RS = 1
53
54
55 @unique
56 class OutSel(Enum):
57 RT = 0
58 RA = 1
59 NONE = 2
60 SPR = 3
61
62
63 @unique
64 class LdstLen(Enum):
65 NONE = 0
66 is1B = 1
67 is2B = 2
68 is4B = 3
69
70
71 @unique
72 class RC(Enum):
73 NONE = 0
74 ONE = 1
75 RC = 2
76
77
78 @unique
79 class CryIn(Enum):
80 ZERO = 0
81 ONE = 1
82 CA = 2
83
84
85 # names of the fields in major.csv that don't correspond to an enum
86 single_bit_flags = ['CR in', 'CR out', 'inv A', 'inv out',
87 'cry out', 'BR', 'sgn ext', 'upd', 'rsrv', '32b',
88 'sgn', 'lk', 'sgl pipe']
89
90
91 def get_signal_name(name):
92 return name.lower().replace(' ', '_')
93
94
95 def get_csv(name):
96 file_dir = os.path.dirname(os.path.realpath(__file__))
97 with open(os.path.join(file_dir, name)) as csvfile:
98 reader = csv.DictReader(csvfile)
99 return list(reader)
100
101
102 major_opcodes = get_csv("major.csv")
103
104
105 class PowerMajorDecoder(Elaboratable):
106 def __init__(self):
107 self.opcode_in = Signal(6, reset_less=True)
108
109 self.function_unit = Signal(Function, reset_less=True)
110 self.internal_op = Signal(InternalOp, reset_less=True)
111 self.in1_sel = Signal(In1Sel, reset_less=True)
112 self.in2_sel = Signal(In2Sel, reset_less=True)
113 self.in3_sel = Signal(In3Sel, reset_less=True)
114 self.out_sel = Signal(OutSel, reset_less=True)
115 self.ldst_len = Signal(LdstLen, reset_less=True)
116 self.rc_sel = Signal(RC, reset_less=True)
117 self.cry_in = Signal(CryIn, reset_less=True)
118 for bit in single_bit_flags:
119 name = get_signal_name(bit)
120 setattr(self, name,
121 Signal(reset_less=True, name=name))
122
123 def elaborate(self, platform):
124 m = Module()
125 comb = m.d.comb
126
127 with m.Switch(self.opcode_in):
128 for row in major_opcodes:
129 opcode = int(row['opcode'])
130 with m.Case(opcode):
131 comb += self.function_unit.eq(Function[row['unit']])
132 comb += self.internal_op.eq(InternalOp[row['internal op']])
133 comb += self.in1_sel.eq(In1Sel[row['in1']])
134 comb += self.in2_sel.eq(In2Sel[row['in2']])
135 comb += self.in3_sel.eq(In3Sel[row['in3']])
136 comb += self.out_sel.eq(OutSel[row['out']])
137 comb += self.ldst_len.eq(LdstLen[row['ldst len']])
138 comb += self.rc_sel.eq(RC[row['rc']])
139 comb += self.cry_in.eq(CryIn[row['cry in']])
140 for bit in single_bit_flags:
141 sig = getattr(self, get_signal_name(bit))
142 comb += sig.eq(int(row[bit]))
143 return m
144
145 def ports(self):
146 regular =[self.opcode_in,
147 self.function_unit,
148 self.in1_sel,
149 self.in2_sel,
150 self.in3_sel,
151 self.out_sel,
152 self.ldst_len,
153 self.rc_sel,
154 self.internal_op]
155 single_bit_ports = [getattr(self, get_signal_name(x))
156 for x in single_bit_flags]
157 return regular + single_bit_ports