向量扩展在RISC-V基础标量指令集的基础上增加了32个向量寄存器和7个非特权CSR寄存器。CSR寄存器如下表所示,关键的是vtype和vl寄存器。
mstatus寄存器中添加了一个向量上下文状态域 VS(mstatus[10:9]),类似于其中的浮点上下文状态域 FS。当 VS 关闭时,任何试图执行向量指令、或访问向量CSR寄存器的操作都会引起非法指令异常。当存在 hypervisor 扩展时,vsstatus寄存器也需要添加一个向量上下文状态域。
2.1 vtype 寄存器(Vector typer register)
向量元素索引划分:在一条向量指令执行过程中,要操作的所有向量元素可以分为三部分,如下图所示(划分的单位是一个向量元素)。
- prestart:元素索引低于 vstart 寄存器起始值的向量元素,这部分内容不会引起异常也不会更新目标寄存器。
- body:元素索引不低于 vstart 寄存器起始值,且小于当前向量长度的向量元素。这部分内容又可分为两部分:active 和 inactive部分,active部分指 mask 使能的元素位,inactive指 mask 未使能的元素位,inactive 内容不会引起异常且只在 vtype.vma 为1时更新目标寄存器。
- tail:超出vl指示的向量个数的向量元素部分。
2.2 vl 寄存器(vector length register)
2.3 vstart 寄存器(vector start index CSR)
3. 向量元素到向量寄存器状态的映射
根据当前的 VLEN、SEW 和 LMUL 配置将不同宽度的向量元素打包到一个向量寄存器中,小端模式。
混合宽度操作映射举例:
在下例中,同时对宽度为 8b、16b、32b 和 64b 的元素打包,VLEN=128b。
可以看到,通过对每个宽度的元素设置不同的 SEW 和 LMUL 值,打包后每个宽度的元素个数均为8。
4. vector masking
许多向量指令都支持 masking,masked off 的元素不会导致异常,目标向量寄存器对应的元素根据 mask-undisturbed 或 mask-agnostic 机制处理,根据 vtype.vma 确定采用哪种机制。
用于控制掩码向量执行的掩码值由向量寄存器 v0 提供。寄存器 v0 的一位控制一个向量元素,元素数量不会超过 v0 宽度,因为 v0 宽度 VLEN 即为 VLMAX的最大值。
指令编码中的 vm 位指示 masking 情况,当 vm 为 0 时表示 masked。
5. 配置设置指令(vsetvli/vsetivli/vsetvl)
一个通用的处理大量元素的方法是“stripmining”,即通过循环迭代的方式,每次迭代处理一定数量的元素,直到所有元素处理完毕。RISC-V的向量扩展为这种方法提供了直接的、合适的支持。应用程序指定要处理的元素总数作为 vl 的候选值,硬件基于 vtype 的设置计算,通过一个通用目的寄存器返回硬件每次迭代处理的元素个数。
基于上述思想,RISC-V 提供了一组指令用于快速配置 vl 和 vtype 的值以满足应用程序的需求。vset{i}vl{i} 指令基于参数设置 vtype 和 vl CSR寄存器,并将 vl 的新值写回 rd(vl 即为本次迭代要处理的元素数量)。
stripmining 举例:
6. 向量 load 和 store
向量 load 和 store 在向量寄存器和存储器之间移动值,是 masked 的,非活跃元素不会引起异常。masked 的向量 load 不会更新向量寄存器组中的非活跃元素,除非开启 mask-agnostic 机制;masked 的向量 store 则只会更新活跃的存储器元素。
6.1 指令编码
unit-stride 和 constant-strided 方式直接将EEW编码为指令中静态传输的数据的宽度,以减少在混合宽度元素访存过程中 vtype 变化的次数。indexed 方式则。。。。
6.2 vertor load/store 地址模式
支持 unit-stride 、constant-strided 和 indexed 三种地址模式,基址寄存器和步幅来自通用寄存器组。在指令编码中通过 mop[1:0] 指示地址模式。
6.3 向量 load/store 宽度编码
向量 load 和 store 指令直接在指令中编码了一个 EEW(字段width[2:0]),相应的 EMUL=(EEW/SEW)*LMUL,如果EMUL超出合法范围(大于8或小于1/8)则指令编码无效。
其中,unit-stride 和 constant-stride 方式直接为数据值使用指令中的 EEW/EMUL 编码。而 indexed 方式则为索引值使用这一编码,数据值则使用 vtype 中的SEW/LMUL 编码。