4. 多模式约束管理实战
多模式时序收敛的核心难点,不在于单个模式能否收敛,而在于多个模式共享同一套设计时,约束如何既准确表达各模式意图,又不互相污染。本节围绕三个动作展开:为每个模式创建专属约束、处理模式之间的约束差异、排查并调试约束冲突。
一、模式专属约束的创建方式
在 Cadence 流程中,多模式约束通常通过 SDC 的 set_case_analysis、模式化时钟定义、以及基于 current_mode 或 set_active_modes 的约束分组来实现。推荐做法是:先定义模式集合,再为每个模式单独维护一份约束文件,最后在顶层用模式选择机制合并。
# modes.sdc —— 模式定义
create_mode func_fast
create_mode func_slow
create_mode scan_shift
create_mode test_capture
# func_fast.sdc —— 功能快模式专属约束
set_active_modes func_fast
create_clock -name clk_core -period 1.2 [get_ports clk_core]
set_case_analysis 0 [get_ports test_en]
set_case_analysis 1 [get_ports func_sel]
set_clock_uncertainty 0.06 [get_clocks clk_core]
# scan_shift.sdc —— 扫描移位模式专属约束
set_active_modes scan_shift
create_clock -name clk_scan -period 8.0 [get_ports clk_scan]
set_case_analysis 1 [get_ports test_en]
set_case_analysis 0 [get_ports func_sel]
set_false_path -from [get_ports scan_in] -to [get_ports scan_out]
关键点在于:每个模式文件只声明该模式真正有效的时钟、case analysis、false path 和 multicycle。不要把某个模式的例外约束写到全局文件里,否则它会泄漏到其他模式,造成过度放松或过度约束。
二、模式间约束差异的处理策略
模式差异通常集中在四类对象上:时钟频率与来源、工作条件(电压/温度角)、功能选择信号、以及测试结构(扫描链、BIST、JTAG)。处理差异时,建议按“共享约束 + 模式增量”两层组织:共享部分包括端口、基本时钟骨架、通用 IO 延迟;增量部分只写该模式特有的周期、uncertainty、case analysis 和例外。
例如功能模式与扫描模式共享同一时钟端口,但周期不同:功能模式 1.2 ns,扫描移位模式 8.0 ns。此时不应在共享文件里写死周期,而应在各自模式文件中用 create_clock 重新定义,或使用 set_clock_groups 明确模式间时钟关系。对于跨模式共享的异步时钟域,应在每个模式中分别声明 set_clock_groups -asynchronous,而不是只在某一个模式中声明。
三、约束冲突的排查与调试
约束冲突的典型表现有三类:同一对象被多个模式同时约束、例外约束与时钟定义矛盾、以及模式未激活导致约束被忽略。排查时先看约束是否真正生效,再看是否互相覆盖。
在 Cadence 工具中,可用以下命令检查模式与约束的绑定关系:
# 查看当前激活模式
report_active_modes
# 查看某模式下的时钟定义
report_clocks -modes func_fast
# 检查 case analysis 是否冲突
report_case_analysis -modes scan_shift
# 检查例外约束是否被应用
report_exceptions -modes func_fast -ignored
如果 report_exceptions -ignored 显示某条 false path 被忽略,常见原因是:该路径的起点或终点在当前模式下被 case analysis 固定为常量,或该路径所属时钟未在当前模式中定义。此时应回到模式文件,确认时钟是否创建、case analysis 是否与例外约束语义一致。
另一类冲突是同一路径在不同模式下分别被设为 false path 和 multicycle。这本身不一定是错误,但必须确保每个模式只看到自己那条约束。若两个模式同时激活,工具会按优先级或报冲突,此时应检查 set_active_modes 是否误将两个模式同时打开。
四、一张图看清模式、约束与冲突的关系
下图把模式集合、专属约束、共享约束以及冲突检查点放在同一视图中,帮助定位“哪条约束属于哪个模式、在哪里可能冲突”。
五、实战检查清单
在交付多模式约束前,建议逐项确认:每个模式是否有独立的 set_active_modes 作用域;每个模式是否只包含该模式有效的时钟和 case analysis;共享层是否只保留与模式无关的约束;report_exceptions -ignored 是否为空或已解释;跨模式异步时钟组是否在每个模式中分别声明。完成这些检查后,再进入时序分析,可显著减少“约束看似写了、实际没生效”的返工。