2. PrimeTime工作环境与复杂SoC数据准备
在复杂SoC的时序收敛流程中,PrimeTime(后文简称PT)并不是一个"打开就能跑"的孤立工具,它需要一整套与设计环境严格对齐的输入:工艺库、网表、约束、寄生参数以及运行环境变量。数据准备阶段的任何一处错位——库版本不一致、SDC作用域写错、多电压域UPF未加载——都会在后续时序分析中表现为难以定位的违例或虚假通过。本节围绕"如何把PT启动起来并喂给它正确的数据"展开,重点讲清启动方式、库加载、网表与SDC读入顺序,以及多电压域和层次化设计下的脚本组织方法。
一、启动方式与运行环境
PT的启动有两种典型形态:交互式shell与批处理脚本。交互式适合调试约束、探查路径;批处理适合回归与签核。无论哪种方式,第一步都是确认工具版本与工艺库版本匹配,例如使用 pt_shell -version 查看版本,并核对库文件是否来自同一PDK release。
# 交互式启动
pt_shell -f setup.tcl
# 批处理启动(推荐用于回归)
pt_shell -batch -f run_pt.tcl | tee pt.log
启动后需要设置的关键环境变量包括:search_path(库与网表搜索路径)、link_path(链接库路径)、target_library(目标工艺库)、link_library(链接库,通常包含 * 与IO库)、symbol_library(符号库,仅用于图形界面)。其中 link_library 中的 * 表示"已加载的设计优先",这是层次化设计链接的关键。
sh_command_abort_on_error true,让命令出错时立即终止,避免错误被后续命令掩盖。二、加载设计库与读入网表
库加载顺序直接影响链接结果。推荐顺序为:先设 target_library 与 link_library,再 read_verilog 或 read_db 读入网表,最后 link_design 完成链接。若设计包含多个电压域,还需在链接前读入UPF。
set target_library "sc9_cln40ll_base_ssg_0p99v_125c.db"
set link_library "* sc9_cln40ll_base_ssg_0p99v_125c.db \
sc9_cln40ll_io_ssg_0p99v_125c.db"
set search_path ". ./libs ./netlist ./sdc ./upf"
read_verilog ./netlist/soc_top.v
read_verilog ./netlist/cpu_core.v
link_design soc_top
链接完成后,用 list_designs 与 current_design 确认顶层设计正确,用 report_design 检查是否有未解析的实例(unresolved reference)。若出现 Linking failed,优先检查 link_library 是否包含对应单元库,以及网表模块名与库单元名是否大小写一致。
三、读入SDC与多电压域处理
SDC读入必须在 link_design 之后,因为约束中的 get_cells、get_pins 需要设计已链接才能解析。对于多电压域设计,UPF应在SDC之前加载,使电源域信息先建立,SDC中的电压相关约束才能正确作用。
read_upf ./upf/soc_top.upf
read_sdc ./sdc/soc_top.sdc
check_timing
report_clock -skew
report_case_analysis
多电压域下需要特别关注三类问题:一是跨电压域路径的level shifter是否被正确插入并约束;二是isolation cell的使能信号是否有时序约束;三是retention寄存器的save/restore路径是否被覆盖。可用 report_power_domain 查看域划分,用 report_level_shifter 检查电平转换器插入情况。
四、层次化设计的脚本组织
复杂SoC通常包含CPU、GPU、DDR、外设等多个子系统,若把所有约束写在一个SDC里,维护成本极高。工程化做法是按层次拆分:顶层SDC负责时钟定义、IO约束、跨模块时序例外;各子系统SDC负责内部路径约束,通过 source 逐层引入。
# soc_top.sdc
source ./sdc/clocks.sdc
source ./sdc/io.sdc
source ./sdc/cpu_core.sdc
source ./sdc/ddr_ctrl.sdc
source ./sdc/exceptions.sdc
脚本组织建议遵循"三段式":环境段(库、路径、变量)、构建段(读网表、链接、读UPF/SDC)、分析段(check_timing、report_*)。每段之间用 echo 打印阶段标记,便于日志定位。对于回归,可将不同corner封装为独立脚本,通过 -f 传入,避免变量污染。
五、常见数据准备错误与排查
实际工程中,数据准备阶段的错误往往以"时序结果异常"的形式暴露。以下三类最为典型:
- 链接失败:
link_design报 unresolved reference。检查link_library是否包含所有引用库,网表模块名是否与库单元名一致,以及search_path是否覆盖网表目录。 - SDC未生效:
report_clock显示无时钟。检查read_sdc是否在link_design之后,SDC中get_cells的层次路径是否与当前设计匹配。 - UPF未加载:
report_power_domain为空。检查read_upf是否在link_design之后、read_sdc之前,UPF文件中的domain名是否与设计一致。
set_voltage)可能被忽略,导致时序分析使用错误的电压值。务必保证加载顺序为:link_design → read_upf → read_sdc。六、可复用的数据准备检查清单
为便于工程落地,下面给出一份可直接用于回归脚本的检查清单,覆盖从启动到约束加载的关键节点:
| 检查项 | 命令/方法 | 通过标准 |
|---|---|---|
| 工具版本与库版本匹配 | pt_shell -version + 库release note |
版本号一致 |
| 库路径设置正确 | echo $target_library |
路径存在且可读 |
| 网表链接成功 | link_design + report_design |
无unresolved reference |
| UPF加载成功 | report_power_domain |
域列表与预期一致 |
| SDC约束完整 | check_timing |
无unconstrained endpoint |
| 时钟定义正确 | report_clock -skew |
时钟频率/周期符合预期 |
| 跨域路径已约束 | report_level_shifter |
跨域路径均有LS或例外 |
把上述检查项封装为 check_data_ready.tcl,在每次回归前自动执行,可以显著减少因数据准备不当导致的无效迭代。数据准备做扎实,后续的时序分析与优化才有可靠的基础。