在 VCS 中使用 TCL 脚本和 dump.list 生成 FSDB 波形
在 VCS 中使用 TCL 脚本和 dump.list 生成 FSDB 波形
在 Synopsys VCS 中通过 TCL 脚本生成 FSDB 波形时,使用 dump.list 文件定义要抓取的层级结构是一种高效的方法。这样可以灵活控制波形抓取范围,避免不必要的信号占用磁盘空间。
完整实现方案
1. 创建 dump.list 文件
创建一个文本文件 dump.list,定义要抓取的层级结构和信号。格式如下:
# dump.list - 定义要抓取的波形层级
# 格式: [深度] [模块路径] [可选: 特定信号]
# 深度: 0 = 所有子层级, 1 = 仅当前层级, n = 向下n层
# 顶层信号
0 tb_top
# 特定模块 (深度2)
2 tb_top.dut
# 特定信号
0 tb_top.clk
0 tb_top.reset_n
0 tb_top.data_bus
# 带通配符的信号组
0 tb_top.mem_inst.*
2. 创建 TCL 脚本 (dump_fsdb.tcl)
# dump_fsdb.tcl - 使用 dump.list 生成 FSDB 波形
# 设置 FSDB 文件名
fsdbDumpfile "wave.fsdb" -size 1024M -fileNum 100 -fifo_size 1024
# 启用高级功能
fsdbDumpMDA ;# 抓取存储器内容
fsdbDumpSAC ;# 启用层次压缩
# 解析 dump.list 文件
set dump_file [open "dump.list" r]
while {[gets $dump_file line] >= 0} {
# 跳过空行和注释
set line [string trim $line]
if {$line eq ""} continue
if {[string match "#*" $line]} continue
# 分割行内容
set parts [regexp -inline -all -- {\S+} $line]
# 解析参数
set depth [lindex $parts 0]
set path [lindex $parts 1]
# 处理特定信号的情况
if {[llength $parts] > 2} {
set signal [lindex $parts 2]
set full_path "${path}.${signal}"
puts "Dumping signal: $full_path (depth: $depth)"
fsdbDumpvars $depth $full_path
} else {
puts "Dumping module: $path (depth: $depth)"
fsdbDumpvars $depth $path
}
}
close $dump_file
# 可选:添加额外信号
# fsdbDumpvars 0 tb_top.extra_signal
# 运行仿真
run -all
exit
3. 编译设计(启用 FSDB 支持)
# 设置环境变量
export VERDI_HOME=/path/to/verdi
export VCS_HOME=/path/to/vcs
# 编译命令
vcs -full64 -debug_acc+all -sverilog \
-LDFLAGS "-Wl,--no-as-needed" \
-P $VERDI_HOME/share/PLI/VCS/LINUX64/novas.tab \
$VERDI_HOME/share/PLI/VCS/LINUX64/pli.a \
-f filelist.f -top tb_top -l compile.log
4. 运行仿真
./simv -ucli -do dump_fsdb.tcl -l sim.log
高级用法
1. 条件化波形抓取
修改 TCL 脚本,根据仿真阶段动态控制波形抓取:
# 在 dump_fsdb.tcl 中添加
# 初始化阶段不抓波形
run 100ns
fsdbDumpoff
# 解析 dump.list 文件
# ... [与前面相同] ...
# 在关键阶段抓波形
fsdbDumpon
run 1us
# 暂停抓取非关键阶段
fsdbDumpoff
run 10us
# 恢复抓取
fsdbDumpon
run -all
2. 多文件层级管理
对于大型设计,分割为多个 .list 文件:
# waveforms.list - 主控制文件
include cpu.list
include mem.list
include io.list
在 TCL 脚本中添加处理:
proc process_dump_file {filename} {
set file [open $filename r]
while {[gets $file line] >= 0} {
set line [string trim $line]
if {$line eq ""} continue
if {[string match "#*" $line]} continue
# 处理 include 指令
if {[string match "include *" $line]} {
set include_file [lindex $line 1]
process_dump_file $include_file
} else {
# 处理常规行
set parts [regexp -inline -all -- {\S+} $line]
set depth [lindex $parts 0]
set path [lindex $parts 1]
fsdbDumpvars $depth $path
}
}
close $file
}
# 主入口
process_dump_file "waveforms.list"
3. 信号排除列表
创建 exclude.list 并修改 TCL 脚本:
# 加载排除列表
set exclude_patterns {}
set exclude_file [open "exclude.list" r]
while {[gets $exclude_file line] >= 0} {
set line [string trim $line]
if {$line ne "" && ![string match "#*" $line]} {
lappend exclude_patterns $line
}
}
close $exclude_file
# 在解析 dump.list 时应用排除
proc should_dump_signal {path} {
global exclude_patterns
foreach pattern $exclude_patterns {
if {[string match $pattern $path]} {
return 0
}
}
return 1
}
# 在 dump 循环中添加检查
if {[should_dump_signal $full_path]} {
fsdbDumpvars $depth $full_path
} else {
puts "Excluding signal: $full_path"
}
常见问题解决
1. 信号未出现在波形中
- 检查项:
- 确保编译时使用了
-debug_acc+all选项 - 确认
dump.list中的路径与设计层次完全匹配 - 检查是否有信号被优化:添加编译选项
-debug_region+cell
- 确保编译时使用了
2. FSDB 文件过大
在 dump.list 和 TCL 脚本中优化:
# 使用更精确的层次控制
1 tb_top.cpu_unit # 仅抓取一级子模块
# 在 TCL 脚本中添加
fsdbDumpSingle ;# 单节点压缩
fsdbDumpSAC ;# 结构压缩
3. 通配符匹配问题
# 正确使用通配符
0 tb_top.mem_inst.* # 匹配 mem_inst 下所有信号
0 tb_top.bus* # 匹配所有 bus 开头的模块
4. 性能优化技巧
# 延迟波形抓取开始时间
run 1us
# 仅关键阶段抓波形
fsdbDumpoff
run 100us
fsdbDumpon
run 10us
fsdbDumpoff
# 减少刷新频率
fsdbAutoflushOff ;# 手动控制刷新
run 1us
fsdbDumpflush ;# 手动刷新到磁盘
完整工作流示例
文件结构
project/
├── rtl/
├── tb/
├── wave_config/
│ ├── dump.list
│ ├── cpu.list
│ ├── mem.list
│ └── exclude.list
├── scripts/
│ └── dump_fsdb.tcl
└── run_vcs.sh
run_vcs.sh
#!/bin/bash
# 设置环境
export VERDI_HOME=/opt/synopsys/verdi
export VCS_HOME=/opt/synopsys/vcs
# 编译
$VCS_HOME/bin/vcs -full64 -debug_acc+all -debug_region+cell \
-sverilog -f filelist.f -top tb_top \
-LDFLAGS "-Wl,--no-as-needed" \
-P $VERDI_HOME/share/PLI/VCS/LINUX64/novas.tab \
$VERDI_HOME/share/PLI/VCS/LINUX64/pli.a \
-l compile.log
# 仿真
./simv -ucli -do scripts/dump_fsdb.tcl -l sim.log
# 查看波形
$VERDI_HOME/bin/verdi -ssf wave.fsdb &
通过这种方法,您可以:
- 集中管理波形抓取配置(dump.list)
- 灵活控制抓取范围和深度
- 轻松排除不需要的信号
- 优化波形文件大小和仿真性能
这种方法特别适合大型设计,可以显著减少波形文件大小,同时确保关键信号的可调试性。
浙公网安备 33010602011771号