RISCV
指令编码规则
每个支持向量扩展的硬件线程(hart)定义了两个参数:(1)向量元素最大比特数,ELEN ≥ 8 (2)单个向量寄存器包含的比特数,VLEN ≥ ELEN,该值必须是 2 的幂次方
指令集扩展:1.加define 2.加decode 3. 加ex
1. 香山工具记录
1.1 基础工具介绍
- 香山处理器使用 DiffTest 协同仿真框架进行仿真验证:对于根据riscv手册的两种实现, 给定相同的正确程序, 它 们的状态变化应当一致,其中一种是我们的CPU,另一种模拟器就可以了
lightSSS,它可以在仿真进程出错时自动保存出错点附近的波形和debug信息- Nexus-am,生成workload
- NEMU是参考模型,辅助香山比较和验证微架构,而XiangShan
ChiselDB来将结构化数据存储在数据库
1
2
3
4
5
6
7
8
9
10
11
12
13
#1)generate workload
cd xs-env/nexus-am/apps/xxx
make ARCH=riscv64-xs -j48
#2)using NEMU running workload
cd xs-env/NEMU
make clean && make defconfig riscv64-xs_defconfig && make -j48
$NEMU_HOME/build/riscv64-nemu-interpreter -b xxx.bin
#3)在香山核仿真程序上仿真运行 workload
##这个命令会将 NEMU 模拟器编译成动态链接库,将会在 build 目录下生成文件 interpreter-so ,从而接入到香山仿真差分测试中
make clean && make defconfig riscv64-xs-ref_defconfig && make -j48
#running xiangshan && NEMU to difftest
cd xs-env/XiangShan
./build/emu -i xxx.bin
性能评估验证—还没看
1.2 workload生成(nexus-am/apps代码阅读)
1.3 gdb调试
1
2
3
4
5
6
7
qemu-riscv64 -g 1234 ./main.elf
# 另开一个终端
riscv64-unknown-linux-gnu-gdb main.elf
(gdb) target remote :1234
(gdb) continue
# 程序崩溃后:
(gdb) bt
1.4 qemu运行
accelr-net/tvm-riscv-demo: Demonstrator on running TVM on RISC-V with RN18 and KWS examples
1
2
3
4
5
6
7
8
#1.启动
qemu-system-riscv64 -cpu rv64,v=true -machine virt -nographic -m 8192 -smp 8 -bios opensbi/build/platform/generic/firmware/fw_jump.bin -kernel u-boot/u-boot -device virtio-net-device,netdev=eth0 -netdev user,id=eth0,hostfwd=tcp::2222-:22 -device virtio-rng-pci -drive file=./ubuntu.img,format=raw,if=virtio
#2.ssh
ssh ubuntu@localhost -p 2222
#3.关机
sudo shutdown -h now
#当你想要关闭 QEMU 时,可以在 QEMU 的窗口(非SSH链接)中按 `Ctrl+A`,然后 `X`
2. RVV标准向量扩展介绍
RVV 拥有独立的32个vector寄存器和7个CSRs寄存器,向量指令:设置向量CSR+访存+计算
RVV的tail agnostic,mask agnostic和vector masking
不可知(agnostic)意味着这部分元素不应成为源操作数
RVV规范也充分考虑了不同实现中如何处理非活跃元素(inactive,tail)更方便高效。
对非重命名向量寄存器的处理器来说,给非active元素应用undisturbed策略最经济。因为这类处理器往往VLEN超长,一次仅处理数个元素,跳过非活跃元素可以加速运算,而写1就无法加速运算。因此非重命名架构直接用undisturbed处理更简单。
而重命名架构VLEN较短,通过检查mask和vl,跳过个别元素的收益并不大。在重命名架构中,每个uop读写的寄存器都是经过重命名映射的物理寄存器,对于同一个vd,读和写分别是不同的物理寄存器。于是undisturbed模式就额外多了一个源操作数,发射队列需要多存一份旧vd对应的物理寄存器,也会给物理寄存器堆增加一个旧vd的读取需求,这样会增加物理实现开销。
所以在重命名架构中,解除指令对旧vd的数据依赖对设计是有优化,按写1实现agnostic更有利于性能。
RISC-V “V” Vector Extension Version 1.0 -知乎
2.1 利用rvv指令的方式
编译器支持的话最好,不支持的话,目前intrinsics 函数编程是最容易的
2.x 矢量加载指令的地址模式
矢量元素个数为VLEN/EEW*EMUL
- unit-stride:矢量中每个元素在内存的地址空间中是连续的
- stride:矢量中元素在内存的地址空间是不连续的,并且每个相邻元素的间距(stride)为固定的
- indexed:矢量中元素在内存的地址空间是不连续的,同时每个相邻元素的间距是不固定的
- indexed地址模式又可以细分为保序(ordered)和非保序(unordered)两种,而unit-stride以及strided均为非保序的。保序要求每个元素的访存行为按照其索引大小的顺序发生
1
2
3
4
5
6
7
8
9
10
#1)unit-stride: vd 为目的矢量寄存器, rs1 为内存基地址, vm为掩码(v0.t or <missing>)
vle8.v vd, (rs1), vm # EEW = 8b
#2)strided: ,vd 为目的矢量寄存器, rs1 为内存基地址, rs2 为stride
vlse8.v vd, (rs1), rs2, vm # EEW = 8b
#3)indexed: vd 为目的矢量寄存器, rs1 为内存机地址, vs2 为offset
vluxei8.v vd, (rs1), vs2, vm # unordered, EEW = 8b
vloxei8.v vd, (rs1), vs2, vm # ordered, EEW = 8b
- Minimum Vector Length Standard Extensions(Minimum VLEN 32~1024):用以拓展向量扩展的最小向量长度,有
Zvl32b~Zvl1024b六种 - zve扩展(Vector Extensions for Embedded Processors)

