NICE协处理器
赛题要求:
对蜂鸟E203 RISC-V内核进行运算算子(譬如加解密算法、浮点运算、矢量运算等)的扩展,可通过NICE协处理器接口进行添加,也可直接实现RISC-V指令子集(譬如P扩展、F/D扩展、V扩展、B扩展、K扩展等)
对于采用NICE协处理器接口进行的扩展实现,需要在蜂鸟软件开发平台HBird SDK中进行相关软件驱动的添加
-
实现思路:
- 1.硬件设计,编写相应的verilog文件,需要注意的是NICE协处理器定义了一些基本的接口;
- 2.编写驱动,通过内联汇编的伪指令.insn配置相关的驱动设置;
- 3.编写用于测试的.C文件。
-
参考示例:
- 背景: 假设有一个3行3列的矩阵按顺序存储在存储器中,每个元素都是32位的整数,目标进行逐行和逐列的累加和,若采用C语言调用主数据通路进行实现,基本思路是循环,按行/列读取各个元素然后相加得到各行/列的累加和,将其转换为汇编语言,则需要约上百个周期才能完成全部运算。
-
硬件实现:(不太好写)
(e203_hbirdv2-mastere203_hbirdv2-masterrtle203subsyse203_subsys_nice_core.v)->NICE协处理器工作机理:
- 请求通道:主处理器在流水线的EXU级时,将指令的编码信息和源操作数传输到协处理器。
- 反馈通道:协处理器告诉主处理器其已完成了该指令,并将结果反馈到主处理器。
- 存储器请求通道:协处理器向主处理器发起存储器读写请求。
- 存储器反馈通道:主处理器向协处理器写回存储器读写结果。
->NICE示例协处理器的设计:
控制模块(和主处理器通过NICE协处理器的接口进行交互)+累加器(累加运算)->NICE示例协处理器的自定义指令
->verilog文件中包含内容:
自定义指令的编码+各模块功能实现(以状态机实现的转换) -
软件驱动:
(nuclei-board-labs-masternuclei-board-labs-mastere203_hbirdv2commondemo_niceinsn.h)
基本格式:
.insn r opcode, func3, func7, rd, rs1, rs2 //.insn告知编译器当前的指令是.insn形式的指令 //r用来表示指令类型为R-type //opcode、func3、func7、rd、rs1、rs2分别代表R类型指令格式的各位域
具体实现:(累加和)
// custom lbuf __STATIC_FORCEINLINE void custom_lbuf(int addr) { int zero = 0; asm volatile ( ".insn r 0x7b, 2, 1, x0, %1, x0" :"=r"(zero) :"r"(addr) ); } // custom sbuf __STATIC_FORCEINLINE void custom_sbuf(int addr) { int zero = 0; asm volatile ( ".insn r 0x7b, 2, 2, x0, %1, x0" :"=r"(zero) :"r"(addr) ); } // custom rowsum __STATIC_FORCEINLINE int custom_rowsum(int addr) { int rowsum; asm volatile ( ".insn r 0x7b, 6, 6, %0, %1, x0" :"=r"(rowsum) :"r"(addr) ); return rowsum; }
- 测试程序:(nuclei-board-labs-masternuclei-board-labs-mastere203_hbirdv2commondemo_niceinsn.c –> 功能实现;nuclei-board-labs-masternuclei-board-labs-mastere203_hbirdv2commondemo_n服务器托管网icemain.c –> 顶层文件,测试输出)
/***********************************insn.c*********************************/ // normal_case:通过主流水线来实现的累加操作 int normal_case(unsigned int array[ROW_LEN][COL_LEN]) { volatile unsigned char i=0, j=0; volatile unsigned int col_sum[COL_LEN]={0}; volatile unsigned int row_sum[ROW_LEN]={0}; volatile unsigned int tmp=0; for (i = 0; i
-
实际测试:
-
法一:(不推荐)通过.c文件配置工程,参考这里(5.3. 无模板手动创建项目)
-
法二:(推荐)
- 创建HelloWorld例程,删除左侧相应工程目录下application/main.c文件
- 将我们所编写的软件驱动文件和测试文件放入该目录下
- 点击锤子进行编译,做好硬件连接后,点击️️绿色的三角运行。
-
采用NICE协处理器进行的累加所用的指令数和周期数都远小于普通情况,如下图所示。
-
一些疑惑:
- 对于NICE协处理器和普通的情况,均进行了诸如循环读寄存器数据之类的操作,那么实现NICE协处理器相较于普通情况的优化体现在什么服务器托管网方面,节约的是进行取数+计算的时间,还是其他诸如循环控制等的时间;
- 是否应该根据后续的系统及应用来判断进行什么样的扩展;
- 对于添加了NICE协处理器的内核,其跑分结果应该有所提高,那么该如何通过跑分的程序测试出来;
3.NucleiStudio+Vivado联合仿真教程
猜测后续的工作流程:
-
Benchmark:
Vivado中修改RTL设计–>NucleiStudio中跑分验证/Vivado中仿真验证(尝试跑通中); -
指令集扩展:
Vivado中添加RTL设计+IDE中添加软件驱动–>NucleiStudio中验证功能/Vivado中仿真验证功能(当前尝试的NICE协处理器可仿真验证)
编写了一个Nucleistudio+Vivado联合仿真的教程,或许会有用((。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net