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