第五章Tcl 脚本编程
Tcl 基础
Tcl 三大公理
- Tcl 中一切都是字符串
- 每个字符串都是一个列表
- 每个列表由空白分隔的零个或多个元素组成
基本语法
# 变量
set x 42
set name "hello"
# 变量替换 $
puts $x ;# 输出 42
puts "$name world" ;# 输出 hello world
# 命令替换 []
set y [expr $x + 1]
# 字符替换(转义) \
puts "Line1\nLine2"
# 大括号 {}:阻止替换
set z {$x + $y} ;# z 是字符串 "$x + $y",不替换
# 双引号 "": 允许替换
set w "$x + $y" ;# w 是字符串 "42 + 43"
Procedures(函数)
proc add {{a 0} {b 0}} {
# 过程定义,a 和 b 有默认值 0
return [expr $a + $b]
}
add 3 4 ;# 返回 7
add 5 ;# 返回 5
Return Values 和 Return Status
- 每个 Tcl 命令都有返回值
- 命令可能正常返回或产生错误(error)
catch命令捕获错误
if {{[catch {some_command} result]}} {{
puts "Error: $result"
}}
Standard Tcl vs Jasper Tcl 的差异
JasperGold 在标准 Tcl 基础上增加了硬件设计相关扩展:
- HDL 信号引用(层次路径用
.或/) - 特殊字符处理(
[、]、$在 HDL 名称中有特殊含义时需要转义) - 对象查询命令
JasperGold 脚本常用任务
-silent 模式
# 静默模式运行,减少输出
jg -fpv script.tcl -silent
Structure Queries(结构查询)
# 查询设计层次
get_design_info
# 列出所有模块
report_modules -list
# 查找信号
find_signal -pattern "fifo*"
Cone of Influence (COI) Queries
# 查看属性的影响锥
report_coi -property a_assertion_name
# 列出 COI 中的寄存器
report_coi -property a_name -registers
常见脚本模式
# 对所有 failed 属性做处理
foreach prop [get_properties -status failed] {{
puts "Failed: $prop"
report_counterexample -property $prop
}}
# 批量设置引擎时间
foreach prop [get_properties -type assert] {{
set_prove_per_property_time_limit 30s -property $prop
}}
脚本化方法论
为什么要写 Tcl 脚本而不是只用 GUI?脚本让验证流程可复现、可回归、可自动化。
为什么需要脚本
- 可复现:RTL 修改后重跑脚本得到一致结果
- 可回归:每次 RTL 迭代自动跑回归,确保无新 bug
- 自动化 signoff:脚本自动检查关键断言 proven 并生成报告
- 团队共享:脚本可版本控制,团队使用同一套验证环境
标准脚本模板结构
# ===== 标准 FPV 脚本模板 =====
clear -all
# 1. 设置路径
set RTL_PATH ../source/design
set PROP_PATH ../source/properties
# 2. 分析设计和属性
analyze -sv ${RTL_PATH}/top.v
analyze -sva ${PROP_PATH}/bindings.sva
# 3. 展开设计
elaborate -top top
# 4. 时钟和复位
clock clk
reset ~rstN
# 5. 获取设计信息
get_design_info
# 6. 第一轮:快速证明
set_max_trace_length 20
prove -all
# 7. 第二轮:深度证明
set_max_trace_length 50
set_prove_per_property_time_limit 30s
set_engine_mode {K I N}
prove -all
# 8. 报告
report
report -file proof_results.rpt
# 9. CI 检查
set failed [get_property_list -status {failed bounded unknown} -silent]
if {[llength $failed] > 0} {
puts "ERROR: [llength $failed] properties not proven!"
exit 1
}常用脚本技巧
批量操作断言
# 批量操作断言
assert -disable {*}[get_property_list -tag debug_* -silent]
prove -property {top.submodule.*}
# 保存数据库
set proj_dir [get_proj_dir]
save -jdb $proj_dir/session.jdb -capture_setup脚本最佳实践:
- 总是从
clear -all开始,确保脚本独立运行 - 使用变量管理路径,不要硬编码绝对路径
- 脚本末尾用 exit code 通知 CI 系统是否通过
- 保存数据库(
save -jdb),后续可用 GUI 打开调试 - 注释每个主要步骤的意图,方便团队理解
来源文档
AN_scripting.pdf