(no commit message)
[libreriscv.git] / simple_v_extension / abridged_spec.mdwn
1
2 # Simple-V (Parallelism Extension Proposal) Specification (Abridged)
3
4 * Copyright (C) 2017, 2018, 2019 Luke Kenneth Casson Leighton
5 * Status: DRAFTv0.6
6 * Last edited: 27 jun 2019
7 * See: main [[specification]] and [[appendix]]
8
9 [[!toc ]]
10
11 # Introduction
12
13 Simple-V is a uniform parallelism API for RISC-V hardware that allows
14 the Program Counter to enter "sub-contexts" in which, ultimately, standard
15 RISC-V scalar opcodes are executed.
16
17 Regardless of the actual amount of hardware parallelism (if any is
18 added at all by the implementor),
19 in direct contrast to SIMD
20 hardware parallelism is entirely transparent to software.
21
22 The sub-context execution is "nested" in "re-entrant" form, in the
23 following order:
24
25 * Main standard RISC-V Program Counter (PC)
26 * VBLOCK sub-execution context (PCVBLK increments whilst PC is paused).
27 * VL element loops (STATE srcoffs and destoffs increment, PC and PCVBLK pause).
28 Predication bits may be individually applied per element.
29 * Optional SUBVL element loops (STATE svdestoffs increments, VL pauses).
30 Individual predicate bits from VL loops apply to the *group* of SUBVL
31 elements.
32
33 An ancillary "SVPrefix" Format (P48/P64) [[sv_prefix_proposal]] may run
34 its own VL/SUBVL "loops" and specifies its own Register and Predication
35 format on the 32-bit RV scalar opcode embedded within it.
36
37 The [[vblock_format]] specifies how VBLOCK sub-execution contexts
38 operate.
39
40 SV is never actually switched "off". VL or SUBVL may be equal to 1,
41 and Register or Predicate over-ride tables may be empty: under such
42 circumstances the behaviour becomes effectively identical to standard
43 RV execution, however SV is never truly actually "off".
44
45 Note: **there are *no* new vector opcodes**. The scheme works *entirely*
46 on hidden context that augments (nests) *scalar* RISC-V instructions.
47 Thus it may cover existing, future and custom scalar extensions, turning
48 all existing, all future and all custom scalar operations parallel,
49 without requiring any special (identical, parallel variant) opcodes to do so.
50
51 Associated proposals for use with 3D and HPC:
52
53 * [[specification/sv.setvl]] - replaces the use of CSRs to set VL (saves
54 32 bits)
55 * [[specification/mv.x]] - provides MV.swizzle and MVX (reg[rd] = reg[reg[rs]])
56 * [[ztrans_proposal]] - provides trigonometric and transcendental operations
57
58 # CSRs <a name="csrs"></a>
59
60 There are five CSRs, available in any privilege level:
61
62 * MVL (the Maximum Vector Length)
63 * VL (which has different characteristics from standard CSRs)
64 * SUBVL (effectively a kind of SIMD)
65 * STATE (containing copies of MVL, VL and SUBVL as well as context information)
66 * PCVBLK (the current operation being executed within a VBLOCK Group)
67
68 For Privilege Levels (trap handling) there are the following CSRs,
69 where x may be u, m, s or h for User, Machine, Supervisor or Hypervisor
70 Modes respectively:
71
72 * (x)ePCVBLK (a copy of the sub-execution Program Counter, that is relative
73 to the start of the current VBLOCK Group, set on a trap).
74 * (x)eSTATE (useful for saving and restoring during context switch,
75 and for providing fast transitions)
76
77 The u/m/s CSRs are treated and handled exactly like their (x)epc
78 equivalents. On entry to or exit from a privilege level, the contents
79 of its (x)eSTATE are swapped with STATE.
80
81 (x)EPCVBLK CSRs must be treated exactly like their corresponding (x)epc
82 equivalents. See VBLOCK section for details.
83
84 ## MAXVECTORLENGTH (MVL) <a name="mvl" />
85
86 MAXVECTORLENGTH is the same concept as MVL in RVV, except that it
87 is variable length and may be dynamically set. MVL is
88 however limited to the regfile bitwidth XLEN (1-32 for RV32,
89 1-64 for RV64 and so on).
90
91 ## Vector Length (VL) <a name="vl" />
92
93 VSETVL is slightly different from RVV. Similar to RVV, VL is set to be within
94 the range 1 <= VL <= MVL (where MVL in turn is limited to 1 <= MVL <= XLEN)
95
96 VL = rd = MIN(vlen, MVL)
97
98 where 1 <= MVL <= XLEN
99
100 ## SUBVL - Sub Vector Length
101
102 This is a "group by quantity" that effectively asks each iteration
103 of the hardware loop to load SUBVL elements of width elwidth at a
104 time. Effectively, SUBVL is like a SIMD multiplier: instead of just 1
105 operation issued, SUBVL operations are issued.
106
107 The main effect of SUBVL is that predication bits are applied per
108 **group**, rather than by individual element. Legal values are 1 to 4.
109 Illegal values raise an exception.
110
111 ## STATE
112
113 This is a standard CSR that contains sufficient information for a
114 full context save/restore. It contains (and permits setting of):
115
116 * MVL
117 * VL
118 * destoffs - the destination element offset of the current parallel
119 instruction being executed
120 * srcoffs - for twin-predication, the source element offset as well.
121 * SUBVL
122 * dsvoffs - the subvector destination element offset of the current
123 parallel instruction being executed
124
125 The format of the STATE CSR is as follows:
126
127 | (31..28) | (27..26) | (25..24) | (23..18) | (17..12) | (11..6) | (5...0) |
128 | -------- | -------- | -------- | -------- | -------- | ------- | ------- |
129 | rsvd | dsvoffs | subvl | destoffs | srcoffs | vl | maxvl |
130
131 The relationship between SUBVL and the subvl field is:
132
133 | SUBVL | (25..24) |
134 | ----- | -------- |
135 | 1 | 0b00 |
136 | 2 | 0b01 |
137 | 3 | 0b10 |
138 | 4 | 0b11 |
139
140 Notes:
141
142 * The entries are truncated to be within range. Attempts to set VL to
143 greater than MAXVL will truncate VL.
144 * Both VL and MAXVL are stored offset by one. 0b000000 represents VL=1,
145 0b000001 represents VL=2. This allows the full range 1 to XLEN instead
146 of 0 to only 63.
147
148 ## VL, MVL and SUBVL instruction aliases
149
150 This table contains pseudo-assembly instruction aliases. Note the
151 subtraction of 1 from the CSRRWI pseudo variants, to compensate for the
152 reduced range of the 5 bit immediate.
153
154 | alias | CSR |
155 | - | - |
156 | SETVL rd, rs | CSRRW VL, rd, rs |
157 | SETVLi rd, #n | CSRRWI VL, rd, #n-1 |
158 | GETVL rd | CSRRW VL, rd, x0 |
159 | SETMVL rd, rs | CSRRW MVL, rd, rs |
160 | SETMVLi rd, #n | CSRRWI MVL,rd, #n-1 |
161 | GETMVL rd | CSRRW MVL, rd, x0 |
162
163 Note: CSRRC and other bitsetting may still be used, they are however
164 not particularly useful (very obscure).
165
166 ## Register key-value (CAM) table <a name="regcsrtable" />
167
168 The purpose of the Register table is to mark which registers change
169 behaviour if used in a "Standard" (normally scalar) opcode.
170
171 [[!inline raw="yes" pages="simple_v_extension/reg_table_format" ]]
172
173 Fields:
174
175 * i/f is set to "1" to indicate that the redirection/tag entry is to
176 be applied to integer registers; 0 indicates that it is relevant to
177 floating-point registers.
178 * isvec indicates that the register (whether a src or dest) is to progress
179 incrementally forward on each loop iteration. this gives the "effect"
180 of vectorisation. isvec is zero indicates "do not progress", giving
181 the "effect" of that register being scalar.
182 * vew overrides the operation's default width. See table below
183 * regkey is the register which, if encountered in an op (as src or dest)
184 is to be "redirected"
185 * in the 16-bit format, regidx is the *actual* register to be used
186 for the operation (note that it is 7 bits wide)
187
188 | vew | bitwidth |
189 | --- | ------------------- |
190 | 00 | default (XLEN/FLEN) |
191 | 01 | 8 bit |
192 | 10 | 16 bit |
193 | 11 | 32 bit |
194
195 As the above table is a CAM (key-value store) it may be appropriate
196 (faster, less gates, implementation-wise) to expand it as follows:
197
198 [[!inline raw="yes" pages="simple_v_extension/reg_table" ]]
199
200 ## Predication Table <a name="predication_csr_table"></a>
201
202 The Predication Table is a key-value store indicating whether, if a
203 given destination register (integer or floating-point) is referred to
204 in an instruction, it is to be predicated. Like the Register table, it
205 is an indirect lookup that allows the RV opcodes to not need modification.
206
207 * regidx is the register that in combination with the
208 i/f flag, if that integer or floating-point register is referred to in a
209 (standard RV) instruction results in the lookup table being referenced
210 to find the predication mask to use for this operation.
211 * predidx is the *actual* (full, 7 bit) register to be used for the
212 predication mask.
213 * inv indicates that the predication mask bits are to be inverted
214 prior to use *without* actually modifying the contents of the
215 register from which those bits originated.
216 * zeroing is either 1 or 0, and if set to 1, the operation must
217 place zeros in any element position where the predication mask is
218 set to zero. If zeroing is set to 0, unpredicated elements *must*
219 be left alone (unaltered), even when elwidth != default.
220 * ffirst is a special mode that stops sequential element processing when
221 a data-dependent condition occurs, whether a trap or a conditional test.
222 The handling of each (trap or conditional test) is slightly different:
223 see Instruction sections for further details
224
225 [[!inline raw="yes" pages="simple_v_extension/pred_table_format" ]]
226
227 Pseudocode for predication:
228
229 [[!inline raw="yes" pages="simple_v_extension/pred_table" ]]
230 [[!inline raw="yes" pages="simple_v_extension/get_pred_value" ]]
231
232 ## Swizzle Table <a name="swizzle_table"></a>
233
234 The swizzle table is a key-value store that indicates (if a given
235 register is used, and SUBVL is 2, 3 or 4) that the sub-elements are to
236 be re-ordered according to the indices in the Swizzle format.
237 Like the Predication Table, it is an indirect lookup: use of a
238 source or destination register in any given operation, if that register
239 occurs in the table, "activates" sub-vector element swizzling for
240 that register. Note that the target is taken from the "Register Table"
241 (regidx).
242
243 Source vectors are free to have the swizzle indices point to the same
244 sub-vector element. However when using swizzling on destination vectors,
245 the swizzle **must** be a permutation (no two swizzle indices point to
246 the same sub-element). An illegal instruction exception must be raised
247 if this occurs.
248
249 [[!inline raw="yes" pages="simple_v_extension/swizzle_table_format" ]]
250
251 Simplified pseudocode example, when SUBVL=4 and swizzle is set on rd:
252
253 # default indices if no swizzling table entry present
254 x, y, z, w = 0, 1, 2, 3
255
256 # lookup swizzling in table for rd
257 if swizzle_table[rd].active:
258 swizzle = swizzle_table[rd].swizzle
259
260 # decode the swizzle table entry for rd
261 x = swizzle[0:1] # sub-element 0
262 y = swizzle[2:3] # sub-element 1
263 z = swizzle[4:5] # sub-element 2
264 w = swizzle[6:7] # sub-element 3
265
266 # redirect register numbers through Register Table
267 rd = int_vec[rd ].isvector ? int_vec[rd ].regidx : rd;
268 rs1 = int_vec[rs1].isvector ? int_vec[rs1].regidx : rs1;
269 rs2 = int_vec[rs2].isvector ? int_vec[rs2].regidx : rs2;
270
271 # loop on VL: SUBVL loop is unrolled (SUBVL=4)
272 for (i in 0; i < VL; i++)
273 ireg[rd+i*4+x] = OPERATION(ireg[rs1+i*4+0], ireg[rs2+i*4+0])
274 ireg[rd+i*4+y] = OPERATION(ireg[rs1+i*4+1], ireg[rs2+i*4+1])
275 ireg[rd+i*4+z] = OPERATION(ireg[rs1+i*4+2], ireg[rs2+i*4+2])
276 ireg[rd+i*4+w] = OPERATION(ireg[rs1+i*4+3], ireg[rs2+i*4+3])
277
278 For more information on swizzling, see the Khronos wiki page
279 <https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Swizzling>
280
281 ## Fail-on-First Mode <a name="ffirst-mode"></a>
282
283 ffirst is a special data-dependent predicate mode. There are two
284 variants: one is for faults: typically for LOAD/STORE operations, which
285 may encounter end of page faults during a series of operations. The other
286 variant is comparisons, and anything that returns "zero" or "fail". Note:
287 no instruction may operate in both fault mode and "condition fail" mode.
288
289 Fail on first critically relies on the program order being sequential,
290 even for elements. Out of order designs must *commit* in-order, and are
291 required to cancel elements at and beyond the fail point.
292
293 See [[appendix]] for more details on fail-on-first modes.
294
295 # Simplified Pseudo-code example
296
297 A greatly simplified example illustrating (just) the VL hardware for-loop
298 is as follows:
299
300 [[!inline raw="yes" pages="simple_v_extension/simple_add_example" ]]
301
302 Note that zeroing, elwidth handling, SUBVL and PCVLIW have all been
303 left out, for clarity. For examples on how to handle each, see
304 [[appendix]].
305
306 # Vector Block Format <a name="vliw-format"></a>
307
308 The Vector Block format uses the RISC-V 80-192 bit format from Section 1.5
309 of the RISC-V Spec. It permits an optional VL/MVL/SUBVL block, up to 4
310 16-bit (or 8 8-bit) Register Table entries, the same for Predicate Entries,
311 and the rest of the instruction may be either standard RV opcodes or the
312 SVPrefix opcodes ([[sv_prefix_proposal]])
313
314 [[!inline raw="yes" pages="simple_v_extension/vblock_format_table" ]]
315
316 For full details see ancillary resource: [[vblock_format]]
317
318 # Exceptions
319
320 Exception handling **MUST** be precise, in-order, and exactly
321 like Standard RISC-V as far as the instruction execution order is
322 concerned, regardless of whether it is PC, PCVBLK, VL or SUBVL that
323 is currently being incremented.
324
325 This.is extremely important. Exceptions
326 **MUST** be raised one at a time and in
327 strict sequential program order.
328
329 No instructions are permitted to be out of
330 sequence, therefore no exceptions are permitted to be, either.
331
332 # Hints
333
334 With Simple-V being capable of issuing *parallel* instructions where
335 rd=x0, the space for possible HINTs is expanded considerably. VL
336 could be used to indicate different hints. In addition, if predication
337 is set, the predication register itself could hypothetically be passed
338 in as a *parameter* to the HINT operation.
339
340 No specific hints are yet defined in Simple-V
341
342 # Subsets of RV functionality
343
344 It is permitted to only implement SVprefix and not the VBLOCK instruction
345 format option, and vice-versa. UNIX Platforms **MUST** raise illegal
346 instruction on seeing an unsupported VBLOCK or SVprefix opcode, so that
347 traps may emulate the format.
348
349 It is permitted in SVprefix to either not implement VL or not implement
350 SUBVL (see [[sv_prefix_proposal]] for full details. Again, UNIX Platforms
351 *MUST* raise illegal instruction on implementations that do not support
352 VL or SUBVL.
353
354 It is permitted to limit the size of either (or both) the register files
355 down to the original size of the standard RV architecture. However, below
356 the mandatory limits set in the RV standard will result in non-compliance
357 with the SV Specification.
358