之前在“简评几款开源RISC-V处理器”提到开源RISC-V处理器蜂鸟E203没有Verilator的仿真环境,自己何不去动手建一个呢?建起来之后,还可以把GDB接进去进行调试。我曾经总结过RISC-V的基于仿真的调试系统:“浅谈RISC-V的DEBUG系统及其仿真”,相信把GDB接入Verilator编译仿真的蜂鸟E203也不是不可能的事。说干就干,看看完成这项任务需要几步。
1. Iverilog Flow
开源蜂鸟E203提供了Iverilog的环境。第一步先把Iverilog flow跑通,倒不是说verilator需要调用其环境,而是基于以下两点的考虑:
Iverilog仿真环境的Makefile可以帮助我们生成所需的file list和一些宏定义
建Verilator环境遇到问题的时候,可以使用Iverilog生成waveform进行对比,帮助debug
出师不利,遇到了问题,Iverilog不支持$value$plusargs
,从TB中把它去掉了之后能跑起来,但是会hang住,永远停在0 ticks。最后分析下来是我的Iverilog是Ubuntu源里面拉的,太老了,于是从github上下了最新的Iverilog,编译、安装,最终解决了问题。看到最终PASS的提示还是长舒了一口气,万里长征迈出了第一步。
Iverilog能是能用,但实在太慢了,无法忍受。Iverilog用来作为初学者仿真一些简单的设计是非常好的(无需使用D版的modelsim或VCS,虽然主要支持Verilog,很多System Verilog的语法不支持),仿真稍微有些规模的设计(比如此蜂鸟E203系统)就不大合适了。
好了,下面我们上Verilator。
2. 用Verilator仿真ISA test
先从简单的开始,从ITCM中执行ISA test,这也是之前使用Iverilog跑通的内容。Iverilog环境中tb
下的tb_top.v
里面有一些Verilator不支持的语法,需要自己重新写一个,基本指导思想是把e200_soc_top
例化一下,最终顶层只接出一个clk
和一个rst
。Verilator还要求我们建一个自己的C++顶层,里面的main函数里对clk
和rst
施加激励。当然我们为了debug方便,还会加入识别参数中含有-t
或--trace
进行dump waveform的功能。
int main(int argc, char **argv) {
Verilated::commandArgs(argc, argv); Ve203_soc_top_verilator *soc = new Ve203_soc_top_verilator; // check if trace is enabled int trace_en = 0; for (int i=0; i if (strcmp(argv[i], "-t") == 0) trace_en = 1; if (strcmp(argv[i], "--trace") == 0) trace_en = 1; } //enable waveform int main_time; VerilatedVcdC* tfp = new VerilatedVcdC; if (trace_en) {
Verilated::traceEverOn(true); soc->trace(tfp, 99); // Trace 99 levels of hi