Vivado中tcl.pre/post获取TOP模块失败及时间注入方案问询
Vivado TCL脚本动态注入日期时间问题解答
问题背景
在Vivado 2021.2中编写TCL脚本,目标是将当前日期时间动态注入顶层模块:
- 手动在TCL控制台执行
set top_module [get_property TOP [current_fileset]]可正常获取顶层模块名 - 将该命令加入综合设置的
tcl.pre/tcl.post时无法返回值 - 通过
source D:/Ananth/Own_Work/Dtae_Time_Automation/TestTCL.tcl调用脚本时,虽能获取顶层模块名,但报错找不到对应.vhd文件
问题1:为什么控制台执行正常,tcl.pre/post中失效?
核心原因是执行上下文的差异:
- 交互式控制台执行时,已处于打开工程、加载设计的状态,
current_fileset默认指向当前激活的工程文件集,TOP属性已被正确初始化。 tcl.pre/tcl.post绑定到综合流程,执行时机更早(tcl.pre在综合启动前),此时Vivado的设计上下文可能未完全加载:- 默认
current_fileset可能未指向综合专用文件集,需要显式指定:set synth_fileset [get_filesets synth_1] current_fileset $synth_fileset set top_module [get_property TOP $synth_fileset] - 若工程存在多个run或文件集,未明确指定的话,
current_fileset可能指向错误对象,导致无法获取TOP属性。
- 默认
- 你通过
source调用脚本时能获取顶层名但找不到文件,是因为只获取了模块名称,未关联对应物理文件路径。需通过模块名反向查找文件:set top_module [get_property TOP [current_fileset]] set top_file [get_files -of_objects [get_modules $top_module]] # 此时top_file会包含顶层模块对应的.vhd文件路径
问题2:综合时动态注入日期时间到顶层模块的更优方案
推荐以下无需修改原顶层源文件的方案,避免直接修改代码带来的版本控制问题:
方案1:通过Generic参数传递(最简洁)
- 在顶层VHDL模块中定义字符串类型的Generic参数:
entity top_module is generic ( BUILD_DATETIME : string := "UNKNOWN" ); port ( -- 你的端口定义 ); end entity; - 在综合前的TCL脚本中设置该Generic参数:
综合时Vivado会自动将日期时间传入顶层模块,无需修改源文件。set current_time [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S"] set_property generic "BUILD_DATETIME=\"$current_time\"" [current_fileset]
方案2:自动生成包含日期时间的常量包
- 编写TCL脚本动态生成VHDL包,包含日期时间常量:
set pkg_file "./build_info_pkg.vhd" set current_time [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S"] set fp [open $pkg_file w] puts $fp "package build_info_pkg is" puts $fp " constant BUILD_DATETIME : string := \"$current_time\";" puts $fp "end package;" close $fp -- 将生成的包添加到工程文件集 add_files -norecurse $pkg_file set_property used_in_synthesis true [get_files $pkg_file] - 在顶层模块中引用该包:
之后可直接在顶层模块中使用library work; use work.build_info_pkg.all;BUILD_DATETIME常量。
方案3:使用Vivado生成语句结合TCL变量
若需将日期时间硬编码到电路中(如ROM内容或寄存器值),可使用Vivado的generate语句配合TCL变量:
- 在顶层模块中添加生成块(需VHDL 2008及以上版本支持):
generate constant BUILD_DATETIME : string := string'(`BUILD_DATETIME`); end generate; - 在TCL脚本中定义变量并传递给综合:
set current_time [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S"] set_property verilog_define "BUILD_DATETIME=\"$current_time\"" [current_fileset]
内容的提问来源于stack exchange,提问作者Ananth K
相关产品推荐
相关产品推荐

