RISC-V MCU中文社区

【分享】 利用vcs仿真NICE协处理器demo

发表于 全国大学生集成电路创新创业大赛 2023-05-27 17:35:38
0
1470
1

团队编号:CICC2136
团队名称:芯如止水

NICE协处理器demo实现功能介绍:

假设有一个3*3的矩阵,需要计算其逐行的累加和以及逐列的累加和,如果采用常规c语言程序进行计算,需要采用循环的方式

// normal test case without NICE accelerator.
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 < ROW_LEN; i++)
  {
    tmp = 0;
    for (j = 0; j < COL_LEN; j++)
    {
      col_sum[j] += array[i][j];
      tmp += array[i][j];
    }
    row_sum[i] = tmp;
  }
  return 0;
}

转化成汇编代码需要较多指令,因此可以使用协处理器加速这一过程

NICE协处理器demo自定义指令:

NICEdemo中定义了clw,csw,cacc三条指令

clw: 从内存中加载数据至行数据缓存
csw:从行数据缓存中存储数据至内存
cacc:用于计算行累加值,并通过结果寄存器返回累加值

自定义指令需要通过伪指令.insn实现,使用格式如下:

.insn r opcode func3 func5 rd rs1 rs2

因此,NICEdemo自定义指令的表示方式如下:

.insn r 0x7b 2,1,x0,%1,x0
.insn r 0x7b 2,2,x0,%1,x0
.insn r 0x7b 6,6,%0,%1,x0

相应的软件驱动可以表示为:

// 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; 
}

仿真NICEdemo

  • 在路径”/nuclei-board-labs-master/e203_hbirdv2/common/demo_nice”下可以找到demo_nice的相关代码
  • 编译demo_nice,得到demo_nice.verilog文件
  • 在e203_hbirdv2-master/vsim/Makefile中,修改TESTNAME和TESTCASE,修改为demo_nice.verilog文件对应的路径
  • 在vsim中使用make run_test命令,可以运行demo_nice的仿真
    最终运行结果如下:
喜欢1
用户评论

积分
问答
粉丝
关注
  • RV-STAR 开发板
  • RISC-V处理器设计系列课程
  • 培养RISC-V大学土壤 共建RISC-V教育生态
RV-STAR 开发板