4、基本仿真流程:编译、运行、波形查看、调试技巧、VCS常用选项

好,咱们直接进入正题。仿真,说白了就是验证你写的代码能不能按预期工作。很多新手一上来就急着跑仿真,结果报错一堆,波形也不会看,白白浪费时间。今天我就把这一整套流程掰开揉碎了讲给你听。

4.1 编译:把RTL代码变成仿真器能懂的东西

编译这一步,就是把你的Verilog或SystemVerilog代码,翻译成仿真器内部的数据结构。VCS用的命令是 vlogan 或者直接 vcs

我个人习惯用 vcs 一步到位。比如:

vcs -full64 -sverilog -debug_access+all \
    -f filelist.f \
    -l compile.log

这里几个参数我解释一下:

  • -full64:64位模式,现在基本是标配了,不然大设计跑不动。
  • -sverilog:支持SystemVerilog语法。如果你只用Verilog,可以不加。
  • -debug_access+all:打开所有调试权限,方便后面看波形、设断点。
  • -f filelist.f:文件列表,里面写着你所有要编译的源文件路径。
  • -l compile.log:把编译信息输出到日志文件里,方便查错。
我的小经验: 编译报错时,别只看最后一行。往上翻,找到第一个error,那往往是真正的根因。后面的error经常是连锁反应。

4.2 运行:让仿真器动起来

编译通过后,会生成一个可执行文件,默认叫 simv。运行它就行了:

./simv -l run.log

就这么简单?嗯,基本是这样。但实际项目中,我们通常要加一些选项:

  • +vcs+lic+wait:如果license暂时拿不到,就等着,别直接退出。
  • -l run.log:把仿真运行时的打印信息存下来。
  • -gui:启动图形界面,方便看波形。
  • +UVM_TESTNAME=my_test:指定要跑的UVM测试用例。

举个例子,我经常这样跑:

./simv +UVM_TESTNAME=test_reset \
        +vcs+lic+wait \
        -l run.log \
        -gui
注意: 仿真时间设置要合理。别一上来就跑100万时钟周期,先跑1000个周期看看波形对不对。我曾经有个项目,仿真跑了三天三夜,结果发现是激励给错了……从那以后,我都是先小规模验证。

4.3 波形查看:用眼睛验证逻辑

波形是验证工程师的眼睛。没有波形,你就像在黑暗中摸索。VCS默认生成的是VPD格式的波形文件。

要生成波形,你得在代码里加上:

initial begin
    $vcdpluson();  // 或者 $vpdpluson();
end

或者在运行命令里指定:

./simv -vcd test.vcd

我个人更推荐用 $vcdpluson(),因为它可以灵活控制要dump哪些信号。比如:

initial begin
    $vcdpluson(0, tb_top);  // dump tb_top及其下所有层次
end

波形生成后,用DVE或Verdi打开。DVE是VCS自带的,Verdi是第三方工具,但更强大。我习惯用Verdi,因为它支持自动连线、状态机显示,调试效率高很多。

看波形的技巧:
  • 先看时钟和复位,确保它们正常。
  • 再看关键控制信号,比如使能、状态机跳转。
  • 最后看数据通路,确认数据对不对。
  • 善用“光标”和“标记”,对比多个信号的时间关系。

4.4 调试技巧:快速定位问题

调试是验证工程师的日常。我总结了几个实用技巧:

  1. 加打印信息:在关键位置加 $display$info,打印当前状态和关键变量值。别怕打印太多,仿真跑完 grep 一下就行。
  2. 设断点:在DVE或Verdi里,可以在某行代码或某个信号变化时停下来。比如信号 data_valid 拉高时断住,然后单步执行。
  3. 用断言:SystemVerilog断言(SVA)是自动检查的好帮手。比如:
assert property (@(posedge clk) req |=> ##[1:3] ack);

这句的意思是:当req拉高后,1到3个时钟周期内,ack必须拉高。如果没拉高,仿真会报错。

避坑指南: 我曾经在一个项目里,花了整整两天查一个bug,最后发现是波形dump的层次不对,关键信号根本没抓到。所以,开始仿真前,先确认波形文件里有没有你需要的信号。

4.5 VCS常用选项速查表

下面这个表是我平时最常用的VCS选项,建议你收藏:

选项 作用 我的备注
-full64 64位模式 大设计必开
-sverilog 支持SystemVerilog 现在基本都加
-debug_access+all 开启所有调试权限 调试时必加,跑回归时可以去掉
-l logfile 输出日志到文件 方便查错,强烈推荐
-gui 启动图形界面 调试时用,回归时别用
+vcs+lic+wait 等待license 服务器上跑仿真必备
-vcd filename 生成VCD波形 文件大,但兼容性好
-timescale=1ns/1ps 设置时间精度 默认是1ns/1ns,有时不够用

好了,基本仿真流程就这些。编译、运行、看波形、调试,每一步都有它的门道。你刚开始可能觉得繁琐,但多做几个项目,这些操作就会变成肌肉记忆。下一章我们聊聊UVM的基本结构,那才是验证的硬骨头。