EDA开源仿真工具verilator入门11: vcd波形文件分析

上一节介绍了如何使用verilator保存vcd波形文件,本节将详细介绍vcd波形文件的格式,我们先给一个例子:

verilog代码文件:

module multi_logic (a,b,c,out,clk);
	input a,b,c,clk;
	output out;      
	reg a,b,c,clk,out,tmp_ou;
	add add1(.a (a), .b(b), .clk(clk), .out(tmp_ou));         
	always @(posedge clk) begin
        out <= tmp_ou ^ c;
	end
endmodule

module add(a, b, clk, out);
	input a, b, clk;
	output out;
	reg a, b, clk, out;
	always @(posedge clk) begin
		out <= a + b;
	end
endmodule

cpp主文件:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
 
#include "Vmulti_logic.h"  // create `multi_logic.v`,so use `Vmulti_logic.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);
  Vmulti_logic* multiLogic = new Vmulti_logic{contextp};
  
 
  VerilatedVcdC* tfp = new VerilatedVcdC; //初始化VCD对象指针
  contextp->traceEverOn(true); //打开追踪功能
  multiLogic->trace(tfp, 0); //
  tfp->open("wave.vcd"); //设置输出的文件wave.vcd
  int clk = 1;
  int count = 0;
  while (!contextp->gotFinish()) {
    count++;
    int a = rand() & 1;
    int b = rand() & 1;
    int c = rand() & 1;
    clk = (clk + 1) % 2;
    multiLogic->a = a;
    multiLogic->b = b;
    multiLogic->c = c;
    multiLogic->clk = clk;
 
    multiLogic->eval();
    printf("a = %d, b = %d, c = %d, clk = %d, out = %d\n",
     a, b, c, clk, multiLogic->out);
 
    tfp->dump(contextp->time()); //dump wave
    contextp->timeInc(1); //推动仿真时间
    if (count > 5) 
        break;
    //assert(top->f == ~((a&b) | (~(c&d))));
  }
  delete multiLogic;
  tfp->close();
  delete contextp;
  return 0;
}

打印结果:

a = 1, b = 0, c = 1, clk = 0, out = 0
a = 1, b = 1, c = 1, clk = 1, out = 1
a = 0, b = 0, c = 1, clk = 0, out = 1
a = 1, b = 0, c = 1, clk = 1, out = 1
a = 0, b = 1, c = 1, clk = 0, out = 1
a = 0, b = 0, c = 0, clk = 1, out = 1

wave.vcd 内容:

$timescale 1ps $end

 $scope module TOP $end
  $var wire  1 # a $end
  $var wire  1 $ b $end
  $var wire  1 % c $end
  $var wire  1 & clk $end
  $var wire  1 ' out $end
  $scope module multi_logic $end
   $var wire  1 # a $end
   $var wire  1 $ b $end
   $var wire  1 % c $end
   $var wire  1 & clk $end
   $var wire  1 ' out $end
   $var wire  1 ( tmp_ou $end
   $scope module add1 $end
    $var wire  1 # a $end
    $var wire  1 $ b $end
    $var wire  1 & clk $end
    $var wire  1 ( out $end
   $upscope $end
  $upscope $end
 $upscope $end
$enddefinitions $end


#0
1#
0$
1%
0&
0'
0(
#1
1$
1&
1'
#2
0#
0$
0&
#3
1#
1&
1(
#4
0#
1$
0&
#5
0$
0%
1&
0(

我们来看vcd文件的内容,首先会给出层次结构下的所有信号,每有一个新的层次结构都以 #scope 开始 #upscope结束。每一个信号都有一个对应的替换符号来替代:

# -> a
$ -> b
% -> c
& -> clk
' -> out
( -> tmp_ou

随后,每个 #time都是一个时间戳,表示一个新的cycle的开始,每个信号变量通过对应替换符号表示,且第一个时间戳会保存所有信号的值,之后的时间戳只保存变化的信号值,显然信号的符号替代以及只保存变化量都是为了节省空间占用。

通过这个简单的例子,可以帮助我们很快的理解vcd波形文件的基本格式。当然还有很多其他的波形文件(fsdb、SHM、VPD等),目前verilator并不支持,如果感兴趣我们后面也可以讨论下,增加相应的内容。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值