
在PrimeTime眼里同样是门控电路AND门和XOR门的运气完全不同。我见过不少项目设计里明明只是用了一个不起眼的AND门做时钟门控PrimeTime自动就能把使能信号的setup/hold窗口算得明明白白但一旦换成XOR门工具立刻装死既不报门控violation也不做任何时序检查。这背后其实是不同门控电路在STA工具中的检查策略差异在起作用。这篇文章会从AND、NAND、OR、NOR、XOR这5种最基础的门控逻辑入手结合我在项目里的实际踩坑经历讲清楚PrimeTime分别会怎么识别它们、怎么做clock gating check以及你该在SDC里手动补哪些约束。做后端STA的、写SDC约束的或者刚接触低功耗设计想搞懂门控电路原理的工程师都可以参考。1. 为什么纯组合门控在PrimeTime中比ICG更难处理1.1 从ICG到纯逻辑门门控的两种实现路线低功耗设计里时钟门控几乎是必做项。主流做法是在标准单元库里面选专用的ICG单元Integrated Clock Gating cell比如Synopsys的CW_ICG、各工艺库自带的ICG单元。这类单元内部结构通常是锁存器 与门或者锁存器 或门特点是输入输出角色固定时钟端、使能端、输出端在Liberty库里就写死了PrimeTime看到这种单元直接按时钟门控去检查不需要额外推断。但实际项目里并不总是能用ICG。比如某些成熟工艺库没有ICG单元或者设计规模很小、只有几个门控点为了省面积直接用基本逻辑门搭一个又比如在综合后网表或者定制数字模块里综合工具优化出来的门控结构可能是一堆AND/OR/NAND/NOR的组合并没有实例化成ICG。这时候PrimeTime就只能靠猜——根据电路拓扑和逻辑门的时序敏感性判断哪个引脚是时钟输入、哪个引脚是门控信号、哪个输出是门控后的时钟。问题就出在这个猜上。猜得准不准跟逻辑门的单调性unate property强相关。1.2 单调逻辑与非单调逻辑PrimeTime识别门控的分水岭在时序分析里逻辑单元从输入到输出可以分为三类时序敏感性positive unate输入上升输出只会上升或不变输入下降输出只会下降或不变。典型如AND门、OR门。negative unate输入上升输出只会下降或不变输入下降输出只会上升或不变。典型如NAND门、NOR门、反相器。non-unate输入变化时输出可能上升也可能下降取决于另一个输入的状态。典型就是XOR门、XNOR门。对unate逻辑门PrimeTime能明确建立时钟输入到输出的极性关系也能明确判断门控信号在什么条件下会关断或导通时钟所以自动门控识别的准确率很高。但对XOR这种non-unate逻辑同一个输入引脚既可能是正传路径也可能是反传路径PrimeTime无法确定这个信号到底是把时钟打开了还是反相了于是默认会选择不把它当作门控单元处理。这也是我文章标题的由来AND门控顺风顺水XOR门控处处碰壁中间的NAND/OR/NOR各自带有极性或有效电平的额外复杂度。下面逐个展开。2. AND与NAND门控绝大多数项目里最先遇到的两类差异2.1 AND门控PrimeTime默认检查最顺的结构AND门控的表达式很简单gclk CLK EN。EN高有效当EN1时时钟正常翻转当EN0时时钟被关断门控后的时钟空闲电平为低。有一个72位总线寄存器组的项目当时为了省功耗给每个字节都加了一个AND门控。综合后网表里就是简单的AND2单元时钟从A端进使能从B端进输出Z驱动一组寄存器时钟端。跑PrimeTime时工具自动识别了所有AND门控并在每个AND单元上创建了clock gating checkreport_clock_gating_check能看到每个门控点都有一条记录。AND门控之所以让PrimeTime省心本质上是因为它是positive unate逻辑。工具能确定当CLK0时无论EN怎么变输出恒为0门控信号对时钟路径没有影响当CLK1时输出跟随EN所以EN必须在CLK高电平期间保持稳定否则gclk上就会出现毛刺。因此门控检查的参考事件是CLK的上升沿也就是gclk的上升沿检查内容是EN在该沿之前满足setup、之后满足hold。这意味着AND门控的检查窗口天然集中在CLK高电平相位。从实际约束角度只要EN信号来自某个寄存器的Q端输出它只会在时钟沿前后跳变一次然后保持一个周期整个高电平期间都是稳定的PrimeTime的默认检查就足够覆盖风险。反过来说如果EN是组合逻辑直接产生那么即使setup/hold满足组合毛刺也可能落在CLK高电平中间这属于静态检查默认管不到的场景后面我会专门说。2.2 NAND门控输出反相把参考沿和检查窗口全带偏了NAND门控的表达式是gclk ~(CLK EN)。它和AND门控一样是EN高有效但因为输出反相空闲电平变成了高。更关键的是当EN1时gclk是CLK的反相时钟gclk的上升沿对应CLK的下降沿。这就带来一个容易被忽略的连锁反应如果NAND门控的输出直接接到上升沿触发的寄存器时钟端寄存器实际的采样时刻是CLK的下降沿。也就是说这个寄存器相当于工作在原始时钟的反沿。而门控检查的参考事件也跟着变成了CLK下降沿要求在CLK下降沿前后EN保持稳定。我在一个项目里遇到过真实案例。同事为了省掉一个反相器把原本AND门控 反相器恢复极性的结构改成了NAND门控然后下游寄存器全部改成下降沿触发。结果在时序收敛阶段门控检查的hold violation一片一片地冒出来。原因很简单EN信号由另一个上升沿触发的寄存器输出它只在CLK上升沿附近发生变化而门控检查的参考沿是CLK下降沿这两个沿之间只隔着半个周期。EN在CLK上升沿后的变化必须在一个很窄的窗口内完成并稳定才能满足CLK下降沿附近的门控hold要求显然很紧张。这就是NAND门控和AND门控的实质差异逻辑表达式只有一个取反但检查策略的参考沿往前挪了半个周期整个时序预算完全变了。如果你的设计里确实要用NAND门控至少要把两件事确认清楚门控后时钟的有效沿是什么下游寄存器的触发沿是否和它匹配门控信号的来源沿到门控检查参考沿之间是否留够了半个周期甚至更长的裕量。2.3 AND/NAND检查实践一个快速自查方法拿到网表后可以在PrimeTime里直接看门控报告report_clock_gating_check -verbose重点看每一行的Clock Pin和Gating Pin是否和你预期一致。如果某个NAND门控结构里工具把门控信号当作clock pin、把时钟信号当作gating pin就说明工具识别反了门控检查的结果完全不可信。这种情况我见过不止一次尤其是NAND门控后还跟着反相器的时候。如果识别方向正确但想收紧或放宽检查裕量可以用set_clock_gating_check手动指定setup和hold值set_clock_gating_check -setup 0.2 -hold 0.05 [get_pins u_gate/B]这里的u_gate/B是门控单元的gate信号引脚。手动指定后PrimeTime会优先使用这个值而不是库里的默认值。我一般只在工艺库默认值明显偏乐观或者偏悲观的时候才这么做属于特事特办。3. OR与NOR门控低有效使能带来的检查窗口错位3.1 OR门控敏感相位变成了CLK低电平OR门控的表达式是gclk CLK | ENB这里的ENB是低有效使能信号。当ENB0时门控完全透明时钟正常翻转当ENB1时门控关断gclk恒为1空闲电平为高。很多人第一次用OR门控都不太适应因为它和AND门控在空闲相位上是互补的。AND门控下CLK0时gclk恒为0EN怎么翻转都影响不了输出但OR门控恰恰相反CLK0时gclk直接等于ENBENB一翻gclk就跟着翻。所以OR门控的敏感相位是CLK低电平期间ENB必须在这个窗口内保持稳定否则同样会在gclk上产生多余沿。这里有一个需要特别留意的事实PrimeTime默认的门控检查参考事件还是gclk的有效沿也就是CLK上升沿附近它并没有对整个低电平相位做完整覆盖。换句话说默认检查能保证ENB在有效沿前后稳定但不保证ENB在CLK低电平中间不乱翻。这个风险要靠设计结构来兜底ENB必须来自寄存器输出或者经过锁存器保持不能是组合逻辑的即时输出。我之前在高性能IO模块里见过一个OR门控ENB来自一个组合逻辑的或门网络结果仿真的时候出现了极其偶发的功能错误定位了很久才发现是ENB在CLK低电平中间的毛刺穿过了OR门控给寄存器产生了额外时钟沿。静态时序分析里这种毛刺风险是不会直接报出来的因为默认门控检查模型假设门控信号是一个干净的、每个周期只跳变一次的信号。3.2 OR门控的SDC落地写法与扫描链隐患OR门控在SDC层面并不需要特殊命令时钟定义还是定义在原始CLK上门控后的gclk由工具自动推导。但有一个场景很容易踩坑DFT扫描链。扫描模式下扫描使能SE通常是高有效而且不会为每个门控单独生成一个同步后的副本。如果SE直接接到OR门控的ENB端当SE从0变1去切换shift模式时恰好卡在CLK低电平期间OR门控的输出就会多出一个沿导致扫描链上的时序错乱。这种问题在功能仿真里可能被波形掩盖但到了芯片实测阶段就会变成偶发fail。我的建议是用OR门控的地方扫描使能必须经过ICG单元或者锁存器整形后再接入ENB端如果没有这个条件干脆把OR门控替换成AND门控加反相器虽然多了一个门但检查策略和DFT安全性都会简单很多。3.3 NOR门控低有效与反相输出的双重叠加NOR门控的表达式是gclk ~(CLK | ENB)。ENB低有效输出反相空闲电平为低。NOR门控相当于把OR门控的低有效特性和NAND门控的反相输出问题叠加在了一起。一方面敏感相位在CLK低电平期间另一方面gclk的有效沿和CLK的有效沿错位参考事件的下游寄存器触发沿选择也需要额外核对。实际项目里NOR门控几乎是最后的选择因为它没有任何一个维度是省心的。如果看到网表里出现了NOR门控我的第一反应是回溯综合日志看它是不是综合工具为了优化面积而引入的然后评估要不要改成OR门加反相器。从时序分析角度看OR门加反相器是两级单元每一级都是unate逻辑PrimeTime的识别和检查都更可控NOR门控虽然面积略小但换来的是检查策略上的双重负担得不偿失。4. XOR门控非单调逻辑让PrimeTime的门控识别失效4.1 XOR门控的用途可控极性的时钟路径XOR门控的表达式是gclk CLK ^ EN。当EN0时gclkCLK当EN1时gclk~CLK。它的本质是一个可控反相器可以在运行中动态改变时钟极性。这种结构在可配置接口、双沿采样转单沿采样、或者需要动态调整时钟相位的定制模块里偶尔会出现。比如某些接口协议允许主设备配置采用上升沿还是下降沿采样RTL工程师图省事直接用XOR门把时钟极性配置掉了。综合工具默认不会把它优化成标准门控单元于是XOR门就留在了时钟网络上。也有一种情况是综合工具主动引入的某些数据通路的逻辑化简后XOR结构被综合到了时钟相关的逻辑上虽然不是设计者故意用XOR做门控但它客观上形成了一个控制端翻转会导致时钟沿变化的结构同样需要警惕。4.2 为什么PrimeTime对XOR门控默认视而不见XOR是non-unate逻辑这是它和AND/OR/NAND/NOR最本质的区别。以AND门为例无论CLK怎么变、EN怎么变输出对CLK始终是positive unate的工具可以稳定地建立CLK是时钟、EN是门控的角色划分。XOR则完全不同当EN0时输出跟随CLK同相当EN1时输出跟随CLK反相反过来输出对EN的sense也取决于CLK的状态。工具无法从静态分析中确定哪一个输入是时钟、哪一个输入是门控因为这两个角色本身就是可以互换的而且sense不固定。所以在默认情况下PrimeTime遇到XOR门控时不会把它识别成门控单元也不会在上面创建clock gating check。你可以在report_clock_gating_check里翻一遍根本找不到XOR单元的条目。这不是工具坏了而是它在non-unate逻辑上无法建立确定性的检查模型。还有个更隐蔽的问题XOR门控对比AND/OR门控毛刺风险窗口更宽。AND门控在CLK0时对EN免疫OR门控在CLK1时对ENB免疫但XOR门控对两个输入端的变化都是即时响应的无论CLK处于高还是低只要EN发生翻转输出就会翻转。这种无相位免疫的特性使得XOR门控的毛刺风险远高于其他四种。4.3 处理XOR门控的三种实操方案方案一set_case_analysis固定控制端让XOR退化成单沿逻辑。# 分析EN0的工况此时XOR等价于buffer set_case_analysis 0 [get_pins u_xor/B] # 分析EN1的工况此时XOR等价于inverter set_case_analysis 1 [get_pins u_xor/B]把控制端固定住之后XOR就退化成buffer或inverterPrimeTime可以正常做时序传播门控信号路径的检查也能落到前一级真正的门控单元上。缺点很明显必须把两种工况都跑一遍而且set_case_analysis会旁路掉XOR本身对另一输入端的时序分析这实际上是把动态门控人为变成了静态配置不适合真正的动态切换场景。方案二在RTL或综合阶段把时钟路径上的XOR结构替换掉。最简单的办法是改成MUX加ICG配置信号选时钟源ICG做真正的门控。这样时钟网络上的逻辑都是确定性的PrimeTime从源头就能做完整的门控检查。方案三在设计规则上直接禁止时钟路径出现XOR。我自己的规矩是时钟网络上只允许出现ICG、AND、OR、BUFFER、INVERTERNAND/NOR要经过额外reviewXOR一律不允许。这个规矩虽然保守但在多个项目的signoff过程中帮我挡掉了很多半夜调时序的麻烦。4.4 如果XOR门控已经进网表signoff前怎么检查如果设计里确实已经存在XOR门控而且短期改不了RTL那在signoff前至少要做以下几件事在report_clock_gating_check里确认XOR门控确实不在列表中不要默认工具已经帮你查了用set_case_analysis对XOR控制端做两种工况的STA分别看时序是否收敛额外做一次毛刺敏感性的动态仿真重点观察控制端翻转和CLK翻转重叠时gclk上有没有窄脉冲。这些动作都不能完全替代结构性修复但至少能把风险暴露在流片之前。5. 五类门控检查策略横向对照与我的落地建议5.1 五类门控电路检查特性对照表门控类型逻辑表达式使能极性门控后空闲电平输出相对CLK极性PrimeTime自动门控识别默认门控检查质量主要风险点ANDCLK EN高有效低同相可靠高EN在CLK高电平期间翻转产生毛刺NAND~(CLK EN)高有效高反相可靠中输出反相导致参考沿偏移检查窗口错位ORCLK | ENB低有效高同相可靠高ENB在CLK低电平期间翻转产生多余沿NOR~(CLK | ENB)低有效低反相可靠中低有效和反相双重极性叠加XORCLK ^ EN可编程不定可控反相弱或无法识别低控制端翻转不受CLK电平免疫毛刺风险最大从表里能直观看到AND和OR是天然适合做门控的主要风险点落在使能信号由组合逻辑产生这个使用场景上NAND和NOR把极性做了一次反转自动检查质量就降一档到了XOR检查质量直接掉到最低因为它连门控识别的门槛都过不去。5.2 我在项目里一直遵守的四条原则第一条原则纯逻辑门控只用于低速时钟和次要路径。能用ICG的地方绝不用逻辑门逻辑门方案只留给那些时钟频率不高、门控数量少、面积约束紧的场景。ICG在Liberty里自带门控检查属性PrimeTime处理它是吃透的纯逻辑门控则要额外验证识别方向。第二条原则使能信号必须来自寄存器输出。这是我对所有逻辑门控的硬性要求。无论AND还是OR门控只要使能信号是组合逻辑直接产生默认门控检查就存在覆盖盲区因为组合毛刺可能落在敏感相位中间。如果实在无法避免组合逻辑驱动使能至少要在使能路径上加一个保持锁存器或延迟单元让毛刺被吸收掉。第三条原则signoff前必须全量过一遍report_clock_gating_check。我会重点筛查两类异常一类是应该识别成门控的单元没有识别出来比如XOR门控另一类是识别出来的门控单元中Clock Pin和Gating Pin的角色颠倒了。这两种情况都不会直接报violation但本质上等于没有检查比报几个violation危险得多。第四条原则NAND/NOR门控要专门reviewXOR门控在时钟网络上禁用。NAND和NOR不是不能用但使用前要确认门控后时钟的有效沿与下游寄存器触发沿匹配并且对门控检查的参考事件心中有数。XOR门控在时钟网络上禁用这是我吃过亏之后立的规矩因为它的毛刺风险无相位免疫PrimeTime又默认不查属于设计里埋雷但工具却不报警的典型场景。5.3 给你一份可以直接抄的门控检查命令清单签核阶段我一般会在PrimeTime里依次执行下面几条命令作为门控检查的固定动作# 报告所有被识别到的门控单元及检查值 report_clock_gating_check -verbose # 报告门控setup/hold时序路径详情 report_clock_timing -type gating_setup report_clock_timing -type gating_hold # 对所有未被识别的XOR门控进行确认搜索 get_cells -hier *xor* -quiet # 对必要的门控手动指定检查窗口 set_clock_gating_check -setup 0.2 -hold 0.05 [get_pins u_gate/B]执行完生成报告后逐条确认每个门控点的时钟输入和门控输入是否与设计意图一致。这个习惯我保持了很长时间它不止一次帮我抓出了综合工具在优化过程中引入的意外门控结构。最后再分享一个经验XOR门控问题最容易出现在项目后期因为前期仿真覆盖率不够毛刺风险很难被触发。等芯片回到实验室偶发功能错误定位到时钟网络上时成本就非常高了。与其在测试阶段用逻辑分析仪抓波形不如在设计阶段就守住时钟网络不用XOR这条线。我的看法是门控电路的选择不仅仅是一个逻辑等价问题更是时序分析的确定性问题和工程风险的控制问题后者往往比前者更值钱。