verilator手册中 9.1.8 How do I generate waveforms (traces) in C++?
9.1.8 How do I generate waveforms (traces) in C++?
See also the next question for tracing in SystemC mode.
A. Pass the --trace option to Verilator
-
Pass the
--traceoption to Verilator. Then you may use$dumpfileand$dumpvarsto enable traces, the same as with any Verilog simulator, although Verilator ignores the arguments to$dumpvars. -
See the example in
examples/make_tracing_cin the distribution. -
If writing the top-level C code, call
Verilated::traceEverOn(true)to enable tracing. This is done for you if using--binary.
B. Or, for finer-grained control, or C++ files with multiple Verilated modules
You may also create the trace purely from C++. Create a VerilatedVcdC object, and in your main loop, right after eval(), call trace_object->dump(contextp->time()) every time step, and finally call trace_object->close().
#include "verilated_vcd_c.h"
...
int main(int argc, char** argv) {
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
...
Verilated::traceEverOn(true); // Enable tracing
VerilatedVcdC* tfp = new VerilatedVcdC;
topp->trace(tfp, 99); // Trace 99 levels of hierarchy (or see below)
// tfp->dumpvars(1, "t"); // trace 1 level under "t"
tfp->open("obj_dir/t_trace_ena_cc/simx.vcd");
...
while (contextp->time() < sim_time && !contextp->gotFinish()) {
contextp->timeInc(1); // Increment simulation time
topp->eval(); // Evaluate the module
tfp->dump(contextp->time()); // Dump trace at current time
}
tfp->close(); // Close the trace file
}
9.1.8 如何在 C++ 中生成波形(Trace)
参见下一个问题,了解如何在 SystemC 模式下进行跟踪。
步骤A. 使用 --trace 选项生成波形
-
通过将
--trace选项传递给 Verilator 来启用波形生成。然后可以使用$dumpfile和$dumpvars来启用波形输出,就像在任何 Verilog 仿真器中一样,尽管 Verilator 会忽略$dumpvars的参数。 -
参考
examples/make_tracing_c中的示例。 -
如果你编写的是顶层 C 代码,调用
Verilated::traceEverOn(true)来开启跟踪功能。如果你使用的是--binary,则此操作已经为你完成。
步骤B. 通过 C++ 进行更细粒度的控制
如果你的项目包含多个 Verilated 模块,并且你想要更细粒度的控制,可以完全通过 C++ 代码来生成波形。具体步骤如下:
- 创建一个
VerilatedVcdC对象。 - 在每个仿真步骤中,调用
trace_object->dump(contextp->time())来记录当前时间步的波形数据。 - 最后,调用
trace_object->close()来关闭波形文件。
官方文档中所附带的代码:
#include "verilated_vcd_c.h"
...
int main(int argc, char** argv) {
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
...
Verilated::traceEverOn(true); // 启用波形生成
VerilatedVcdC* tfp = new VerilatedVcdC;
topp->trace(tfp, 99); // 追踪 99 层的层级(或者参考下文)
// tfp->dumpvars(1, "t"); // 追踪 "t" 下的一层
tfp->open("obj_dir/t_trace_ena_cc/simx.vcd");
...
while (contextp->time() < sim_time && !contextp->gotFinish()) {
contextp->timeInc(1); // 增加仿真时间
topp->eval(); // 评估模块
tfp->dump(contextp->time()); // 记录波形
}
tfp->close(); // 关闭波形文件
}
示例代码(含注释,Verilog文件为top.v,顶层模块名为top):
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
// assert.h 是一个标准 C 语言头文件,它定义了 assert 宏,用于在程序中插入断言 (assertion)。
// 断言的作用是帮助程序员验证程序在运行时的假设是否成立,主要用于调试。
#include "Vtop.h"
#include "verilated.h"
#include "verilated_vcd_c.h"// 引入 Verilator VCD 追踪库
int main(int argc, char** argv) {
// 创建并初始化一个 Verilator 仿真上下文 contextp
VerilatedContext* contextp = new VerilatedContext;
contextp->commandArgs(argc, argv);
// 创建顶层模块实例
Vtop* top = new Vtop{contextp};
// 启用波形跟踪,这一行代码启用了波形追踪功能。它必须在仿真开始之前调用,确保 Verilator 会生成波形数据。
// 这个函数告诉 Verilator 启用波形记录并为每个仿真步骤生成数据。
Verilated::traceEverOn(true); // 必须在仿真时间开始之前调用,因此它通常位于仿真初始化部分。
// 创建 VCD 文件输出对象
// 这里创建了一个 VerilatedVcdC 对象,负责管理和输出仿真波形数据。VerilatedVcdC 是 Verilator
// 提供的类,用于将仿真数据转储到 .vcd 文件中。
VerilatedVcdC* tfp = new VerilatedVcdC;
// 配置追踪等级
// top->trace() 用来设置我们要追踪的信号。top 是我们实例化的 Verilog 顶层模块对象,trace() 函数将 tfp
// 传入,以便将波形数据保存到 tfp 指定的 VCD 文件中。
// 99 表示信号的层级深度。一般来说,设置为 99
// 可以追踪所有信号(包括所有子模块的信号)。这个参数可以根据需要调整,通常设置为 99 以确保捕获完整的波形。
top->trace(tfp, 99); // Trace 99 levels of hierarchy
// 这一行打开一个名为 waveform.vcd 的文件,将仿真波形写入这个文件。
// VCD(Value Change Dump)文件是一种标准的波形格式,可以被许多波形查看工具(如 GTKWave)读取。open()
// 函数会打开文件供写入,如果文件不存在,Verilator 会创建该文件。
tfp->open("waveform.vcd"); // 打开 VCD 文件
// 仿真主循环
while (!contextp->gotFinish()) {
int a = rand() & 1;
int b = rand() & 1;
top->a = a;
top->b = b;
top->eval();// eval() 会根据当前信号和状态更新设计的状态,并执行任何时序或组合逻辑的计算。
printf("a = %d, b = %d, f = %d\n", a, b,top->f);
assert(top->f == (a ^ b)); // 检查 XOR 输出是否正确
tfp->dump(contextp->time()); // 记录当前时间的波形数据
contextp->timeInc(1);// 增加时间步长
}
// 关闭 VCD 文件
// 仿真结束后,调用 close() 关闭 VCD 文件。关闭文件是确保所有数据被正确保存的重要步骤。
tfp->close();
// 释放资源
delete top;
delete contextp;
return 0;
}
浙公网安备 33010602011771号