Replace MSB-i by symbolic subfield indices and selectors
[soc.git] / src / soc / consts.py
1 # sigh create little-ended versions of bitfield flags
2 from nmigen import Cat
3
4
5 def botchify(bekls, lekls, msb=63):
6 for attr in dir(bekls):
7 if attr[0] == '_':
8 continue
9 setattr(lekls, attr, msb-getattr(bekls, attr))
10
11
12 # Can't think of a better place to put these functions.
13 # Return an arbitrary subfield of a larger field.
14 def field_slice(msb0_start, msb0_end, field_width=64):
15 """field_slice
16
17 Answers with a subfield slice of the signal r ("register"),
18 where the start and end bits use IBM "MSB 0" conventions.
19
20 see: https://en.wikipedia.org/wiki/Bit_numbering#MSB_0_bit_numbering
21
22 * assertion: msb0_start < msb0_end.
23 * The range specified is inclusive on both ends.
24 * field_width specifies the total number of bits (note: not bits-1)
25 """
26 if msb0_start >= msb0_end:
27 raise ValueError(
28 "start ({}) must be less than end ({})".format(msb0_start, msb0_end)
29 )
30 # sigh. MSB0 (IBM numbering) is inverted. converting to python
31 # we *swap names* so as not to get confused by having "end, start"
32 lsb0_end = (field_width-1) - msb0_start
33 lsb0_start = (field_width-1) - msb0_end
34
35 return slice(lsb0_start, lsb0_end + 1)
36
37
38 def field(r, msb0_start, msb0_end=None, field_width=64):
39 """Answers with a subfield of the signal r ("register"), where
40 the start and end bits use IBM conventions. start < end, if
41 end is provided. The range specified is inclusive on both ends.
42
43 Answers with a subfield of the signal r ("register"),
44 where the start and end bits use IBM "MSB 0" conventions.
45 If end is not provided, a single bit subfield is returned.
46
47 see: https://en.wikipedia.org/wiki/Bit_numbering#MSB_0_bit_numbering
48
49 * assertion: msb0_start < msb0_end.
50 * The range specified is inclusive on both ends.
51 * field_width specifies the total number of bits (note: not bits-1)
52
53 Example usage:
54
55 comb += field(insn, 0, 6, field_width=32).eq(17)
56 # NOTE: NEVER DIRECTLY ACCESS OPCODE FIELDS IN INSTRUCTIONS.
57 # This example is purely for illustrative purposes only.
58 # Use self.fields.FormXYZ.etcetc instead.
59
60 comb += field(msr, MSRb.TEs, MSRb.TEe).eq(0)
61
62 Proof by substitution:
63
64 field(insn, 0, 6, field_width=32).eq(17)
65 == insn[field_slice(0, 6, field_width=32)].eq(17)
66 == insn[slice((31-6), (31-0)+1)].eq(17)
67 == insn[slice(25, 32)].eq(17)
68 == insn[25:32].eq(17)
69
70 field(msr, MSRb.TEs, MSRb.TEe).eq(0)
71 == field(msr, 53, 54).eq(0)
72 == msr[field_slice(53, 54)].eq(0)
73 == msr[slice((63-54), (63-53)+1)].eq(0) # note cross-over!
74 == msr[slice(9, 11)].eq(0)
75 == msr[9:11].eq(0)
76 """
77 if msb0_end is None:
78 return r[(field_width - 1) - msb0_start]
79 else:
80 return r[field_slice(msb0_start, msb0_end)]
81
82
83 def sel(r, sel_bits, field_width=None):
84 """Forms a subfield from a selection of bits of the signal `r`
85 ("register").
86
87 :param r: signal containing the field from which to select the subfield
88 :param sel_bits: bit indices of the subfield, in "MSB 0" convention,
89 from most significant to least significant. Note that
90 the indices are allowed to be non-contiguous and
91 out-of-order.
92 :param field_width: field width. If absent, use the signal `r` own width.
93 """
94 # find the MSB index in LSB0 numbering
95 if field_width is None:
96 msb = len(r) - 1
97 else:
98 msb = field_width - 1
99 # extract the selected bits
100 sig_list = []
101 for idx in sel_bits:
102 sig_list.append(r[msb - idx])
103 # place the LSB at the front of the list,
104 # since, in nMigen, Cat starts from the LSB
105 sig_list.reverse()
106 return Cat(*sig_list)
107
108
109 # Listed in V3.0B Book III Chap 4.2.1
110 # MSR bit numbers, *bigendian* order (PowerISA format)
111 # use this in the simulator
112 class MSRb:
113 SF = 0 # Sixty-Four bit mode
114 HV = 3 # Hypervisor state
115 UND = 5 # Undefined behavior state (see Bk 2, Sect. 3.2.1)
116 TSs = 29 # Transactional State (subfield)
117 TSe = 30 # Transactional State (subfield)
118 TM = 31 # Transactional Memory Available
119 VEC = 38 # Vector Available
120 VSX = 40 # VSX Available
121 S = 41 # Secure state
122 EE = 48 # External interrupt Enable
123 PR = 49 # PRoblem state
124 FP = 50 # FP available
125 ME = 51 # Machine Check int enable
126 FE0 = 52 # Floating-Point Exception Mode 0
127 TEs = 53 # Trace Enable (subfield)
128 TEe = 54 # Trace Enable (subfield)
129 FE1 = 55 # Floating-Point Exception Mode 1
130 IR = 58 # Instruction Relocation
131 DR = 59 # Data Relocation
132 PMM = 60 # Performance Monitor Mark
133 RI = 62 # Recoverable Interrupt
134 LE = 63 # Little Endian
135
136 # use this inside the HDL (where everything is little-endian)
137 class MSR:
138 pass
139
140 botchify(MSRb, MSR)
141
142 # Listed in V3.0B Book III 7.5.9 "Program Interrupt"
143
144 # note that these correspond to trap_input_record.traptype bits 0,1,2,3,4
145 # (TODO: add more?)
146 # IMPORTANT: when adding extra bits here it is CRITICALLY IMPORTANT
147 # to expand traptype to cope with the increased range
148
149 # use this in the simulator
150 class PIb:
151 INVALID = 33 # 1 for an invalid mem err
152 PERMERR = 35 # 1 for an permanent mem err
153 TM_BAD_THING = 42 # 1 for a TM Bad Thing type interrupt
154 FP = 43 # 1 if FP exception
155 ILLEG = 44 # 1 if illegal instruction (not doing hypervisor)
156 PRIV = 45 # 1 if privileged interrupt
157 TRAP = 46 # 1 if exception is "trap" type
158 ADR = 47 # 0 if SRR0 = address of instruction causing exception
159
160 # and use this in the HDL
161 class PI:
162 pass
163
164 botchify(PIb, PI)
165
166 # see traptype (and trap main_stage.py)
167 # IMPORTANT: when adding extra bits here it is CRITICALLY IMPORTANT
168 # to expand traptype to cope with the increased range
169
170 class TT:
171 FP = 1<<0
172 PRIV = 1<<1
173 TRAP = 1<<2
174 ADDR = 1<<3
175 EINT = 1<<4 # external interrupt
176 DEC = 1<<5 # decrement counter
177 MEMEXC = 1<<6 # LD/ST exception
178 ILLEG = 1<<7 # currently the max
179 # TODO: support for TM_BAD_THING (not included yet in trap main_stage.py)
180 size = 8 # MUST update this to contain the full number of Trap Types
181
182
183 # EXTRA3 3-bit subfield (spec)
184 class SPECb:
185 VEC = 0 # 1 for vector, 0 for scalar
186 MSB = 1 # augmented register number, MSB
187 LSB = 2 # augmented register number, LSB
188
189
190 SPEC_SIZE = 3
191 SPEC = SPECb
192 botchify(SPECb, SPEC, SPEC_SIZE-1)
193
194
195 # EXTRA field, with EXTRA2 subfield encoding
196 class EXTRA2b:
197 IDX0_VEC = 0
198 IDX0_MSB = 1
199 IDX1_VEC = 2
200 IDX1_MSB = 3
201 IDX2_VEC = 4
202 IDX2_MSB = 5
203 IDX3_VEC = 6
204 IDX3_MSB = 7
205 RESERVED = 8
206
207
208 EXTRA2_SIZE = 9
209 EXTRA2 = EXTRA2b
210 botchify(EXTRA2b, EXTRA2, EXTRA2_SIZE-1)
211
212
213 # EXTRA field, with EXTRA3 subfield encoding
214 class EXTRA3:
215 IDX0 = [0, 1, 2]
216 IDX1 = [3, 4, 5]
217 IDX2 = [6, 7, 8]
218
219
220 EXTRA3_SIZE = 9