Verilator是一种开源的Verilog/SystemVerilog仿真器,可用于编译代码以及代码在线检查,Verilator能够读取Verilog或者SystemVerilog文件,并进行lint checks(基于lint工具的语法检测),并最终将其转换成C++的源文件.cpp和.h。
Verilator不直接将Verilog HDL转换为C++或者SystemC,反之Verilator将代码编译成更快的优化过的并且支持多线程的模型,该模型被依次包装在(wrapped)在C++/SystemC模型中。这样就生成一个编译的Verilog模型,其功能和Verilog是一致的,但效率由于基于C++即使是单线程模型也可以10倍快于SystemC,100倍快于基于解释Verilog的仿真器,并且通过多线程可以进一步加速。
Verilator的优点:将Verilog/SystemVerilog转换成C++/SystemC,仿真速度快很多,如果有这方面的需求,那Verilator是不错的选择。
本节将先介绍下Verilator的安装以及基本的使用方法,所有操作均在Ubuntu16系统上实现。
安装必要的软件包:
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 libfl-dev
sudo apt-get install zlibc zlib1g zlib1g-dev
git上拷贝源代码:
git clone https://github.com/verilator/verilator
编译前的准备工作:
unset VERILATOR_ROOT # For bash
cd verilator
git pull # Make sure git repository is up-to-date
git tag # See what versions exist
这里选择编译版本v4.210(最新版本会报错)
git checkout v4.210
配置编译安装:
autoconf # Create ./configure script
./configure # Configure and create Makefile
make -j `nproc` # Build Verilator itself (if error, try just 'make')
sudo make install
如果成功的话输入:
verilator --version
可以看到verilator的版本信息:
下面我们看下官方示例,最简单的hello world代码,文件位置在verilator/examples/make_hello_c/下,主要两个文件:
top.v
// DESCRIPTION: Verilator: Verilog example module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2017 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
// See also the EXAMPLE section in the verilator manpage/document.
module top;
initial begin
$display("Hello World!");
$finish;
end
endmodule
sim_main.cpp
// DESCRIPTION: Verilator: Verilog example module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2017 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
//======================================================================
// Include common routines
#include
// Include model header, generated from Verilating "top.v"
#include "Vtop.h"
int main(int argc, char** argv, char** env) {
// See a similar example walkthrough in the verilator manpage.
// This is intended to be a minimal example. Before copying this to start a
// real project, it is better to start with a more complete example,
// e.g. examples/c_tracing.
// Prevent unused variable warnings
if (false && argc && argv && env) {}
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
Vtop* top = new Vtop;
// Simulate until $finish
while (!Verilated::gotFinish()) {
// Evaluate model
top->eval();
}
// Final model cleanup
top->final();
// Destroy model
delete top;
// Return good completion status
return 0;
}
MakeFile文件:
######################################################################
#
# DESCRIPTION: Verilator Example: Small Makefile
#
# This calls the object directory makefile. That allows the objects to
# be placed in the "current directory" which simplifies the Makefile.
#
# This file ONLY is placed under the Creative Commons Public Domain, for
# any use, without warranty, 2020 by Wilson Snyder.
# SPDX-License-Identifier: CC0-1.0
#
######################################################################
# Check for sanity to avoid later confusion
ifneq ($(words $(CURDIR)),1)
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
endif
######################################################################
# This is intended to be a minimal example. Before copying this to start a
# real project, it is better to start with a more complete example,
# e.g. examples/make_tracing_c.
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
# package install, and verilator is in your path. Otherwise find the
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
ifeq ($(VERILATOR_ROOT),)
VERILATOR = verilator
else
export VERILATOR_ROOT
VERILATOR = $(VERILATOR_ROOT)/bin/verilator
endif
default:
@echo "-- Verilator hello-world simple example"
@echo "-- VERILATE & BUILD --------"
$(VERILATOR) -cc --exe --build -j top.v sim_main.cpp
@echo "-- RUN ---------------------"
obj_dir/Vtop
@echo "-- DONE --------------------"
@echo "Note: Once this example is understood, see examples/make_tracing_c."
@echo "Note: Also see the EXAMPLE section in the verilator manpage/document."
######################################################################
maintainer-copy::
clean mostlyclean distclean maintainer-clean::
-rm -rf obj_dir *.log *.dmp *.vpd core
MakeFile中核心的编译语句其实就是执行:
verilator -Wall --cc --exe --build top.v sim_main.cpp
直接执行编译:
make
执行生成的C++可执行文件,结果如下:
可以看到C++实现了和verilog相同的功能。
gtkwave同样是开源的工具其git地址为:
https://github.com/gtkwave/gtkwave.git
这里我们直接安装:
sudo apt-get install gtkwave
以一个简单的逻辑组合为例:
top.v
module top(
input a,
input b,
input c,
input d,
output f
);
assign f = ~((a&b) | (~(c&d)));
endmodule
top_main.cpp
#include
#include
#include
#include "Vtop.h" // create `top.v`,so use `Vtop.h`
#include "verilated.h"
#include "verilated_vcd_c.h" //可选,如果要导出vcd则需要加上
int main(int argc, char** argv, char** env) {
VerilatedContext* contextp = new VerilatedContext;
contextp->commandArgs(argc, argv);
Vtop* top = new Vtop{contextp};
VerilatedVcdC* tfp = new VerilatedVcdC; //初始化VCD对象指针
contextp->traceEverOn(true); //打开追踪功能
top->trace(tfp, 0); //
tfp->open("wave.vcd"); //设置输出的文件wave.vcd
while (!contextp->gotFinish()) {
int a = rand() & 1;
int b = rand() & 1;
int c = rand() & 1;
int d = rand() & 1;
top->a = a;
top->b = b;
top->c = c;
top->d = d;
top->eval();
printf("a = %d, b = %d, c = %d, d = %d, f = %d\n", a, b, c, d, top->f);
tfp->dump(contextp->time()); //dump wave
contextp->timeInc(1); //推动仿真时间
assert(top->f == ~((a&b) | (~(c&d))));
}
delete top;
tfp->close();
delete contextp;
return 0;
}
执行编译:
verilator -Wall top.v top_main.cpp --cc --trace --exe --build
#增加了--trace 是为了显示波形的
./obj_dir/Vtop //必须执行这个,才会出现.vcd文件,需要强制退出
gtkwave wave.vcd //如果报错缺少canberra-gtk-module,apt安装即可
结果如下图:
这一节先说到这里。