2. Tempus环境搭建与数据准备
Tempus 的时序签核结果是否可信,首先取决于环境搭建与数据准备是否完整、一致。Tempus 本身是一个时序分析引擎,它并不产生设计数据,而是消费来自综合、布局布线、寄生参数提取等环节的输入。因此,启动 Tempus 之前必须把五类核心数据准备齐全:工艺库(Liberty/.lib)、网表(Verilog 或 DEF)、时序约束(SDC)、寄生参数(SPEF 或 DSPF)以及库交换格式(LEF,用于物理感知分析)。本节围绕这五类数据的加载方式、命令组织与常见配置检查展开。
一、Tempus 启动所需的数据构成
从数据流角度看,Tempus 的输入可以分为“逻辑视图”和“物理视图”两条线。逻辑视图由工艺库、网表和 SDC 组成,用于建立时序图(timing graph)并施加约束;物理视图由 LEF 与 SPEF 组成,用于提供单元/线网的物理位置与寄生 RC,从而支撑物理感知的时序计算。两者缺一不可:只有逻辑视图时,Tempus 只能做基于线负载模型(WLM)的估算;只有物理视图时,则无法建立正确的时序弧和约束关系。
工艺库方面,通常需要加载标准单元库、IO 库、存储器宏库,以及对应的 CCS 或 NLDM 时序模型。若设计包含多电压域,还需加载 UPF/CPF 描述的电源意图。网表可以是综合后的门级 Verilog,也可以是 P&R 导出的 Verilog 或 DEF。SDC 必须与当前网表版本严格对应,否则会出现约束对象找不到(unconstrained endpoint)或约束错位。SPEF 需与提取所用的 RC 工艺角(corner)匹配,例如 Cmax/Cmin 分别对应 setup/hold 分析。
二、加载顺序与命令组织
Tempus 的加载顺序遵循“先库后网表、先约束后寄生”的原则。典型脚本结构如下:
# 1. 设置搜索路径与库角
set search_path [list ./libs ./netlist ./sdc ./spef]
set link_path "* sc9mcpp84_ss_0p72v_125c.db sc9mcpp84_ff_0p88v_m40c.db"
# 2. 读入工艺库(逻辑库)
read_lib sc9mcpp84_ss_0p72v_125c.lib
read_lib sc9mcpp84_ff_0p88v_m40c.lib
# 3. 读入网表
read_verilog ./netlist/top_apr.v
current_design top
# 4. 读入 SDC 约束
read_sdc ./sdc/top_func.sdc
# 5. 读入寄生参数(按 corner 分别加载)
read_spef -corner ss_125c ./spef/top_ss_125c.spef
read_spef -corner ff_m40c ./spef/top_ff_m40c.spef
# 6. 链接设计并检查
link_design
check_timing
report_analysis_coverage
这里有几个关键点。第一,link_path 必须包含所有被引用的库,否则 link_design 会报 unresolved reference。第二,read_spef 的 -corner 参数必须与后续 set_operating_conditions 或 set_timing_derate 中使用的 corner 名称一致,否则寄生参数不会生效。第三,check_timing 是环境搭建后的第一道体检,它会报告未约束端点、无时钟路径、未驱动端口等问题。
三、常见配置检查与判断依据
环境搭建完成后,不能直接跑 report_timing,而应先做几项检查。首先是库角一致性:确认 SDC 中 set_operating_conditions 指定的条件在已加载的 .lib 中存在,且电压/温度与 SPEF 提取时使用的条件匹配。其次是 SDC 版本检查:用 report_sdc -verbose 查看约束是否全部被解析,重点关注 create_clock、set_input_delay、set_output_delay 是否作用到了正确的端口。第三是 SPEF 覆盖率:用 report_spef_coverage 检查有多少线网成功映射了寄生参数,覆盖率低于 95% 通常意味着网表与 SPEF 版本不一致。
一个实用的检查清单如下表所示,可作为环境搭建后的快速核对依据:
| 检查项 | 命令 / 方法 | 通过判据 | 常见异常 |
|---|---|---|---|
| 库链接完整性 | link_design |
无 unresolved reference | 库路径错误、库角缺失 |
| 时序约束覆盖 | check_timing |
unconstrained endpoint = 0 | SDC 与网表版本不匹配 |
| 时钟定义 | report_clock |
时钟数量、周期与预期一致 | 时钟未传播、generated clock 缺失 |
| SPEF 映射率 | report_spef_coverage |
覆盖率 ≥ 95% | 网表与 SPEF 版本不一致 |
| RC corner 匹配 | report_annotated_parasitics |
各 corner 均有寄生数据 | corner 名称拼写不一致 |
report_analysis_coverage,它会汇总 setup/hold 检查的覆盖情况。若某类检查覆盖率为 0,说明对应的约束或库角没有正确加载,此时不应继续做时序签核。
四、实操示例:一个可复用的环境检查脚本
下面给出一个可直接参考的环境搭建与检查脚本片段,假设设计名为 top,使用 ss_125c 与 ff_m40c 两个 corner:
# env_setup.tcl
set DESIGN top
set LIB_DIR ./libs
set NETLIST ./netlist/${DESIGN}_apr.v
set SDC ./sdc/${DESIGN}_func.sdc
set SPEF_SS ./spef/${DESIGN}_ss_125c.spef
set SPEF_FF ./spef/${DESIGN}_ff_m40c.spef
set search_path [list $LIB_DIR ./netlist ./sdc ./spef]
set link_path "* sc9mcpp84_ss_0p72v_125c.db sc9mcpp84_ff_0p88v_m40c.db"
read_lib sc9mcpp84_ss_0p72v_125c.lib
read_lib sc9mcpp84_ff_0p88v_m40c.lib
read_verilog $NETLIST
current_design $DESIGN
read_sdc $SDC
read_spef -corner ss_125c $SPEF_SS
read_spef -corner ff_m40c $SPEF_FF
link_design
# 检查
check_timing > ./rpt/check_timing.rpt
report_clock > ./rpt/clock.rpt
report_spef_coverage > ./rpt/spef_cov.rpt
report_annotated_parasitics > ./rpt/annotated_para.rpt
report_analysis_coverage > ./rpt/analysis_cov.rpt
运行后应逐项查看报告。若 check_timing 报告中有未约束端点,需要回到 SDC 中补充 set_input_delay 或 create_clock;若 report_spef_coverage 显示覆盖率偏低,应核对网表与 SPEF 是否来自同一次 P&R 导出。只有这些检查全部通过,Tempus 的时序结果才具备签核意义。
link_design 直接读 SPEF。未链接的设计中,Tempus 无法将 SPEF 中的实例名与网表对象对应,寄生参数会被静默忽略,导致时序结果偏乐观。
总结来说,Tempus 环境搭建的核心是“五类数据、一个顺序、四项检查”。五类数据是 .lib、网表、SDC、SPEF、LEF;一个顺序是先库后网表、先约束后寄生;四项检查是库链接、约束覆盖、SPEF 映射率、RC corner 匹配。把这套流程固化成脚本,每次签核前自动执行,可以显著减少因环境问题导致的误判。