VID.V

RISC-V VID.V 指令详解

指令手册OPMVV

把每个活动元素的元素索引 i 写入目标整数向量 vd;索引值按当前 SEW 宽度写入。

指令语法

vid.v vd, vm
操作数说明
32 位 OP-V:opcode=1010111、funct3=010、funct6=010100。vs1=10001 是固定 selector;vs2=00000,其他值保留。语法没有普通源向量。
活动元素 i 写入编号 i,掩码不重新编号。SEW 较宽时零扩展,编号溢出时保留低 SEW 位;不是字节偏移,也不读取内存。
vd 使用当前 LMUL 的整数向量组;masked 目标不能与 v0 重叠。
省略 v0.t 为 vm=1,写出为 vm=0。prestart 不更新;inactive/tail 按 vma/vta 处理,undisturbed 保留旧值,agnostic 可保留旧值或写全1。vl=0 或 vstart≥vl 不更新任何目标(包括 tail);成功执行后 vstart=0。
V 1.0 适用于 RV32/RV64;要求合法 vtype 和 VS 已启用。动画固定 SEW=32、LMUL=m1、VLEN=4096、vstart=0、ta/ma;不展示非零 vstart 或索引截断边界,不表示处理器周期。
V向量重排/索引置换

指令行为说明

VID.V 是 RISC-V V 扩展的元素索引生成指令。对每个活动 body 元素 i,它把无符号元素编号 i 写入 vd[i];vm=0 时只有 v0.t 选中的元素写入生成的索引,vm=1 时所有 body 元素写入索引;非活动及尾部元素按 vma/vta 处理。该指令不读取内存,也不读取普通源向量。

VID.V 指令解析与执行动画

从 OP-V 编码字段开始,展示 VID.V 如何不读取源向量,直接把 active lane 的元素编号写入整数向量。

输入的指令
vid.v
reserved
vs2=00000
语法无源向量
执行环境
vstart0本教学模型从元素 0 开始;早于非零 vstart 的元素保持不变
source
不读取源向量
VID.V 只使用 lane 编号

教学环境:SEW=32、LMUL=m1、VLEN=4096、VLMAX=128、vstart=0、合法 vtype、VS 已启用、ta/ma。活动索引按 SEW 零扩展或保留低位;本例最大索引 63,无截断。masked-off/tail 可保留旧值或写全1,不显示确定值。VL=0 不更新任何目标元素,包括 tail;成功执行后 vstart=0。步骤不表示处理器周期。

OP-V encodingfunct6 | vm | vs2=00000 | vs1=10001 | funct3 | vd | opcode
funct6
010100
vm
0
vs2(res)
00000
vs1
10001
funct3
010
vd
01100
opcode
1010111
lane
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
v0.t
1
0
1
1
1
1
0
1
1
1
1
0
1
1
1
1
scan
0
off
2
3
4
5
off
7
8
9
10
off
12
13
14
15
v12
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
当前步骤

显示 OP-V 32 位编码字段

vid.v 使用 OP-V 编码;vs1 字段固定为 10001,vs2 字段也固定为保留值 00000。

动画只展示官方 V 扩展定义的 ISA 可见关系:OP-V 字段解析、vl 内 active mask bit 扫描、目标整数向量写回;不模拟流水线、缓存或执行时延。

快速理解与检索要点

VID.V 将活动元素的编号 i 写入 vd[i];掩码不改变编号,关闭元素按 vma 保留旧值或采用 agnostic 策略。

官方语法为 `vid.v vd, vm`;OP-V VMUNARY0 编码使用 `funct6=010100`、`funct3=010`、`vs1=10001`,并要求保留的 `vs2` 字段为 `00000`。
对每个 active body 元素 i,结果为元素编号 i;结果按当前 SEW 宽度写入目标整数向量元素。
vm=0 时 v0.t 选择活动元素,但不重新编号;关闭元素按 vma 处理,不保证为0。
该指令不读取普通源向量或内存,常用于为 gather、scatter、compress 或条件选择构造元素索引。

向量执行上下文

32 位 OP-V:opcode=1010111、funct3=010、funct6=010100。vs1=10001 是固定 selector;vs2=00000,其他值保留。语法没有普通源向量。

活动元素 i 写入编号 i,掩码不重新编号。SEW 较宽时零扩展,编号溢出时保留低 SEW 位;不是字节偏移,也不读取内存。

vd 使用当前 LMUL 的整数向量组;masked 目标不能与 v0 重叠。

省略 v0.t 为 vm=1,写出为 vm=0。prestart 不更新;inactive/tail 按 vma/vta 处理,undisturbed 保留旧值,agnostic 可保留旧值或写全1。vl=0 或 vstart≥vl 不更新任何目标(包括 tail);成功执行后 vstart=0。

V 1.0 适用于 RV32/RV64;要求合法 vtype 和 VS 已启用。动画固定 SEW=32、LMUL=m1、VLEN=4096、vstart=0、ta/ma;不展示非零 vstart 或索引截断边界,不表示处理器周期。

The RISC-V Instruction Set Manual, Volume I: Unprivileged Architecture — Version 20260120, Chapter 31

常见使用场景

序列生成

假定合法 e32,m1、VS 已启用、所需格式受支持、VLMAX≥4、a0=4,vsetvli 后 vl=4、vstart=0。v0.t 选择 lane 0、2、3;v0 mask=1011 → v1=[0,agnostic,2,3]。非活动/尾部按 ma/ta 处理,不保证清零。

循环计数器

假定合法 e32,m1、VS 已启用、所需格式受支持、VLMAX≥4、a0=4,vsetvli 后 vl=4、vstart=0。v0.t 选择 lane 0、2、3;v0 mask=1011 → v1=[0,agnostic,2,3]。非活动/尾部按 ma/ta 处理,不保证清零。

用作gather索引

假定合法 e32,m1、VS 已启用、所需格式受支持、VLMAX≥4、a0=4,vsetvli 后 vl=4、vstart=0。v0.t 选择 lane 0、2、3;v0 mask=1011 → v1=[0,agnostic,2,3]。非活动/尾部按 ma/ta 处理,不保证清零。

使用前检查清单

语法检查
  • 32 位 OP-V:opcode=1010111、funct3=010、funct6=010100。vs1=10001 是固定 selector;vs2=00000,其他值保留。语法没有普通源向量。
  • 活动元素 i 写入编号 i,掩码不重新编号。SEW 较宽时零扩展,编号溢出时保留低 SEW 位;不是字节偏移,也不读取内存。
语义检查
  • vd 使用当前 LMUL 的整数向量组;masked 目标不能与 v0 重叠。
  • 省略 v0.t 为 vm=1,写出为 vm=0。prestart 不更新;inactive/tail 按 vma/vta 处理,undisturbed 保留旧值,agnostic 可保留旧值或写全1。vl=0 或 vstart≥vl 不更新任何目标(包括 tail);成功执行后 vstart=0。
  • V 1.0 适用于 RV32/RV64;要求合法 vtype 和 VS 已启用。动画固定 SEW=32、LMUL=m1、VLEN=4096、vstart=0、ta/ma;不展示非零 vstart 或索引截断边界,不表示处理器周期。

容易混淆 / 常见误区

VID.V 生成的是元素编号 0,1,2,...,不是字节偏移、内存地址或寄存器组内的字节位置。
语法只有 vd 和可选 vm;编码中的 vs2 字段为保留字段,不是可编辑源向量操作数。
vm=0 时 v0.t=0 的 body 元素不写入索引结果;vma=0 保留旧值,vma=1 可保留旧值或写全1。尾部按 vta 处理。
如果索引值不能用当前 SEW 表示,结果按低 SEW 位写入;普通学习示例通常选择能容纳 vl-1 的 SEW。

常见问题

VID.V 的索引是字节偏移吗?

不是。VID.V 写入的是元素编号 i,从 0 开始;如果后续要形成字节地址,还需要结合元素宽度或显式缩放。

VID.V 会读取 vs2 吗?

不会。规范把 VID.V 归在同一类 OP-V 编码中,但它的保留源字段必须为 00000,语法中没有 vs2 源操作数。

掩码关闭的 VID.V 元素会写入 0 吗?

不保证为0。vma=0 保留旧值,vma=1 可保留旧值或写全1;尾部按 vta 处理。vl=0 时所有目标元素包括 tail 均不更新。