The extension adds 32 vector registers (v0–v31, VLEN bits each)
and seven unprivileged CSRs. Context status rides in mstatus.VS
[10:9] — an exact FS analog: Off traps everything,
vector-state changes dirty it, and under the H extension
vsstatus.VS gates in parallel.
| Role | |
|---|---|
| vtype (0xC21, RO) | The interpretation contract: SEW, LMUL, tail/mask policies, vill. Writable ONLY via vset{i}vl{i}. |
| vl (0xC20, RO) | Elements each instruction updates. Written only by vset{i}vl{i} and fault-only-first loads. |
| vlenb (0xC22, RO) | VLEN/8 — a design constant, readable without disturbing vl/vtype (context-save sizing). |
| vstart (0x008, RW) | Trap-resume element index: hardware writes it on a mid-vector trap; EVERY vector instruction resets it to 0. User-writable for threading libraries; apps should leave it alone. |
| vxrm (0x00A) / vxsat (0x009) / vcsr (0x00F) | Fixed-point rounding mode (rnu/rne/rdn/rod; increment r per Table 46), sticky saturation flag, and their combined mirror. |
vtype — the interpretation register
vtype (0xC21) — Table 43
LMUL lmul Vector register group multiplier (vtype.vlmul, powers of two from 1/8 to 8): LMUL>1 gangs 2/4/8 aligned registers into one operand (VLMAX = LMUL·VLEN/SEW); fractional LMUL parks narrow data in a register fraction so mixed-width loops keep all 32 register names usable. defined in ch. I·31 — open in glossary gangs registers: LMUL=2 pairs v2n, v2n+1, LMUL=4 takes multiples of four, LMUL=8 multiples of eight — misaligned bases are reserved encodings. Its raison d’être is mixed-width math: a widening add producing 2× SEW sew Selected Element Width (vtype.vsew): the dynamic element size (8/16/32/64) a vector register is currently viewed as. Widening ops produce 2·SEW results in 2·LMUL groups; ELEN caps the maximum. defined in ch. I·31 — open in glossary results needs 2×LMUL registers to keep the same element count. Fractional LMUL (1/2, 1/4, 1/8) parks narrow operands in a fraction of one register so a mixed-width loop can still name 32 distinct operands. Implementations must support LMUL ≥ SEWmin/ELEN (with SEW up to LMUL·ELEN at each fraction); masks always fit one register.
Tail & mask policies
Elements outside the action — the tail (≥ vl) and inactive
(masked-off) sets — follow vta/vma: undisturbed keeps old
values; agnostic leaves each element old or all-1s,
non-deterministically. The ta/tu + ma/mu flags are mandatory in
vsetvli assembly.
At reset: vill set, rest of vtype zero, vl zero (recommended) — a single vsetvl can save/restore the pair. vxrm/vxsat/vstart and the vector registers may hold garbage; the initial vsetvli sorts everything but vxrm/vxsat, which software resets explicitly.
Hardware Designer Notes
vtype/vl renaming is the key perf decision: unfused, every vsetvli serializes the pipeline. Treat the pair as a speculatively renamed operand and strip-mine loops run at full issue rate.
Minimal Linux-boot hart MUST
- Implement all four ta/ma combinations (accepting them is mandatory even if you execute everything undisturbed)
- Reset vstart to zero at the end of EVERY vector instruction including vset{i}vl{i}, and write the faulting element index on resumable traps
- Keep vill in the sign bit with the all-other-bits-zero rule, and bounce vtype-dependent instructions when it’s set
MAY simplify / trap-and-emulate
- Trap nonzero-vstart arithmetic if your pipeline never produces it (no mid-instruction interrupts on arithmetic)
- Store vtype in ~7 physical bits for an ELEN=32 embedded core (vill encoded in the reserved vsew pattern)
- Rename vl/vtype as one internal control register and fuse vsetvli into the consuming vector op
Check yourself — vector programmer's model
1.Why can vtype only be written by vset{i}vl{i} instructions, never by CSR writes?
2.With VLEN=128, SEW=32, LMUL=4, what is VLMAX and which registers form the group starting at v8?
3.What may an 'agnostic' tail element contain after an instruction executes, and why so loose?
4.What is vstart for, and why does every vector instruction reset it to zero?