add SHAPE / REMAP area to VBLOCK2
[libreriscv.git] / simple_v_extension / vblock_format.mdwn
index e2d9080d72ce7d8c2c641b5ee764bf694c55a755..6cad577b99a2dbf1660387c64d90a7bab851d611 100644 (file)
@@ -1,15 +1,17 @@
+[[!tag standards]]
+
 # Simple-V (Parallelism Extension Proposal) Vector Block Format
 
 * Copyright (C) 2017, 2018, 2019 Luke Kenneth Casson Leighton
-* Status: DRAFTv0.6
-* Last edited: 28 jun 2019
+* Status: DRAFTv0.7.1
+* Last edited: 2 sep 2019
 
 [[!toc ]]
 
 # Vector Block Format <a name="vliw-format"></a>
 
 This is a way to give Vector and Predication Context to a group of
-standard scalar RISC-V instructions, in a highly compact form.
+standard scalar RISC-V instructions, in a highly compact form. Program Execution Order is still preserved (unlike VLIW), just with "context" that would otherwise require much longer instructions.
 
 The format is:
 
@@ -25,57 +27,73 @@ as follows:
 
 [[!inline raw="yes" pages="simple_v_extension/vblock_format_table" ]]
 
-Note: this format is very similar to that used in [[sv_prefix_proposal]]
+Note: The VL Block format is similar to that used in [[sv_prefix_proposal]].
 
-If vlt is 0, VLEN is a 5 bit immediate value, offset by one (i.e
-a bit sequence of 0b00000 represents VL=1 and so on). If vlt is 1,
-it specifies the scalar register from which VL is set by this VBLOCK
-instruction group. VL, whether set from the register or the immediate,
-is then modified (truncated) to be MIN(VL, MAXVL), and the result stored
-in the scalar register specified in VLdest. If VLdest is zero, no store
-in the regfile occurs (however VL is still set).
+* Mode 0b00: set VL to the immediate, truncated to not exceed
+  MVL. Register rd is also set to the same value, if not x0.
+* Mode 0b01: follow [[specification/sv.setvl]] rules, with RVC
+  style registers in the range x8-x15 for rs1 and rd.
+* Mode 0b10: set both MVL and VL to the immediate. Register rd is also
+  set if not x0.
+* Mode 0b11: reserved. All fields must be zero.
 
-This option will typically be used to start vectorised loops, where
+Mode 0b01 will typically be used to start vectorised loops, where
 the VBLOCK instruction effectively embeds an optional "SETSUBVL, SETVL"
 sequence (in compact form).
 
-When bit 15 is set to 1, MAXVL and VL are both set to the immediate,
-VLEN (again, offset by one), which is 6 bits in length, and the same
-value stored in scalar register VLdest (if that register is nonzero).
-A value of 0b000000 will set MAXVL=VL=1, a value of 0b000001 will
-set MAXVL=VL= 2 and so on.
+Modes 0b00 and 0b10 will typically not be used so much for loops as they
+will be for one-off instructions such as saving the entire register file
+to the stack with a single one-off Vectorised and predicated LD/ST,
+or as a way to save or restore registers in a function call with a
+single instruction.
+
+Unlike in RVV, VL is set (within the limits of MVL) to exactly the value
+requested, specifically so that LD/ST-MULTI style behaviour can be done
+in a single instruction.
+
+# VBLOCK Prefix
+
+The purpose of the VBLOCK Prefix is to specify the context in which a
+block of RV Scalar instructions are "vectorised" and/or predicated.
 
-This option will typically not be used so much for loops as it will be
-for one-off instructions such as saving the entire register file to the
-stack with a single one-off Vectorised and predicated LD/ST, or as a way
-to save or restore registers in a function call with a single instruction.
+As there are not very many bits available without going into a prefix
+format longer than 16 bits, some abbreviations are used. Two bits are
+dedicated to specifying whether the Register and Predicate formats are
+16 or 8 bit.
 
-Notes:
+Also, the number of entries in each table is specified with an unusual
+encoding, on the basis that if registers are to be Vectorised, it is
+highly likely that they will be predicated as well.
 
-* Bit 7 specifies if the prefix block format is the full 16 bit format
-  (1) or the compact less expressive format (0). In the 8 bit format,
-  pplen is multiplied by 2.
+The VL Block is optional and also only 16 bits: this because an RVC
+opcode is limited by comparison.
+
+The format is explained as follows:
+
+* Bit 7 specifies if the register prefix block format is the full 16 bit format
+  (1) or the compact less expressive format (0).
 * 8 bit format predicate numbering is implicit and begins from x9. Thus
   it is critical to put blocks in the correct order as required.
-* Bit 7 also specifies if the register block format is 16 bit (1) or 8 bit
-  (0). In the 8 bit format, rplen is multiplied by 2. If only an odd number
-  of entries are needed the last may be set to 0x00, indicating "unused".
+* Bit 8 specifies if the predicate block format is 16 bit (1) or 8 bit
+  (0).
 * Bit 15 specifies if the VL Block is present. If set to 1, the VL Block
   immediately follows the VBLOCK instruction Prefix
-* Bits 8 and 9 define how many RegCam entries (0 to 3 if bit 15 is 1,
-  otherwise 0 to 6) follow the (optional) VL Block.
-* Bits 10 and 11 define how many PredCam entries (0 to 3 if bit 7 is 1,
-  otherwise 0 to 6) follow the (optional) RegCam entries
+* Bits 10 and 11 define how many RegCam entries (0,1,2,4 if bit 7 is 1,
+  otherwise 0,2,4,8) follow the (optional) VL Block.
+* Bit 9 define how many PredCam entries follow the (optional) RegCam block.
+  If pplen is 1, it is equal to rplen. Otherwise, half rplen, rounded up.
+* If the exact number of entries are not required, PredCam and RegCam
+  entries may be set to all zero to indicate "unused" (no effect).
 * Bits 14 to 12 (IL) define the actual length of the instruction: total
   number of bits is 80 + 16 times IL.  Standard RV32, RVC and also
-  SVPrefix (P48/64-\*-Type) instructions fit into this space, after the
+  SVPrefix (P32C/P48/64-\*-Type) instructions fit into this space, after the
   (optional) VL / RegCam / PredCam entries
 * In any RVC or 32 Bit opcode, any registers within the VBLOCK-prefixed
   format *MUST* have the RegCam and PredCam entries applied to the
   operation (and the Vectorisation loop activated)
 * P48 and P64 opcodes do **not** take their Register or predication
   context from the VBLOCK tables: they do however have VL or SUBVL
-  applied (unless VLtyp or svlen are set).
+  applied (overridden when VLtyp or svlen are set).
 * At the end of the VBLOCK Group, the RegCam and PredCam entries
   *no longer apply*.  VL, MAXVL and SUBVL on the other hand remain at
   the values set by the last instruction (whether a CSRRW or the VL
@@ -127,6 +145,47 @@ included here for convenience:
 
 [[!inline raw="yes" pages="simple_v_extension/pred_table_format" ]]
 
+# Swizzle Table Format<a name="swizzle_format"></a>
+
+The swizzle table format is included here for convenience:
+
+[[!inline raw="yes" pages="simple_v_extension/swizzle_table_format" ]]
+
+Swizzle blocks are only accessible using the "VBLOCK2" format.
+
+# REMAP Area Format<a name="remap_format"></a>
+
+The REMAP area is divided into two areas:
+
+* Register-to-SHAPE.  This defines which registers have which shapes.
+  Each entry is 8-bits in length.
+* SHAPE Table entries.  These are 32-bits in length and are aligned
+  to (start on) a 16 bit boundary.
+
+REMAP Table Entries:
+
+| 7:5      | 4:0    |
+| -------- | ------ |
+| shapeidx | regnum |
+
+When both shapeidx and regnum are zero, this indicates the end of the
+REMAP Register-to-SHAPE section.  The REMAP Table section size is then
+aligned to a 16-bit boundary.  32-bit SHAPE Table Entries then fill the
+remainder of the REMAP area, and are indexed in order by shapeidx.
+
+In this way, multiple registers may share the same "shape" characteristics.
+
+# SHAPE Table Format<a name="shape_format"></a>
+
+The shape table format is included here for convenience:
+
+[[!inline raw="yes" pages="simple_v_extension/shape_table_format" ]]
+
+See [[simple_v_extension/remap]] for full details on how SHAPE applies,
+including pseudo-code.
+
+REMAP Shape blocks are only accessible using the "VBLOCK2" format.
+
 # CSRs:
 
 The CSRs needed, in addition to those from the main [[specification]] are:
@@ -157,49 +216,134 @@ SUBVL and ssvoffs).
 
 # PCVBLK CSR Format
 
-Using PCVBLK to store the progression of decoding and subsequent execution of opcodes in a VBLOCK allows a simple single issue design to only need to fetch 32 or 64 bits from the instruction cache on any given clock cycle.
-
-To support this option (where more complex implementations may skip some of these phases), VBLOCK contains partial decode state, that allows a trap to occur even part-way through decode, in order to reduce latency.
-
-The format is as follows:
+Using PCVBLK to store the progression of decoding and subsequent execution
+of opcodes in a VBLOCK allows a simple single issue design to only need to
+fetch 32 or 64 bits from the instruction cache on any given clock cycle.
 
-| status | vlset | 16xil | pplen | rplen | mode | vlblk | opptr |
-| 2 | 1 | 3 | 2 | 2 | 1 | 16 | 5 |
+*(This approach also alleviates one of the main concerns with the VBLOCK
+Format: unlike a VLIW engine, a FSM no longer requires full buffering
+of the entire VBLOCK opcode in order to begin execution. Future versions
+may therefore potentially lift the 192 bit limit).*
 
-* status is the key field that effectively exposes the inner FSM (Finite State Machine) directly.
-* status = 0b00 indicates that the processor is not in "VBLOCK Mode". It is instead in standard RV Scalar opcode execution mode. The processor will leave this mode only after it encounters the beginning of a valid VBLOCK opcode.
-* status = 0b01 indicates that vlset, 16xil, pplen, rplen and mode have all been copied directly from the VBLOCK so that they do not need to be read again from the instruction stream.
-* status=0b10 indicates that the VL Block has been read from the instruction stream and decoded (and copied into vlblk).
-* status=0b11 indicates that the Predicate and Register Blocks have been read from the instruction stream (and put into internal Vector Context)  Simpler implementations are permitted to reset status back to 0b10 and re-read the data after return from a trap. They are not however permitted to destroy opptr in the process.
-* opptr points to where instructions begin in the VBLOCK. 0 indicates the start of the opcodes, and is in multiples of 16 bits ( 2 bytes).  This is the equivalent of a Program Counter, for VBLOCKs.
-* at the end of a VBLOCK, when the last instruction executes (assuming it does not change opptr to earlir in the block), status is reset to 0b00 to indicate exit from the VBLOCK FSM, and the current Vector Predicate and Register Context destroyed (Note: the STATE CSR is **not** altered by exit from a VBLOCK Context).
+To support this option (where more complex implementations may skip some
+of these phases), VBLOCK contains partial decode state, that allows a
+trap to occur even part-way through decode, in order to reduce latency.
 
-When status=0b11, opptr may be written to using CSRRWI. Doing so will cause execution to jump within the block, exactly as if PC had been set in normal RISC-V eexecution. Writing a value outside of the range of the instruction block will cause an illegal instruction exception. Writing a value (any value) when status is not 0b11 likewise causes an illegal instruction exception.
+The format is as follows:
 
-In privileged modes, obviously the above rules do not apply to the completely seoarate (x)ePCVBLK CSRs because these are copies of state, not the actual active PCVBLK. Writing to PCVBLK during a trap however, clearly the rules must apply.
+| 31:30  | 29    | 28:26 | 25:24 | 23:22 | 21   | 20:5    | 4:0   |
+|--------|-------|-------|-------|-------|------|---------|-------|
+| status | vlset | 16xil | pplen | rplen | mode | vblock2 | opptr |
+| 2      | 1     | 3     | 2     | 2     | 1    | 16      | 5     |
+
+* status is the key field that effectively exposes the inner FSM (Finite
+  State Machine) directly.
+* status = 0b00 indicates that the processor is not in "VBLOCK Mode". It
+  is instead in standard RV Scalar opcode execution mode. The processor
+  will leave this mode only after it encounters the beginning of a valid
+  VBLOCK opcode.
+* status=0b01 indicates that vlset, 16xil, pplen, rplen and mode have
+  all been copied directly from the VBLOCK so that they do not need to be
+  read again from the instruction stream, and that VBLOCK2 has also been
+  read and stored,  if 16xil was equal to 0b111.
+* status=0b10 indicates that the VL Block has been read from the instruction
+  stream and actioned.  (This means that a SETVL instruction has been
+  created and executed).  It also indicates that reading of the
+  Predicate, Register and Swizzle Blocks are now being read.
+* status=0b11 indicates that the Predicate and Register Blocks have been
+  read from the instruction stream (and put into internal Vector Context)
+  Simpler implementations are permitted to reset status back to 0b10 and
+  re-read the data after return from a trap that happened to occur in the
+  middle of a VBLOCK. They are not however permitted to destroy opptr in
+  the process, and after re-reading the Predicate and Register Blocks must
+  resume execution pointed to by opptr.
+* opptr points to where instructions begin in the VBLOCK. 0 indicates
+  the start of the opcodes
+  (not the start of the VBLOCK),
+  and is in multiples of 16 bits (2 bytes).
+  This is the equivalent of a Program Counter, for VBLOCKs.
+* at the end of a VBLOCK, when the last instruction executes (assuming it
+  does not change opptr to earlier in the block), status is reset to 0b00
+  to indicate exit from the VBLOCK FSM, and the current Vector Predicate
+  and Register Context destroyed (Note: the STATE CSR is **not** altered
+  purely by exit from a VBLOCK Context).
+
+During the transition from status=0b00 to status=0b01, it is assumed
+that the instruction stream is being read at a mininum of 32 bits at
+a time.  Therefore it is reasonable to expect that VBLOCK2 would be
+successfully read simultaneously with the initial VBLOCK header.
+For this reason there is no separate state in the FSM for updating
+of the vblock2 field in PCVBLK.
+
+When the transition from status=0b01 to status=0b10 occurs, actioning the
+VL Block state *actually* and literally **must** be as if a SETVL instruction
+had occurred.  This can result in updating of the VL and MVL CSRs (and
+the VL destination register target).  Note, below, that this means that
+a context-switch may save/restore VL and MVL (and the integer register file),
+where the remaining tables have no such opportunity.
+
+When status=0b10, and before status=0b11, there is no external indicator
+as to how far the hardware has got in the process of reading the
+Predicate, Register, and Swizzle Blocks.  Implementations are free to use
+any internal means to track progress, however given that if a trap occurs
+the read process will need to be restarted (in simpler implementations),
+there is no point having external indicators of progress.  By complete
+contrast, given that a SETVL actually writes to VL (and MVL), the VL
+Block state *has* been actioned and thus would be successfully restored
+by a context-switch.
+
+When status=0b11, opptr may be written to using CSRRWI. Doing so will
+cause execution to jump within the block, exactly as if PC had been set
+in normal RISC-V execution. Writing a value outside of the range of the
+instruction block will cause an illegal instruction exception. Writing
+a value (any value) when status is not 0b11 likewise causes an illegal
+instruction exception. To be clear: CSRRWI PCVBLK does **not** have the same
+behaviour as CSRRW PCVBLK.
+
+In privileged modes, obviously the above rules do not apply to the completely
+separate (x)ePCVBLK CSRs because these are (inactive) *copies* of state,
+not the actual active PCVBLK. Writing to PCVBLK during a trap however,
+clearly the rules must apply.
+
+If PCVBLK is written to with CSRRW, the same rules apply, however the
+entire register in rs1 is treated as the new opptr.
+
+Note that the value returned in the register rd is the *full* PCVBLK,
+not just the opptr part.
 
-If PCVBLK is written to with CSRRW, the same rules apply, however the entire register in rs1 is treated as the new opptr.
+# Limitations on instructions
 
-Note that the value returned in the register rd is the *full* PCVBLK, not just the opptr part.
+As the pcvblk CSR is relative to the beginning of the VBLOCK, branch
+and jump opcodes MUST NOT be used to point to a location inside a block:
+only at the beginning of an opcode (including another VBLOCK, including
+the current one). However, setting the PCVBLK CSR is permitted, to
+unconditionally jump to any opcode within a block.
 
-# Limitations on instructions
+Also: calling subroutines is likewise not permitted, because PCVBLK
+context cannot be atomically reestablished on return from the function.
 
-As the pcvblk CSR is relative to the beginning of the VBLOCK,
-branch and jump opcodes MUST NOT be used to point to a location inside a block: only at the beginning of an opcode (including another VBLOCK, including the current one). However, setting the PCVBLK CSR is permitted, to unconditionally jump to any opcode within a block.
+ECALL, on the other hand, which will cause a trap that saves and restores
+the full state, is permitted.
 
-Also: calling subroutines is likewise not permitted, because PCVBLK context cannot be atomically reestablished on return from the function.
+Prohibited instructions will cause an illegal instruction trap. If at
+that point, software is capable of then working out how to emulate a
+branch or function call successfully, by manipulating (x)ePCVBLK and
+other state, it is not prohibited from doing so.
 
-ECALL, on the other hand, which will cause a trap that saves and restores the full state, is permitted.
+To reiterate: a normal jump, normal conditional branch and a normal
+function call may only be taken by letting the VBLOCK group finish,
+returning to "normal" standard RV mode, and then using standard RVC,
+32 bit or P48/64-\*-type opcodes.
 
-Prohibited instructions will cause an illegal instruction trap. If at that point, software is capable of then working out how to emulate a branch or function call successfully, by manipulating (x)ePCVBLK and other state, it is not prohibited from doing so.
+The exception to this rule is if the branch or jump within the VBLOCK is back to the start of the same VBLOCK. If this is used, the VBLOCK is, clearly, to be re-executed, including any optional VL blocks and any predication, register table context etc.
 
-A normal jump, normal branch and a normal function call may only be taken
-by letting the VBLOCK group end, returning to "normal" standard RV mode,
-and then using standard RVC, 32 bit or P48/64-\*-type opcodes.
+Given however that the tables are already established, it is only the VL block that needs to be re-run.  The other tables may be left as-is.
 
 # Links
 
 * <https://groups.google.com/d/msg/comp.arch/yIFmee-Cx-c/jRcf0evSAAAJ>
+* <http://lists.libre-riscv.org/pipermail/libre-riscv-dev/2019-June/001824.html>
+* <http://lists.libre-riscv.org/pipermail/libre-riscv-dev/2019-June/001880.html>
 
 # Open Questions: