• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • YouClaw
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

SOC/IP验证工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

在 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 &

通过这种方法,您可以:

  1. 集中管理波形抓取配置(dump.list)
  2. 灵活控制抓取范围和深度
  3. 轻松排除不需要的信号
  4. 优化波形文件大小和仿真性能

这种方法特别适合大型设计,可以显著减少波形文件大小,同时确保关键信号的可调试性。

posted on 2025-06-20 21:43  SOC验证工程师  阅读(675)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3