SDC 补全:前七篇没讲但很实用的 SDC 命令 一、前七篇覆盖了什么还差什么前七篇覆盖了 SDC 中约 80% 的常用命令。但还有 9 个命令/知识点在日常工作中同样重要本文一次性补上。这些命令不常用在日常 SDC 编写中但在debug timing 问题、做 IO 精确建模、分析报告时是关键工具。二、set_driving_cell精确建模输入驱动2.1 为什么需要它set_input_delay描述了数据到达的时间但没有描述信号的驱动强度。驱动强度影响信号的 transition上升/下降时间进而影响路径延迟。# ✗ 粗糙做法用 set_drive 设一个固定的阻抗值 set_drive 1.0 [get_ports data_in] # ✓ 精确做法指定驱动 cell工具用 cell 的驱动能力计算 transition set_driving_cell -lib_cell INV_X2 \ -library ***_rvt \ -pin Z \ [get_ports data_in]打完比方set_drive等于说从外面来了个信号强度一般。set_driving_cell等于说外面接了一个 INV_X2 的输出——工具知道 INV_X2 的驱动能力是多强算出更精确的 input transition。2.2 常用场景# 场景 1外部由某个特定 buffer 驱动 set_driving_cell -lib_cell BUF_X4 \ -library ***_rvt \ -pin Z \ [get_ports data_in] # 场景 2多 bit 总线所有位用相同驱动 set_driving_cell -lib_cell INV_X1 \ -library ***_rvt \ -pin Z \ [get_ports {data_bus[*]}] # 场景 3最差情形用最小驱动 cell 模拟最慢 transition set_driving_cell -lib_cell INV_X1 \ -library ***_rvt \ -pin Z \ -input_pin_activity 0.5 \ -max_transition 3.0 \ [get_ports data_in]2.3 set_drive vs set_driving_cell命令适用场景精度set_drive1.0粗略估算无库信息低set_driving_cellINV_X2已知外部驱动 cell高不设用默认工具用最坏情形假设最悲观三、set_load精确建模输出负载3.1 为什么需要它与set_driving_cell对应——set_output_delay描述了数据输出的时序要求但没描述输出 pin 接了多少负载。负载影响输出级 buffer 的 transition。# 指定输出 pin 的负载电容单位pF set_load 5.0 [get_ports data_out] # 更精确用输入 pin 的电容值 set_load [load_of ***_rvt/INV_X1/A] [get_ports data_out]打完比方set_output_delay说信号必须在 X 时间内到达外面set_load说外面接的电路有 Y 电容。两者加起来才是完整的输出约束。3.2 set_load 的值怎么确定# 方法 1用具体 cell 的 pin 电容值 # 工具自动从库中读取 INV_X1 的 A pin 电容 set_load [load_of ***_rvt/INV_X1/A] [get_ports data_out] # 方法 2用线负载模型估算 set_wire_load_model -name scc18_wl10 -library ***_rvt set_load -wire_load [get_ports data_out] # 方法 3直接指定 pF 值 set_load 5.0 [get_ports data_out]四、group_path路径分组分析4.1 为什么需要它默认情况下report_timing按时钟域分 path group。但在复杂设计中你可能需要自定义分组来聚焦分析。# 把所有输出路径分到一组单独看 group_path -name OUTPUTS -to [all_outputs] # 把复位相关的路径分出来 group_path -name RESET -through [get_pins *rst*] # 把最差的 10 条路径按组报告 report_timing -group OUTPUTS -max_paths 10 -nworst 14.2 实战用法# 在 MMMC 中按不同模式分组 current_view view_func_max # 新建自定义分组 group_path -name CRITICAL -slack_lesser_than 0.5 # 这个分组自动包含所有 slack 0.5ns 的路径 # 报告时只看这个分组 report_timing -group CRITICAL -max_paths 20 -significant 5 # 查看所有分组的汇总 report_path_group输出示例Path Group WNS TNS Failing Endpoints ───────────── ─────── ─────── ───────────────── clk_sys -0.12 -1.45 23 clk_pwm 0.05 0.00 0 INPUTS 0.23 0.00 0 OUTPUTS -0.08 -0.32 5 CRITICAL -0.12 -1.77 28从这里你可以快速定位clk_sys 组有 23 条路径违例WNS -0.12ns。你的优化精力应该放在 clk_sys 组而不是所有路径。五、set_clock_sense时钟感知5.1 什么时候用当时钟经过一个反相器或 AOI 逻辑时工具可能无法判断时钟的极性。// RTL时钟经过反相器 assign clk_inv ~clk_sys;# 工具默认假设时钟经过反相器后极性反转 # 但如果经过了 MUX 或 AOI工具可能判断错误 # 手动指定时钟感知经过这个 pin 后时钟极性不变 set_clock_sense -positive [get_pins u_mux/z]典型场景时钟通过一个 MUX测试模式切换时钟源工具可能不清楚 MUX 输出端的时钟极性用set_clock_sense显式告知。5.2 你的设计用不用如果你的时钟树只经过 buffer 和 inverter没有 MUX工具会自动处理不需要set_clock_sense。但在有时钟 MUXscan_mode 切换时钟的设计中这是有用的。六、set_disable_timing禁用 timing arc6.1 什么时候用当某个 cell 的特定 pin 组合在功能上不会用到时可以禁用对应的 timing arc 来避免假违例。# 例一个 MUX 的 S 端到 Z 端的路径在功能模式下被 test_mode 控制 # test_mode 在功能模式下固定为 0所以 S→Z 的路径不存在 set_disable_timing [get_pins u_mux/S] -to [get_pins u_mux/Z]6.2 常用场景# 测试模式 MUX 的 select→output path 在 func 模式不存在 set_disable_timing [get_pins */test_mux/S] -to [get_pins */test_mux/Z] # 一个失效的 tri-state buffer set_disable_timing [get_pins u_tri/z] # 在 scan 模式下禁用 func 时钟路径 set_disable_timing [get_pins u_occ/func_clk] -to [get_pins u_occ/z]注意set_disable_timing只在确实必要时才用。滥用会掩盖真正的 timing 问题。七、set_data_check自定义时序检查7.1 什么时候用标准 setup/hold 检查只适用于同一时钟驱动的寄存器。对于异步握手或不同时钟域之间的路径可以用set_data_check定义自定义检查。# 异步握手data_valid 必须在 clk_b 上升沿之前保持稳定 set_data_check -from [get_pins u_sync/data_valid_reg/Q] \ -to [get_pins u_sync_b/data_valid_sync/D] \ -setup 10 -hold 5设计用不用大多数异步握手路径可以用set_max_delay替代set_data_check不常用。八、set_timing_derateOCV deratingSDC 侧在 OCV 文章中我们详细讨论了 derating 的原理。在 SDC 中这样写# SDC 中的 OCV derating # data path derate set_timing_derate -early 0.92 -late 1.08 -cell_check set_timing_derate -early 0.92 -late 1.08 -net_delay # clock path derate通常比 data path 宽松一些 set_timing_derate -early 0.95 -late 1.05 -clock注意事项derating 一般在 PrimeTime 脚本中配置不在综合阶段的 SDC 中写。这里列出只是让你知道它的 SDC 命令形式。九、write_sdc / write_sdf输出约束与延时9.1 write_sdc综合/STA 完成后输出完整的 SDC 供后续流程使用# 输出当前所有约束到一个 SDC 文件 write_sdc -output constraints_exported.sdc # 按 view 输出 current_view view_func_max write_sdc -output func_max.constraints.sdc9.2 write_sdf输出标准延时文件SDF供后仿使用# 输出最差 corner 的 SDF write_sdf -views {view_func_max} -output func_max.sdf # 包含 OCV derating 的 SDF write_sdf -views {view_func_max} -include_derating -output func_max_ocv.sdf十、QoR 分析与 ECO 基础10.1 怎么看 timing 报告# 1. 先看全局概览 report_qor -summary # 输出 # WNS (setup): -0.12ns ← 最差的一条 setup 违规 # TNS (setup): -1.45ns ← 所有 setup 违规的 slack 总和 # WNS (hold): 0.08ns ← hold 最差的 slack # Failing endpoints: 23 # 2. 再看最差路径 report_timing -max_paths 5 -slack_lesser_than 0 -significant 5 # 关注path group、delay 占比cell vs net、transition 是否超标 # 3. 按分组的 WNS/TNS report_path_group10.2 ECO 修复的四种解决方法排名方法修改范围效果1Upsize cell换个驱动更大的 cell综合网表⭐⭐⭐ 最有效2插 buffer在长路径上加 buffer综合网表⭐⭐ 改善 transition3改 SDC放宽约束/加例外约束⭐⭐ 如果有过度约束4改 RTL重写关键路径逻辑RTL⭐ 最后手段ECO 的基本流程# 1. 确认最差路径 report_timing -max_paths 1 -significant 5 # 2. 分析延迟分布 # Cell delay: 3.2ns (80%) # Net delay: 0.8ns (20%) # → Cell delay 占比高 → 尝试 upsize cell # → Net delay 占比高 → 查 transition/fanout # 3. 修复在 Innovus 中或 Genus 中 # upsizing: 把 cell 从 X1 换成 X2