ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CCOPT时钟树综合实战:从Clock Spec到Skew Group的约束精解

CCOPT时钟树综合实战:从Clock Spec到Skew Group的约束精解 1. 时钟树综合到底在解决什么问题做数字后端这行的朋友大概率都有过这样的经历跑完Place时序看着还行结果CTS一跑完setup直接崩了hold更是惨不忍睹。然后就开始怀疑人生——明明place阶段时序是收敛的怎么clock tree一插进去就全乱了这个问题的根源在于很多人对CCOPTClock Concurrent Optimization的理解还停留在“让工具自动跑一下clock tree”的层面。实际上CCOPT是Innovus里最核心也最复杂的引擎之一它不只是做clock tree balancing而是把clock tree synthesis和timing optimization放在同一个优化循环里同时求解。你给它的约束越精确它给你的结果就越好你给它的约束含糊不清它就只能靠猜猜出来的结果自然没法看。这篇文章要聊的就是从Clock Spec的编写开始到Skew Group的合理划分再到CCOPT引擎的核心工作机制把这条链路彻底讲透。适合已经跑过完整flow、但对CTS阶段还停留在“跑通就行”阶段的数字后端工程师也适合正在准备面试、需要把CTS这块知识点串起来的同学。我不会只告诉你“怎么点菜单”而是把每个参数背后的why讲清楚让你下次遇到CTS问题时知道往哪个方向查。2. Clock SpecCCOPT的输入到底该怎么写2.1 Clock Spec的本质是什么很多人把Clock Spec当成一个“配置文件”觉得随便写写就行。但在我看来Clock Spec更像是你跟CCOPT引擎之间的一份合同——你告诉它哪些clock需要balance、balance到什么程度、哪些clock之间有关系、哪些完全独立。这份合同写得越清楚CCOPT的执行就越精准。Clock Spec的核心内容包括几个部分clock的定义create_clock、generated clock的定义、clock之间的group关系、每个clock的target skew和target insertion delay、以及特殊情况下的clock gating处理。这些内容最终会通过ccopt_design命令被CCOPT引擎读取成为它做clock tree building和optimization的基础。一个常见的误区是很多人直接拿SDC里的clock定义当Clock Spec用。SDC里的clock定义是为了做timing analysis的它关注的是clock waveform和clock之间的时序关系而Clock Spec需要的是物理实现层面的信息比如clock root在哪里、clock tree需要做成什么形状、skew目标是多少。两者有重叠但关注点完全不同。2.2 Clock Spec的关键参数与编写逻辑先看一个典型的Clock Spec结构。在Innovus中Clock Spec通常以.ctstch文件或者直接在脚本中用命令的方式给出。核心命令包括# 定义clock的基本信息 create_clock -name CLK -period 2.0 -waveform {0 1.0} [get_ports CLK] # 设置clock tree的target skew set_ccopt_property target_skew 50ps # 设置target insertion delay set_ccopt_property target_insertion_delay 500ps # 定义skew group create_ccopt_skew_group -name sg_core -sources CLK -targets {FF1/CK FF2/CK ...}这里面的每个参数都有讲究。target_skew设多少合适这取决于你的clock period和design的timing margin。一般来说target skew应该控制在clock period的5%以内。比如2ns的clocktarget skew设在100ps以内比较合理。如果设得太松CCOPT就不会花力气去balanceskew可能跑到200ps以上如果设得太紧CCOPT会过度优化clock tree导致面积和power飙升。target_insertion_delay这个参数更微妙。它控制的是clock root到leaf pin的延迟。设得太小clock tree做不进去设得太大clock latency增加对setup和hold都有影响。我的经验是先让CCOPT自己跑一轮看看它自然做出来的insertion delay是多少然后在这个基础上加10%-20%作为target给CCOPT留一点优化空间。2.3 Clock Spec中容易踩的坑第一个坑是generated clock的处理。很多design里有多级clock divider或者clock mux这些generated clock在SDC里定义得好好的但在Clock Spec里如果没正确声明CCOPT就不知道它们和master clock的关系做出来的clock tree可能完全不对。正确的做法是用create_ccopt_clock_tree_source_group把master clock和generated clock的关系明确出来。第二个坑是clock gating cell的处理。ICGIntegrated Clock Gatingcell在Clock Spec里需要特别标注因为CCOPT需要知道哪些cell是clock gating、它们的enable信号从哪来。如果没标注CCOPT可能会把ICG当成普通cell处理导致clock tree的balance点选错。第三个坑是clock root的确定。对于多source的clock比如clock mux的输出CCOPT需要知道哪个source是primary、哪个是backup。这个信息如果不给CCOPT可能会把两个source都当成primary来做balance结果就是clock tree做得又大又慢。注意Clock Spec写完后一定要用ccopt_design -check先做一轮检查看看有没有语法错误或者逻辑冲突。这个check花不了几分钟但能帮你省掉后面几小时的debug时间。3. Skew GroupCCOPT优化的基本单元3.1 Skew Group的定义与划分原则Skew Group是CCOPT里最核心的概念之一。简单说一个Skew Group就是一组需要被balance到同一个skew目标的clock sink。CCOPT会为每个Skew Group独立构建一棵clock tree然后在这个group内部做skew minimization。为什么需要Skew Group因为不是所有的clock sink都需要balance到一起。比如一个design里有CPU core和DDR interface它们的clock频率可能不同、timing要求也不同。如果把所有sink都放在一个Skew Group里CCOPT会试图把它们全部balance到同一个skew这既没必要也会浪费大量的clock tree资源。合理的做法是把它们分成不同的Skew Group各自独立优化。Skew Group的划分原则我总结下来有这么几条同一时钟域的sink放在同一个group这是最基本的。不同clock domain的sink本来就不需要balance到一起。timing path密集的sink优先放在一起如果两个sink之间有大量的timing path把它们放在同一个Skew Group里可以减少clock skew对setup/hold的影响。物理位置相近的sink可以考虑合并物理位置相近的sinkCCOPT做balance的成本更低合并成一个group可以提高优化效率。异步clock domain必须分开这个不用多说异步clock之间的skew没有任何意义。3.2 Skew Group的创建与约束设置在Innovus中创建Skew Group的命令是create_ccopt_skew_group。基本用法如下create_ccopt_skew_group -name sg_cpu_core \ -sources [get_clocks CLK_CPU] \ -targets [get_pins -of_objects [get_cells -hier * -filter is_sequentialtrue]]这个命令创建了一个名为sg_cpu_core的Skew Groupsource是CLK_CPUtargets是所有sequential cell的clock pin。实际项目中targets的选取需要更精细——通常会用-targets配合-include和-exclude来精确控制哪些sink属于这个group。创建完Skew Group后还需要设置一些关键属性# 设置这个group的target skew set_ccopt_property -skew_group sg_cpu_core target_skew 30ps # 设置这个group的target insertion delay set_ccopt_property -skew_group sg_cpu_core target_insertion_delay 400ps # 设置这个group的clock tree routing layer set_ccopt_property -skew_group sg_cpu_core route_type trunktarget_skew的设置需要根据这个group里sink的数量和物理分布来调整。sink多、分布广的grouptarget skew可以适当放宽sink少、集中的group可以设得紧一些。3.3 Skew Group划分不当的典型症状Skew Group划分不当最直接的表现就是CTS后timing崩盘。具体来说有几种典型症状第一种是setup violation集中在某几个path上。这通常是因为这些path的launch和capture flop被分在了不同的Skew Group里CCOPT没有对它们之间的skew做优化。解决办法是把这些flop合并到同一个Skew Group或者用set_ccopt_property -skew_group给它们设置一个更紧的skew目标。第二种是clock tree面积异常大。这通常是因为Skew Group划分得太细每个group都要独立建一棵clock tree导致clock buffer数量暴增。解决办法是合并一些物理位置相近、timing要求相似的Skew Group。第三种是hold violation大面积出现。这通常是因为Skew Group的target insertion delay设得太小CCOPT为了满足insertion delay目标把clock tree做得太短导致clock skew过大。解决办法是适当放宽insertion delay目标给CCOPT更多优化空间。提示Skew Group的划分不是一次性的工作。在CTS后的timing analysis中如果发现某些path的skew问题特别严重可以回头调整Skew Group的划分然后重新跑CTS。这个迭代过程通常需要2-3轮。4. CCOPT引擎的核心工作机制4.1 CCOPT与传统CTS的本质区别传统的CTS flow是分步走的先做clock tree building再做clock tree balancing最后做timing optimization。每一步都是独立的前一步的结果是后一步的输入。这种flow的问题在于clock tree building的时候不知道timing optimization的需求timing optimization的时候又改不了clock tree的结构。CCOPT把这个流程彻底重构了。它把clock tree synthesis和timing optimization放在同一个优化引擎里同时求解。具体来说CCOPT会在clock tree building的过程中就考虑timing path的需求在插入clock buffer的时候就会评估这个buffer对setup/hold的影响。如果某个clock buffer的插入会导致某条path的setup变差CCOPT会尝试调整clock tree的结构来避免这个问题。这种concurrent optimization的能力是CCOPT相比传统CTS最大的优势。但代价是CCOPT对输入约束的敏感度也更高。你给它的Clock Spec和Skew Group越精确它的优化效果就越好你给的信息越模糊它就越容易做出错误的决策。4.2 CCOPT的优化流程拆解CCOPT的优化流程大致可以分为几个阶段第一阶段Clock Tree Building。CCOPT根据Clock Spec和Skew Group的定义从clock root开始向下构建clock tree。这个阶段的核心决策是在哪里插入clock buffer、用什么类型的buffer、走哪一层金属。CCOPT会综合考虑sink的物理位置、clock tree的skew目标、以及routing的congestion情况来做这些决策。第二阶段Clock Tree Balancing。Clock tree building完成后CCOPT会计算每个sink的clock latency然后通过调整clock buffer的驱动强度、插入额外的delay cell、或者调整routing长度来balance各个sink的latency。这个阶段的目标是让同一个Skew Group内的sink latency尽可能接近。第三阶段Timing-driven Optimization。在clock tree基本balance之后CCOPT会做一轮timing-driven的优化。它会检查所有timing path的setup和hold情况然后尝试通过调整clock tree的结构来改善timing。比如如果某条path的setup很紧CCOPT可能会尝试减少launch clock的latency或者增加capture clock的latency。第四阶段Post-CTS Refinement。CCOPT完成后还会有一轮post-CTS的refinement包括clock tree的legalization、routing的优化、以及和place阶段的data path optimization的协同。这四个阶段不是严格串行的CCOPT会在它们之间反复迭代直到满足所有的约束或者达到优化上限。4.3 CCOPT的关键参数与调优策略CCOPT的行为受很多参数控制其中最重要的几个包括参数作用推荐设置target_skew控制Skew Group内的skew目标clock period的3%-5%target_insertion_delay控制clock root到leaf的延迟根据design规模通常300ps-800psccopt_effort控制CCOPT的优化力度high对timing要求高的designclock_tree_source_group定义clock source的关系根据clock结构精确设置route_type控制clock net的routing类型trunk主干或 leaf分支ccopt_effort这个参数值得单独说一下。它有三个档位low、medium、high。low档位下CCOPT只做基本的clock tree building和balancing不做timing-driven optimizationmedium档位下CCOPT会做一些timing-driven的优化但力度有限high档位下CCOPT会做全面的timing-driven optimization包括clock tree restructuring。对于timing紧张的design直接上high档位不要犹豫。还有一个容易被忽略的参数是ccopt_skew_group的-targets设置。很多人直接用get_pins把所有sequential cell的clock pin都抓进来但这样会把一些不需要balance的sink也包含进来。更好的做法是用-include和-exclude精确控制比如排除掉scan chain的sink、排除掉已经做了clock gating的sink。5. 从Clock Spec到Skew Group的完整实操流程5.1 实操环境与前期准备在开始CTS之前需要确保几个前提条件已经满足Place已经完成并且时序基本收敛。CTS是在Place的基础上做的如果Place阶段时序就很差CTS后只会更差。SDC已经正确加载并且验证过。Clock的定义、clock之间的时序关系、false path和multicycle path都已经设置好。Floorplan已经确定。Clock root的位置、macro的摆放、power plan都已经完成不会在CTS阶段再做大调整。Routing layer已经规划好。Clock net走哪几层金属、和signal net的layer分配关系已经明确。这些条件如果有一个不满足CTS的结果都会大打折扣。我见过很多caseCTS后timing崩了查了半天发现是SDC里的clock定义有问题或者Floorplan里clock root的位置放错了。5.2 Clock Spec的编写与验证假设我们有一个典型的SoC design包含一个CPU core、一个DDR controller、和一个peripheral bus。Clock结构是一个PLL输出主时钟经过divider产生CPU clock、DDR clock、和bus clock。Clock Spec的编写步骤如下第一步定义primary clock。create_clock -name CLK_PLL -period 1.0 -waveform {0 0.5} [get_ports CLK_PLL]第二步定义generated clock。create_generated_clock -name CLK_CPU -source [get_ports CLK_PLL] \ -divide_by 2 [get_pins CPU_DIV/Q] create_generated_clock -name CLK_DDR -source [get_ports CLK_PLL] \ -divide_by 4 [get_pins DDR_DIV/Q] create_generated_clock -name CLK_BUS -source [get_ports CLK_PLL] \ -divide_by 8 [get_pins BUS_DIV/Q]第三步定义clock tree source group。create_ccopt_clock_tree_source_group -name sg_pll -source CLK_PLL create_ccopt_clock_tree_source_group -name sg_cpu -source CLK_CPU create_ccopt_clock_tree_source_group -name sg_ddr -source CLK_DDR create_ccopt_clock_tree_source_group -name sg_bus -source CLK_BUS第四步设置clock tree的全局属性。set_ccopt_property target_skew 50ps set_ccopt_property target_insertion_delay 500ps set_ccopt_property ccopt_effort high第五步验证Clock Spec。ccopt_design -check这个check会报告Clock Spec中的语法错误、逻辑冲突、以及一些潜在的优化问题。如果check通过就可以进入下一步。5.3 Skew Group的创建与精细调整Clock Spec验证通过后开始创建Skew Group。根据前面的clock结构我们至少需要创建四个Skew GroupCPU、DDR、BUS、以及一个用于cross-domain path的特殊group。# CPU Skew Group create_ccopt_skew_group -name sg_cpu_core \ -sources [get_clocks CLK_CPU] \ -targets [get_pins -of_objects [get_cells -hier * -filter is_sequentialtrue]] \ -include [get_pins -of_objects [get_cells -hier CPU_*]] \ -exclude [get_pins -of_objects [get_cells -hier *scan*]] # DDR Skew Group create_ccopt_skew_group -name sg_ddr_ctrl \ -sources [get_clocks CLK_DDR] \ -targets [get_pins -of_objects [get_cells -hier * -filter is_sequentialtrue]] \ -include [get_pins -of_objects [get_cells -hier DDR_*]] # BUS Skew Group create_ccopt_skew_group -name sg_bus_peri \ -sources [get_clocks CLK_BUS] \ -targets [get_pins -of_objects [get_cells -hier * -filter is_sequentialtrue]] \ -include [get_pins -of_objects [get_cells -hier BUS_*]] # Cross-domain Skew Group create_ccopt_skew_group -name sg_cross_domain \ -sources [get_clocks {CLK_CPU CLK_DDR CLK_BUS}] \ -targets [get_pins -of_objects [get_cells -hier * -filter is_sequentialtrue]] \ -include [get_pins -of_objects [get_cells -hier *sync*]]创建完Skew Group后需要为每个group设置独立的target skew和insertion delayset_ccopt_property -skew_group sg_cpu_core target_skew 30ps set_ccopt_property -skew_group sg_cpu_core target_insertion_delay 400ps set_ccopt_property -skew_group sg_ddr_ctrl target_skew 50ps set_ccopt_property -skew_group sg_ddr_ctrl target_insertion_delay 500ps set_ccopt_property -skew_group sg_bus_peri target_skew 80ps set_ccopt_property -skew_group sg_bus_peri target_insertion_delay 600ps这些数值不是拍脑袋定的。CPU core的timing最紧所以target skew设得最小DDR controller的timing相对宽松可以适当放宽BUS peripheral的timing最松target skew可以设得大一些。insertion delay的设置也是类似的逻辑——timing紧的domaininsertion delay可以设小一点让clock tree做得短一些减少latency对setup的影响。5.4 CCOPT执行与结果检查一切准备就绪后执行CCOPTccopt_designCCOPT的执行时间取决于design规模和优化力度。对于中等规模的SoC100万门左右high effort下大概需要30分钟到1小时。执行完成后需要做几项关键检查检查一Clock tree的skew是否满足目标。report_ccopt_skew_groups这个命令会报告每个Skew Group的实际skew和insertion delay。如果实际skew远大于target说明CCOPT没能满足约束需要检查Skew Group的划分是否合理或者target skew是否设得太紧。检查二Clock tree的buffer数量和面积。report_ccopt_clock_trees -summary这个命令会报告clock tree的buffer数量、面积、以及power消耗。如果buffer数量异常多说明clock tree做得太复杂可能需要合并一些Skew Group。检查三Timing是否收敛。report_timing -max_paths 100 -delay max report_timing -max_paths 100 -delay minCTS后的timing report是检验CCOPT效果的最直接标准。如果setup和hold的violation都在可接受范围内说明CCOPT的工作是成功的。6. 常见问题与排查技巧实录6.1 CTS后setup大面积violation这是最常见的问题。CTS后setup violation突然增多通常有以下几个原因原因一Clock Spec里的target insertion delay设得太小。CCOPT为了满足insertion delay目标把clock tree做得很短导致clock skew过大。解决办法是适当放宽insertion delay目标给CCOPT更多优化空间。原因二Skew Group划分不合理。如果launch和capture flop被分在了不同的Skew Group里CCOPT不会对它们之间的skew做优化。解决办法是把这些flop合并到同一个Skew Group或者用set_ccopt_property给它们设置一个更紧的skew目标。原因三CCOPT的effort设得太低。如果ccopt_effort设的是low或mediumCCOPT不会做全面的timing-driven optimization。解决办法是直接上high effort。排查这类问题时我通常会用report_ccopt_skew_groups先看skew情况然后用report_timing定位具体的violation path最后用get_ccopt_property检查相关Skew Group的设置。6.2 CTS后hold violation严重Hold violation在CTS后出现通常是因为clock skew的方向不对。具体来说如果capture clock的latency比launch clock大很多hold就会变差。解决办法有几个一是调整Skew Group的target skew让CCOPT更严格地控制skew二是在hold critical path上插入delay cell三是调整clock tree的结构让launch和capture clock的latency更接近。我个人的经验是hold violation在CTS阶段不用太紧张因为post-CTS还有一轮hold fixing的机会。但如果hold violation的数量超过1000个就说明clock tree的结构有问题需要回头检查Skew Group的划分。6.3 Clock tree面积过大Clock tree面积过大通常是因为Skew Group划分得太细每个group都要独立建一棵clock tree。解决办法是合并一些物理位置相近、timing要求相似的Skew Group。另一个可能的原因是target skew设得太紧。CCOPT为了满足严格的skew目标会插入大量的clock buffer来做balance。适当放宽target skew可以显著减少clock buffer的数量。还有一个容易被忽略的原因是clock tree的routing layer选择不当。如果clock net走了低层金属resistance大CCOPT需要插入更多的buffer来驱动。把clock net移到高层金属可以减少buffer数量。6.4 常见问题速查表问题现象可能原因排查命令解决办法CTS后setup崩insertion delay太小report_ccopt_skew_groups放宽insertion delayCTS后hold崩clock skew方向不对report_timing -delay min调整Skew Group或插delay cellclock tree面积大Skew Group太细report_ccopt_clock_trees合并Skew Groupskew不满足目标target skew太紧report_ccopt_skew_groups放宽target skewCCOPT跑不完design太大或effort太高查看log降低effort或分块跑提示CCOPT的log文件里有很多有用的信息包括每个阶段的优化结果、遇到的冲突、以及工具的建议。遇到问题时先翻log往往能找到线索。7. 一些实战中的经验体会CCOPT这个引擎我用了很多年踩过的坑也不少。最大的体会是约束的精确度决定了结果的质量。你给CCOPT的信息越精确它做出的决策就越合理。Clock Spec和Skew Group的编写本质上是在把design的timing需求翻译成CCOPT能理解的语言。这个翻译过程做得越好CTS的结果就越好。另一个体会是不要害怕迭代。CTS不是一次就能做好的通常需要2-3轮迭代。第一轮跑完后根据timing report调整Skew Group的划分和target skew的设置然后再跑第二轮。每一轮迭代都会让结果更好。还有一点post-CTS的timing analysis比CTS本身更重要。CCOPT跑完只是开始真正的挑战在于分析CTS后的timing report找出问题的根源然后针对性地调整约束。这个过程需要耐心和经验但也是提升CTS质量的关键。最后分享一个小技巧在跑CCOPT之前先用ccopt_design -check做一轮检查然后用ccopt_design -preview做一轮快速预览。这个预览不会真正插入clock tree但会报告CCOPT对当前约束的评估结果包括预期的skew、insertion delay、以及可能的冲突。这个预览花不了几分钟但能帮你提前发现很多问题。
返回列表