RISC-V ISA instructions for matrix multiplication

All of the information here is taken from The RISC-V Instruction Set Manual, Zvt Family of Vector Matrix Extensions (v0.3). Copyright 2026 by RISC-V International.

The RISC-V® Instruction Set Architecture (ISA) specifications are owned by RISC-V International and licensed under the Creative Commons Attribution 4.0 International License (CC-BY 4.0).

Overview

The RISC-V Zvt matrix extensions add a new architectural state to each hart in the form of square matrix tiles. New instructions perform tall-skinny by short-wide matrix multiplications, in other words outer products or wide-outer products. These instructions source their operands from vector registers and accumulate their results into the square matrix tiles. Each matrix tile row or column must fit within a single vector register group (VLEN*8 bits).

The inputs' data width is specified by SEW, while the accumulators' data width is given by TEW = SEW * TWIDEN, where TWIDEN can be 1, 2, or 4, depending on the instruction.

The matrix computational instructions perform the operation

C[M,N] += A[K,M]^T * B[K,N]

where C is stored in the tile state. Each of the input matrices A and B is held in a set of vector registers, where each row of the matrix is held in a separate vector register group and the number of rows is given by K. The inner dimension K can be a maximum (KMAX) of 1, 2, or 4, depending on the data type of A and B.

Other instructions are provided to move rows and columns of the matrix arrays — moving them either to or from the vector registers or memory.

The Zvtbase extension provides the new architectural state along with the new configuration, move, load, store, and context-manipulation instructions. In the base, the move, load, and store instructions support a tile EEW (TEW) of 32; other TEWs are reserved for these instructions. TEW = 32 is chosen because it is the most common accumulator bit-width.

The ISA fixes the number of TEW=32 tiles to four (mt0, mt4, mt8, mt12) to support all cases at reasonable performance. The matrix state needs to hold at least one accumulator as well as transposes of one or both inputs to support efficient execution of all matrix operations.

The ISA is optimized for the case where TEW=32, as this is the most common accumulator size. When TEW=32, the tiles have dimensions TE x TE elements, where TE is a parameter of the implementation. TE is constrained to be a power of 2, such that VLEN/4 >= TE >= 4. The upper bound is set by the requirement that a tile row or column must fit within a single vector register group (VLEN*8 bits). The configuration instructions, described below, support writing of TE-agnostic code.

The parameter ETE describes the tile dimensions as a function of TEW:

ETE = TEW < 64 ? TE : TE/2

The Zvt matrix functionality is also referred to as Vector Matrix Extensions (VME).

Matrix type (mtype) CSR

Similar to the Vector Type register (vtype), which is used dynamically govern vector configuration, the Zvt matrix extension adds a Matrix Type register named mtype. This register is unprivileged and read-only. It contains the following fields:

Bits Field Definition
XLEN–1:24 reserved
23:10 tm[13:0] — Matrix dimension M, saturated to a maximum value
9:8 reserved
7:5 tk[2:0] — Matrix dimension K, bounded up to KMAX (for example, 3)
4:2 reserved
1:0 mtwiden[1:0]
  • tm can hold values from 0–TE, inclusive.
  • tk can hold values from 0–4, inclusive.
  • If mtwiden=0, the matrix unit is not configured.

This configuration controls the active dimensions and operational parameters of the matrix execution pipeline. Note that the vector configuration register vl controls the matrix dimension N, dynamically tracking the active vector length up to VLMAX.

Matrix-multiply operations

The general form of the matrix-multiply operation is:

C[tm,tn] += A[tk,tm]^T * B[tk,tn]

where the inputs A and B are each sourced from a vector register group, while the accumulator C is held in a matrix tile. A, B, and C are all specified using register specifier fields in the instruction encoding.

A or B matrix operand

A or B Matrix Operand

The values of tm, tn, and tk are obtained from CSRs. tm and tk are fields in the mtype register. tn is derived from vl; it is equal to min(vl,ETE). The new configuration instructions described below allow the values of tm, tn, and tk to be set in an implementation-agnostic manner from the application matrix dimensions.

Each vector register group input has tk rows, where each row is held separately in one or more vector registers, with the total number of vector registers constrained to fit in one eight-register group. Each row fits within a vector register group (i.e. an aligned power-of-2 number of vector registers) and the collection of rows also fits in a (potentially larger) vector register group. The value of tk sets the dimension of the dot products performed for each accumulator element and the maximum value of tk (KMAX) depends on the element widths, with a maximum value of 4.

Matrix Operand Layout

Matrix Operand Layout in Vector Register Group

This format allows existing vector unit-stride loads to be used to load each row of an input from a memory matrix held in row-major format.

Successive rows are separated by (8/KMAX) vector registers. For example, for vector register group specifier v8, and assuming KMAX=4 and LMUL=2, then v8 – v9 holds one matrix row, v10 – v11 holds the next row, v12 – v13 the next, and v14 – v15 the last. But when KMAX=4 and LMUL=1, then v8, v10, v12, and v14 hold the successive rows of the matrix: the separation between rows is the same, but the odd-numbered vector registers are skipped.

Vector register specifiers must be divisible by LMUL. For example, when KMAX=4 and LMUL=2, v8 is valid but v9 is not. But when KMAX=4 and LMUL=1, both are valid: the former represents the even-numbered registers v8 – v14, whereas the latter represents the odd-numbered registers v9 – v15.

Vector register specifiers, when taken modulo 8, must be less than 8/KMAX. For example, when KMAX=4, v10 is invalid.

Matrix configuration instructions

The matrix configuration instructions are summarized in the following table:

Instruction Description
msetmtype rs1,rs2 Write the mtype and vtype CSRs to the values in the rs1 and rs2 registers.
msetmtypei Similar to msetmtype except: 1) the new mtype CSR value is supplied by a zero-extended immediate, 2) the vtype.vsew field value is supplied by a zero-extended immediate, and 3) all other vtype fields are zeroed.
msettn rd,rs1 Set tn/vl to the value in rs1, constrained by the current matrix configuration; sets matrix dimension N. Operates similarly to vsetvl, updating vl from rs1 and writing the new vl to rd. (See note below.*)
msettm rd,rs1 Set tm to the value in rs1, constrained by the current matrix configuration – sets tm to be the lesser of rs1, LMULxEVE, and ETE. Sets matrix dimension M. (See note below.*)
msettk rd,rs1 Set tk to the value in rs1, constrained by the current matrix configuration – sets tk to the lesser of rs1 and KMAX. Sets matrix dimension K. (See note below.*)

* For msettm and msettk, the new field value is written back to the destination register rd. The msettn instruction uses the standard vsetvl datapath to write the updated vl to rd.

Application matrices have varied sizes. The matrix configuration instructions allow a single binary matrix-multiply routine to work for any size application matrix-multiply on any sized matrix-multiply hardware implementation.

The actual size of a matrix-multiply operation is determined by values in two CSRs: tk and tm are fields in the mtype register; tn is derived from the vl register. These CSRs are set using configuration instructions.

The existing vset[i]vl[i] instructions write zero to the mtype CSR.

The msetmtype instruction writes the mtype and vtype CSRs to the values in the rs1 and rs2 registers. First, vl is written with 0, and mtype is written with the value in rs1. Then, vtype is written with the value in rs2, as though by a vsetvl instruction. Finally, if mtype.mtwiden != 0, then vma and vta are set to 1, vill is set if the resulting TEW is unsupported, and vlmul is set.

The msetmtypei instruction is defined similarly, except the new mtype.mtwiden, vtype.vsew, and vtype.altfmt fields are supplied by immediates.

These instructions are included in the Zvtbase extension.

msettn instruction

This instruction sets tn or vl to the value in rs1, constrained by the current matrix configuration. If the matrix unit is not configured, in other words mtwiden=0, the instruction writes vl as if by a vsetvl instruction using the current vtype setting. The new value of tn/vl is also written to the scalar destination register rd.

The msettn instruction operates as follows:

if mtype.mtwiden == 0:
  rd = vl = rs1 (following vsetvl semantics)
else:
  rd = vl = min(rs1, LMUL*EVE, ETE)

The msetmtype and msettn instructions are intended to be used by context-switching routines. Because their semantics degenerate to those of vsetvl when the matrix unit is not configured, the usual vsetvl can be replaced with msetmtype and msettn; there is no need to use a dynamic branch to select between the two schemes.

msettm and msettk instructions

These instructions set tm or tk to the value in rs1, constrained by the current matrix configuration. If the matrix unit has not been configured (mtwiden=0), the new tm or tk value is 0. The new value of tm or tk is also written to the scalar destination register rd.

msettm rd, rs1 // rd = tm = min(rs1, LMUL*EVE, ETE)

The msettm instruction sets tm to be the lesser of rs1, LMUL*EVE, and ETE.

msettk rd, rs1 // rd = tk = ((mtwiden == 0) ? 0 : min(rs1, KMAX))

The msettk instruction sets tk to the lesser of rs1 and KMAX.

Supported SEW, TWIDEN, and KMAX values

The inner dimension specified by tk is used to support dot-product operations on narrower datatypes to increase efficiency. The ISA fixes maximum K values (KMAX) of matrix-multiply instructions according to SEW and TWIDEN to simplify ISA specification of these arithmetic operators.

Unlike other matrix accelerator architectures that support fusion of narrower datatypes by flattening K into both the M and N dimensions, this approach allows software to use standard matrix formats.


TEW=8
SEW TWIDEN KMAX
8     1     4 (4-element dot product)

TEW=16
SEW TWIDEN KMAX
8    2     4 (4-element dot product)
16   1     2 (2-element dot product)

TEW=32
SEW TWIDEN KMAX
8   4      4 (4-element dot product)
16  2      2 (2-element dot product)
32  1      1

Tile subset specifier (TSS)

For operations that move rows or columns between the matrix tiles and vector registers or memory, a scalar value is used to encode the set of tile elements that are accessed and the pattern by which they are accessed.

Bits Field definition
XLEN–1:31 reserved
30:27 tile specifier (0-15)
26:24 pattern (0=row, 1=col, >1 reserved)
23:0 index within pattern (e.g. row/col index)

When there are fewer than 16 tiles due to the specified TEW, the log2(16 / NTiles) LSBs of the tile specifier field are ignored, such that this field always refers to a valid tile. The 3-bit field for pattern only has two encodings defined, row and column. The pattern field defines how the index field is interpreted. For the defined row and column patterns, the index field is treated as an unsigned integer providing a one-dimensional index of the row or column. Row and column indices greater than or equal to ETE are reserved.

Load/store tile subset to memory

The vtle and vtse instructions transfer matrix tile subsets between the tile state and memory. These instructions support TEW values corresponding to all supported SEW settings (8..ELEN). Implementations must provide vector loads and stores with EEWs corresponding to all supported SEW settings (8..ELEN). These instructions are included in the Zvtbase extension.

// Load tile subset from memory, using TEW=EEW
vtle8 rs2, (rs1) // rs1 is memory address, rs2 is TSS
vtle16 rs2, (rs1) // rs1 is memory address, rs2 is TSS
vtle32 rs2, (rs1) // rs1 is memory address, rs2 is TSS
vtle64 rs2, (rs1) // rs1 is memory address, rs2 is TSS

// Store tile subset to memory, using TEW=EEW
vtse8 rs2, (rs1) // rs1 is memory address, rs2 is TSS
vtse16 rs2, (rs1) // rs1 is memory address, rs2 is TSS
vtse32 rs2, (rs1) // rs1 is memory address, rs2 is TSS
vtse64 rs2, (rs1) // rs1 is memory address, rs2 is TSS

The integer register specified by rs1 holds the base address in memory. The integer register specified by rs2 holds the tile subset specifier. These instructions do not support masks. EEW is statically encoded in the instruction.

These instructions always load and store the tile subset to a contiguous region of memory. For the defined row and column patterns, the elements of the row or column are stored in increasing index order in memory.

For these instructions, the body elements are those with indices in the range [vstart, min(vl, ETE) - 1], and the tail elements are those with indices ≥ min(vl, ETE).

Since vl=tn holds the number of columns in the accumulator (the length of a row), these instructions are oriented towards loading and storing accumulator rows. When loading and storing accumulator columns, additional msettn instructions may be needed to program vl=tn to hold the number of rows, that is, the length of a column, instead.

Move tile subset between tile state and vector registers

Tile subset operations transfer elements between a matrix tile and a vector register group. These instructions support TEW values corresponding to all supported SEW settings (8..ELEN). These instructions are included in the Zvtbase extension.

// Move tile subset to vector register group, using TEW=SEW
vtmv.v.t vd, rs1
// vd is destination vector register, rs1 is TSS of source

// Move vector register group to tile subset, using TEW=SEW
vtmv.t.v rs1, vs2
// vs2 is source vector register, rs1 is TSS of destination

Matrix arithmetic instructions

These instructions all have the form C += A^T * B, where C is held in a matrix tile and A and B are supplied by vector register groups.

Floating-point matmuls (OCP, BF16, IEEE)

vtfmm.tvv mtd, vs2, vs1
vtfmm.alt.tvv mtd, vs2, vs1
  • vtype holds SEW and altfmt; mtype holds TWIDEN
  • vs2 specifies A vector register group
  • vs1 specifies B vector register group
  • mtd is C destination tile specifier

Integer matmuls

vtmmu.tvv mtd, vs2, vs1
vtmms.tvv mtd, vs2, vs1

These instructions use the values of tm, tn, and tk to determine what computations to perform. If any of these values are zero, then no computation is performed and no state is updated.

Matrix tile-zero instruction

The vtzero instruction writes 0 to each element of the tm by tn submatrix of the destination matrix tile. This instruction is included in the Zvtbase extension.

vtzero mtd

Context status

The mtype CSR is considered part of the vector context; access to this CSR is controlled by the various VS fields. Additional MS context-status fields are added to reduce the cost of saving and restoring the matrix tile state.

Zvt context status in mstatus

A Zvt context status field, MS, is added to mstatus[30:29] and shadowed in sstatus[30:29]. It is defined analogously to the floating-point context status field, FS.

Zvt context discard instruction

The vtdiscard instruction is provided to inform the runtime that the matrix tile state is no longer useful and need not be saved.