RISC-V MCU中文社区

【分享】 CICC2033:关于C语言仿真的一些说明

发表于 全国大学生集成电路创新创业大赛 2023-05-31 20:27:26
0
663
1

C语言运行说明

操作说明(以helloworld为例)

1、在SDK环境下写好C语言相关代码。

最简单的写法为根据已有demo进行更改。如果说需要重新创建新的SDK项目,具体写法可以参考官方sdk文档。

2、在C语言SDK项目的目录下编译、汇编

进入C语言SDK项目的目录(此处以helloworld为例),具体路径如下:

/home/wangchen666/Riscv/nuclei-sdk/application/baremetal/helloworld

执行如下命令:

make dasm CORE=e203 DOWNLOAD=ilm SIMULATION=1

此命令中:dasm 命令表示生成.verilog文件,CORE=e203代表当前的CORE为e203,DOWNLOAD=ilm表示直接从ilm中运行程序,SIMULATION=1可以优化仿真的过程。

可以观察到生成了.verilog文件。

3、将上述汇编后的项目放入仿真环境

具体仿真环境路径如下:

/home/wangchen666/Riscv/Project1/n200_rls_pkg/n200/vsim

注意:最好将整个项目搬移过来(指整个helloworld文件夹),不过也可以只复制.verilog文件,毕竟最后读进去的是.verilog文件。

在仿真路径中执行如下命令:

make run_test TESTCASE=$PWD/helloworld/helloworld

此命令中:TESTCASE=$PWD/helloworld/helloworld,前面的/helloworld代表进入helloworld文件夹,后面的helloworld代表helloworld.verilog

执行完成后就可以看到相关输出。

项目的更改事项

1、对SDk部分的更改

更改文件如下:

/home/wangchen666/Riscv/nuclei-sdk/Build/Makefile.rules

文件中有一个命令为dasm,在dasm命令下增加如下两行

sed -i 's/@8000/@0000/g' "$(TARGET).verilog"
sed -i 's/@90000/@00006/g' "$(TARGET).verilog"

增加这两行命令的原因:在实际运行中,ilm的进入地址为@8000_0000,dlm的进入地址为@9000_0000。但是在运行testbench的时候,tb_mem_init.v文件中只单独读取了ilm,此处默认读取ilm后@0000_0000对应于实际运行情况下的@8000_0000。dlm与之同理,将dlm的进入地址设置为@0000_6000对应于之际情况下的@9000_0000

完整的dasm命令如下:

dasm: $(TARGET).elf
    -$(OBJDUMP) -S -d $< > $(TARGET).dump
    -$(OBJDUMP) -d $< > $(TARGET).dasm
    -$(OBJCOPY) $< -O ihex $(TARGET).hex
    -$(OBJCOPY) $< -O srec $(TARGET).srec
    -$(OBJCOPY) $< -O verilog $(TARGET).verilog
    sed -i 's/@8000/@0000/g' "$(TARGET).verilog"
    sed -i 's/@90000/@00006/g' "$(TARGET).verilog"

在更改完成后,再去编译、汇编C程序,就行了。

2、对testbench部分的更改

更改文件如下:

/home/wangchen666/Riscv/Project1/n200_rls_pkg/n200/tb/tb_mem_init.v

首先添加一个总的mem用于存放所用的程序部分包括(指令ilm、数据dlm),并将程序读入这个mem

reg [7:0] mem [0:32'h0000ffff];
$readmemh({testcase, ".verilog"}, mem);

注意:由于原本的tb_mem_init.v中并没有读取dlm这个步骤,所以需要将声明dlm相关的内容,具体声明内容如下:

localparam DLM_RAM_DP = `N200_DLM_RAM_DP;
reg [7:0] dlm_mem [0:(DLM_RAM_DP*`N200_DLM_WMSK_WIDTH)-1];
reg [6:0] dlm_mem_ecc_code[0:DLM_RAM_DP-1];

然后将这个mem分为ilm和dlm:

for (i=0;i<(ILM_RAM_DP);i=i+1) begin
    ilm_mem[i]=mem[i];
end   
for (i=0;i<(DLM_RAM_DP);i=i+1) begin
    dlm_mem[i]=mem[i+32'h00006000];
end

最后,由于tb_mem_init.v中默认将dlm_mem全部赋值为0,所以这一部分需要改成如下内容:

for (i=0;i<(ILM_RAM_DP);i=i+1) begin
    `DLM_MEM[i][00+7:00] = dlm_mem[i*4+0];
    `DLM_MEM[i][08+7:08] = dlm_mem[i*4+1];
    `DLM_MEM[i][16+7:16] = dlm_mem[i*4+2];
    `DLM_MEM[i][24+7:24] = dlm_mem[i*4+3];
    `ifdef N200_HAS_ECC//{
        `ifdef N200_HAS_DLM
    `DLM_MEM[i][38:32] = ecc_code_32gen(`DLM_MEM[i][31:0]);
    `DLM_MEM[i][39] = 1'b0;
        `endif
    `endif//}
end

最后在vsim中就可以正常运行了。

喜欢1
用户评论
CICC2033-陈挺然

CICC2033-陈挺然 实名认证

懒的都不写签名

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