add MMU FunctionUnit
[soc.git] / src / soc / decoder / power_enums.py
1 from enum import Enum, unique
2 import csv
3 import os
4 from os.path import dirname, join
5 from collections import namedtuple
6
7
8 def find_wiki_file(name):
9 filedir = os.path.dirname(os.path.abspath(__file__))
10 basedir = dirname(dirname(dirname(filedir)))
11 tabledir = join(basedir, 'libreriscv')
12 tabledir = join(tabledir, 'openpower')
13 tabledir = join(tabledir, 'isatables')
14
15 file_path = join(tabledir, name)
16 return file_path
17
18
19 def get_csv(name):
20 file_path = find_wiki_file(name)
21 with open(file_path, 'r') as csvfile:
22 reader = csv.DictReader(csvfile)
23 return list(reader)
24
25
26 # names of the fields in the tables that don't correspond to an enum
27 single_bit_flags = ['inv A', 'inv out',
28 'cry out', 'BR', 'sgn ext', 'rsrv', '32b',
29 'sgn', 'lk', 'sgl pipe']
30
31 # default values for fields in the table
32 default_values = {'unit': "NONE", 'internal op': "OP_ILLEGAL",
33 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
34 'CR in': 'NONE',
35 'ldst len': 'NONE',
36 'upd': '0',
37 'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'}
38
39
40 def get_signal_name(name):
41 if name[0].isdigit():
42 name = "is_" + name
43 return name.lower().replace(' ', '_')
44
45 # this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
46 # is to process and guard the operation. they are roughly divided by having
47 # the same register input/output signature (X-Form, etc.)
48 @unique
49 class Function(Enum):
50 NONE = 0
51 ALU = 1 << 1
52 LDST = 1 << 2
53 SHIFT_ROT = 1 << 3
54 LOGICAL = 1 << 4
55 BRANCH = 1 << 5
56 CR = 1 << 6
57 TRAP = 1 << 7
58 MUL = 1 << 8
59 DIV = 1 << 9
60 SPR = 1 << 10
61 MMU = 1 << 11
62
63
64 @unique
65 class Form(Enum):
66 NONE = 0
67 I = 1
68 B = 2
69 SC = 3
70 D = 4
71 DS = 5
72 DQ = 6
73 DX = 7
74 X = 8
75 XL = 9
76 XFX = 10
77 XFL = 11
78 XX1 = 12
79 XX2 = 13
80 XX3 = 14
81 XX4 = 15
82 XS = 16
83 XO = 17
84 A = 18
85 M = 19
86 MD = 20
87 MDS = 21
88 VA = 22
89 VC = 23
90 VX = 24
91 EVX = 25
92 EVS = 26
93 Z22 = 27
94 Z23 = 28
95
96
97 # supported instructions: make sure to keep up-to-date with CSV files
98 # just like everything else
99 _insns = [
100 "NONE", "add", "addc", "addco", "adde", "addeo", "addi", "addic", "addic.",
101 "addis", "addme", "addmeo", "addo", "addze", "addzeo", "and", "andc",
102 "andi.", "andis.", "attn", "b", "bc", "bcctr", "bclr", "bctar",
103 "bpermd", "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
104 "cntlzd", "cntlzw", "cnttzd", "cnttzw", "crand", "crandc", "creqv",
105 "crnand", "crnor", "cror", "crorc", "crxor", "darn", "dcbf", "dcbst",
106 "dcbt", "dcbtst", "dcbz", "divd", "divde", "divdeo", "divdeu",
107 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
108 "divweu", "divweuo", "divwo", "divwu", "divwuo", "eqv", "extsb",
109 "extsh", "extsw", "extswsli", "hrfid", "icbi", "icbt", "isel", "isync",
110 "lbarx", "lbz", "lbzu", "lbzux", "lbzx", "ld", "ldarx", "ldbrx",
111 "ldu", "ldux", "ldx", "lha", "lharx", "lhau", "lhaux", "lhax",
112 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", "lwa", "lwarx", "lwaux",
113 "lwax", "lwbrx", "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", "mcrf", "mcrxr",
114 "mcrxrx", "mfcr/mfocrf", "mfmsr", "mfspr", "modsd", "modsw", "modud",
115 "moduw", "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr", "mulhd", "mulhdu",
116 "mulhw", "mulhwu", "mulld", "mulldo", "mulli", "mullw", "mullwo",
117 "nand", "neg", "nego", "nop", "nor", "or", "orc", "ori", "oris",
118 "popcntb", "popcntd", "popcntw", "prtyd", "prtyw", "rfid", "rldcl",
119 "rldcr", "rldic", "rldicl", "rldicr", "rldimi", "rlwimi", "rlwinm",
120 "rlwnm", "setb", "sim_cfg", "slbia", "sld", "slw", "srad", "sradi", "sraw",
121 "srawi", "srd", "srw", "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
122 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx", "sth", "sthbrx", "sthcx",
123 "sthu", "sthux", "sthx", "stw", "stwbrx", "stwcx", "stwu", "stwux",
124 "stwx", "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
125 "subfme", "subfmeo", "subfo", "subfze", "subfzeo", "sync", "td",
126 "tdi", "tlbie", "tlbiel", "tw", "twi", "xor", "xori", "xoris",
127 ]
128
129 # two-way lookup of instruction-to-index and vice-versa
130 insns = {}
131 asmidx = {}
132 for i, insn in enumerate(_insns):
133 insns[i] = insn
134 asmidx[insn] = i
135
136 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
137 @unique
138 class MicrOp(Enum):
139 OP_ILLEGAL = 0 # important that this is zero (see power_decoder.py)
140 OP_NOP = 1
141 OP_ADD = 2
142 OP_ADDPCIS = 3
143 OP_AND = 4
144 OP_ATTN = 5
145 OP_B = 6
146 OP_BC = 7
147 OP_BCREG = 8
148 OP_BPERM = 9
149 OP_CMP = 10
150 OP_CMPB = 11
151 OP_CMPEQB = 12
152 OP_CMPRB = 13
153 OP_CNTZ = 14
154 OP_CRAND = 15
155 OP_CRANDC = 16
156 OP_CREQV = 17
157 OP_CRNAND = 18
158 OP_CRNOR = 19
159 OP_CROR = 20
160 OP_CRORC = 21
161 OP_CRXOR = 22
162 OP_DARN = 23
163 OP_DCBF = 24
164 OP_DCBST = 25
165 OP_DCBT = 26
166 OP_DCBTST = 27
167 OP_DCBZ = 28
168 OP_DIV = 29
169 OP_DIVE = 30
170 OP_EXTS = 31
171 OP_EXTSWSLI = 32
172 OP_ICBI = 33
173 OP_ICBT = 34
174 OP_ISEL = 35
175 OP_ISYNC = 36
176 OP_LOAD = 37
177 OP_STORE = 38
178 OP_MADDHD = 39
179 OP_MADDHDU = 40
180 OP_MADDLD = 41
181 OP_MCRF = 42
182 OP_MCRXR = 43
183 OP_MCRXRX = 44
184 OP_MFCR = 45
185 OP_MFSPR = 46
186 OP_MOD = 47
187 OP_MTCRF = 48
188 OP_MTSPR = 49
189 OP_MUL_L64 = 50
190 OP_MUL_H64 = 51
191 OP_MUL_H32 = 52
192 OP_OR = 53
193 OP_POPCNT = 54
194 OP_PRTY = 55
195 OP_RLC = 56
196 OP_RLCL = 57
197 OP_RLCR = 58
198 OP_SETB = 59
199 OP_SHL = 60
200 OP_SHR = 61
201 OP_SYNC = 62
202 OP_TRAP = 63
203 OP_XOR = 67
204 OP_SIM_CONFIG = 68
205 OP_CROP = 69
206 OP_RFID = 70
207 OP_MFMSR = 71
208 OP_MTMSRD = 72
209 OP_SC = 73
210 OP_MTMSR = 74
211 OP_TLBIE = 75
212
213
214 @unique
215 class In1Sel(Enum):
216 NONE = 0
217 RA = 1
218 RA_OR_ZERO = 2
219 SPR = 3
220 RS = 4 # for some ALU/Logical operations
221
222
223 @unique
224 class In2Sel(Enum):
225 NONE = 0
226 RB = 1
227 CONST_UI = 2
228 CONST_SI = 3
229 CONST_UI_HI = 4
230 CONST_SI_HI = 5
231 CONST_LI = 6
232 CONST_BD = 7
233 CONST_DS = 8
234 CONST_M1 = 9
235 CONST_SH = 10
236 CONST_SH32 = 11
237 SPR = 12
238 RS = 13 # for shiftrot (M-Form)
239
240
241 @unique
242 class In3Sel(Enum):
243 NONE = 0
244 RS = 1
245 RB = 2 # for shiftrot (M-Form)
246
247
248 @unique
249 class OutSel(Enum):
250 NONE = 0
251 RT = 1
252 RA = 2
253 SPR = 3
254
255
256 @unique
257 class LdstLen(Enum):
258 NONE = 0
259 is1B = 1
260 is2B = 2
261 is4B = 4
262 is8B = 8
263
264
265 @unique
266 class LDSTMode(Enum):
267 NONE = 0
268 update = 1
269 cix = 2
270 cx = 3
271
272
273 @unique
274 class RC(Enum):
275 NONE = 0
276 ONE = 1
277 RC = 2
278
279
280 @unique
281 class CryIn(Enum):
282 ZERO = 0
283 ONE = 1
284 CA = 2
285 # TODO OV = 3
286
287
288 @unique
289 class CRInSel(Enum):
290 NONE = 0
291 CR0 = 1
292 BI = 2
293 BFA = 3
294 BA_BB = 4
295 BC = 5
296 WHOLE_REG = 6
297
298
299 @unique
300 class CROutSel(Enum):
301 NONE = 0
302 CR0 = 1
303 BF = 2
304 BT = 3
305 WHOLE_REG = 4
306
307
308 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
309 # http://libre-riscv.org/openpower/isatables/sprs.csv
310 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
311
312 spr_csv = get_csv("sprs.csv")
313 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
314 spr_dict = {}
315 spr_byname = {}
316 for row in spr_csv:
317 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
318 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
319 idx=int(row['Idx']))
320 spr_dict[int(row['Idx'])] = info
321 spr_byname[row['SPR']] = info
322 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
323 SPR = Enum('SPR', fields)
324
325
326 XER_bits = {
327 'SO': 32,
328 'OV': 33,
329 'CA': 34,
330 'OV32': 44,
331 'CA32': 45
332 }
333
334 if __name__ == '__main__':
335 # find out what the heck is in SPR enum :)
336 print("sprs", len(SPR))
337 print(dir(SPR))
338 print(dir(Enum))
339 print(SPR.__members__['TAR'])
340 for x in SPR:
341 print(x, x.value, str(x), x.name)
342
343 print ("function", Function.ALU.name)