芯片原厂必学课程 - 第十篇章 - 基于 RISC-V SoC 的 1024 点 FFT 设计
10-02-11 RISC-V 自定义指令的设计流程
新芯设计:专注,积累,探索,挑战
文章目录
引言
本次项目的设计主要是针对海量点数 FFT 的高速实时处理,搭建了一个基于 RISC-V 指令集架构的专用矢量多核硬件系统。基于不同基数的张量 FFT 算法的矢量与并行的硬件匹配特性,在上一章节的 RISC-V FFT 系统设计的基础上,对其 RISC-V 内核进行部分的删减以及增加一些专用的硬件 PE 设计单元及其对应的 RISC-V 自定义指令二进制编码。最终,构造了基于专用 RISC-V 矢量内核的张量 FFT 多核系统。实验结果表明,本次设计的张量 FFT 专用多核系统,相比于时分 FFT 通用单核系统,能够取得良好的指令加速比,且随着 FFT 输入点数的增加而提高。
针对本文的矢量硬件 PE 加速设计,需要相应的 RISC-V 自定义指令来驱动数据与控制信号。RISC-V 指令的自定义是比较复杂的,不仅需要在硬件部分上加以修改,更是要建立其软硬件的生态环境。这是 RISC-V 一系列的完整的自定义指令开发流程,主要分为硬件部分和软件部分的更改。
NOTES:本文来自《芯片原厂必学课程 - 第十篇章 - 基于 RISC-V SoC 的 1024 点 FFT 设计》技术专栏
🌏 一、RISC-V 自定义指令的流程
✅ 硬件部分
首先是确定硬件加速单元的操作类型,可以是矢量的形式,也可以是数组的形式,可以是四个数据相乘,也可以是八个数据相加,可以是基于矩阵相乘,也可以是基于向量內积等等。然后就是自定义相应的指令,给出对应的操作码、源地址、目的地址等等。在确定硬件单元及其对应指令毕之后,就可以开始电路的设计,修改 Verilog HDL 代码。其中,包括了宏定义的修改、译码模块的改动以及 ALU 中的自定义 IP 硬件逻辑设计。接着,对数据通路与控制通路进行整合,增加或者合并数据通路和控制信号,并检查控制信号和数据通路是否完备,使其能够顺利完成每一条指令的执行而不发生冲突冒险等等。最后就可以根据输入的一些自定义的指令,通过时序仿真来查看相应的寄存器数据的变换是否符合预期。这里暂时不需要进行交叉编译生成二进制机器代码去仿真,因为还涉及到软件的自定义指令的修改。可以自己先简单地在 Testbench 上自己输入相关的具体的指令,从而判断自己的添加的自定义模块的设计是否正确。
✅ 软件部分
对于软件部分的改动,主要是对 GCC 工具链增添一些相关的定义。首先是定义自定义的指令,从而生成操作码宏定义。接着是修改 GNU 工具链,令新的指令嵌入到 GCC 工具链中,使其得以编译实现。最后,就可以进行 C 程序的编写及其二进制代码的生成,并加以测试。这样,通过软硬件部分的协同改动,才能够建立起 RISC-V 自定义指令的生态。
🌏 二、RISC-V 自定义指令的类型
在 RISC-V 的指令架构设计中,为 RISC-V 指令的自定义设计预先保留了大量的指令编码空间以及预定义的、能够支持不同长度的 CUSTOM 指令。由于本次项目是以 32 位自定义指令的形式,因此,主要讨论RISC-V架构是如何支持 32 位指令扩展的。这是 RISC-V 32 位架构的指令操作码表,指令的低 7 位为操作码类型,且操作码的低 2 位都为二进制 1。
由表可知,RISC-V 预留出了 4 个用户自定义类型,即 custom-0、custom-1、custom-2 和 custom-3。其中,custom-0 和 custom-1 用于 RV32 的自定义指令集扩展,而 custom-2 和 custom-3 主要预留给 RV128。这 4 类指令统称为 CUSTOM 指令,用户可以使用该指令来扩展硬件加速单元或者协处理器的指令。其实,对于不需要或者没被使用的指令空间,我们均可以加以使用,关键部分在于译码模块和 ALU 模块对应的数据通路。
🌏 三、RISC-V 自定义指令的编码
针对上述表格,操作码字段选取“00_010_11”或者“01_010_11”为指令的低 7 位 opcode,这就定义了一种新的类型的指令。