能否修改Rocketchip Verilator仿真测试台而无需重制核心?
Rocket Chip Verilator 仿真相关问题解答
一、TestDriver.v的角色与修改后的构建要求
你的核心理解方向是对的,但有细节需要明确:
- Rocket Chip的Scala代码通过Chisel生成Verilog并存储在
./emulator/generated-src/,这部分无误。 - Verilator仿真的测试台是Verilog模块+Verilator生成的C封装+自定义C控制代码的组合:
TestDriver.v是顶层Verilog模块,负责衔接Rocket Chip核心与仿真IO接口;- Verilator会把所有Verilog代码(包括
TestDriver.v和生成的Rocket Chip核心Verilog)转换为C++类; - 最终可执行文件还会结合
./emulator/src/main/cpp/下的C++代码(比如emulator.cc),这部分负责控制仿真流程、处理交互逻辑。
所以TestDriver.v确实会被编译进最终可执行文件,修改后必须重新构建模拟器——因为Verilator需要重新将Verilog转换为软件模型,再重新编译整个项目。目前没有办法修改Verilog测试台后跳过重新构建,这是Verilator“硬件转软件”的本质决定的。
二、用$readmemh加载C程序二进制的实现方法
完全可以通过$readmemh从测试台加载C程序的二进制文件,替代当前将二进制嵌入可执行文件的方式,具体步骤如下:
生成C程序的hex格式文件
先把C程序编译为RISC-V二进制,再转换为Verilog兼容的hex格式:riscv64-unknown-elf-gcc -o helloworld helloworld.c -march=rv64gc -mabi=lp64d -static -nostdlib riscv64-unknown-elf-objcopy -O verilog helloworld helloworld.hex修改TestDriver.v添加加载逻辑
在TestDriver.v的初始化块中,添加$readmemh语句加载hex文件。假设Rocket Chip的指令内存是imem,可以这样修改:initial begin // 加载指令内存,确保hex文件路径是仿真运行时的工作路径 $readmemh("helloworld.hex", imem.mem); // 若需初始化数据内存,可添加对应语句 // $readmemh("data.hex", dmem.mem); end修改C++控制代码跳过默认加载逻辑
默认的emulator.cc会从命令行参数读取二进制文件并加载,需要注释或删除这部分逻辑(比如load_program函数相关代码),避免和$readmemh的初始化冲突。重新构建模拟器
因为修改了Verilog和C++代码,需要重新构建:cd emulator make VERILATOR=1启动仿真
直接运行生成的可执行文件即可,无需再传递二进制文件参数:./emulator-freechips.rocketchip.system-DefaultConfig
补充优化方案
如果不想每次修改内存加载逻辑都重新跑Verilator的Verilog转C步骤,可以考虑用Verilator的DPI接口,把内存加载逻辑放到C代码中。这种方式修改加载逻辑后,只需要重新编译C++部分,能节省大量构建时间。
内容的提问来源于stack exchange,提问作者Jasminy
相关产品推荐
相关产品推荐

