使用Verilator仿真基于Verilog编写的testbench并用GTKWave查看波形

文章介绍了Verilator开源仿真工具的仿真步骤,包括verilate转换、构建C++运行环境、编译及运行可执行文件,以及如何使用新版本的Verilator进行时序仿真。此外,还提供了DUV的RTL代码和基于Verilog的testbench示例,以及如何编写wrapperfile和执行仿真命令。
摘要由CSDN通过智能技术生成

一、Verilator仿真过程简介

Verilator是一个开源的Verilog、SystemVerilog仿真EDA。

它进行仿真的第一步称为“verilate”,将编写好的.v/.sv文件转化成为C++编写的类和方法。

第二步则是建立C++运行环境wrapper file,在里面编写的main函数用于例化第一步里生成的和Verilator自带的仿真不可缺少的类,之后运行Verilator得到make文件.mk。

第三步则是用make命令调用外部编译器(gcc等)编译生成的.mk文件,得到可执行文件。

第四步运行可执行文件可以得到相关的.vcd/.fst波形文件和覆盖率报告。

二、新版本的Verilator

一般进行数字设计和验证都是编写Verilog的RTL代码,再编写verilog或者systemverilog的测试平台testbench,然后由VCS或者Modelsim等仿真器仿真。在新版本的Verilator(v5.002以上)里新增加了时序选项,支持延时语法和fork语句,使得用Verilog编写的testbench可以直接用Verilator仿真而不必在wrapper file里花时间设计激励,而只需在wrapper file里添加几句将波形和覆盖率写进文件的C++语句。

使用apt-get install verilator安装的不一定是最新版本,请参考官网给出的另外安装方式以获得最新版本。

查看Verilator版本的命令。

verilator --version

 下面进入简单例子。

三、DUV的RTL代码和基于Verilog的testbench

待测设计是一个可变进制的计数器,根据输入信号ceil改变进制。以下是RTL代码,文件名为cnt_ceil.v

//这是一个根据ceil信号改变进制的计数器
//这句在用Verilator静态检查时每个模块都要加的,如果有些模块有而有些模块没有则会报错
`timescale 1ns/1ns
//模块
module cnt_ceil(
  input        clk,
  input        en,
  input        rst_n,
  input  [3:0] ceil,
  output [3:0] cnt,
  output       co
);
  reg [3:0] cnt_reg;
  always@(posedge clk,negedge rst_n)
    begin
      if(!rst_n)
        cnt_reg <= 'b0;
      else
        if(en)
          if(cnt_reg >= ceil)
            cnt_reg <= 'b0;
          else
            cnt_reg <= cnt_reg + 1'b1;
    end
  assign cnt = cnt_reg;
  assign co  = en && (cnt_reg==ceil);
endmodule

区别于采用VCS和Modelsim仿真,被例化的模块文件里是不需要时刻定义语句(timescale)的,而在Verilator的静态代码检查时却是需要的,如果仿真前有静态错误则会直接退出仿真,所以在仿真前可以先使用--lint-only -Wall选项来查看所有可能的error和warning并修改设计以消除隐患。

以下是基于Verilog的testbench代码,文件名为cnt_ceil_tb.v。

`timescale 1ns/1ns
module cnt_ceil_tb();
//输入信号
  reg        clk;
  reg        en;
  reg        rst_n;
  reg  [3:0] ceil;
//输出信号
  wire [3:0] cnt;
  wire       co;
//例化计数器
  cnt_ceil cnt_ceil_0(
    .clk   (clk),
    .en    (en),
    .rst_n (rst_n),
    .ceil  (ceil),
    .cnt   (cnt),
    .co    (co)
);
//初始化输入信号
  initial begin
    clk   = 1'b0;
    en    = 1'b0;
    rst_n = 1'b1;
    ceil  = 4'b1100;//12
  end
  initial begin//clk
    forever #1 clk = ~clk;
  end
  initial begin//en
    #1  en = 1'b1;
    #99 en = 1'b0;
  end
  initial begin//rst_n
    #10 rst_n = 1'b0;
    #1  rst_n = 1'b1;
  end
  initial begin//ceil
    #40 ceil = 4'b0110;//6
  end
  initial begin//finish
//重要的一句,在wrapper file的main函数里要能够识别到该完成语句作为结束运行的标志
    #110 $finish;
  end
endmodule

四、wrapper file的编写

该文件旨在提供一个main入口,用于执行对例化的设计的类的操作,文件名为sim_main.cpp

#include <verilated.h>
#include <verilated_vcd_c.h>
#include "Vcnt_ceil_tb.h"

int main(int argc, char** argv){
//构造环境对象,设计对象,波形对象
  VerilatedContext* m_contextp = new VerilatedContext;//环境
  VerilatedVcdC*    m_tracep   = new VerilatedVcdC;//波形
  Vcnt_ceil_tb*     m_duvp     = new Vcnt_ceil_tb;//设计
//波形配置
  m_contextp->traceEverOn(true);//环境里打开波形开关
  m_duvp->trace(m_trace,3);//深度为3
  m_trace->open("cnt_ceil_wf.vcd");//打开要存数据的vcd文件
//写入数据到波形文件里
  while (!m_contextp->gotFinish()){
  //刷新电路状态
    m_duvp->eval();
  //dump数据
    m_tracep->dump(m_contextp->time());
  //增加仿真时间
    m_contextp->timeInc(1);
  }
//记得关闭trace对象以保存文件里的数据
  m_tracep->close();
//释放内存
  delete m_duvp;
  return 0;
}

这是一个C++的wrapper,如果是systemC则需要包含不同的头文件。

五、执行仿真命令

运行Verilator生成make文件.mk。只需对顶层文件运行仿真。

-cc表示把后面的.v/.sv文件verilate成C++文件,-trace表示打开波形开关,--timing表示允许时序控制。-exe表示根据后面的文件来生成可执行文件。

verilator -cc -trace --timing cnt_ceil_tb.v -exe sim_main.cpp

进入包含生成文件的文件夹obj_dir。

cd ./obj_dir

make。调用外部gcc编译成可执行文件。

make -f Vcnt_ceil_tb.mk

运行可执行文件。

./Vcnt_ceil_tb

用GTKWave查看波形。

gtkwave cnt_ceil_wf.vcd

 GTKWave的安装

sudo apt-get install gtkwave

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值