Ubuntu(22.04.2 LTS)中,使用verilator
开源verilog仿真工具,进行RTL功能仿真。现构建版本为5.008
的verilator
仿真环境。
安装流程
安装依赖
sudo apt-get install git perl python3 make autoconf g++ flex bison ccache
sudo apt-get install libgoogle-perftools-dev numactl perl-doc
sudo apt-get install libfl2
sudo apt-get install libfl-dev
sudo apt-get install zlibc zlib1g zlib1g-dev
获取源码
git clone https://github.com/verilator/verilator
选择合适的版本(5.008
)
unsetenv VERILATOR_ROOT
unset VERILATOR_ROOT
cd verilator
git pull
git tag
git checkout v5.008
编译
autoconf
./configure
make
sudo make install
简单C++测试用例
创建测试文件夹test_our
mkdir test_our
cd test_our
创建Verilog/SystemVerilog文件our.v
,内容如下
cat >our.v <<'EOF'
module our;
initial begin $display("Hello World"); $finish; end
endmodule
EOF
创建C++文件sim_main.cpp
,内容如下
cat >sim_main.cpp <<'EOF'
#include "Vour.h"
#include "verilated.h"
int main(int argc, char** argv) {
VerilatedContext* contextp = new VerilatedContext;
contextp->commandArgs(argc, argv);
Vour* top = new Vour{contextp};
while (!contextp->gotFinish()) { top->eval(); }
delete top;
delete contextp;
return 0;
}
EOF
使用verilator
仿真
verilator --cc --exe --build -Wall sim_main.cpp our.v
--cc
:获取C++输出。--exe
:创建可执行文件。--build
:verilator
自动进行make。Wall
:更严格的warning检查。
运行仿真
obj_dir/Vour
真实电路模块
现在测试真实电路模块,并记录仿真过程。
创建Verilog/SystemVerilog文件top.v
,内容如下
module top(
input a,
input b,
output f
);
assign f = a ^ b;
endmodule
将Verilog/SystemVerilog文件转换(Verilate
)成C++
# --cc表示将文件转换成C++
verilator -cc top.v
转换后会生成文件夹obj_dir
,包含转换后所有的文件
创建C++ testbench文件tb_top.cpp
,内容如下
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "verilated.h"
#include "verilated_vcd_c.h"
#include "Vtop.h"
#define MAX_SIM_TIME 20
vluint64_t sim_time = 0;
int main(int argc, char** argv) {
Vtop *dut = new Vtop;
Verilated::traceEverOn(true);
VerilatedVcdC* m_trace = new VerilatedVcdC;
dut->trace(m_trace, 5);
m_trace->open("waveform.vcd");
while (sim_time < MAX_SIM_TIME) {
int a = rand() & 1;
int b = rand() & 1;
dut->a = a;
dut->b = b;
dut->eval();
printf("a = %d, b = %d, f = %d\n", a, b, dut->f);
m_trace->dump(sim_time);
sim_time++;
assert(dut->f == (a ^ b));
}
m_trace->close();
delete dut;
return 0;
}
头文件包含verilated.h
和verilated_vcd_c.h
,verilated.h
为verilator
所需的库函数的头文件,verilated_vcd_c.h
为将波形写入VCD(value change dump)文件的头文件。Vtop *dut = new Vtop
实例化Verilog文件中的电路模块。VerilatedVcdC* m_trace = new VerilatedVcdC
创建对象m_trace
,并且dut->trace(m_trace, 5)
将m_trace
传递给dut
,参数5
限制波形生成的模型层次。dut->eval()
更新top模块中所有的信号。m_trace->dump(sim_time)
会将所有信号记录到波形文件中。
C++ testbench编写完成后,需要生成obj_dir
中的.mk
文件,以包含C++ testbench
# --trace表示记录波形
verilator -Wall --trace -cc top.v --exe tb_top.cpp
生成仿真可执行文件
# -C obj_dir表示工作目录为obj_dir
# -f Vtop.mk传入所需的makefile文件
make -C obj_dir -f Vtop.mk Vtop
运行仿真
./obj_dir/Vtop
查看波形
gtkwave waveform.vcd
自动化Makefile脚本
要求电路模块文件名为"电路模块".v
,testbench文件名为tb_"电路模块".cpp
,使用make MODULE="电路模块" "执行模式"
,进行自动化仿真。其中执行模式
包括以下几种
sim
:执行仿真流程,并生成波形文件。build
:生成仿真所需文件和波形文件。wave
:查看波形文件。module_verilate
:仅生成电路模块的C++文件。testbench_verilate
:生成电路模块和testbench的C++文件。
MODULE =
default:
ifndef MODULE
@echo "Set MODULE name"
else
@echo "Select the execution mode: sim, build, wave, module_verilate, testbench_verilate"
endif
.PHONY: sim
sim: waveform.vcd
.PHONY: build
build: ./obj_dir/V${MODULE}
.PHONY: module_verilate
module_verilate: .module.verilate
.PHONY: testbench_verilate
testbench_verilate: .testbench.verilate
.PHONY: wave
wave: waveform.vcd
@echo "### WAVE ###"
gtkwave waveform.vcd
waveform.vcd: ./obj_dir/V${MODULE}
@echo "### SIMULATING ###"
./obj_dir/V${MODULE}
./obj_dir/V${MODULE}: .testbench.verilate
@echo "### BUILDING SIM ###"
make -C obj_dir -f V$(MODULE).mk V${MODULE}
.testbench.verilate: $(MODULE).v tb_${MODULE}.cpp
@echo "### TESTBENCH VERILATING ###"
verilator -Wall --trace -cc $(MODULE).v --exe tb_${MODULE}.cpp
.module.verilate: $(MODULE).v
@echo "### MODULE VERILATING ###"
verilator -cc $(MODULE).v
.PHONY: clean
clean:
rm -rf ./obj_dir
rm -rf waveform.vcd