编程模型¶
控制和状态寄存器¶
根据RISC-V向量指令集文档v0.8,实现一个RISC-V向量指令集拓展需要增加六个控制和状态寄存器,这里仅给出了实现最小集所必须的两个寄存器信息(vtype和vl)。关于其他寄存器(vstart、vxsat、vxrm、vlenb)的详细信息将在未来加以补充,亦可参考RISC-V向量指令集文档。
vtype寄存器¶
vtype寄存器是一个只读寄存器,其宽度为XLEN。vtype寄存器的值只能通过vsetvl/vsetvli指令进行更新。vtype寄存器的结构如下表所示。
| 位 | 名称 | 说明 |
|---|---|---|
| XLEN-1 | vill | 非法值标识位 |
| XLEN-2:7 | 保留(写入0) | |
| 6:5 | vediv[1:0] | EDIV拓展使用 |
| 4:2 | vsew[2:0] | 标准单元宽度(SEW)设置 |
| 1:0 | vlmul[1:0] | 向量寄存器分组乘数(LMUL)设置 |
vsew 域动态设置标准单元宽度(SEW),其与标准单元宽度的对应关系如下表所示。注意,SEW的最大值ELEN为设计时参数,其值应满足不超过向量寄存器宽度 VLEN 。
| vsew[2:0] | SEW |
|---|---|
| 000 | 8 |
| 001 | 16 |
| 010 | 32 |
| 011 | 64 |
| 100 | 128 |
| 101 | 256 |
| 110 | 512 |
| 111 | 1024 |
vlmul域涉及向量寄存器分组的信息,满足 LMUL = 2^{vlmul[1:0]}
Warning
TODO:补充vlmul域说明。
vl寄存器¶
vl寄存器是一个只读寄存器,其宽度为XLEN。vl寄存器的值只能通过vsetl/vsetli指令进行更新(通过更新vtype寄存器的值来间接地更新vl)。vl寄存器保存一个无符号整数,用以指明一个向量操作中更新的单元数。下标值不小于vl的目标向量寄存器(组)中单元将保持不变。
向量寄存器¶
RISC-V向量拓展要求增加32个向量寄存器vv0-vv31。其中每个寄存器的宽度为VLEN,VLEN为设计时参数。
Warning
TODO: 补充关于向量寄存器内部多个标准单元的组织以及向量寄存器分组的内容。
共享寄存器¶
为了实现向量处理的解耦,除了向量形式的向量寄存器,向量处理器中还应当具备一组共享的标量寄存器vs0-vs31。其宽度应当为ELEN,即可保存一个单元。
参数¶
来自控制处理器的参数:
XLEN- 处理器寄存器宽度,一般为 32/64, 即 32/64 位处理器。
FLEN- 可运算的浮点数宽度,一般为 32/64,对应单精度/双精度浮点。
向量处理器自身身的参数:
VLEN- 向量寄存器的宽度,是一个设计时常量。
ELEN- 每个向量元素的最大宽度,是一个设计时常量。
SLEN- 影响
LMUL大于一的时候元素的排列顺序,是一个设计时常量。 SEW- 运算时每个元素的宽度,是一个运行时变量,需要支持常见的宽度。
LMUL- 运算时操作的相邻向量寄存器的个数,是一个运行时变量。
VLMAX- 一条指令操作的元素的最大个数,通过以上参数计算而来。
MLEN- 运算时 mask 的位置的间距,一个 bit 对应一个 element,通过以上参数运算而来。
它们满足以下等式:
LMUL <= 8 <= SEW <= ELEN <= VLEN
32 <= SLEN <= VLEN
VLMAX = LMUL * VLEN / SEW
MLEN = VLEN / VLMAX
除了这些约束外,上述的所有量都只能取 2 的某个幂次。
为了设计简单,可以设 ELEN = max(XLEN, FLEN),即 VP 中每个向量元素的宽度不大于控制处理器能处理的整数和浮点数的宽度。这意味着 FP 中的所有运算器件(ALU 和 FPU)需要支持宽度在 8 到 ELEN 比特之间的的操作数长度。
此外,在任何 RISC-V 向量处理器系统中,一条指令最多操作个元素为 VLEN 个,此时 LMUL = SEW = 8,VLMAX = 8 * VLEN / 8 = VLEN。
运行流程¶
控制核上的代码需要进行的操作:
- vsetvl/vsetvli 按照当前剩余的元素个数设置新的 vl 。
- vmcs 把控制核的通用寄存器赋值给向量核的共享寄存器。
- vf 启动向量线程。
- 从当前剩余的元素个数减去 vl,如果还有剩余,回到第一步。
- 计算完毕,通过 fence 指令等待所有向量线程结束。
向量线程模型:
- 向量线程启动时会对当前的共享寄存器进行一次快照,在这个快照上运行向量代码,不会影响原来的值。
- vmcs 只保证下一次 vf 启动的向量线程看到共享寄存器的更新,之后的 vf 不提供这个保证。
Info
实际上实现为两套寄存器,一套供正在运行的向量线程使用,一套临时共享寄存器供 vmcs 更新。每次 vf 会交换向量线程的寄存器和临时共享寄存器。