XSim 批处理 dump VCD:GUI 起不来时离线看波形
更新时间:2026-10-22。面向已经能用 Vivado 命令行批处理仿真 跑通三连、但卡在「看波形」这一步的同学。CI 服务器、远程 SSH、容器里都没有桌面环境,
xsim -gui根本起不来——但调时序不能没有波形。本文的解法:批处理仿真里直接用 tcl 命令把波形 dump 成 VCD 文件,拿回本地用任意波形工具离线打开。全部命令与输出都在 Vivado 2017.4 上真实跑过,导出的counter.vcd可下载核对。
本文要回答的问题
- VCD 是什么格式,为什么它是跨工具波形交换的通用语?
- XSim 批处理里 dump VCD 需要哪几条 tcl 命令、挂在哪一步?
- 导出的 VCD 文件长什么样,怎么读懂里面的跳变记录?
- 除了 VCD,还有哪些离线波形路线,各适合什么场景?
一、为什么选 VCD
VCD(Value Change Dump,值变化转储)是 Verilog 标准(IEEE 1364)定义的波形交换格式:纯文本、按时间戳记录每个信号的值变化。它的三个优点正好命中无 GUI 场景:任何波形工具都能开(GTKWave、Surfer、ModelSim、甚至 Vivado 自己);文件就是文本,可以 grep、可以脚本解析、可以进 git diff;仿真器零依赖,生成端只要有 open_vcd/log_vcd 这两条 XSim 内建 tcl 命令,不需要装任何插件。
代价也有:纯文本体积大(大设计长跑会到 GB 级)、dump 本身拖慢仿真、只记录被 log_vcd 挂接的信号。所以它的正确定位是「中小设计、回归留证、无 GUI 环境」的离线波形方案,不是大型 SoC 全量波形的主力。
读这张概念卡抓住选型逻辑:要「任何机器都能看」选 VCD;要「大设计省空间」选 WDB 拷回本地;只要 PASS/FAIL 结论时 $monitor 文本就够,连波形都不用存。本文走第一条。
二、三条 tcl 命令:dump 流程本身
XSim 批处理挂 VCD 只需要一个 tcl 文件,本实验的 vcd_setup.tcl 内容就四行:
open_vcd C:/eda-lab/vcd-dump/counter.vcd
log_vcd /tb_counter4/dut/*
run all
close_vcd每条命令的分工:open_vcd <路径> 打开一个 VCD 文件准备写入(路径建议绝对路径,相对路径相对 xsim 运行目录);log_vcd <信号范围> 把指定层次的信号挂进记录列表,/tb_counter4/dut/* 表示 DUT 实例下的全部端口/内部信号;run all 跑到底;close_vcd 收尾落盘。然后三连照旧,只是最后一步换成 xsim sim_vcd -tclbatch vcd_setup.tcl。
读这张图注意:VCD 的生成完全发生在 xsim 运行阶段,xvlog 和 xelab 不需要任何改动——同一个快照,加不加 -tclbatch 决定出不出波形,这也是为什么它能无损叠加在既有 CI 流程上。
三、真实跑一遍:三步全绿、VCD 落盘
读这张终端卡抓四处证据:## open_vcd C:/eda-lab/vcd-dump/counter.vcd 与 ## log_vcd /tb_counter4/dut/* 两行回显说明 tcl 被正确执行;run all 之后 $monitor 照常逐拍打印 count 递增到 0xf 回卷,TEST PASS 与 $finish 都在——挂 VCD 不影响仿真行为本身;xsim exit=0 干净退出;日志尾部显示 vcd copied, bytes=1056——这个最小工程的 VCD 只有 1KB 出头,印证「中小设计 VCD 很轻」。
四、读懂 VCD:1KB 里的完整时间轴
VCD 文件分两段:头部声明 + 变化记录。头部用 $var 给每个信号分配一个单字符代号:
$timescale
1ps
$end
$scope module tb_counter4 $end
$scope module dut $end
$var wire 1 ! clk $end
$var wire 1 " rst_n $end
$var reg 4 # count [3:0] $end即 ! = clk、" = rst_n、# = count,时间精度 1ps。变化记录里 #数字 是时间戳(单位 ps),0!/1! 是单比特信号赋新值,b101 # 是总线赋新值(二进制 101 = 5)。对照原文逐拍读:clk 每 5000ps 翻转一次(10ns 周期);#25000 处 1"(rst_n 释放)同时 b1 #(count=1);之后每个上升沿 count 加一,#165000 到 b1111(15),#175000 回卷 b0——与上一节 $monitor 的文本输出逐拍互证,两份证据来自同一次仿真、互为交叉验证。
读这张波形图注意三个对齐关系:clk 每两格一个周期(10ns,对应 VCD 里 5000ps 半周期);rst_n 在第 5 格(25ns)拉高,正是 VCD 的 #25000 1";count 从 25ns 起每个上升沿加一,图中 0→7 的取值序列与 VCD 里 b1 # / b10 # / b11 # / b100 #…… 完全一一对应。这张图就是按 counter.vcd 的真实时间戳画的,不是示意图——这也正是 VCD 的价值:它是可机器核对的事实,不依赖任何人的转述。
五、VCD 到手之后:离线打开与 log_vcd 进阶
VCD 拷回本地后,两个最常用的打开方式:GTKWave(开源、跨平台)直接 gtkwave counter.vcd,左侧层次树勾选信号拖入波形区即可;Surfer(Rust 系新秀)surfer counter.vcd 同理。Vivado 自己也能开(Flow → Open Static Simulation),但既然都已经离线了,一般没必要再动用它。
log_vcd 的信号范围写法比本文用到的更灵活,按需要选粒度:
| 写法 | 记录范围 | 适用 |
|---|---|---|
log_vcd /tb_counter4/dut/* | DUT 实例下一层的全部信号 | 小设计一把梭(本文用法) |
log_vcd /tb_counter4/dut/count | 单个信号 | 只要关键信号、文件最小 |
log_vcd -level 0 /tb_counter4/* | 层次递归到底 | 需要看子模块内部信号时 |
-level 0 表示不限深度递归;不写 -level 时默认只记当前层次一层。层次越深、信号越多,VCD 越大、仿真越慢,所以原则是「够用就好」——回归留证挂 DUT 端口层,真出问题再针对该用例加深层次重跑。
六、常见坑与选型对照
| 现象 | 原因 | 处置 |
|---|---|---|
| VCD 文件是空的/只有头部 | log_vcd 挂在 run 之后,或路径写错 | 顺序固定为 open → log → run → close |
| 找不到 VCD 文件 | 相对路径,xsim 运行目录不是你以为的那个 | 用绝对路径,或先确认工作目录 |
| 文件巨大 | log 了整个 TB 层次、仿真时间长 | 缩小 log_vcd 范围(只挂 DUT 关键层次) |
| 波形里全是 x | 信号在 log 前就有跳变没被记录 | log_vcd 尽量在 run 之前尽早挂 |
| 2017.4 想缩放 GUI 波形 | 没有 wave 命令(ModelSim 语法) | 批处理场景直接走 VCD;GUI 场景用 wcfg,另见 wave 报错排错篇 |
与另两条路线的对照一句话:VCD 胜在通用与可核对,WDB 胜在省空间(但只能用 Vivado 系打开),$monitor 胜在零成本(但只覆盖你打印的点)。回归流水线里推荐组合是「$monitor 做断言 + VCD 留证据」,CI 挂了先看出错用例的文本输出,需要翻波形再打开对应的 VCD。
实验环境
- 机器/系统:Windows 10 工作站(Vivado 2017.4 实机)
- 工具版本:Vivado Simulator 2017.4(
xvlog.bat/xelab.bat/xsim.bat,D:\Xilinx\Vivado\2017.4) - 日期:2026-10-22
- 完整命令:
xvlog.bat counter4.v tb_counter4.v;xelab.bat -debug typical tb_counter4 -s sim_vcd;xsim.bat sim_vcd -tclbatch vcd_setup.tcl(tcl 内容:open_vcd/log_vcd /tb_counter4/dut/*/run all/close_vcd)
代码获取:本实验完整代码(
counter4.v、tb_counter4.v、vcd_setup.tcl)见公开仓库 derekzhuo/geek-doc.cn 的experiments/xsim-dump-vcd-offline/。把 tcl 里的 VCD 输出路径与 Vivado 路径改成本机环境即可复现。
这一篇在知识体系里的位置
本篇是 FPGA 入门 波形主题在无 GUI 场景下的延伸:前置是 Vivado 命令行批处理仿真(三连流程)与 仿真波形怎么看(波形阅读基础);挂波形时最容易踩的语法坑见 XSim 报 invalid command name wave;仿真通过、进入综合后的下一步是 Vivado 利用率报告怎么读。
一句话总结
GUI 起不来的环境照样能看波形:open_vcd 开文件、log_vcd 挂信号、run all、close_vcd 四行 tcl 往 xsim -tclbatch 一挂,同一个仿真快照零改动就能导出标准 VCD——它是纯文本、任何波形工具都能开、可与 $monitor 文本逐拍互证的硬证据,回归流水线里「断言靠 monitor、留证靠 VCD」就是最省心的组合。