(no commit message)
[libreriscv.git] / simple_v_extension / simple_v_chennai_2018.tex
index 113676081d12e1c2afa7d02f2f2862058257dac1..3e6e47d7cf86681ca0c66b4f955fab37ec6bf574 100644 (file)
 
 \frame{
    \begin{center}
 
 \frame{
    \begin{center}
-    \huge{Simple-V RISC-V Extension for Vectors and SIMD}\\
+    \huge{Simple-V RISC-V Parallelism Abstraction Extension}\\
     \vspace{32pt}
     \Large{Flexible Vectorisation}\\
     \Large{(aka not so Simple-V?)}\\
     \vspace{32pt}
     \Large{Flexible Vectorisation}\\
     \Large{(aka not so Simple-V?)}\\
-    \Large{(aka How to Parallelise the RISC-V ISA)}\\
+    \Large{(aka A Parallelism API for the RISC-V ISA)}\\
     \vspace{24pt}
     \Large{[proposed for] Chennai 9th RISC-V Workshop}\\
     \vspace{16pt}
     \vspace{24pt}
     \Large{[proposed for] Chennai 9th RISC-V Workshop}\\
     \vspace{16pt}
@@ -50,7 +50,7 @@
    https://sigarch.org/simd-instructions-considered-harmful
    \item Setup and corner-cases alone are extremely complex.\\
             Hardware is easy, but software is hell.
    https://sigarch.org/simd-instructions-considered-harmful
    \item Setup and corner-cases alone are extremely complex.\\
             Hardware is easy, but software is hell.
-   \item O($N^{6}$) ISA opcode proliferation!\\
+   \item O($N^{6}$) ISA opcode proliferation (1000s of instructions)\\
             opcode, elwidth, veclen, src1-src2-dest hi/lo
   \end{itemize}
 }
             opcode, elwidth, veclen, src1-src2-dest hi/lo
   \end{itemize}
 }
 \frame{\frametitle{Quick refresher on RVV}
 
  \begin{itemize}
 \frame{\frametitle{Quick refresher on RVV}
 
  \begin{itemize}
-   \item Extremely powerful (extensible to 256 registers)\vspace{10pt}
-   \item Supports polymorphism, several datatypes (inc. FP16)\vspace{10pt}
-   \item Requires a separate Register File (16 w/ext to 256)\vspace{10pt}
-   \item Implemented as a separate pipeline (no impact on scalar)\vspace{10pt}
-  \end{itemize}
-  However...\vspace{10pt}
+   \item Effectively a variant of SIMD / SIMT (arbitrary length)\vspace{4pt}
+   \item Fascinatingly, despite being a SIMD-variant, RVV only has
+         O(N) opcode proliferation! (extremely well designed)
+   \item Extremely powerful (extensible to 256 registers)\vspace{4pt}
+   \item Supports polymorphism, several datatypes (inc. FP16)\vspace{4pt}
+   \item Requires a separate Register File (32 w/ext to 256)\vspace{4pt}
+   \item Implemented as a separate pipeline (no impact on scalar)
+  \end{itemize}
+  However...
    \begin{itemize}
    \begin{itemize}
-   \item 98 percent opcode duplication with rest of RV (CLIP)
+   \item 98 percent opcode duplication with rest of RV
    \item Extending RVV requires customisation not just of h/w:\\
             gcc, binutils also need customisation (and maintenance)
   \end{itemize}
    \item Extending RVV requires customisation not just of h/w:\\
             gcc, binutils also need customisation (and maintenance)
   \end{itemize}
    \item Why?
          Implementors need flexibility in vectorisation to optimise for
          area or performance depending on the scope:
    \item Why?
          Implementors need flexibility in vectorisation to optimise for
          area or performance depending on the scope:
-            embedded DSP, Mobile GPU's, Server CPU's and more.\vspace{4pt}\\
+            embedded DSP, Mobile GPU's, Server CPU's and more.\\
                 Compilers also need flexibility in vectorisation to optimise for cost 
                 of pipeline setup, amount of state to context switch
                 Compilers also need flexibility in vectorisation to optimise for cost 
                 of pipeline setup, amount of state to context switch
-                and software portability\vspace{4pt}
+                and software portability
    \item How?
             By marking INT/FP regs as "Vectorised" and
             adding a level of indirection,
             SV expresses how existing instructions should act 
    \item How?
             By marking INT/FP regs as "Vectorised" and
             adding a level of indirection,
             SV expresses how existing instructions should act 
-            on [contiguous] blocks of registers, in parallel.\vspace{4pt}
+            on [contiguous] blocks of registers, in parallel, WITHOUT
+            needing any new extra arithmetic opcodes.
    \item What?
                 Simple-V is an "API" that implicitly extends
                 existing (scalar) instructions with explicit parallelisation\\
    \item What?
                 Simple-V is an "API" that implicitly extends
                 existing (scalar) instructions with explicit parallelisation\\
-                (i.e. SV is actually about parallelism NOT vectors per se)
+                i.e. SV is actually about parallelism NOT vectors per se.\\
+                Has a lot in common with VLIW (without the actual VLIW).
   \end{itemize}
 }
 
   \end{itemize}
 }
 
 \frame{\frametitle{What's the value of SV? Why adopt it even in non-V?}
 
  \begin{itemize}
 \frame{\frametitle{What's the value of SV? Why adopt it even in non-V?}
 
  \begin{itemize}
-   \item memcpy becomes much smaller (higher bang-per-buck)
+   \item memcpy has a much higher bang-per-buck ratio
    \item context-switch (LOAD/STORE multiple): 1-2 instructions
    \item Compressed instrs further reduces I-cache (etc.)
    \item context-switch (LOAD/STORE multiple): 1-2 instructions
    \item Compressed instrs further reduces I-cache (etc.)
-   \item Greatly-reduced I-cache load (and less reads)
-   \item Amazingly, SIMD becomes (more) tolerable\\
-            (corner-cases for setup and teardown are gone)
+   \item Reduced I-cache load (and less I-reads)
+   \item Amazingly, SIMD becomes tolerable (no corner-cases)
    \item Modularity/Abstraction in both the h/w and the toolchain.
    \item Modularity/Abstraction in both the h/w and the toolchain.
+   \item "Reach" of registers accessible by Compressed is enhanced
+   \item Future: double the standard INT/FP register file sizes.
   \end{itemize}
   Note:
    \begin{itemize}
    \item It's not just about Vectors: it's about instruction effectiveness
   \end{itemize}
   Note:
    \begin{itemize}
    \item It's not just about Vectors: it's about instruction effectiveness
-   \item Anything that makes SIMD tolerable has to be a good thing
    \item Anything implementor is not interested in HW-optimising,\\
             let it fall through to exceptions (implement as a trap).
   \end{itemize}
    \item Anything implementor is not interested in HW-optimising,\\
             let it fall through to exceptions (implement as a trap).
   \end{itemize}
 \frame{\frametitle{How does Simple-V relate to RVV? What's different?}
 
  \begin{itemize}
 \frame{\frametitle{How does Simple-V relate to RVV? What's different?}
 
  \begin{itemize}
-   \item RVV very heavy-duty (excellent for supercomputing)\vspace{10pt}
-   \item Simple-V abstracts parallelism (based on best of RVV)\vspace{10pt}
-   \item Graded levels: hardware, hybrid or traps (fit impl. need)\vspace{10pt}
-   \item Even Compressed become vectorised (RVV can't)\vspace{10pt}
+   \item RVV very heavy-duty (excellent for supercomputing)\vspace{4pt}
+   \item Simple-V abstracts parallelism (based on best of RVV)\vspace{4pt}
+   \item Graded levels: hardware, hybrid or traps (fit impl. need)\vspace{4pt}
+   \item Even Compressed become vectorised (RVV can't)\vspace{4pt}
+   \item No polymorphism in SV (too complex)\vspace{4pt}
   \end{itemize}
   \end{itemize}
-  What Simple-V is not:\vspace{10pt}
+  What Simple-V is not:\vspace{4pt}
    \begin{itemize}
    \begin{itemize}
-   \item A full supercomputer-level Vector Proposal
+   \item A full supercomputer-level Vector Proposal\\
+            (it's not actually a Vector Proposal at all!)
    \item A replacement for RVV (SV is designed to be over-ridden\\
             by - or augmented to become - RVV)
   \end{itemize}
    \item A replacement for RVV (SV is designed to be over-ridden\\
             by - or augmented to become - RVV)
   \end{itemize}
          registers are reinterpreted through a level of indirection
    \item Primarily at the Instruction issue phase (except SIMD)\\
          Note: it's ok to pass predication through to ALU (like SIMD)
          registers are reinterpreted through a level of indirection
    \item Primarily at the Instruction issue phase (except SIMD)\\
          Note: it's ok to pass predication through to ALU (like SIMD)
-   \item Standard (and future, and custom) opcodes now parallel\vspace{10pt}
+   \item Standard and future and custom opcodes now parallel\\
+         (crucially: with NO extra instructions needing to be added)
   \end{itemize}
   \end{itemize}
-  Note: EVERYTHING is parallelised:
+  Note: EVERY scalar op now paralleliseable
    \begin{itemize}
    \item All LOAD/STORE (inc. Compressed, Int/FP versions)
    \begin{itemize}
    \item All LOAD/STORE (inc. Compressed, Int/FP versions)
-   \item All ALU ops (soft / hybrid / full HW, on per-op basis)
-   \item All branches become predication targets (C.FNE added?)
+   \item All ALU ops (Int, FP, SIMD, DSP, everything)
+   \item All branches become predication targets (note: no FNE)
    \item C.MV of particular interest (s/v, v/v, v/s)
    \item FCVT, FMV, FSGNJ etc. very similar to C.MV
   \end{itemize}
 }
 
 
    \item C.MV of particular interest (s/v, v/v, v/s)
    \item FCVT, FMV, FSGNJ etc. very similar to C.MV
   \end{itemize}
 }
 
 
-\frame{\frametitle{Implementation Options}
-
- \begin{itemize}
-   \item Absolute minimum: Exceptions (if CSRs indicate "V", trap)
-   \item Hardware loop, single-instruction issue\\
-                (Do / Don't send through predication to ALU)
-   \item Hardware loop, parallel (multi-instruction) issue\\
-                (Do / Don't send through predication to ALU)
-   \item Hardware loop, full parallel ALU (not recommended)
-  \end{itemize}
-  Notes:\vspace{6pt}
-  \begin{itemize}
-   \item 4 (or more?) options above may be deployed on per-op basis
-   \item SIMD always sends predication bits through to ALU
-   \item Minimum MVL MUST be sufficient to cover regfile LD/ST
-   \item Instr. FIFO may repeatedly split off N scalar ops at a time
-  \end{itemize}
-}
-% Instr. FIFO may need its own slide.  Basically, the vectorised op
-% gets pushed into the FIFO, where it is then "processed".  Processing
-% will remove the first set of ops from its vector numbering (taking
-% predication into account) and shoving them **BACK** into the FIFO,
-% but MODIFYING the remaining "vectorised" op, subtracting the now
-% scalar ops from it.
-
-\frame{\frametitle{Predicated 8-parallel ADD: 1-wide ALU}
- \begin{center}
-  \includegraphics[height=2.5in]{padd9_alu1.png}\\
-  {\bf \red Predicated adds are shuffled down: 6 cycles in total}
- \end{center}
-}
-
-
-\frame{\frametitle{Predicated 8-parallel ADD: 4-wide ALU}
- \begin{center}
-  \includegraphics[height=2.5in]{padd9_alu4.png}\\
-  {\bf \red Predicated adds are shuffled down: 4 in 1st cycle, 2 in 2nd}
- \end{center}
-}
-
-
-\frame{\frametitle{Predicated 8-parallel ADD: 3 phase FIFO expansion}
- \begin{center}
-  \includegraphics[height=2.5in]{padd9_fifo.png}\\
-  {\bf \red First cycle takes first four 1s; second takes the rest}
- \end{center}
-}
-
-
-\frame{\frametitle{How are SIMD Instructions Vectorised?}
-
- \begin{itemize}
-   \item SIMD ALU(s) primarily unchanged\vspace{6pt}
-   \item Predication is added to each SIMD element\vspace{6pt}
-   \item Predication bits sent in groups to the ALU\vspace{6pt}
-   \item End of Vector enables (additional) predication\vspace{10pt}
-  \end{itemize}
-  Considerations:\vspace{4pt}
-   \begin{itemize}
-   \item Many SIMD ALUs possible (parallel execution)
-   \item Implementor free to choose (API remains the same)
-   \item Unused ALU units wasted, but s/w DRASTICALLY simpler 
-   \item Very long SIMD ALUs could waste significant die area
-  \end{itemize}
-}
-% With multiple SIMD ALUs at for example 32-bit wide they can be used 
-% to either issue 64-bit or 128-bit or 256-bit wide SIMD operations
-% or they can be used to cover several operations on totally different
-% vectors / registers.
-
-\frame{\frametitle{Predicated 9-parallel SIMD ADD}
- \begin{center}
-  \includegraphics[height=2.5in]{padd9_simd.png}\\
-  {\bf \red 4-wide 8-bit SIMD, 4 bits of predicate passed to ALU}
- \end{center}
-}
-
-
 \frame{\frametitle{What's the deal / juice / score?}
 
  \begin{itemize}
    \item Standard Register File(s) overloaded with CSR "reg is vector"\\
             (see pseudocode slides for examples)
 \frame{\frametitle{What's the deal / juice / score?}
 
  \begin{itemize}
    \item Standard Register File(s) overloaded with CSR "reg is vector"\\
             (see pseudocode slides for examples)
-   \item Element width (and type?) concepts remain same as RVV\\
-            (CSRs give new size (and meaning?) to elements in registers)
-   \item CSRs are key-value tables (overlaps allowed)\vspace{10pt}
+   \item "2nd FP\&INT register bank" possibility, reserved for future\\
+         (would allow standard regfiles to remain unmodified)
+   \item Element width concept remain same as RVV\\
+            (CSRs give new size: overrides opcode-defined meaning)
+   \item CSRs are key-value tables (overlaps allowed: v. important)
   \end{itemize}
   \end{itemize}
-  Key differences from RVV:\vspace{10pt}
+  Key differences from RVV:
    \begin{itemize}
    \begin{itemize}
-   \item Predication in INT regs as a BIT field (max VL=XLEN)
+   \item Predication in INT reg as a BIT field (max VL=XLEN)
    \item Minimum VL must be Num Regs - 1 (all regs single LD/ST)
    \item Minimum VL must be Num Regs - 1 (all regs single LD/ST)
-   \item SV may condense sparse Vecs: RVV lets ALU do predication
-   \item Choice to Zero or skip non-predicated elements
+   \item SV may condense sparse Vecs: RVV cannot (SIMD-like):\\
+         SV gives choice to Zero or skip non-predicated elements\\
+         (no such choice in RVV: zeroing-only)
   \end{itemize}
 }
 
   \end{itemize}
 }
 
@@ -259,9 +192,9 @@ function op\_add(rd, rs1, rs2, predr) # add not VADD!
   for (i = 0; i < VL; i++)
     if (ireg[predr] & 1<<i) # predication uses intregs
        ireg[rd+id] <= ireg[rs1+irs1] + ireg[rs2+irs2];
   for (i = 0; i < VL; i++)
     if (ireg[predr] & 1<<i) # predication uses intregs
        ireg[rd+id] <= ireg[rs1+irs1] + ireg[rs2+irs2];
-    if (reg\_is\_vectorised[rd]) \{ id += 1; \}
-    if (reg\_is\_vectorised[rs1]) \{ irs1 += 1; \}
-    if (reg\_is\_vectorised[rs2]) \{ irs2 += 1; \}
+    if (reg\_is\_vectorised[rd] )  \{ id += 1; \}
+    if (reg\_is\_vectorised[rs1])  \{ irs1 += 1; \}
+    if (reg\_is\_vectorised[rs2])  \{ irs2 += 1; \}
 \end{semiverbatim}
 
   \begin{itemize}
 \end{semiverbatim}
 
   \begin{itemize}
@@ -295,6 +228,7 @@ for (int i = 0; i < VL; ++i)
    \item If s1 and s2 both scalars, Standard branch occurs
    \item Predication stored in integer regfile as a bitfield
    \item Scalar-vector and vector-vector supported
    \item If s1 and s2 both scalars, Standard branch occurs
    \item Predication stored in integer regfile as a bitfield
    \item Scalar-vector and vector-vector supported
+   \item Overload Branch immediate to be predication target rs3
   \end{itemize}
 \end{frame}
 
   \end{itemize}
 \end{frame}
 
@@ -305,7 +239,7 @@ for (int i = 0; i < VL; ++i)
 if (unit-strided) stride = elsize;
 else stride = areg[as2]; // constant-strided
 for (int i = 0; i < VL; ++i)
 if (unit-strided) stride = elsize;
 else stride = areg[as2]; // constant-strided
 for (int i = 0; i < VL; ++i)
-  if (preg\_enabled[rd] && ([!]preg[rd] & 1<<i))
+  if ([!]preg[rd] & 1<<i)
     for (int j = 0; j < seglen+1; j++)
       if (reg\_is\_vectorised[rs2]) offs = vreg[rs2+i]
       else offs = i*(seglen+1)*stride;
     for (int j = 0; j < seglen+1; j++)
       if (reg\_is\_vectorised[rs2]) offs = vreg[rs2+i]
       else offs = i*(seglen+1)*stride;
@@ -319,66 +253,88 @@ for (int i = 0; i < VL; ++i)
 \end{frame}
 
 
 \end{frame}
 
 
-\frame{\frametitle{Why are overlaps allowed in Regfiles?}
+\frame{\frametitle{Register key-value CSR store (lookup table / CAM)}
 
  \begin{itemize}
 
  \begin{itemize}
-   \item Same register(s) can have multiple "interpretations"
-   \item Set "real" register (scalar) without needing to set/unset CSRs.
-   \item xBitManip plus SIMD plus xBitManip = Hi/Lo bitops
-   \item (32-bit GREV plus 4x8-bit SIMD plus 32-bit GREV:\\
-            GREV @ VL=N,wid=32; SIMD @ VL=Nx4,wid=8)
-   \item RGB 565 (video): BEXTW plus 4x8-bit SIMD plus BDEPW\\
-            (BEXT/BDEP @ VL=N,wid=32; SIMD @ VL=Nx4,wid=8)
-   \item Same register(s) can be offset (no need for VSLIDE)\vspace{6pt}
+   \item key is int regfile number or FP regfile number (1 bit)
+   \item treated as vector if referred to in op (5 bits, key)
+   \item starting register to actually be used (5 bits, value)
+   \item element bitwidth: default, dflt/2, 8, 16 (2 bits)
+   \item is vector: Y/N (1 bit)
+   \item is packed SIMD: Y/N (1 bit)
+   \item register bank: 0/reserved for future ext. (1 bit)
   \end{itemize}
   \end{itemize}
-  Note:
+  Notes:
    \begin{itemize}
    \begin{itemize}
-   \item xBitManip reduces O($N^{6}$) SIMD down to O($N^{3}$)
-   \item Hi-Performance: Macro-op fusion (more pipeline stages?)
+   \item References different (internal) mapping table for INT or FP
+   \item Level of indirection has implications for pipeline latency
+   \item (future) bank bit, no need to extend opcodes: set bank=1,
+         just use normal 5-bit regs, indirection takes care of the rest.
   \end{itemize}
 }
 
 
   \end{itemize}
 }
 
 
-\frame{\frametitle{To Zero or not to place zeros in non-predicated elements?}
+\frame{\frametitle{Register element width and packed SIMD}
 
 
+  Packed SIMD = N:
  \begin{itemize}
  \begin{itemize}
-   \item Zeroing is an implementation optimisation favouring OoO
-   \item Simple implementations may skip non-predicated operations
-   \item Simple implementations explicitly have to destroy data
-   \item Complex implementations may use reg-renames to save power\\
-            Zeroing on predication chains makes optimisation harder
-   \item Compromise: REQUIRE both (specified in predication CSRs).
+   \item default: RV32/64/128 opcodes define elwidth = 32/64/128
+   \item default/2: RV32/64/128 opcodes, elwidth = 16/32/64 with
+         top half of register ignored (src), zero'd/s-ext (dest)
+   \item 8 or 16: elwidth = 8 (or 16), similar to default/2
   \end{itemize}
   \end{itemize}
-  Considerations:
-  \begin{itemize}
-   \item Complex not really impacted, simple impacted a LOT\\
-         with Zeroing... however it's useful (memzero)
-   \item Non-zero'd overlapping "Vectors" may issue overlapping ops\\
-            (2nd op's predicated elements slot in 1st's non-predicated ops)
-   \item Please don't use Vectors for "security" (use Sec-Ext)
+  Packed SIMD = Y (default is moot, packing is 1:1)
+ \begin{itemize}
+   \item default/2: 2 elements per register @ opcode-defined bitwidth
+   \item 8 or 16: standard 8 (or 16) packed SIMD
+  \end{itemize}
+  Notes:
+ \begin{itemize}
+   \item Different src/dest widths (and packs) PERMITTED
+   \item RV* already allows (and defines) how RV32 ops work in RV64\\
+         so just logically follow that lead/example.
   \end{itemize}
 }
   \end{itemize}
 }
-% with overlapping "vectors" - bearing in mind that "vectors" are
-% just a remap onto the standard register file, if the top bits of
-% predication are zero, and there happens to be a second vector
-% that uses some of the same register file that happens to be
-% predicated out, the second vector op may be issued *at the same time*
-% if there are available parallel ALUs to do so.
+
+
+\begin{frame}[fragile]
+\frametitle{Register key-value CSR table decoding pseudocode}
+
+\begin{semiverbatim}
+struct vectorised fp\_vec[32], int\_vec[32];
+for (i = 0; i < 16; i++) // 16 CSRs?
+   tb = int\_vec if CSRvec[i].type == 0 else fp\_vec
+   idx = CSRvec[i].regkey // INT/FP src/dst reg in opcode
+   tb[idx].elwidth  = CSRvec[i].elwidth
+   tb[idx].regidx   = CSRvec[i].regidx  // indirection
+   tb[idx].regidx  += CSRvec[i].bank << 5 // 0 (1=rsvd)
+   tb[idx].isvector = CSRvec[i].isvector
+   tb[idx].packed   = CSRvec[i].packed  // SIMD or not
+   tb[idx].enabled  = true
+\end{semiverbatim}
+
+ \begin{itemize}
+   \item All 32 int (and 32 FP) entries zero'd before setup
+   \item Might be a bit complex to set up in hardware (keep as CAM?)
+  \end{itemize}
+
+\end{frame}
 
 
 \frame{\frametitle{Predication key-value CSR store}
 
  \begin{itemize}
 
 
 \frame{\frametitle{Predication key-value CSR store}
 
  \begin{itemize}
-   \item key is int regfile number or FP regfile number (1 bit)\vspace{6pt}
-   \item register to be predicated if referred to (5 bits, key)\vspace{6pt}
-   \item register to store actual predication in (5 bits, value)\vspace{6pt}
-   \item predication is inverted Y/N (1 bit)\vspace{6pt}
-   \item non-predicated elements are to be zero'd Y/N (1 bit)\vspace{6pt}
+   \item key is int regfile number or FP regfile number (1 bit)
+   \item register to be predicated if referred to (5 bits, key)
+   \item INT reg with actual predication mask (5 bits, value)
+   \item predication is inverted Y/N (1 bit)
+   \item non-predicated elements are to be zero'd Y/N (1 bit)
+   \item register bank: 0/reserved for future ext. (1 bit)
   \end{itemize}
   Notes:\vspace{10pt}
    \begin{itemize}
    \item Table should be expanded out for high-speed implementations
   \end{itemize}
   Notes:\vspace{10pt}
    \begin{itemize}
    \item Table should be expanded out for high-speed implementations
-   \item Multiple "keys" (and values) theoretically permitted
+   \item Key-value overlaps permitted, but (key+type) must be unique
    \item RVV rules about deleting higher-indexed CSRs followed
   \end{itemize}
 }
    \item RVV rules about deleting higher-indexed CSRs followed
   \end{itemize}
 }
@@ -388,21 +344,21 @@ for (int i = 0; i < VL; ++i)
 \frametitle{Predication key-value CSR table decoding pseudocode}
 
 \begin{semiverbatim}
 \frametitle{Predication key-value CSR table decoding pseudocode}
 
 \begin{semiverbatim}
-struct pred fp\_pred[32];
-struct pred int\_pred[32];
-
+struct pred fp\_pred[32], int\_pred[32];
 for (i = 0; i < 16; i++) // 16 CSRs?
    tb = int\_pred if CSRpred[i].type == 0 else fp\_pred
 for (i = 0; i < 16; i++) // 16 CSRs?
    tb = int\_pred if CSRpred[i].type == 0 else fp\_pred
-   idx = CSRpred[i].regidx
-   tb[idx].zero     = CSRpred[i].zero
-   tb[idx].inv      = CSRpred[i].inv
-   tb[idx].predidx  = CSRpred[i].predidx
+   idx = CSRpred[i].regkey
+   tb[idx].zero     = CSRpred[i].zero    // zeroing
+   tb[idx].inv      = CSRpred[i].inv     // inverted
+   tb[idx].predidx  = CSRpred[i].predidx // actual reg
+   tb[idx].predidx += CSRvec[i].bank << 5 // 0 (1=rsvd)
    tb[idx].enabled  = true
 \end{semiverbatim}
 
  \begin{itemize}
    tb[idx].enabled  = true
 \end{semiverbatim}
 
  \begin{itemize}
-   \item All 64 (int and FP) Entries zero'd before setting
-   \item Might be a bit complex to set up (TBD)
+   \item All 32 int and 32 FP entries zero'd before setting\\
+            (predication disabled)
+   \item Might be a bit complex to set up in hardware (keep as CAM?)
   \end{itemize}
 
 \end{frame}
   \end{itemize}
 
 \end{frame}
@@ -414,73 +370,111 @@ for (i = 0; i < 16; i++) // 16 CSRs?
 \begin{semiverbatim}
 def get\_pred\_val(bool is\_fp\_op, int reg):
    tb = int\_pred if is\_fp\_op else fp\_pred
 \begin{semiverbatim}
 def get\_pred\_val(bool is\_fp\_op, int reg):
    tb = int\_pred if is\_fp\_op else fp\_pred
-   if (!tb[reg].enabled):
-      return ~0x0              // all ops enabled
-   predidx = tb[reg].predidx   // redirection occurs HERE
+   if (!tb[reg].enabled): return ~0x0 // all ops enabled
+   predidx  = tb[reg].predidx  // redirection occurs HERE
+   predidx += tb[reg].bank << 5 // 0 (1=rsvd)
    predicate = intreg[predidx] // actual predicate HERE
    if (tb[reg].inv):
    predicate = intreg[predidx] // actual predicate HERE
    if (tb[reg].inv):
-      predicate = ~predicate
+      predicate = ~predicate   // invert ALL bits
    return predicate
 \end{semiverbatim}
 
  \begin{itemize}
    \item References different (internal) mapping table for INT or FP
    \item Actual predicate bitmask ALWAYS from the INT regfile
    return predicate
 \end{semiverbatim}
 
  \begin{itemize}
    \item References different (internal) mapping table for INT or FP
    \item Actual predicate bitmask ALWAYS from the INT regfile
+   \item Hard-limit on MVL of XLEN (predication only 1 intreg)
   \end{itemize}
 
 \end{frame}
 
 
   \end{itemize}
 
 \end{frame}
 
 
-\frame{\frametitle{Register key-value CSR store}
+\frame{\frametitle{To Zero or not to place zeros in non-predicated elements?}
 
  \begin{itemize}
 
  \begin{itemize}
-   \item key is int regfile number or FP regfile number (1 bit)\vspace{6pt}
-   \item treated as vector if referred to in op (5 bits, key)\vspace{6pt}
-   \item starting register to actually be used (5 bits, value)\vspace{6pt}
-   \item element bitwidth: default/8/16/32/64/rsvd (3 bits)\vspace{6pt}
-   \item element type: still under consideration\vspace{6pt}
+   \item Zeroing is an implementation optimisation favouring OoO
+   \item Simple implementations may skip non-predicated operations
+   \item Simple implementations explicitly have to destroy data
+   \item Complex implementations may use reg-renames to save power\\
+            Zeroing on predication chains makes optimisation harder
+   \item Compromise: REQUIRE both (specified in predication CSRs).
   \end{itemize}
   \end{itemize}
-  Notes:\vspace{10pt}
-   \begin{itemize}
-   \item Same notes apply (previous slide) as for predication CSR table
-   \item Level of indirection has implications for pipeline latency
+  Considerations:
+  \begin{itemize}
+   \item Complex not really impacted, simple impacted a LOT\\
+         with Zeroing... however it's useful (memzero)
+   \item Non-zero'd overlapping "Vectors" may issue overlapping ops\\
+            (2nd op's predicated elements slot in 1st's non-predicated ops)
+   \item Please don't use Vectors for "security" (use Sec-Ext)
   \end{itemize}
 }
   \end{itemize}
 }
+% with overlapping "vectors" - bearing in mind that "vectors" are
+% just a remap onto the standard register file, if the top bits of
+% predication are zero, and there happens to be a second vector
+% that uses some of the same register file that happens to be
+% predicated out, the second vector op may be issued *at the same time*
+% if there are available parallel ALUs to do so.
 
 
 
 
-\begin{frame}[fragile]
-\frametitle{Register key-value CSR table decoding pseudocode}
-
-\begin{semiverbatim}
-struct vectorised fp\_vec[32];
-struct vectorised int\_vec[32];
-
-for (i = 0; i < 16; i++) // 16 CSRs?
-   tb = int\_vec if CSRvectortb[i].type == 0 else fp\_vec
-   idx = CSRvectortb[i].regidx
-   tb[idx].elwidth  = CSRpred[i].elwidth
-   tb[idx].regidx   = CSRpred[i].regidx
-   tb[idx].isvector = true
-\end{semiverbatim}
+\frame{\frametitle{Implementation Options}
 
  \begin{itemize}
 
  \begin{itemize}
-   \item All 64 (int and FP) Entries zero'd before setting
-   \item Might be a bit complex to set up (TBD)
+   \item Absolute minimum: Exceptions: if CSRs indicate "V", trap.\\
+         (Requires as absolute minimum that CSRs be in Hardware)
+   \item Hardware loop, single-instruction issue\\
+                (Do / Don't send through predication to ALU)
+   \item Hardware loop, parallel (multi-instruction) issue\\
+         (Do / Don't send through predication to ALU)
+   \item Hardware loop, full parallel ALU (not recommended)
+  \end{itemize}
+  Notes:\vspace{4pt}
+  \begin{itemize}
+   \item 4 (or more?) options above may be deployed on per-op basis
+   \item SIMD always sends predication bits to ALU (if requested)
+   \item Minimum MVL MUST be sufficient to cover regfile LD/ST
+   \item Instr. FIFO may repeatedly split off N scalar ops at a time
   \end{itemize}
   \end{itemize}
+}
+% Instr. FIFO may need its own slide.  Basically, the vectorised op
+% gets pushed into the FIFO, where it is then "processed".  Processing
+% will remove the first set of ops from its vector numbering (taking
+% predication into account) and shoving them **BACK** into the FIFO,
+% but MODIFYING the remaining "vectorised" op, subtracting the now
+% scalar ops from it.
 
 
-\end{frame}
+\frame{\frametitle{Predicated 8-parallel ADD: 1-wide ALU (no zeroing)}
+ \begin{center}
+  \includegraphics[height=2.5in]{padd9_alu1.png}\\
+  {\bf \red Predicated adds are shuffled down: 6 cycles in total}
+ \end{center}
+}
+
+
+\frame{\frametitle{Predicated 8-parallel ADD: 4-wide ALU (no zeroing)}
+ \begin{center}
+  \includegraphics[height=2.5in]{padd9_alu4.png}\\
+  {\bf \red Predicated adds are shuffled down: 4 in 1st cycle, 2 in 2nd}
+ \end{center}
+}
+
+
+\frame{\frametitle{Predicated 8-parallel ADD: 3 phase FIFO expansion}
+ \begin{center}
+  \includegraphics[height=2.5in]{padd9_fifo.png}\\
+  {\bf \red First cycle takes first four 1s; second takes the rest}
+ \end{center}
+}
 
 
 \begin{frame}[fragile]
 
 
 \begin{frame}[fragile]
-\frametitle{ADD pseudocode with redirection, this time}
+\frametitle{ADD pseudocode with redirection (and proper predication)}
 
 \begin{semiverbatim}
 function op\_add(rd, rs1, rs2) # add not VADD!
   int i, id=0, irs1=0, irs2=0;
 
 \begin{semiverbatim}
 function op\_add(rd, rs1, rs2) # add not VADD!
   int i, id=0, irs1=0, irs2=0;
+  predval = get\_pred\_val(FALSE, rd);
   rd  = int\_vec[rd ].isvector ? int\_vec[rd ].regidx : rd;
   rs1 = int\_vec[rs1].isvector ? int\_vec[rs1].regidx : rs1;
   rs2 = int\_vec[rs2].isvector ? int\_vec[rs2].regidx : rs2;
   rd  = int\_vec[rd ].isvector ? int\_vec[rd ].regidx : rd;
   rs1 = int\_vec[rs1].isvector ? int\_vec[rs1].regidx : rs1;
   rs2 = int\_vec[rs2].isvector ? int\_vec[rs2].regidx : rs2;
-  predval = get\_pred\_val(FALSE, rd);
   for (i = 0; i < VL; i++)
     if (predval \& 1<<i) # predication uses intregs
        ireg[rd+id] <= ireg[rs1+irs1] + ireg[rs2+irs2];
   for (i = 0; i < VL; i++)
     if (predval \& 1<<i) # predication uses intregs
        ireg[rd+id] <= ireg[rs1+irs1] + ireg[rs2+irs2];
@@ -495,6 +489,60 @@ function op\_add(rd, rs1, rs2) # add not VADD!
 \end{frame}
 
 
 \end{frame}
 
 
+\frame{\frametitle{How are SIMD Instructions Vectorised?}
+
+ \begin{itemize}
+   \item SIMD ALU(s) primarily unchanged
+   \item Predication added down to each SIMD element (if requested,
+         otherwise entire block will be predicated as a whole)
+   \item Predication bits sent in groups to the ALU (if requested,
+         otherwise just one bit for the entire packed block)
+   \item End of Vector enables (additional) predication:
+            completely nullifies end-case code (ONLY in multi-bit
+            predication mode)
+  \end{itemize}
+  Considerations:
+   \begin{itemize}
+   \item Many SIMD ALUs possible (parallel execution)
+   \item Implementor free to choose (API remains the same)
+   \item Unused ALU units wasted, but s/w DRASTICALLY simpler
+   \item Very long SIMD ALUs could waste significant die area
+  \end{itemize}
+}
+% With multiple SIMD ALUs at for example 32-bit wide they can be used
+% to either issue 64-bit or 128-bit or 256-bit wide SIMD operations
+% or they can be used to cover several operations on totally different
+% vectors / registers.
+
+\frame{\frametitle{Predicated 9-parallel SIMD ADD (Packed=Y)}
+ \begin{center}
+  \includegraphics[height=2.5in]{padd9_simd.png}\\
+  {\bf \red 4-wide 8-bit SIMD, 4 bits of predicate passed to ALU}
+ \end{center}
+}
+
+
+\frame{\frametitle{Why are overlaps allowed in Regfiles?}
+
+ \begin{itemize}
+   \item Same target register(s) can have multiple "interpretations"
+   \item CSRs are costly to write to (do it once)
+   \item Set "real" register (scalar) without needing to set/unset CSRs.
+   \item xBitManip plus SIMD plus xBitManip = Hi/Lo bitops
+   \item (32-bit GREV plus 4x8-bit SIMD plus 32-bit GREV:\\
+            GREV @ VL=N,wid=32; SIMD @ VL=Nx4,wid=8)
+   \item RGB 565 (video): BEXTW plus 4x8-bit SIMD plus BDEPW\\
+            (BEXT/BDEP @ VL=N,wid=32; SIMD @ VL=Nx4,wid=8)
+   \item Same register(s) can be offset (no need for VSLIDE)\vspace{6pt}
+  \end{itemize}
+  Note:
+   \begin{itemize}
+   \item xBitManip reduces O($N^{6}$) SIMD down to O($N^{3}$) on its own.
+   \item Hi-Performance: Macro-op fusion (more pipeline stages?)
+  \end{itemize}
+}
+
+
 \frame{\frametitle{C.MV extremely flexible!}
 
  \begin{itemize}
 \frame{\frametitle{C.MV extremely flexible!}
 
  \begin{itemize}
@@ -503,15 +551,15 @@ function op\_add(rd, rs1, rs2) # add not VADD!
    \item scalar-to-vector (w/ 1-bit dest-pred): VINSERT
    \item vector-to-scalar (w/ [1-bit?] src-pred): VEXTRACT
    \item vector-to-vector (w/ no pred): Vector Copy
    \item scalar-to-vector (w/ 1-bit dest-pred): VINSERT
    \item vector-to-scalar (w/ [1-bit?] src-pred): VEXTRACT
    \item vector-to-vector (w/ no pred): Vector Copy
-   \item vector-to-vector (w/ src pred): Vector Gather
-   \item vector-to-vector (w/ dest pred): Vector Scatter
+   \item vector-to-vector (w/ src pred): Vector Gather (inc VSLIDE)
+   \item vector-to-vector (w/ dest pred): Vector Scatter (inc. VSLIDE)
    \item vector-to-vector (w/ src \& dest pred): Vector Gather/Scatter
   \end{itemize}
   \vspace{4pt}
   Notes:
    \begin{itemize}
    \item vector-to-vector (w/ src \& dest pred): Vector Gather/Scatter
   \end{itemize}
   \vspace{4pt}
   Notes:
    \begin{itemize}
-   \item Surprisingly powerful!
-   \item Same arrangement for FVCT, FMV, FSGNJ etc.
+   \item Surprisingly powerful! Zero-predication even more so
+   \item Same arrangement for FCVT, FMV, FSGNJ etc.
   \end{itemize}
 }
 
   \end{itemize}
 }
 
@@ -540,17 +588,49 @@ function op\_mv(rd, rs) # MV not VMV!
 \end{frame}
 
 
 \end{frame}
 
 
+\begin{frame}[fragile]
+\frametitle{VSELECT: stays or goes? Stays if MV.X exists...}
+
+\begin{semiverbatim}
+def op_mv_x(rd, rs):         # (hypothetical) RV MX.X
+   rs = regfile[rs]          # level of indirection (MV.X)
+   regfile[rd] = regfile[rs] # straight regcopy
+\end{semiverbatim}
+
+Vectorised version aka "VSELECT":
+
+\begin{semiverbatim}
+def op_mv_x(rd, rs):              # SV version of MX.X
+   for i in range(VL):
+      rs1 = regfile[rs+i]         # indirection
+      regfile[rd+i] = regfile[rs] # straight regcopy
+\end{semiverbatim}
+
+  \begin{itemize}
+   \item However MV.X does not exist in RV, so neither can VSELECT
+   \item \red SV is not about adding new functionality, only parallelism
+  \end{itemize}
+
+
+\end{frame}
+
+
 \frame{\frametitle{Opcodes, compared to RVV}
 
  \begin{itemize}
 \frame{\frametitle{Opcodes, compared to RVV}
 
  \begin{itemize}
-   \item All integer and FP opcodes all removed (no CLIP!)\vspace{8pt}
-   \item VMPOP, VFIRST etc. all removed (use xBitManip)\vspace{8pt}
-   \item VSLIDE removed (use regfile overlaps)\vspace{8pt}
-   \item C.MV covers VEXTRACT VINSERT and VSPLAT (and more)\vspace{8pt}
-   \item VSETVL, VGETVL, VSELECT stay\vspace{8pt}
-   \item Issue: VCLIP is not in RV* (add with custom ext?)\vspace{8pt}
-   \item Vector (or scalar-vector) use C.MV (MV is a pseudo-op)\vspace{8pt}
-   \item VMERGE: twin predicated C.MVs (one inverted. macro-op'd)\vspace{8pt}
+   \item All integer and FP opcodes all removed (no CLIP, FNE)
+   \item VMPOP, VFIRST etc. all removed (use xBitManip)
+   \item VSLIDE removed (use regfile overlaps)
+   \item C.MV covers VEXTRACT VINSERT and VSPLAT (and more)
+   \item Vector (or scalar-vector) copy: use C.MV (MV is a pseudo-op)
+   \item VMERGE: twin predicated C.MVs (one inverted. macro-op'd)
+   \item VSETVL, VGETVL stay (the only ops that do!)
+  \end{itemize}
+  Issues:
+ \begin{itemize}
+   \item VSELECT stays? no MV.X, so no (add with custom ext?)
+   \item VSNE exists, but no FNE (use predication inversion?)
+   \item VCLIP is not in RV* (add with custom ext? or CSR?)
   \end{itemize}
 }
 
   \end{itemize}
 }
 
@@ -600,14 +680,14 @@ loop:
 
 
 \begin{frame}[fragile]
 
 
 \begin{frame}[fragile]
-\frametitle{SV DAXPY assembly (RV64G)}
+\frametitle{SV DAXPY assembly (RV64D)}
 
 \begin{semiverbatim}
 # a0 is n, a1 is ptr to x[0], a2 is ptr to y[0], fa0 is a
  CSRvect1 = \{type: F, key: a3, val: a3, elwidth: dflt\}
  CSRvect2 = \{type: F, key: a7, val: a7, elwidth: dflt\}
 loop:
 
 \begin{semiverbatim}
 # a0 is n, a1 is ptr to x[0], a2 is ptr to y[0], fa0 is a
  CSRvect1 = \{type: F, key: a3, val: a3, elwidth: dflt\}
  CSRvect2 = \{type: F, key: a7, val: a7, elwidth: dflt\}
 loop:
- setvl  t0, a0, 4       # vl = t0 = min(4, n)
+ setvl  t0, a0, 4       # vl = t0 = min(min(63, 4), a0))
  ld     a3, a1          # load 4 registers a3-6 from x
  slli   t1, t0, 3       # t1 = vl * 8 (in bytes)
  ld     a7, a2          # load 4 registers a7-10 from y
  ld     a3, a1          # load 4 registers a3-6 from x
  slli   t1, t0, 3       # t1 = vl * 8 (in bytes)
  ld     a7, a2          # load 4 registers a7-10 from y
@@ -621,14 +701,14 @@ loop:
 \end{frame}
 
 
 \end{frame}
 
 
-\frame{\frametitle{Under consideration}
+\frame{\frametitle{Under consideration (some answers documented)}
 
  \begin{itemize}
 
  \begin{itemize}
-   \item Is C.FNE actually needed? Should it be added if it is?
-   \item Element type implies polymorphism.  Should it be in SV?
+   \item Should future extra bank be included now?
+   \item How many Register and Predication CSRs should there be?\\
+         (and how many in RV32E)
+   \item How many in M-Mode (for doing context-switch)?
    \item Should use of registers be allowed to "wrap" (x30 x31 x1 x2)?
    \item Should use of registers be allowed to "wrap" (x30 x31 x1 x2)?
-   \item Is detection of all-scalar ops ok (without slowing pipeline)?
-   \item Can VSELECT be removed? (it's really complex)
    \item Can CLIP be done as a CSR (mode, like elwidth)
    \item SIMD saturation (etc.) also set as a mode?
    \item Include src1/src2 predication on Comparison Ops?\\
    \item Can CLIP be done as a CSR (mode, like elwidth)
    \item SIMD saturation (etc.) also set as a mode?
    \item Include src1/src2 predication on Comparison Ops?\\
@@ -636,6 +716,7 @@ loop:
    \item 8/16-bit ops is it worthwhile adding a "start offset"? \\
          (a bit like misaligned addressing... for registers)\\
          or just use predication to skip start?
    \item 8/16-bit ops is it worthwhile adding a "start offset"? \\
          (a bit like misaligned addressing... for registers)\\
          or just use predication to skip start?
+   \item see http://libre-riscv.org/simple\_v\_extension/\#issues
   \end{itemize}
 }
 
   \end{itemize}
 }
 
@@ -646,10 +727,10 @@ loop:
             (scalar ops are just vectors of length 1)\vspace{4pt}
    \item Tightly coupled with the core (instruction issue)\\
          could be disabled through MISA switch\vspace{4pt}
             (scalar ops are just vectors of length 1)\vspace{4pt}
    \item Tightly coupled with the core (instruction issue)\\
          could be disabled through MISA switch\vspace{4pt}
-   \item An extra pipeline phase is pretty much essential\\
+   \item An extra pipeline phase almost certainly essential\\
          for fast low-latency implementations\vspace{4pt}
    \item With zeroing off, skipping non-predicated elements is hard:\\
          for fast low-latency implementations\vspace{4pt}
    \item With zeroing off, skipping non-predicated elements is hard:\\
-         it is however an optimisation (and could be skipped).\vspace{4pt}
+         it is however an optimisation (and need not be done).\vspace{4pt}
    \item Setting up the Register/Predication tables (interpreting the\\
             CSR key-value stores) might be a bit complex to optimise
             (any change to a CSR key-value entry needs to redo the table)
    \item Setting up the Register/Predication tables (interpreting the\\
             CSR key-value stores) might be a bit complex to optimise
             (any change to a CSR key-value entry needs to redo the table)
@@ -657,19 +738,12 @@ loop:
 }
 
 
 }
 
 
-\frame{\frametitle{Is this OK (low latency)? Detect scalar-ops (only)}
- \begin{center}
-  \includegraphics[height=2.5in]{scalardetect.png}\\
-  {\bf \red Detect when all registers are scalar for a given op}
- \end{center}
-}
-
-
 \frame{\frametitle{Summary}
 
  \begin{itemize}
 \frame{\frametitle{Summary}
 
  \begin{itemize}
-   \item Actually about parallelism, not Vectors (or SIMD) per se
-   \item Only needs 3 actual instructions (plus CSRs)\\
+   \item Actually about parallelism, not Vectors (or SIMD) per se\\
+         and NOT about adding new ALU/logic/functionality.
+   \item Only needs 2 actual instructions (plus the CSRs).\\
          RVV - and "standard" SIMD - require ISA duplication
    \item Designed for flexibility (graded levels of complexity)
    \item Huge range of implementor freedom
          RVV - and "standard" SIMD - require ISA duplication
    \item Designed for flexibility (graded levels of complexity)
    \item Huge range of implementor freedom
@@ -677,20 +751,24 @@ loop:
    \item Reduces SIMD ISA proliferation by 3-4 orders of magnitude \\
             (without SIMD downsides or sacrificing speed trade-off)
    \item Covers 98\% of RVV, allows RVV to fit "on top"
    \item Reduces SIMD ISA proliferation by 3-4 orders of magnitude \\
             (without SIMD downsides or sacrificing speed trade-off)
    \item Covers 98\% of RVV, allows RVV to fit "on top"
-   \item Not designed for supercomputing (that's RVV), designed for
-         in between: DSPs, RV32E, Embedded 3D GPUs etc.
-   \item Not specifically designed for Vectorisation: designed to\\
-            reduce code size (increase efficiency, just
-                like Compressed)
+   \item Byproduct of SV is a reduction in code size, power usage
+            etc. (increase efficiency, just like Compressed)
   \end{itemize}
 }
 
 
 \frame{
   \begin{center}
   \end{itemize}
 }
 
 
 \frame{
   \begin{center}
-    {\Huge \red The end\vspace{20pt}\\
-                           Thank you}
+    {\Huge The end\vspace{20pt}\\
+                  Thank you\vspace{20pt}\\
+                  Questions?\vspace{20pt}
+       }
   \end{center}
   \end{center}
+  
+  \begin{itemize}
+       \item Discussion: ISA-DEV mailing list
+       \item http://libre-riscv.org/simple\_v\_extension/
+  \end{itemize}
 }
 
 
 }