RISCV 向量指令集和NICE接口学习笔记

本文档链接 https://blog.youkuaiyun.com/weixin_42487906/article/details/115437890

RISCV向量指令集学习

参考链接

https://github.com/riscv/riscv-v-spec
RSIC-V——指令集spec阅读笔记——向量扩展0.9
RISC-V Vector Extension学习笔记

向量指令集用例

可以对照下面的说明来看这个例子

.text
    .balign 4
    .global vvaddint32
    # vector-vector add routine of 32-bit integers
    # void vvaddint32(size_t n, const int*x, const int*y, int*z)
    # {
    for (size_t i=0; i<n; i++) {
    z[i]=x[i]+y[i]; } }
    #
    # a0 = n, a1 = x, a2 = y, a3 = z
    # Non-vector instructions are indented
vvaddint32:
    vsetvli t0, a0, e32, ta,ma  # Set vector length based on 32-bit vectors
    vle32.v v0, (a1)         # Get first vector
      sub a0, a0, t0         # Decrement number done
      slli t0, t0, 2         # Multiply number done by 4 bytes
      add a1, a1, t0         # Bump pointer
    vle32.v v1, (a2)         # Get second vector
      add a2, a2, t0         # Bump pointer
    vadd.vv v2, v0, v1       # Sum vectors
    vse32.v v2, (a3)         # Store result
      add a3, a3, t0         # Bump pointer
      bnez a0, vvaddint32    # Loop back
      ret                    # Finished

名词解释

ELEN 向量中单个元素的最大长度,bit为单位,要求ELEN>=8,且为2的幂
VLEN 向量寄存器的位数,bit为单位,要求VLEN ≥ ELEN,并且必须是2的幂
SLEN 分段距离(The striping distance in bits),要求必须为VLEN ≥ SLEN ≥ 32,并且必须为2的幂,这个暂时没懂
SEW 标准元素宽度,以bit为单位,指向量中一个元素占向量寄存器中的位数
LMUL 向量寄存器分组数
寄存器定义
v0-v31 向量数据寄存器,共32个,固定位宽为VLEN位
vtype 向量数据类型寄存器,并且只能通过vsetvl{i}指令进行更新,向量类型还决定了每个向量寄存器中元素的排布,以及如何对多个向量寄存器进行分组。
vsew[2:0] 变化的标准元素宽度(SEW, standard element width)值通过vsew中的值设置。默认情况下,向量寄存器被视为分成 VLEN / SEW 个标准宽度元素。
vlmul[2:0 ] 向量寄存器分组,分成一组的多个向量寄存器可以当作一个操作数来用,用来存放一个向量,该值也可以是小数,用来等效增加向量数据寄存器的数量
VLMAX VLMAX = LMUL * VLEN / SEW,
vta和vma 这两位元素值在执行向量指令期间分别修改了目标尾部元素(Tail Elements)和非活跃的掩码元素(Inactive masked-off Elements)的行为。
vill vill位用于编码先前的vsetvl{i} 指令试图向vtype写入不支持的值
vl 向量长度寄存器,以存放向量总共有多少个元素,只能通过vsetvli和vsetvl指令进行更新。
vlen 向量寄存器长度寄存器,是一个常数,保存值 VLEN / 8,即向量寄存器长度(以字节为单位)。
vstart vstart是一个可读可写的CSR寄存器,指定向量指令要执行的第一个元素的索引。每个向量指令执行完后,该寄存器清零。
vcsr 向量控制和状态寄存器vcsr,保存定点舍入的方式和饱和状态

在这里插入图片描述
在这里插入图片描述

向量元素到向量寄存器的映射

根据当前的 SEW 和 LMUL 设置以及 ELEN,VLEN 和 SLEN 的值,怎么将不同宽度的元素存放到矢量寄存器的字节中。并且使用最少位数的最低有效字节将元素放到每个向量寄存器中。
当 VLEN=SLEN , LMUL=1 时,从向量寄存器的最低有效位到最高有效位依次对元素进行简单排布。当 LMUL <1 时,仅使用向量寄存器中的第一个 LMUL * VLEN / SEW 元素。 向量寄存器中的剩余空间被视为尾部的一部分。

在这里插入图片描述
在这里插入图片描述
VLEN = SLEN 且 LMUL > 1时, 将向量寄存器分组后,根据向量寄存器组中的向量寄存器来划分组中的元素。当 SLEN = VLEN 时,按元素顺序将其放在组中的每个向量寄存器中,填满一个向量寄存器后,便移至组中下一个编号最高的向量寄存器。

在这里插入图片描述
在这里插入图片描述
向量 ISA 的设计目的是支持混合宽度操作,并且不需要大量显式的额外的重排指令,也不需要大量额外的数据路径(datapath)布线。在对不同精度值的向量进行操作时,推荐的做法是动态修改 vtype 值,从而使得 SEW/LMUL 为常量(因此 VLMAX 常量)。向量寄存器分组因子(LMUL)按相关元素大小增加,这样每个向量寄存器组可以保存相同数量的向量元素(本例中 VLMAX=16 ),从而简化 stripmining 代码。下表列出了执行混合宽度操作的循环的每个可能的 SEW / LMUL 操作点。 每列代表一个恒定的 SEW / LMUL 操作点。 表中列出的内容是 LMUL 值,该值生成该列的 SEW / LMUL 值。 在同一列中, LMUL 的值不同,但 VLMAX 值相同。(可以保证每个向量寄存器组中的向量元素数量相同)
在这里插入图片描述
在这里插入图片描述

配置寄存器操作指令

vsetvli/vsetvl

用例
vsetvli rd, rs1, vtypei # rd = new vl, rs1 = AVL, vtypei = new vtype setting
vsetvl  rd, rs1, rs2    # rd = new vl, rs1 = AVL, rs2 = new vtype value

在这里插入图片描述

解释

指令根据其参数设置 vtype 和 vl CSRs,并将 vl 的新值写入 rd。
两个指令的区别:vtypei是个立即数,rs2是个寄存器
AVL=应用程序向量长度

vsetvl{i}指令首先根据 vtype 参数,设定 VLMAX ,然后设置vl服从以下约束:

  • 如果 AVL ≤ VLMAX ,则 vl = AVL
  • 如果 AVL < (2 * VLMAX),则ceil(AVL / 2) ≤ vl ≤ VLMAX
  • 如果 AVL ≥ (2 * VLMAX),则 vl = VLMAX
  • 如果输入相同的 AVL 和 VLMAX 值,则任何实现中,v1 都是确定的
    满足之前提及的规则:
    如果 AVL = 0,则 vl = 0
    如果 AVL > 0,vl > 0
    vl ≤ VLMAX
    vl ≤ AVL
    从 vl 中读取的值(用作 vsetvl{i} 的 AVL 参数时)会在 vl 中产生相同的值,前提是所得的 VLMAX 等于读取vl时的 VLMAX 值
    在这里插入图片描述
    在这里插入图片描述

向量操作指令中的掩码

掩码vm
在指令中占一位,使用v0寄存器存放掩码值,vm为1时不启动掩码,vm为0时,当v0的相应位为1,目标向量寄存器写入相应的值
在这里插入图片描述

掩码向量的加载操作不会更新目标向量寄存器组中的非活跃元素。掩码向量的存储操作只更新内存中的活跃元素。

向量加载和存储指令(访存)

在这里插入图片描述

mop 访存时选择访存模式

在这里插入图片描述
支持连续访存,跨步访存和按索引访存

lumop/sumop

还没搞懂是做什么用的 fault only first似乎可以简化循环操作
在这里插入图片描述

向量加载/存储的宽度编码
  • Mem bits(内存位)是内存中访问的每个元素的大小。
  • Reg bits(寄存器位)是寄存器中访问的每个元素的大小。
    在这里插入图片描述
向量单步幅跨步(Unit-Stride)指令
#vd destination, rs1 base address, vm is mask encoding (v0.t or <missing>)
    vle32.v  vd, (rs1), vm # 32-bit loads

l代表load,e32代表向量元素长32

#vs3 store data, rs1 base address, vm is mask encoding (v0.t or <missing>)
    vse64.v  vs3, (rs1), vm  # 64-bit stores

s代表save

向量跨步(Strided)指令
# vd destination, rs1 base address, rs2 byte stride
    vlse8.v  vd, (rs1), rs2, vm  # Load bytes separated by stride

vls中l代表load,s代表stride,rs2存放跨步值

# vs3 store data, rs1 base address, rs2 byte stride
    vsse128.v vs3, (rs1), rs2, vm  # Store 128b values separated by stride.

vsse128中,第一个s是save,第二个是stride

向量索引(indexed)指令
# vd destination, rs1 base address, vs2 indices
    vlxei16.v  vd, (rs1), vs2, vm  # vs2 data EEW = SEW, indices EEW = 16b

有序加载,vs2存放索引,vs2中元素大小为16bit

# Vector unordered-indexed store instructions
    vsuxei64.v vs3, (rs1), vs2, vm # SEW data, 64b indices

无序存储,vs2中元素大小为64bit

向量原子操作

原子操作指令 暂时用不到

向量计算指令

向量的算术指令使用与 OP-FP 相邻的新的主要操作码1010111。 funct3 字段的三位用于定义向量指令的子类。
在这里插入图片描述
向量与标量之间的运算可以采取三种可能的形式,但无论采取哪种形式,都要从 vs2 指定的向量寄存器组中获取一个操作数向量,并从三个替代源之一获取第二个标量源操作数。

  • 对于整数运算,标量可以是编码在 rs1 字段中5位立即数。该值通过符号扩展或加零扩展到SEW 位。
  • 对于整数运算,可以从rs1 指定的标量寄存器x中提取标量。如果 XLEN > SEW,则使用x的最低有效SEW位。如果 XLEN < SE
### 回答1: RISC-V Spec中文版是一个关于RISC-V指令集架构的规范文档。RISC-V是一种开放的、基于精简指令集计算(Reduced Instruction Set Computing, RISC)原则的指令集架构,旨在提供灵活性、可扩展性定制性。 RISC-V Spec中文版详细描述了RISC-V的指令集架构,包括指令的格式、操作码、寄存器集合、指令执行的行为及其对应的功能。它定义了RISC-V的各个指令的用法、语法特性,以及各种数据类型、寄存器操作内存操作。 RISC-V Spec中文版也介绍了RISC-V支持的不同扩展,包括整数扩展、浮点扩展向量扩展。这些扩展允许使用者根据自己的需求来选择定制指令集,使得RISC-V适用于不同领域应用,如嵌入式系统、高性能计算、人工智能等。 RISC-V Spec中文版还包含了系统级指令特权指令的规范。系统级指令用于处理器的初始化、中断处理、存储管理外设控制等操作。而特权指令用于访问系统资源保护机制,如访问特权级别、异常处理虚拟内存管理等。 通过阅读RISC-V Spec中文版,人们可以深入了解RISC-V指令集架构的细节特性,从而能够更好地设计、实现优化RISC-V处理器。同时,该规范也为RISC-V生态系统的发展提供了基础,帮助各类硬件供应商、软件开发者学术研究者更好地使用推广RISC-V技术。 ### 回答2: RISC-V(Reduced Instruction Set Computing)是一种指令集架构(ISA),其规范(spec)提供了一套与计算机硬件系统软件相关的详细设计指南,以实现基于RISC-V ISA的处理器设计。 RISC-V的设计目标是提供一个简洁、模块化、可扩展开放的指令集架构。RISC-V规范中文版提供了对于指令编码、寄存器架构、内存管理、中断处理、异常处理、外设支持指令集扩展等方面的详细描述规定。 RISC-V指令编码使用固定长度的指令,包括基本整数指令、浮点指令、原子指令等。通过不同的扩展模块,RISC-V可以支持不同级别的复杂性功能,从而满足不同应用的需求。规范中规定了指令的具体编码格式操作数类型,保证了软件在不同实现上的可移植性。 寄存器架构是RISC-V的一个重要组成部分,规范中详细描述了寄存器的数量、用途寄存器文件的布局。RISC-V使用了一个基于Load/Store的内存模型,规范中定义了内存访问指令内存管理机制,并对虚拟内存页表机制提供了支持。 RISC-V规范中文版还包括了中断处理异常处理的规定。通过中断,处理器可以响应外部事件或用户程序的请求。规范中定义了中断源中断控制器的接口,以及中断处理的程序执行流程。异常处理允许处理器在出现错误或异常情况时进行适当的响应处理。 最后,RISC-V规范中文版提供了对于外设支持指令集扩展的描述。外设支持允许处理器与外部设备进行通信数据交换,规范中定义了外设的接口数据传输方式。指令集扩展可以通过添加新的指令功能来提供更丰富的处理器功能,规范中提供了相关的扩展机制规定。 总的来说,RISC-V规范中文版提供了一套详细的设计指南,可以帮助硬件设计师系统软件开发人员了解实现基于RISC-V ISA的处理器系统。它的开放性灵活性使得RISC-V成为了一个备受关注的指令集架构,并在各个领域得到广泛应用。 ### 回答3: RISC-V(Reduced Instruction Set Computer-V)是一种基于开放标准的指令集架构(ISA),它是为了满足广泛应用特定需求而设计的。RISC-V ISA的设计简洁、清晰,易于理解实现。RISC-V的设计采用了精简的指令集,从而帮助开发者降低了设计验证的复杂性,提高了处理器的性能效能。 RISC-V的规范是由RISC-V国际联盟制定的,该联盟由来自学术界、工业界开源社区的成员组成。RISC-V规范提供了完整而详细的指令集架构描述,这使得任何人都可以根据其规范设计、实现定制自己的RISC-V处理器。 RISC-V规范中文版是对RISC-V规范的中文翻译版本。它的存在帮助了不懂英文的开发者理解RISC-V的设计原理指令集架构。RISC-V规范中文版通常包括对指令集的分类、指令集的详细介绍、寄存器的描述以及处理器的工作方式等内容。 对于想要从事RISC-V处理器设计开发的开发者来说,熟悉RISC-V规范中文版非常重要。通过阅读理解规范,开发者可以了解RISC-V处理器的设计原理、指令运行的方式结构,从而更好地进行相关开发工作。 总而言之,RISC-V规范中文版是对RISC-V规范的翻译版本,它帮助开发者理解RISC-V的设计原则指令集架构,为RISC-V处理器的设计开发提供了重要的参考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值