move instructions to appendix
[libreriscv.git] / simple_v_extension / specification.mdwn
1 # Simple-V (Parallelism Extension Proposal) Specification
2
3 * Copyright (C) 2017, 2018, 2019 Luke Kenneth Casson Leighton
4 * Status: DRAFTv0.6
5 * Last edited: 21 jun 2019
6 * Ancillary resource: [[opcodes]]
7 * Ancillary resource: [[sv_prefix_proposal]]
8 * Ancillary resource: [[abridged_spec]]
9 * Ancillary resource: [[vblock_format]]
10 * Ancillary resource: [[appendix]]
11
12 With thanks to:
13
14 * Allen Baum
15 * Bruce Hoult
16 * comp.arch
17 * Jacob Bachmeyer
18 * Guy Lemurieux
19 * Jacob Lifshay
20 * Terje Mathisen
21 * The RISC-V Founders, without whom this all would not be possible.
22
23 [[!toc ]]
24
25 # Summary and Background: Rationale
26
27 Simple-V is a uniform parallelism API for RISC-V hardware that has several
28 unplanned side-effects including code-size reduction, expansion of
29 HINT space and more. The reason for
30 creating it is to provide a manageable way to turn a pre-existing design
31 into a parallel one, in a step-by-step incremental fashion, without adding any new opcodes, thus allowing
32 the implementor to focus on adding hardware where it is needed and necessary.
33 The primary target is for mobile-class 3D GPUs and VPUs, with secondary
34 goals being to reduce executable size (by extending the effectiveness of RV opcodes, RVC in particular) and reduce context-switch latency.
35
36 Critically: **No new instructions are added**. The parallelism (if any
37 is implemented) is implicitly added by tagging *standard* scalar registers
38 for redirection. When such a tagged register is used in any instruction,
39 it indicates that the PC shall **not** be incremented; instead a loop
40 is activated where *multiple* instructions are issued to the pipeline
41 (as determined by a length CSR), with contiguously incrementing register
42 numbers starting from the tagged register. When the last "element"
43 has been reached, only then is the PC permitted to move on. Thus
44 Simple-V effectively sits (slots) *in between* the instruction decode phase
45 and the ALU(s).
46
47 The barrier to entry with SV is therefore very low. The minimum
48 compliant implementation is software-emulation (traps), requiring
49 only the CSRs and CSR tables, and that an exception be thrown if an
50 instruction's registers are detected to have been tagged. The looping
51 that would otherwise be done in hardware is thus carried out in software,
52 instead. Whilst much slower, it is "compliant" with the SV specification,
53 and may be suited for implementation in RV32E and also in situations
54 where the implementor wishes to focus on certain aspects of SV, without
55 unnecessary time and resources into the silicon, whilst also conforming
56 strictly with the API. A good area to punt to software would be the
57 polymorphic element width capability for example.
58
59 Hardware Parallelism, if any, is therefore added at the implementor's
60 discretion to turn what would otherwise be a sequential loop into a
61 parallel one.
62
63 To emphasise that clearly: Simple-V (SV) is *not*:
64
65 * A SIMD system
66 * A SIMT system
67 * A Vectorisation Microarchitecture
68 * A microarchitecture of any specific kind
69 * A mandary parallel processor microarchitecture of any kind
70 * A supercomputer extension
71
72 SV does **not** tell implementors how or even if they should implement
73 parallelism: it is a hardware "API" (Application Programming Interface)
74 that, if implemented, presents a uniform and consistent way to *express*
75 parallelism, at the same time leaving the choice of if, how, how much,
76 when and whether to parallelise operations **entirely to the implementor**.
77
78 # Basic Operation
79
80 The principle of SV is as follows:
81
82 * Standard RV instructions are "prefixed" (extended) through a 48/64
83 bit format (single instruction option) or a variable
84 length VLIW-like prefix (multi or "grouped" option).
85 * The prefix(es) indicate which registers are "tagged" as
86 "vectorised". Predicates can also be added, and element widths
87 overridden on any src or dest register.
88 * A "Vector Length" CSR is set, indicating the span of any future
89 "parallel" operations.
90 * If any operation (a **scalar** standard RV opcode) uses a register
91 that has been so "marked" ("tagged"), a hardware "macro-unrolling loop"
92 is activated, of length VL, that effectively issues **multiple**
93 identical instructions using contiguous sequentially-incrementing
94 register numbers, based on the "tags".
95 * **Whether they be executed sequentially or in parallel or a
96 mixture of both or punted to software-emulation in a trap handler
97 is entirely up to the implementor**.
98
99 In this way an entire scalar algorithm may be vectorised with
100 the minimum of modification to the hardware and to compiler toolchains.
101
102 To reiterate: **There are *no* new opcodes**. The scheme works *entirely*
103 on hidden context that augments *scalar* RISCV instructions.
104
105 # CSRs <a name="csrs"></a>
106
107 * An optional "reshaping" CSR key-value table which remaps from a 1D
108 linear shape to 2D or 3D, including full transposition.
109
110 There are five additional CSRs, available in any privilege level:
111
112 * MVL (the Maximum Vector Length)
113 * VL (which has different characteristics from standard CSRs)
114 * SUBVL (effectively a kind of SIMD)
115 * STATE (containing copies of MVL, VL and SUBVL as well as context information)
116 * PCVBLK (the current operation being executed within a VBLOCK Group)
117
118 For User Mode there are the following CSRs:
119
120 * uePCVBLK (a copy of the sub-execution Program Counter, that is relative
121 to the start of the current VBLOCK Group, set on a trap).
122 * ueSTATE (useful for saving and restoring during context switch,
123 and for providing fast transitions)
124
125 There are also two additional CSRs for Supervisor-Mode:
126
127 * sePCVBLK
128 * seSTATE
129
130 And likewise for M-Mode:
131
132 * mePCVBLK
133 * meSTATE
134
135 The u/m/s CSRs are treated and handled exactly like their (x)epc
136 equivalents. On entry to or exit from a privilege level, the contents of its (x)eSTATE are swapped with STATE.
137
138 Thus for example, a User Mode trap will end up swapping STATE and ueSTATE
139 (on both entry and exit), allowing User Mode traps to have their own
140 Vectorisation Context set up, separated from and unaffected by normal
141 user applications. If an M Mode trap occurs in the middle of the U Mode trap, STATE is swapped with meSTATE, and restored on exit: the U Mode trap continues unaware that the M Mode trap even occurred.
142
143 Likewise, Supervisor Mode may perform context-switches, safe in the
144 knowledge that its Vectorisation State is unaffected by User Mode.
145
146 The access pattern for these groups of CSRs in each mode follows the
147 same pattern for other CSRs that have M-Mode and S-Mode "mirrors":
148
149 * In M-Mode, the S-Mode and U-Mode CSRs are separate and distinct.
150 * In S-Mode, accessing and changing of the M-Mode CSRs is transparently
151 identical
152 to changing the S-Mode CSRs. Accessing and changing the U-Mode
153 CSRs is permitted.
154 * In U-Mode, accessing and changing of the S-Mode and U-Mode CSRs
155 is prohibited.
156
157 An interesting side effect of SV STATE being
158 separate and distinct in S Mode
159 is that
160 Vectorised saving of an entire register file to the stack is a single
161 instruction (through accidental provision of LOAD-MULTI semantics). If the
162 SVPrefix P64-LD-type format is used, LOAD-MULTI may even be done with a
163 single standalone 64 bit opcode (P64 may set up SUBVL, VL and MVL from an
164 immediate field, to cover the full regfile). It can even be predicated, which opens up some very
165 interesting possibilities.
166
167 (x)EPCVBLK CSRs must be treated exactly like their corresponding (x)epc
168 equivalents. See VBLOCK section for details.
169
170 ## MAXVECTORLENGTH (MVL) <a name="mvl" />
171
172 MAXVECTORLENGTH is the same concept as MVL in RVV, except that it
173 is variable length and may be dynamically set. MVL is
174 however limited to the regfile bitwidth XLEN (1-32 for RV32,
175 1-64 for RV64 and so on).
176
177 The reason for setting this limit is so that predication registers, when
178 marked as such, may fit into a single register as opposed to fanning
179 out over several registers. This keeps the hardware implementation a
180 little simpler.
181
182 The other important factor to note is that the actual MVL is internally
183 stored **offset by one**, so that it can fit into only 6 bits (for RV64)
184 and still cover a range up to XLEN bits. Attempts to set MVL to zero will
185 return an exception. This is expressed more clearly in the "pseudocode"
186 section, where there are subtle differences between CSRRW and CSRRWI.
187
188 ## Vector Length (VL) <a name="vl" />
189
190 VSETVL is slightly different from RVV. Similar to RVV, VL is set to be within
191 the range 1 <= VL <= MVL (where MVL in turn is limited to 1 <= MVL <= XLEN)
192
193 VL = rd = MIN(vlen, MVL)
194
195 where 1 <= MVL <= XLEN
196
197 However just like MVL it is important to note that the range for VL has
198 subtle design implications, covered in the "CSR pseudocode" section
199
200 The fixed (specific) setting of VL allows vector LOAD/STORE to be used
201 to switch the entire bank of registers using a single instruction (see
202 Appendix, "Context Switch Example"). The reason for limiting VL to XLEN
203 is down to the fact that predication bits fit into a single register of
204 length XLEN bits.
205
206 The second and most important change is that, within the limits set by
207 MVL, the value passed in **must** be set in VL (and in the
208 destination register).
209
210 This has implication for the microarchitecture, as VL is required to be
211 set (limits from MVL notwithstanding) to the actual value
212 requested. RVV has the option to set VL to an arbitrary value that suits
213 the conditions and the micro-architecture: SV does *not* permit this.
214
215 The reason is so that if SV is to be used for a context-switch or as a
216 substitute for LOAD/STORE-Multiple, the operation can be done with only
217 2-3 instructions (setup of the CSRs, VSETVL x0, x0, #{regfilelen-1},
218 single LD/ST operation). If VL does *not* get set to the register file
219 length when VSETVL is called, then a software-loop would be needed.
220 To avoid this need, VL *must* be set to exactly what is requested
221 (limits notwithstanding).
222
223 Therefore, in turn, unlike RVV, implementors *must* provide
224 pseudo-parallelism (using sequential loops in hardware) if actual
225 hardware-parallelism in the ALUs is not deployed. A hybrid is also
226 permitted (as used in Broadcom's VideoCore-IV) however this must be
227 *entirely* transparent to the ISA.
228
229 The third change is that VSETVL is implemented as a CSR, where the
230 behaviour of CSRRW (and CSRRWI) must be changed to specifically store
231 the *new* value in the destination register, **not** the old value.
232 Where context-load/save is to be implemented in the usual fashion
233 by using a single CSRRW instruction to obtain the old value, the
234 *secondary* CSR must be used (STATE). This CSR by contrast behaves
235 exactly as standard CSRs, and contains more than just VL.
236
237 One interesting side-effect of using CSRRWI to set VL is that this
238 may be done with a single instruction, useful particularly for a
239 context-load/save. There are however limitations: CSRWI's immediate
240 is limited to 0-31 (representing VL=1-32).
241
242 Note that when VL is set to 1, vector operations cease (but not subvector
243 operations: that requires setting SUBVL=1) the hardware loop is reduced
244 to a single element: scalar operations. This is in effect the default,
245 normal operating mode. However it is important to appreciate that this
246 does **not** result in the Register table or SUBVL being disabled. Only
247 when the Register table is empty (P48/64 prefix fields notwithstanding)
248 would SV have no effect.
249
250 ## SUBVL - Sub Vector Length
251
252 This is a "group by quantity" that effectivrly asks each iteration
253 of the hardware loop to load SUBVL elements of width elwidth at a
254 time. Effectively, SUBVL is like a SIMD multiplier: instead of just 1
255 operation issued, SUBVL operations are issued.
256
257 Another way to view SUBVL is that each element in the VL length vector is
258 now SUBVL times elwidth bits in length and now comprises SUBVL discrete
259 sub operations. An inner SUBVL for-loop within a VL for-loop in effect,
260 with the sub-element increased every time in the innermost loop. This
261 is best illustrated in the (simplified) pseudocode example, later.
262
263 The primary use case for SUBVL is for 3D FP Vectors. A Vector of 3D
264 coordinates X,Y,Z for example may be loaded and multiplied the stored, per
265 VL element iteration, rather than having to set VL to three times larger.
266
267 Legal values are 1, 2, 3 and 4 (and the STATE CSR must hold the 2 bit
268 values 0b00 thru 0b11 to represent them).
269
270 Setting this CSR to 0 must raise an exception. Setting it to a value
271 greater than 4 likewise.
272
273 The main effect of SUBVL is that predication bits are applied per
274 **group**, rather than by individual element.
275
276 This saves a not insignificant number of instructions when handling 3D
277 vectors, as otherwise a much longer predicate mask would have to be set
278 up with regularly-repeated bit patterns.
279
280 See SUBVL Pseudocode illustration for details.
281
282 ## STATE
283
284 This is a standard CSR that contains sufficient information for a
285 full context save/restore. It contains (and permits setting of):
286
287 * MVL
288 * VL
289 * destoffs - the destination element offset of the current parallel
290 instruction being executed
291 * srcoffs - for twin-predication, the source element offset as well.
292 * SUBVL
293 * svdestoffs - the subvector destination element offset of the current
294 parallel instruction being executed
295 * svsrcoffs - for twin-predication, the subvector source element offset
296 as well.
297
298 Interestingly STATE may hypothetically also be modified to make the
299 immediately-following instruction to skip a certain number of elements,
300 by playing with destoffs and srcoffs (and the subvector offsets as well)
301
302 Setting destoffs and srcoffs is realistically intended for saving state
303 so that exceptions (page faults in particular) may be serviced and the
304 hardware-loop that was being executed at the time of the trap, from
305 user-mode (or Supervisor-mode), may be returned to and continued from
306 exactly where it left off. The reason why this works is because setting
307 User-Mode STATE will not change (not be used) in M-Mode or S-Mode (and
308 is entirely why M-Mode and S-Mode have their own STATE CSRs, meSTATE
309 and seSTATE).
310
311 The format of the STATE CSR is as follows:
312
313 | (29..28 | (27..26) | (25..24) | (23..18) | (17..12) | (11..6) | (5...0) |
314 | ------- | -------- | -------- | -------- | -------- | ------- | ------- |
315 | dsvoffs | ssvoffs | subvl | destoffs | srcoffs | vl | maxvl |
316
317 When setting this CSR, the following characteristics will be enforced:
318
319 * **MAXVL** will be truncated (after offset) to be within the range 1 to XLEN
320 * **VL** will be truncated (after offset) to be within the range 1 to MAXVL
321 * **SUBVL** which sets a SIMD-like quantity, has only 4 values so there
322 are no changes needed
323 * **srcoffs** will be truncated to be within the range 0 to VL-1
324 * **destoffs** will be truncated to be within the range 0 to VL-1
325 * **ssvoffs** will be truncated to be within the range 0 to SUBVL-1
326 * **dsvoffs** will be truncated to be within the range 0 to SUBVL-1
327
328 NOTE: if the following instruction is not a twin predicated instruction,
329 and destoffs or dsvoffs has been set to non-zero, subsequent execution
330 behaviour is undefined. **USE WITH CARE**.
331
332 ### Hardware rules for when to increment STATE offsets
333
334 The offsets inside STATE are like the indices in a loop, except
335 in hardware. They are also partially (conceptually) similar to a
336 "sub-execution Program Counter". As such, and to allow proper context
337 switching and to define correct exception behaviour, the following rules
338 must be observed:
339
340 * When the VL CSR is set, srcoffs and destoffs are reset to zero.
341 * Each instruction that contains a "tagged" register shall start
342 execution at the *current* value of srcoffs (and destoffs in the case
343 of twin predication)
344 * Unpredicated bits (in nonzeroing mode) shall cause the element operation
345 to skip, incrementing the srcoffs (or destoffs)
346 * On execution of an element operation, Exceptions shall **NOT** cause
347 srcoffs or destoffs to increment.
348 * On completion of the full Vector Loop (srcoffs = VL-1 or destoffs =
349 VL-1 after the last element is executed), both srcoffs and destoffs
350 shall be reset to zero.
351
352 This latter is why srcoffs and destoffs may be stored as values from
353 0 to XLEN-1 in the STATE CSR, because as loop indices they refer to
354 elements. srcoffs and destoffs never need to be set to VL: their maximum
355 operating values are limited to 0 to VL-1.
356
357 The same corresponding rules apply to SUBVL, svsrcoffs and svdestoffs.
358
359 ## MVL and VL Pseudocode
360
361 The pseudo-code for get and set of VL and MVL use the following internal
362 functions as follows:
363
364 set_mvl_csr(value, rd):
365 regs[rd] = STATE.MVL
366 STATE.MVL = MIN(value, STATE.MVL)
367
368 get_mvl_csr(rd):
369 regs[rd] = STATE.VL
370
371 set_vl_csr(value, rd):
372 STATE.VL = MIN(value, STATE.MVL)
373 regs[rd] = STATE.VL # yes returning the new value NOT the old CSR
374 return STATE.VL
375
376 get_vl_csr(rd):
377 regs[rd] = STATE.VL
378 return STATE.VL
379
380 Note that where setting MVL behaves as a normal CSR (returns the old
381 value), unlike standard CSR behaviour, setting VL will return the **new**
382 value of VL **not** the old one.
383
384 For CSRRWI, the range of the immediate is restricted to 5 bits. In order to
385 maximise the effectiveness, an immediate of 0 is used to set VL=1,
386 an immediate of 1 is used to set VL=2 and so on:
387
388 CSRRWI_Set_MVL(value):
389 set_mvl_csr(value+1, x0)
390
391 CSRRWI_Set_VL(value):
392 set_vl_csr(value+1, x0)
393
394 However for CSRRW the following pseudocode is used for MVL and VL,
395 where setting the value to zero will cause an exception to be raised.
396 The reason is that if VL or MVL are set to zero, the STATE CSR is
397 not capable of storing that value.
398
399 CSRRW_Set_MVL(rs1, rd):
400 value = regs[rs1]
401 if value == 0 or value > XLEN:
402 raise Exception
403 set_mvl_csr(value, rd)
404
405 CSRRW_Set_VL(rs1, rd):
406 value = regs[rs1]
407 if value == 0 or value > XLEN:
408 raise Exception
409 set_vl_csr(value, rd)
410
411 In this way, when CSRRW is utilised with a loop variable, the value
412 that goes into VL (and into the destination register) may be used
413 in an instruction-minimal fashion:
414
415 CSRvect1 = {type: F, key: a3, val: a3, elwidth: dflt}
416 CSRvect2 = {type: F, key: a7, val: a7, elwidth: dflt}
417 CSRRWI MVL, 3 # sets MVL == **4** (not 3)
418 j zerotest # in case loop counter a0 already 0
419 loop:
420 CSRRW VL, t0, a0 # vl = t0 = min(mvl, a0)
421 ld a3, a1 # load 4 registers a3-6 from x
422 slli t1, t0, 3 # t1 = vl * 8 (in bytes)
423 ld a7, a2 # load 4 registers a7-10 from y
424 add a1, a1, t1 # increment pointer to x by vl*8
425 fmadd a7, a3, fa0, a7 # v1 += v0 * fa0 (y = a * x + y)
426 sub a0, a0, t0 # n -= vl (t0)
427 st a7, a2 # store 4 registers a7-10 to y
428 add a2, a2, t1 # increment pointer to y by vl*8
429 zerotest:
430 bnez a0, loop # repeat if n != 0
431
432 With the STATE CSR, just like with CSRRWI, in order to maximise the
433 utilisation of the limited bitspace, "000000" in binary represents
434 VL==1, "00001" represents VL==2 and so on (likewise for MVL):
435
436 CSRRW_Set_SV_STATE(rs1, rd):
437 value = regs[rs1]
438 get_state_csr(rd)
439 STATE.MVL = set_mvl_csr(value[11:6]+1)
440 STATE.VL = set_vl_csr(value[5:0]+1)
441 STATE.destoffs = value[23:18]>>18
442 STATE.srcoffs = value[23:18]>>12
443
444 get_state_csr(rd):
445 regs[rd] = (STATE.MVL-1) | (STATE.VL-1)<<6 | (STATE.srcoffs)<<12 |
446 (STATE.destoffs)<<18
447 return regs[rd]
448
449 In both cases, whilst CSR read of VL and MVL return the exact values
450 of VL and MVL respectively, reading and writing the STATE CSR returns
451 those values **minus one**. This is absolutely critical to implement
452 if the STATE CSR is to be used for fast context-switching.
453
454 ## VL, MVL and SUBVL instruction aliases
455
456 This table contains pseudo-assembly instruction aliases. Note the
457 subtraction of 1 from the CSRRWI pseudo variants, to compensate for the
458 reduced range of the 5 bit immediate.
459
460 | alias | CSR |
461 | - | - |
462 | SETVL rd, rs | CSRRW VL, rd, rs |
463 | SETVLi rd, #n | CSRRWI VL, rd, #n-1 |
464 | GETVL rd | CSRRW VL, rd, x0 |
465 | SETMVL rd, rs | CSRRW MVL, rd, rs |
466 | SETMVLi rd, #n | CSRRWI MVL,rd, #n-1 |
467 | GETMVL rd | CSRRW MVL, rd, x0 |
468
469 Note: CSRRC and other bitsetting may still be used, they are however not particularly useful (very obscure).
470
471 ## Register key-value (CAM) table <a name="regcsrtable" />
472
473 *NOTE: in prior versions of SV, this table used to be writable and
474 accessible via CSRs. It is now stored in the VBLOCK instruction format. Note
475 that this table does *not* get applied to the SVPrefix P48/64 format,
476 only to scalar opcodes*
477
478 The purpose of the Register table is three-fold:
479
480 * To mark integer and floating-point registers as requiring "redirection"
481 if it is ever used as a source or destination in any given operation.
482 This involves a level of indirection through a 5-to-7-bit lookup table,
483 such that **unmodified** operands with 5 bits (3 for some RVC ops) may
484 access up to **128** registers.
485 * To indicate whether, after redirection through the lookup table, the
486 register is a vector (or remains a scalar).
487 * To over-ride the implicit or explicit bitwidth that the operation would
488 normally give the register.
489
490 Note: clearly, if an RVC operation uses a 3 bit spec'd register (x8-x15)
491 and the Register table contains entried that only refer to registerd
492 x1-x14 or x16-x31, such operations will *never* activate the VL hardware
493 loop!
494
495 If however the (16 bit) Register table does contain such an entry (x8-x15
496 or x2 in the case of LWSP), that src or dest reg may be redirected
497 anywhere to the *full* 128 register range. Thus, RVC becomes far more
498 powerful and has many more opportunities to reduce code size that in
499 Standard RV32/RV64 executables.
500
501 16 bit format:
502
503 | RegCAM | | 15 | (14..8) | 7 | (6..5) | (4..0) |
504 | ------ | | - | - | - | ------ | ------- |
505 | 0 | | isvec0 | regidx0 | i/f | vew0 | regkey |
506 | 1 | | isvec1 | regidx1 | i/f | vew1 | regkey |
507 | .. | | isvec.. | regidx.. | i/f | vew.. | regkey |
508 | 15 | | isvec15 | regidx15 | i/f | vew15 | regkey |
509
510 8 bit format:
511
512 | RegCAM | | 7 | (6..5) | (4..0) |
513 | ------ | | - | ------ | ------- |
514 | 0 | | i/f | vew0 | regnum |
515
516 Showing the mapping (relationship) between 8-bit and 16-bit format:
517
518 | RegCAM | 15 | (14..8) | 7 | (6..5) | (4..0) |
519 | ------ | - | - | - | ------ | ------- |
520 | 0 | isvec=1 | regnum0<<2 | i/f | vew0 | regnum0 |
521 | 1 | isvec=1 | regnum1<<2 | i/f | vew1 | regnum1 |
522 | 2 | isvec=1 | regnum2<<2 | i/f | vew2 | regnum2 |
523 | 3 | isvec=1 | regnum2<<2 | i/f | vew3 | regnum3 |
524
525 i/f is set to "1" to indicate that the redirection/tag entry is to
526 be applied to integer registers; 0 indicates that it is relevant to
527 floating-point registers.
528
529 The 8 bit format is used for a much more compact expression. "isvec"
530 is implicit and, similar to [[sv-prefix-proposal]], the target vector
531 is "regnum<<2", implicitly. Contrast this with the 16-bit format where
532 the target vector is *explicitly* named in bits 8 to 14, and bit 15 may
533 optionally set "scalar" mode.
534
535 Note that whilst SVPrefix adds one extra bit to each of rd, rs1 etc.,
536 and thus the "vector" mode need only shift the (6 bit) regnum by 1 to
537 get the actual (7 bit) register number to use, there is not enough space
538 in the 8 bit format (only 5 bits for regnum) so "regnum<<2" is required.
539
540 vew has the following meanings, indicating that the instruction's
541 operand size is "over-ridden" in a polymorphic fashion:
542
543 | vew | bitwidth |
544 | --- | ------------------- |
545 | 00 | default (XLEN/FLEN) |
546 | 01 | 8 bit |
547 | 10 | 16 bit |
548 | 11 | 32 bit |
549
550 As the above table is a CAM (key-value store) it may be appropriate
551 (faster, implementation-wise) to expand it as follows:
552
553 struct vectorised fp_vec[32], int_vec[32];
554
555 for (i = 0; i < len; i++) // from VBLOCK Format
556 tb = int_vec if CSRvec[i].type == 0 else fp_vec
557 idx = CSRvec[i].regkey // INT/FP src/dst reg in opcode
558 tb[idx].elwidth = CSRvec[i].elwidth
559 tb[idx].regidx = CSRvec[i].regidx // indirection
560 tb[idx].isvector = CSRvec[i].isvector // 0=scalar
561
562 ## Predication Table <a name="predication_csr_table"></a>
563
564 *NOTE: in prior versions of SV, this table used to be writable and
565 accessible via CSRs. It is now stored in the VBLOCK instruction format.
566 The table does **not** apply to SVPrefix opcodes*
567
568 The Predication Table is a key-value store indicating whether, if a
569 given destination register (integer or floating-point) is referred to
570 in an instruction, it is to be predicated. Like the Register table, it
571 is an indirect lookup that allows the RV opcodes to not need modification.
572
573 It is particularly important to note
574 that the *actual* register used can be *different* from the one that is
575 in the instruction, due to the redirection through the lookup table.
576
577 * regidx is the register that in combination with the
578 i/f flag, if that integer or floating-point register is referred to in a
579 (standard RV) instruction results in the lookup table being referenced
580 to find the predication mask to use for this operation.
581 * predidx is the *actual* (full, 7 bit) register to be used for the
582 predication mask.
583 * inv indicates that the predication mask bits are to be inverted
584 prior to use *without* actually modifying the contents of the
585 register from which those bits originated.
586 * zeroing is either 1 or 0, and if set to 1, the operation must
587 place zeros in any element position where the predication mask is
588 set to zero. If zeroing is set to 0, unpredicated elements *must*
589 be left alone. Some microarchitectures may choose to interpret
590 this as skipping the operation entirely. Others which wish to
591 stick more closely to a SIMD architecture may choose instead to
592 interpret unpredicated elements as an internal "copy element"
593 operation (which would be necessary in SIMD microarchitectures
594 that perform register-renaming)
595 * ffirst is a special mode that stops sequential element processing when
596 a data-dependent condition occurs, whether a trap or a conditional test.
597 The handling of each (trap or conditional test) is slightly different:
598 see Instruction sections for further details
599
600 16 bit format:
601
602 | PrCSR | (15..11) | 10 | 9 | 8 | (7..1) | 0 |
603 | ----- | - | - | - | - | ------- | ------- |
604 | 0 | predidx | zero0 | inv0 | i/f | regidx | ffirst0 |
605 | 1 | predidx | zero1 | inv1 | i/f | regidx | ffirst1 |
606 | 2 | predidx | zero2 | inv2 | i/f | regidx | ffirst2 |
607 | 3 | predidx | zero3 | inv3 | i/f | regidx | ffirst3 |
608
609 Note: predidx=x0, zero=1, inv=1 is a RESERVED encoding. Its use must
610 generate an illegal instruction trap.
611
612 8 bit format:
613
614 | PrCSR | 7 | 6 | 5 | (4..0) |
615 | ----- | - | - | - | ------- |
616 | 0 | zero0 | inv0 | i/f | regnum |
617
618 The 8 bit format is a compact and less expressive variant of the full
619 16 bit format. Using the 8 bit formatis very different: the predicate
620 register to use is implicit, and numbering begins inplicitly from x9. The
621 regnum is still used to "activate" predication, in the same fashion as
622 described above.
623
624 Thus if we map from 8 to 16 bit format, the table becomes:
625
626 | PrCSR | (15..11) | 10 | 9 | 8 | (7..1) | 0 |
627 | ----- | - | - | - | - | ------- | ------- |
628 | 0 | x9 | zero0 | inv0 | i/f | regnum | ff=0 |
629 | 1 | x10 | zero1 | inv1 | i/f | regnum | ff=0 |
630 | 2 | x11 | zero2 | inv2 | i/f | regnum | ff=0 |
631 | 3 | x12 | zero3 | inv3 | i/f | regnum | ff=0 |
632
633 The 16 bit Predication CSR Table is a key-value store, so
634 implementation-wise it will be faster to turn the table around (maintain
635 topologically equivalent state):
636
637 struct pred {
638 bool zero; // zeroing
639 bool inv; // register at predidx is inverted
640 bool ffirst; // fail-on-first
641 bool enabled; // use this to tell if the table-entry is active
642 int predidx; // redirection: actual int register to use
643 }
644
645 struct pred fp_pred_reg[32]; // 64 in future (bank=1)
646 struct pred int_pred_reg[32]; // 64 in future (bank=1)
647
648 for (i = 0; i < len; i++) // number of Predication entries in VBLOCK
649 tb = int_pred_reg if PredicateTable[i].type == 0 else fp_pred_reg;
650 idx = PredicateTable[i].regidx
651 tb[idx].zero = CSRpred[i].zero
652 tb[idx].inv = CSRpred[i].inv
653 tb[idx].ffirst = CSRpred[i].ffirst
654 tb[idx].predidx = CSRpred[i].predidx
655 tb[idx].enabled = true
656
657 So when an operation is to be predicated, it is the internal state that
658 is used. In Section 6.4.2 of Hwacha's Manual (EECS-2015-262) the following
659 pseudo-code for operations is given, where p is the explicit (direct)
660 reference to the predication register to be used:
661
662 for (int i=0; i<vl; ++i)
663 if ([!]preg[p][i])
664 (d ? vreg[rd][i] : sreg[rd]) =
665 iop(s1 ? vreg[rs1][i] : sreg[rs1],
666 s2 ? vreg[rs2][i] : sreg[rs2]); // for insts with 2 inputs
667
668 This instead becomes an *indirect* reference using the *internal* state
669 table generated from the Predication CSR key-value store, which is used
670 as follows.
671
672 if type(iop) == INT:
673 preg = int_pred_reg[rd]
674 else:
675 preg = fp_pred_reg[rd]
676
677 for (int i=0; i<vl; ++i)
678 predicate, zeroing = get_pred_val(type(iop) == INT, rd):
679 if (predicate && (1<<i))
680 result = iop(s1 ? regfile[rs1+i] : regfile[rs1],
681 s2 ? regfile[rs2+i] : regfile[rs2]);
682 (d ? regfile[rd+i] : regfile[rd]) = result
683 if preg.ffirst and result == 0:
684 VL = i # result was zero, end loop early, return VL
685 return
686 else if (zeroing)
687 (d ? regfile[rd+i] : regfile[rd]) = 0
688
689 Note:
690
691 * d, s1 and s2 are booleans indicating whether destination,
692 source1 and source2 are vector or scalar
693 * key-value CSR-redirection of rd, rs1 and rs2 have NOT been included
694 above, for clarity. rd, rs1 and rs2 all also must ALSO go through
695 register-level redirection (from the Register table) if they are
696 vectors.
697 * fail-on-first mode stops execution early whenever an operation
698 returns a zero value. floating-point results count both
699 positive-zero as well as negative-zero as "fail".
700
701 If written as a function, obtaining the predication mask (and whether
702 zeroing takes place) may be done as follows:
703
704 def get_pred_val(bool is_fp_op, int reg):
705 tb = int_reg if is_fp_op else fp_reg
706 if (!tb[reg].enabled):
707 return ~0x0, False // all enabled; no zeroing
708 tb = int_pred if is_fp_op else fp_pred
709 if (!tb[reg].enabled):
710 return ~0x0, False // all enabled; no zeroing
711 predidx = tb[reg].predidx // redirection occurs HERE
712 predicate = intreg[predidx] // actual predicate HERE
713 if (tb[reg].inv):
714 predicate = ~predicate // invert ALL bits
715 return predicate, tb[reg].zero
716
717 Note here, critically, that **only** if the register is marked
718 in its **register** table entry as being "active" does the testing
719 proceed further to check if the **predicate** table entry is
720 also active.
721
722 Note also that this is in direct contrast to branch operations
723 for the storage of comparisions: in these specific circumstances
724 the requirement for there to be an active *register* entry
725 is removed.
726
727 ## Fail-on-First Mode <a name="ffirst-mode"></a>
728
729 ffirst is a special data-dependent predicate mode. There are two
730 variants: one is for faults: typically for LOAD/STORE operations,
731 which may encounter end of page faults during a series of operations.
732 The other variant is comparisons such as FEQ (or the augmented behaviour
733 of Branch), and any operation that returns a result of zero (whether
734 integer or floating-point). In the FP case, this includes negative-zero.
735
736 Note that the execution order must "appear" to be sequential for ffirst
737 mode to work correctly. An in-order architecture must execute the element
738 operations in sequence, whilst an out-of-order architecture must *commit*
739 the element operations in sequence (giving the appearance of in-order
740 execution).
741
742 Note also, that if ffirst mode is needed without predication, a special
743 "always-on" Predicate Table Entry may be constructed by setting
744 inverse-on and using x0 as the predicate register. This
745 will have the effect of creating a mask of all ones, allowing ffirst
746 to be set.
747
748 ### Fail-on-first traps
749
750 Except for the first element, ffault stops sequential element processing
751 when a trap occurs. The first element is treated normally (as if ffirst
752 is clear). Should any subsequent element instruction require a trap,
753 instead it and subsequent indexed elements are ignored (or cancelled in
754 out-of-order designs), and VL is set to the *last* instruction that did
755 not take the trap.
756
757 Note that predicated-out elements (where the predicate mask bit is zero)
758 are clearly excluded (i.e. the trap will not occur). However, note that
759 the loop still had to test the predicate bit: thus on return,
760 VL is set to include elements that did not take the trap *and* includes
761 the elements that were predicated (masked) out (not tested up to the
762 point where the trap occurred).
763
764 If SUBVL is being used (SUBVL!=1), the first *sub-group* of elements
765 will cause a trap as normal (as if ffirst is not set); subsequently,
766 the trap must not occur in the *sub-group* of elements. SUBVL will **NOT**
767 be modified.
768
769 Given that predication bits apply to SUBVL groups, the same rules apply
770 to predicated-out (masked-out) sub-groups in calculating the value that VL
771 is set to.
772
773 ### Fail-on-first conditional tests
774
775 ffault stops sequential element conditional testing on the first element result
776 being zero. VL is set to the number of elements that were processed before
777 the fail-condition was encountered.
778
779 Note that just as with traps, if SUBVL!=1, the first of any of the *sub-group*
780 will cause the processing to end, and, even if there were elements within
781 the *sub-group* that passed the test, that sub-group is still (entirely)
782 excluded from the count (from setting VL). i.e. VL is set to the total
783 number of *sub-groups* that had no fail-condition up until execution was
784 stopped.
785
786 Note again that, just as with traps, predicated-out (masked-out) elements
787 are included in the count leading up to the fail-condition, even though they
788 were not tested.
789
790 The pseudo-code for Predication makes this clearer and simpler than it is
791 in words (the loop ends, VL is set to the current element index, "i").
792
793 ## REMAP CSR <a name="remap" />
794
795 (Note: both the REMAP and SHAPE sections are best read after the
796 rest of the document has been read)
797
798 There is one 32-bit CSR which may be used to indicate which registers,
799 if used in any operation, must be "reshaped" (re-mapped) from a linear
800 form to a 2D or 3D transposed form, or "offset" to permit arbitrary
801 access to elements within a register.
802
803 The 32-bit REMAP CSR may reshape up to 3 registers:
804
805 | 29..28 | 27..26 | 25..24 | 23 | 22..16 | 15 | 14..8 | 7 | 6..0 |
806 | ------ | ------ | ------ | -- | ------- | -- | ------- | -- | ------- |
807 | shape2 | shape1 | shape0 | 0 | regidx2 | 0 | regidx1 | 0 | regidx0 |
808
809 regidx0-2 refer not to the Register CSR CAM entry but to the underlying
810 *real* register (see regidx, the value) and consequently is 7-bits wide.
811 When set to zero (referring to x0), clearly reshaping x0 is pointless,
812 so is used to indicate "disabled".
813 shape0-2 refers to one of three SHAPE CSRs. A value of 0x3 is reserved.
814 Bits 7, 15, 23, 30 and 31 are also reserved, and must be set to zero.
815
816 It is anticipated that these specialist CSRs not be very often used.
817 Unlike the CSR Register and Predication tables, the REMAP CSRs use
818 the full 7-bit regidx so that they can be set once and left alone,
819 whilst the CSR Register entries pointing to them are disabled, instead.
820
821 ## SHAPE 1D/2D/3D vector-matrix remapping CSRs
822
823 (Note: both the REMAP and SHAPE sections are best read after the
824 rest of the document has been read)
825
826 There are three "shape" CSRs, SHAPE0, SHAPE1, SHAPE2, 32-bits in each,
827 which have the same format. When each SHAPE CSR is set entirely to zeros,
828 remapping is disabled: the register's elements are a linear (1D) vector.
829
830 | 26..24 | 23 | 22..16 | 15 | 14..8 | 7 | 6..0 |
831 | ------- | -- | ------- | -- | ------- | -- | ------- |
832 | permute | offs[2] | zdimsz | offs[1] | ydimsz | offs[0] | xdimsz |
833
834 offs is a 3-bit field, spread out across bits 7, 15 and 23, which
835 is added to the element index during the loop calculation.
836
837 xdimsz, ydimsz and zdimsz are offset by 1, such that a value of 0 indicates
838 that the array dimensionality for that dimension is 1. A value of xdimsz=2
839 would indicate that in the first dimension there are 3 elements in the
840 array. The format of the array is therefore as follows:
841
842 array[xdim+1][ydim+1][zdim+1]
843
844 However whilst illustrative of the dimensionality, that does not take the
845 "permute" setting into account. "permute" may be any one of six values
846 (0-5, with values of 6 and 7 being reserved, and not legal). The table
847 below shows how the permutation dimensionality order works:
848
849 | permute | order | array format |
850 | ------- | ----- | ------------------------ |
851 | 000 | 0,1,2 | (xdim+1)(ydim+1)(zdim+1) |
852 | 001 | 0,2,1 | (xdim+1)(zdim+1)(ydim+1) |
853 | 010 | 1,0,2 | (ydim+1)(xdim+1)(zdim+1) |
854 | 011 | 1,2,0 | (ydim+1)(zdim+1)(xdim+1) |
855 | 100 | 2,0,1 | (zdim+1)(xdim+1)(ydim+1) |
856 | 101 | 2,1,0 | (zdim+1)(ydim+1)(xdim+1) |
857
858 In other words, the "permute" option changes the order in which
859 nested for-loops over the array would be done. The algorithm below
860 shows this more clearly, and may be executed as a python program:
861
862 # mapidx = REMAP.shape2
863 xdim = 3 # SHAPE[mapidx].xdim_sz+1
864 ydim = 4 # SHAPE[mapidx].ydim_sz+1
865 zdim = 5 # SHAPE[mapidx].zdim_sz+1
866
867 lims = [xdim, ydim, zdim]
868 idxs = [0,0,0] # starting indices
869 order = [1,0,2] # experiment with different permutations, here
870 offs = 0 # experiment with different offsets, here
871
872 for idx in range(xdim * ydim * zdim):
873 new_idx = offs + idxs[0] + idxs[1] * xdim + idxs[2] * xdim * ydim
874 print new_idx,
875 for i in range(3):
876 idxs[order[i]] = idxs[order[i]] + 1
877 if (idxs[order[i]] != lims[order[i]]):
878 break
879 print
880 idxs[order[i]] = 0
881
882 Here, it is assumed that this algorithm be run within all pseudo-code
883 throughout this document where a (parallelism) for-loop would normally
884 run from 0 to VL-1 to refer to contiguous register
885 elements; instead, where REMAP indicates to do so, the element index
886 is run through the above algorithm to work out the **actual** element
887 index, instead. Given that there are three possible SHAPE entries, up to
888 three separate registers in any given operation may be simultaneously
889 remapped:
890
891 function op_add(rd, rs1, rs2) # add not VADD!
892 ...
893 ...
894  for (i = 0; i < VL; i++)
895 xSTATE.srcoffs = i # save context
896 if (predval & 1<<i) # predication uses intregs
897    ireg[rd+remap(id)] <= ireg[rs1+remap(irs1)] +
898 ireg[rs2+remap(irs2)];
899 if (!int_vec[rd ].isvector) break;
900 if (int_vec[rd ].isvector)  { id += 1; }
901 if (int_vec[rs1].isvector)  { irs1 += 1; }
902 if (int_vec[rs2].isvector)  { irs2 += 1; }
903
904 By changing remappings, 2D matrices may be transposed "in-place" for one
905 operation, followed by setting a different permutation order without
906 having to move the values in the registers to or from memory. Also,
907 the reason for having REMAP separate from the three SHAPE CSRs is so
908 that in a chain of matrix multiplications and additions, for example,
909 the SHAPE CSRs need only be set up once; only the REMAP CSR need be
910 changed to target different registers.
911
912 Note that:
913
914 * Over-running the register file clearly has to be detected and
915 an illegal instruction exception thrown
916 * When non-default elwidths are set, the exact same algorithm still
917 applies (i.e. it offsets elements *within* registers rather than
918 entire registers).
919 * If permute option 000 is utilised, the actual order of the
920 reindexing does not change!
921 * If two or more dimensions are set to zero, the actual order does not change!
922 * The above algorithm is pseudo-code **only**. Actual implementations
923 will need to take into account the fact that the element for-looping
924 must be **re-entrant**, due to the possibility of exceptions occurring.
925 See MSTATE CSR, which records the current element index.
926 * Twin-predicated operations require **two** separate and distinct
927 element offsets. The above pseudo-code algorithm will be applied
928 separately and independently to each, should each of the two
929 operands be remapped. *This even includes C.LDSP* and other operations
930 in that category, where in that case it will be the **offset** that is
931 remapped (see Compressed Stack LOAD/STORE section).
932 * Offset is especially useful, on its own, for accessing elements
933 within the middle of a register. Without offsets, it is necessary
934 to either use a predicated MV, skipping the first elements, or
935 performing a LOAD/STORE cycle to memory.
936 With offsets, the data does not have to be moved.
937 * Setting the total elements (xdim+1) times (ydim+1) times (zdim+1) to
938 less than MVL is **perfectly legal**, albeit very obscure. It permits
939 entries to be regularly presented to operands **more than once**, thus
940 allowing the same underlying registers to act as an accumulator of
941 multiple vector or matrix operations, for example.
942
943 Clearly here some considerable care needs to be taken as the remapping
944 could hypothetically create arithmetic operations that target the
945 exact same underlying registers, resulting in data corruption due to
946 pipeline overlaps. Out-of-order / Superscalar micro-architectures with
947 register-renaming will have an easier time dealing with this than
948 DSP-style SIMD micro-architectures.
949
950 # Instruction Execution Order
951
952 Simple-V behaves as if it is a hardware-level "macro expansion system",
953 substituting and expanding a single instruction into multiple sequential
954 instructions with contiguous and sequentially-incrementing registers.
955 As such, it does **not** modify - or specify - the behaviour and semantics of
956 the execution order: that may be deduced from the **existing** RV
957 specification in each and every case.
958
959 So for example if a particular micro-architecture permits out-of-order
960 execution, and it is augmented with Simple-V, then wherever instructions
961 may be out-of-order then so may the "post-expansion" SV ones.
962
963 If on the other hand there are memory guarantees which specifically
964 prevent and prohibit certain instructions from being re-ordered
965 (such as the Atomicity Axiom, or FENCE constraints), then clearly
966 those constraints **MUST** also be obeyed "post-expansion".
967
968 It should be absolutely clear that SV is **not** about providing new
969 functionality or changing the existing behaviour of a micro-architetural
970 design, or about changing the RISC-V Specification.
971 It is **purely** about compacting what would otherwise be contiguous
972 instructions that use sequentially-increasing register numbers down
973 to the **one** instruction.
974
975 # Instructions <a name="instructions" />
976
977 See [[appendix]]
978
979 # Exceptions
980
981 TODO: expand. Exceptions may occur at any time, in any given underlying
982 scalar operation. This implies that context-switching (traps) may
983 occur, and operation must be returned to where it left off. That in
984 turn implies that the full state - including the current parallel
985 element being processed - has to be saved and restored. This is
986 what the **STATE** CSR is for.
987
988 The implications are that all underlying individual scalar operations
989 "issued" by the parallelisation have to appear to be executed sequentially.
990 The further implications are that if two or more individual element
991 operations are underway, and one with an earlier index causes an exception,
992 it may be necessary for the microarchitecture to **discard** or terminate
993 operations with higher indices.
994
995 This being somewhat dissatisfactory, an "opaque predication" variant
996 of the STATE CSR is being considered.
997
998 # Hints
999
1000 A "HINT" is an operation that has no effect on architectural state,
1001 where its use may, by agreed convention, give advance notification
1002 to the microarchitecture: branch prediction notification would be
1003 a good example. Usually HINTs are where rd=x0.
1004
1005 With Simple-V being capable of issuing *parallel* instructions where
1006 rd=x0, the space for possible HINTs is expanded considerably. VL
1007 could be used to indicate different hints. In addition, if predication
1008 is set, the predication register itself could hypothetically be passed
1009 in as a *parameter* to the HINT operation.
1010
1011 No specific hints are yet defined in Simple-V
1012
1013 # Vector Block Format <a name="vliw-format"></a>
1014
1015 See ancillary resource: [[vblock_format]]
1016
1017 # Under consideration <a name="issues"></a>
1018
1019 for element-grouping, if there is unused space within a register
1020 (3 16-bit elements in a 64-bit register for example), recommend:
1021
1022 * For the unused elements in an integer register, the used element
1023 closest to the MSB is sign-extended on write and the unused elements
1024 are ignored on read.
1025 * The unused elements in a floating-point register are treated as-if
1026 they are set to all ones on write and are ignored on read, matching the
1027 existing standard for storing smaller FP values in larger registers.
1028
1029 ---
1030
1031 info register,
1032
1033 > One solution is to just not support LR/SC wider than a fixed
1034 > implementation-dependent size, which must be at least 
1035 >1 XLEN word, which can be read from a read-only CSR
1036 > that can also be used for info like the kind and width of 
1037 > hw parallelism supported (128-bit SIMD, minimal virtual 
1038 > parallelism, etc.) and other things (like maybe the number 
1039 > of registers supported). 
1040
1041 > That CSR would have to have a flag to make a read trap so
1042 > a hypervisor can simulate different values.
1043
1044 ----
1045
1046 > And what about instructions like JALR? 
1047
1048 answer: they're not vectorised, so not a problem
1049
1050 ----
1051
1052 * if opcode is in the RV32 group, rd, rs1 and rs2 bitwidth are
1053 XLEN if elwidth==default
1054 * if opcode is in the RV32I group, rd, rs1 and rs2 bitwidth are
1055 *32* if elwidth == default
1056
1057 ---
1058
1059 TODO: document different lengths for INT / FP regfiles, and provide
1060 as part of info register. 00=32, 01=64, 10=128, 11=reserved.
1061
1062 ---
1063
1064 TODO, update to remove RegCam and PredCam CSRs, just use SVprefix and
1065 VBLOCK format
1066
1067 ---
1068
1069 Could the 8 bit Register VBLOCK format use regnum<<1 instead, only accessing regs 0 to 64?
1070
1071 --
1072
1073 Expand the range of SUBVL and its associated svsrcoffs and svdestoffs by
1074 adding a 2nd STATE CSR (or extending STATE to 64 bits). Future version?
1075