报名编号:CICC1014 团队名称:华芯极客
本文首先将原蜂鸟E203 SoC中乘法和除法指令的实现模块进行了更改,使其运行周期缩短,之后需要对其进行仿真验证,本文将分享一下仿真验证的方法。
在仿真前先使用vivado对整个工程进行综合执行,之后需要修改仿真文件tb_top.v中的.verilog文件路径,如下图绕圈中所示,该文件由.elf文件转换生成,转换方法见后文,而.elf文件正是由c程序生成的用于下载到开发板中的二进制代码,下面将对用于功能验证的c程序进行设计和介绍。
RISC-V架构一共有4条乘法相关指令和4条除法相关指令,4条乘法指令为mul、mulh、mulhu和mulhsu,其中带h的指令读取乘法结果的高32位,带u表示将操作数当作无符号数,带su表示将rs1和rs2中的操作数分别当作有符号数和无符号数,如果希望得到完整的64位结果,可以使用两条连续的乘法指令"mulh[[s]u] rdh,rs1,rs2;mul rdl,rs1,rs2",其中[]表示可选,如果两条指令的源操作数索引和顺序完全相同,并且rdh和源操作数索引不同,则蜂鸟E203处理器会将其融合成一指令执行,即进入b2b(back to back)模式,因为第一条指令已经生成了64位的乘法结果并保存到了寄存器中,当执行mul指令时可以直接从寄存器中获取结果,而不需要重新计算。4条除法指令为div、divu、rem、remu,div表示取商,rem表示取余数,当执行两条连续的指令"div[u] rdq,rs1,rs2; rem[u] rdr,rs1,rs2"时,蜂鸟E203处理器同样会进行b2b模式,从而提高性能。下面给出本文用于乘法指令和除法指令测试的c程序代码:
#include __STATIC_FORCEINLINE void mul_test(int a,int b){ int begin_cycle,end_cycle,cycle; } __STATIC_FORCEINLINE void div_test(int a,int b){ int main(void) |
这里仅对带符号数进行测试,无符号数测试类似,之后可以按照帖子https://www.rvmcu.com/community-topic-id-386.html那样用nuclei studio生成.verilog文件,或者直接在对应代码文件夹中打开终端并输入make dasm生成,具体请参考https://doc.nucleisys.com/hbirdv2/quick_start/sdk.html,这两种方式本质上都是使用了命令 riscv-nuclei-elf-objcopy ".elf" -O verilog ".verilog"来生成.verilog文件。本文采用了第二种方式,但要注意的是,用make dasm命令生成的.verilog代码的默认起始地址为0x80000000,如下图,需要修改为0x00000000,后面的地址标记也要改为@0开始。最后进行仿真与测试,可参考帖子https://www.rvmcu.com/community-topic-id-386.html。
下图为本文的仿真结果,代码中的printf打印结果在Tcl Console窗口中显示,将乘除法指令实现模块中的信号添加到波形件中,点击感兴趣的信号,并点击"||"符号进行定位(下图红圈所示),即可快速查看感兴趣信号的仿真波形。