2712633c18d632f81cb0cba4a5216460d198faa6
[openpower-isa.git] / src / openpower / consts.py
1 import enum as _enum
2
3
4 # just... don't ask. MSB0 is a massive pain in the neck.
5 # this module, aside from creating various field constants,
6 # helps out by creating alternative (identical) classes with
7 # a "b" name to indicate "MSB0 big-endian".
8
9
10 # sigh create little-ended versions of bitfield flags
11 def botchify(bekls, lekls, msb=63):
12 for attr in dir(bekls):
13 if attr[0] == '_':
14 continue
15 setattr(lekls, attr, msb-getattr(bekls, attr))
16
17
18 # Can't think of a better place to put these functions.
19 # Return an arbitrary subfield of a larger field.
20 def field_slice(msb0_start, msb0_end, field_width=64):
21 """field_slice
22
23 Answers with a subfield slice of the signal r ("register"),
24 where the start and end bits use IBM "MSB 0" conventions.
25
26 see: https://en.wikipedia.org/wiki/Bit_numbering#MSB_0_bit_numbering
27
28 * assertion: msb0_start < msb0_end.
29 * The range specified is inclusive on both ends.
30 * field_width specifies the total number of bits (note: not bits-1)
31 """
32 if msb0_start >= msb0_end:
33 raise ValueError(
34 "start ({}) must be less than end ({})".format(msb0_start, msb0_end)
35 )
36 # sigh. MSB0 (IBM numbering) is inverted. converting to python
37 # we *swap names* so as not to get confused by having "end, start"
38 lsb0_end = (field_width-1) - msb0_start
39 lsb0_start = (field_width-1) - msb0_end
40
41 return slice(lsb0_start, lsb0_end + 1)
42
43
44 def field(r, msb0_start, msb0_end=None, field_width=64):
45 """Answers with a subfield of the signal r ("register"), where
46 the start and end bits use IBM conventions. start < end, if
47 end is provided. The range specified is inclusive on both ends.
48
49 Answers with a subfield of the signal r ("register"),
50 where the start and end bits use IBM "MSB 0" conventions.
51 If end is not provided, a single bit subfield is returned.
52
53 see: https://en.wikipedia.org/wiki/Bit_numbering#MSB_0_bit_numbering
54
55 * assertion: msb0_start < msb0_end.
56 * The range specified is inclusive on both ends.
57 * field_width specifies the total number of bits (note: not bits-1)
58
59 Example usage:
60
61 comb += field(insn, 0, 6, field_width=32).eq(17)
62 # NOTE: NEVER DIRECTLY ACCESS OPCODE FIELDS IN INSTRUCTIONS.
63 # This example is purely for illustrative purposes only.
64 # Use self.fields.FormXYZ.etcetc instead.
65
66 comb += field(msr, MSRb.TEs, MSRb.TEe).eq(0)
67
68 Proof by substitution:
69
70 field(insn, 0, 6, field_width=32).eq(17)
71 == insn[field_slice(0, 6, field_width=32)].eq(17)
72 == insn[slice((31-6), (31-0)+1)].eq(17)
73 == insn[slice(25, 32)].eq(17)
74 == insn[25:32].eq(17)
75
76 field(msr, MSRb.TEs, MSRb.TEe).eq(0)
77 == field(msr, 53, 54).eq(0)
78 == msr[field_slice(53, 54)].eq(0)
79 == msr[slice((63-54), (63-53)+1)].eq(0) # note cross-over!
80 == msr[slice(9, 11)].eq(0)
81 == msr[9:11].eq(0)
82 """
83 if msb0_end is None:
84 return r[(field_width - 1) - msb0_start]
85 else:
86 return r[field_slice(msb0_start, msb0_end, field_width)]
87
88
89 class _Const(_enum.IntEnum):
90 pass
91
92
93 # Listed in V3.0B Book III Chap 4.2.1
94 # MSR bit numbers, *bigendian* order (PowerISA format)
95 # use this in the simulator
96 class MSRb(_Const):
97 SF = 0 # Sixty-Four bit mode
98 HV = 3 # Hypervisor state
99 UND = 5 # Undefined behavior state (see Bk 2, Sect. 3.2.1)
100 TSs = 29 # Transactional State (subfield)
101 TSe = 30 # Transactional State (subfield)
102 TM = 31 # Transactional Memory Available
103 VEC = 38 # Vector Available
104 VSX = 40 # VSX Available
105 S = 41 # Secure state
106 EE = 48 # External interrupt Enable
107 PR = 49 # PRoblem state
108 FP = 50 # FP available
109 ME = 51 # Machine Check int enable
110 FE0 = 52 # Floating-Point Exception Mode 0
111 TEs = 53 # Trace Enable (subfield)
112 TEe = 54 # Trace Enable (subfield)
113 FE1 = 55 # Floating-Point Exception Mode 1
114 IR = 58 # Instruction Relocation
115 DR = 59 # Data Relocation
116 PMM = 60 # Performance Monitor Mark
117 RI = 62 # Recoverable Interrupt
118 LE = 63 # Little Endian
119
120 # use this inside the HDL (where everything is little-endian)
121 class MSR:
122 pass
123
124 botchify(MSRb, MSR)
125
126 # Listed in V3.0B Book III 7.5.9 "Program Interrupt"
127
128 # note that these correspond to trap_input_record.traptype bits 0,1,2,3,4
129 # (TODO: add more?)
130 # IMPORTANT: when adding extra bits here it is CRITICALLY IMPORTANT
131 # to expand traptype to cope with the increased range
132
133 # use this in the simulator
134 class PIb(_Const):
135 INVALID = 33 # 1 for an invalid mem err
136 PERMERR = 35 # 1 for an permanent mem err
137 TM_BAD_THING = 42 # 1 for a TM Bad Thing type interrupt
138 FP = 43 # 1 if FP exception
139 ILLEG = 44 # 1 if illegal instruction (not doing hypervisor)
140 PRIV = 45 # 1 if privileged interrupt
141 TRAP = 46 # 1 if exception is "trap" type
142 ADR = 47 # 0 if SRR0 = address of instruction causing exception
143
144 # and use this in the HDL
145 class PI:
146 pass
147
148 botchify(PIb, PI)
149
150 # see traptype (and trap main_stage.py)
151 # IMPORTANT: when adding extra bits here it is CRITICALLY IMPORTANT
152 # to expand traptype to cope with the increased range
153
154 class TT:
155 FP = 1<<0
156 PRIV = 1<<1
157 TRAP = 1<<2
158 ADDR = 1<<3
159 EINT = 1<<4 # external interrupt
160 DEC = 1<<5 # decrement counter
161 MEMEXC = 1<<6 # LD/ST exception
162 ILLEG = 1<<7 # currently the max
163 # TODO: support for TM_BAD_THING (not included yet in trap main_stage.py)
164 size = 8 # MUST update this to contain the full number of Trap Types
165
166
167 # EXTRA3 3-bit subfield (spec)
168 class SPECb(_Const):
169 VEC = 0 # 1 for vector, 0 for scalar
170 MSB = 1 # augmented register number, MSB
171 LSB = 2 # augmented register number, LSB
172
173
174 SPEC_SIZE = 3
175 SPEC_AUG_SIZE = 2 # augmented subfield size (MSB+LSB above)
176 class SPEC:
177 pass
178 botchify(SPECb, SPEC, SPEC_SIZE-1)
179
180
181 # EXTRA field, with EXTRA2 subfield encoding
182 class EXTRA2b(_Const):
183 IDX0_VEC = 0
184 IDX0_MSB = 1
185 IDX1_VEC = 2
186 IDX1_MSB = 3
187 IDX2_VEC = 4
188 IDX2_MSB = 5
189 IDX3_VEC = 6
190 IDX3_MSB = 7
191 RESERVED = 8
192
193
194 EXTRA2_SIZE = 9
195 class EXTRA2:
196 pass
197 botchify(EXTRA2b, EXTRA2, EXTRA2_SIZE-1)
198
199
200 # EXTRA field, with EXTRA3 subfield encoding
201 class EXTRA3:
202 IDX0 = [0, 1, 2]
203 IDX1 = [3, 4, 5]
204 IDX2 = [6, 7, 8]
205 MASK = [6, 7, 8]
206
207
208 EXTRA3_SIZE = 9
209
210
211 # SVP64 ReMapped Field (from v3.1 EXT001 Prefix)
212 class SVP64P:
213 OPC = range(0, 6)
214 SVP64_7_9 = [7, 9]
215 RM = [6, 8] + list(range(10, 32))
216
217 # 24 bits in RM
218 SVP64P_SIZE = 24
219
220
221 # CR SVP64 offsets
222 class SVP64CROffs:
223 CR0 = 0 # TODO: increase when CRs are expanded to 128
224 CR1 = 1 # TODO: increase when CRs are expanded to 128
225 CRPred = 4 # TODO: increase when CRs are expanded to 128
226
227
228 class SVP64MODEb(_Const):
229 # mode bits
230 MOD2_MSB = 0
231 MOD2_LSB = 1
232 LDST_SHIFT = 2 # set =1 for shift mode
233 # when predicate not set: 0=ignore/skip 1=zero
234 DZ = 3 # for destination
235 SZ = 4 # for source
236 # for branch-conditional
237 BC_SNZ = 3 # for branch-conditional mode
238 BC_VLI = 2 # for VL include/exclude on VLSET mode
239 BC_VLSET = 1 # VLSET mode
240 BC_CTRTEST = 0 # CTR-test mode
241 # reduce mode
242 REDUCE = 2 # 0=normal predication 1=reduce mode
243 PARALLEL = 3 # 1=parallel reduce, 0=scalar reduce
244 SVM = 3 # subvector reduce mode 0=independent 1=horizontal
245 CRM = 4 # CR mode on reduce (Rc=1) 0=some 1=all
246 RG = 4 # Reverse-gear on reduce
247 # saturation mode
248 N = 2 # saturation signed mode 0=signed 1=unsigned
249 # ffirst and predicate result modes
250 INV = 2 # invert CR sense 0=set 1=unset
251 CR_MSB = 3 # CR bit to update (with Rc=1)
252 CR_LSB = 4
253 RC1 = 4 # update CR as if Rc=1 (when Rc=0)
254 # LD immediate els (element-stride) locations, depending on mode
255 ELS_NORMAL = 4
256 ELS_FFIRST_PRED = 3
257 ELS_SAT = 4
258 # BO bits
259 BO_MSB = 2
260 BO_LSB = 4
261
262
263 SVP64MODE_SIZE = 5
264
265
266 class SVP64MODE:
267 pass
268
269
270 botchify(SVP64MODEb, SVP64MODE, SVP64MODE_SIZE-1)
271
272 # add subfields to use with nmutil.sel
273 SVP64MODE.MOD2 = [0, 1]
274 SVP64MODE.CR = [3, 4]
275
276
277 # CR sub-fields
278 class CRb(_Const):
279 LT = 0
280 GT = 1
281 EQ = 2
282 SO = 3
283
284
285 CR_SIZE = 4
286
287
288 class CR:
289 pass
290
291
292 botchify(CRb, CR, CR_SIZE-1)
293
294
295 # POWER9 Register Files
296 # XXX these are specific to Libre-SOC's decoder. really, they
297 # should be in libre-soc. however... long story: because the
298 # PowerDecoder2 has been moved to openpower-isa, and its decoding
299 # depends on that, then... whoops.
300
301 # "State" Regfile
302 class StateRegsEnum:
303 PC = 0
304 MSR = 1
305 SVSTATE = 2
306 DEC = 3
307 TB = 4
308 N_REGS = 5 # maximum number of regs
309
310 # Fast SPRs Regfile
311 class FastRegsEnum:
312 LR = 0
313 CTR = 1
314 SRR0 = 2
315 SRR1 = 3
316 HSRR0 = 4
317 HSRR1 = 5
318 SPRG0 = 6
319 SPRG1 = 7
320 SPRG2 = 8
321 SPRG3 = 9
322 HSPRG0 = 10
323 HSPRG1 = 11
324 XER = 12 # non-XER bits
325 TAR = 13
326 SVSRR0 = 14
327 # only one spare!
328 N_REGS = 15 # maximum number of regs
329
330 # XER Regfile
331 class XERRegsEnum:
332 SO=0 # this is actually 2-bit but we ignore 1 bit of it
333 CA=1 # CA and CA32
334 OV=2 # OV and OV32
335 N_REGS = 3 # maximum number of regs