ARTICLE DETAIL

资讯详情

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

Innovus批量ECO加Repeater效率优化:setEcoMode实战指南

Innovus批量ECO加Repeater效率优化:setEcoMode实战指南 做数字后端的朋友应该都有过这种经历ECO阶段修timing一修就是一两千条net需要往上加repeater。你写个foreach循环一条net一条net地ecoAddRepeater结果跑一个多小时中间还不断弹DRC和overlap告警。我第一次遇到这个场景时第一反应是“是不是机器不行”后来才发现问题出在ECO模式上确切地说是没用好setEcoMode这个全局总开关。今天就把我优化ecoAddRepeater批量操作效率的经验完整写出来。这篇文章适合正在用 Innovus 做数字后端、被批量ECO加buffer耗时间折磨的工程师也适合刚接触ECO流程、想少走弯路的新手。核心只有一件事让工具在一个“批量模式”下干活而不是在“边做边查”的模式下慢慢磨。1. 为什么批量加Repeater会慢到怀疑人生1.1 ecoAddRepeater到底在做什么ecoAddRepeater是 Innovus 里最常用的ECO命令之一主要作用是在指定net上插入buffer或者inverter用来修复max transition、max capacitance、部分DRC违例以及解决hold或者setup问题。听起来就是“加一个单元”但实际执行时工具要考虑的事情远比想象中多。工具拿到你的请求后至少要做这几件事先查一遍目标net当前的topology确认插在哪个位置最合适然后从库里面匹配你指定的cell检查尺寸、阈值电压、是否dontUse接着要在当前floorplan里找一个能放得下的row尽量靠近插入点放完之后还要评估一下对周边cell和net的影响比如是不是挡住了别人是不是引入了新的short。整个过程相当于你在一个已经很拥挤的房间里临时加一把椅子不是把椅子扔进去就行还得看会不会挡路、会不会让房间里的人走不过去。如果只加一两个repeater这些开销完全可以忽略。但问题在于ECO阶段修timing往往是批量操作一次就是几百上千条net。每条net都走一遍完整流程累积起来的时间就非常可观了。1.2 慢的本质每次调用都是一次小规模ECO闭环我自己踩过的一个典型坑是这么写的# 低效示例每加一个repeater都立刻修一遍 foreach net $fixNetList { ecoAddRepeater -cell BUF_X4 -net $net ecoPlace -noSeq check_drc -summary }这段脚本看起来没错甚至很“严谨”——每加一个buffer就place一次、查一次DRC。但严谨的背后是巨大的性能浪费。ecoAddRepeater本身是一个完整的ECO动作工具会同步更新数据库、做局部legalize、计算congestion、检查short。紧接着的ecoPlace -noSeq又把所有ECO cell重新放一遍check_drc更是把整个design都扫一遍。这三件事串在一起每循环一次相当于把ECO流程完整跑了一遍。我实测过一个28nm模块大概8000多个instance需要给1200条net加repeater。用上面这种“边做边查”的写法平均每条net要花2秒多跑完全程接近45分钟。而这里面的ecoPlace和check_drc占了绝大部分时间因为它们每次都是全芯片级别的操作不是增量操作。也就是说很多时间其实浪费在“反复确认同一件事”上真正用来添加repeater的时间可能只有五分钟。1.3 软件世界的同款坑批量写操作这种问题并不是EDA独有的。写过业务系统的朋友应该马上能联想到数据库操作一条条insert和一次性batch insert的差距有多大做过性能优化的人都懂。像MyBatis里如果你在for循环里逐条调用insert每条都要走一次事务、一次网络往返3000条数据可能插到怀疑人生改成批量提交同样数据可能几秒钟就完成。区别不在于SQL本身而在于“提交方式”和“事务粒度”。ecoAddRepeater批量操作也是同一个道理。工具每一次命令调用其实都隐含着“提交”动作更新增量数据库、刷新状态、维护各种index。如果你能通过setEcoMode告诉工具“现在处于批量模式暂时不要做额外修正和检查”工具就可以把大量内部步骤延迟到最后一并处理整体耗时自然就下来了。2. setEcoModeECO批量操作的全局总开关2.1 setEcoMode的设计哲学setEcoMode是 Innovus 中用来配置ECO流程行为的命令影响的不只是ecoAddRepeater还包括ecoDeleteRepeater、ecoPlace、ecoRoute等一整套ECO命令。它的设计初衷很简单ECO场景千差万别有的要求精准微调有的追求速度有的要保留某些cell不动。工具不可能用一个固定策略覆盖所有场景所以把这些行为控制项暴露给你让用户根据自己的需求调整。你可以在Innovus命令行里直接敲setEcoMode -help看一下当前版本支持哪些选项。不用怕记不住常见的就那么几个真正在批量加repeater场景下高频使用的更是屈指可数。还有一个很重要的点setEcoMode设置的是全局状态不是一次性参数。它一旦设置在后续的ECO命令中会持续生效直到你修改它或者退出工具。所以它特别适合放在批处理脚本的开头作为一个“模式开关”来用。我自己的习惯是任何批量ECO脚本的第一行一定是setEcoMode把该关的检查关掉、该开的开关打开。2.2 和批量加Repeater最相关的几个选项这里列一下我在实际项目中用得最多的几个选项以及我为什么这么设置。需要注意不同Innovus版本支持的选项名可能略有差异你们以自己版本setEcoMode -help的输出为准。选项常用设置作用批量加Repeater时的建议-modifyOnlyCelltrue只允许修改你指定的ECO cell避免工具动其他逻辑推荐true防止工具顺手改动无关单元减少额外计算-fixOverlapfalse是否在ECO过程中自动修复cell重叠批量阶段先关掉最后再统一修复-removeDummyCellsfalse是否自动移除dummy cell批量阶段先关掉减少不必要的扫描-summary文件路径输出ECO摘要报告建议打开方便核对每个repeater加到了哪里-legalizefalse是否在每次ECO后自动做legalize如果你的版本支持批量阶段建议先关闭重点解释一下-fixOverlap。默认情况下ECO命令会尽量保证放置结果不产生overlap这个功能本身很好但代价是每次插入repeater都要做局部的合法化检查甚至可能为了避让某个overlap而把附近几个cell挪来挪去。批量操作时这一步会被反复触发非常耗时。更聪明的做法是先关掉它让工具快速把repeater都“扔”进去最后再用一次ecoPlace -noSeq或者setEcoMode -fixOverlap true配合ecoPlace统一整理。另外-removeDummyCells也同样。如果在ECO过程中反复扫描dummy cell时间开销不小。对于批量加buffer这种场景dummy cell完全可以留到最后一起处理。2.3 一个原则把“边做边查”变成“先做后查”理解了setEcoMode的选项核心原则就浮出水面了批量ECO操作要尽量避免在循环过程中做过于频繁的DRC检查、legalize、overlap修复这些“高成本动作”。正确思路是分三个阶段先配置ECO模式然后批量执行插入操作最后统一做收尾检查和修复。这也是setEcoMode真正的价值所在——它让工具知道“现在进入批量模式”从而延迟那些不必要立即执行的动作。打个比方你要在一个小区里装100个快递柜。如果你每装一个柜子都把整个小区的消防通道检查一遍、把所有车辆重新停一遍那装完100个柜子基本天黑了。正确做法是先把100个柜子全部装到位最后统一检查消防通道、调整车辆位置。setEcoMode就是允许你告诉施工队“先别检查装完再说”的那张授权书。3. ecoAddRepeater批量操作的实战优化方法3.1 优化前典型的低效脚本长什么样很多从ICC转过来的工程师刚接触Innovus时写的脚本风格都差不多。举个常见的例子# 低效示例 set fixNetList [get_nets -hier -filter max_transition_violation] foreach net $fixNetList { ecoAddRepeater -cell BUF_X4 -net $net ecoPlace -noSeq }这段脚本有两个问题第一ecoAddRepeater默认的ECO模式会做很多额外保护每次调用都有不小开销第二ecoPlace -noSeq放在循环内每次加完一个repeater就全量重新place一次。这两个问题叠加性能自然惨不忍睹。更隐蔽的是如果某个net因为congestion或者row资源不足导致ecoAddRepeater执行失败脚本会直接中断前面加的所有repeater状态都悬在那里排查起来也麻烦。所以优化批量操作的第一步不是换命令而是改脚本结构把“加一个、查一次”改成“全部添加、统一收尾”。3.2 推荐先用setEcoMode进入ECO批量模式再统一收尾我在实际项目里大量使用下面这套批量加repeater的模板经过多次验证效率提升非常明显# Step 1: 进入ECO批量模式 setEcoMode -modifyOnlyCell true \ -fixOverlap false \ -removeDummyCells false \ -summary eco_summary.txt # Step 2: 批量添加repeater foreach net $fixNetList { if {[catch {ecoAddRepeater -cell BUF_X4 -net $net} err]} { puts Warning: add repeater on $net failed: $err } } # Step 3: 恢复ECO常规模式统一收尾 setEcoMode -fixOverlap true -removeDummyCells true ecoPlace -noSeq check_drc -summaryStep 1里面-modifyOnlyCell true告诉工具只允许操作指定的逻辑单元避免它“好心”去改动周边逻辑。-fixOverlap false和-removeDummyCells false是把最耗时的实时修正延后。-summary会生成一份ECO摘要方便后面核对哪些net成功加了repeater哪些失败了。Step 2里用catch包住ecoAddRepeater是防止某条net失败导致整个脚本中断。这一步非常重要批量操作时一定会遇到个别加不进去的情况比如所在区域太挤、row类型不匹配等。让脚本“报错但继续跑”最后统一看summary比一次中断、反复调试要高效得多。Step 3是收尾把-fixOverlap和-removeDummyCells重新打开然后跑一次ecoPlace -noSeq统一处理所有ECO cell的摆放最后再检查DRC。这套流程下来45分钟的工作量基本能压到10分钟以内。3.3 多技能组合位置指定、批量传参、并行切分如果只是简单把所有net遍历一遍上面的模板已经够用了。但实际项目里还需要处理一些更复杂的场景。有些net必须在特定位置附近加repeater比如在高扇出网络的中间节点插入buffer或者必须插在某个hard macro旁边。这时可以用-loc {x y}指定插入位置。不过我要提醒一句指定位置后工具不会主动帮你选最优插入点如果你给的坐标附近已经没有row空间命令照样会失败。所以除非你清楚自己在做什么否则更推荐让工具自动决定位置。如果一条net需要加多个repeater可以用-num参数比如ecoAddRepeater -cell BUF_X4 -net n12345 -num 3这样一条net直接插3个buffer比循环插3次效率高很多。另外如果netlist量特别大可以考虑把netlist按区域切分成几份同时开几个Innovus session并行处理最后再merge。但这要求你有足够的license和内存而且merge过程有风险容易产生跨区域冲突。我个人的建议是除非net数量真的上到几千条否则不要轻易并行单线程配合setEcoMode已经能获得很好的收益。还有一个小技巧如果你嫌Tcl的foreach效率低可以用perl或python脚本提前生成ECO命令文件然后用source一次性灌进去。这样能省去Tcl解释器的解析开销。实际效果取决于netlist规模但对几千条net的场景确实能再省一点时间。4. 真实案例复盘45分钟到6分钟的优化全过程4.1 场景描述这个案例来自我之前做的一个28nm芯片项目。其中有个模块大概8000多个instance后端实现完成后PR工具报了一堆max transition违例主要集中在高扇出的时钟末端和数据通路上。修这类违例最直接的方法就是加repeater我数了一下需要处理的net大概1200条左右。最开始我用的就是最“朴实无华”的脚本foreach循环每个netecoAddRepeater然后立刻ecoPlace -noSeq偶尔中间加一条check_drc。跑一次全流程需要45分钟左右。如果只是偶尔跑一次也就算了问题是修完一轮之后还要重新做时序收敛来回迭代好几次每次都要等接近一个小时效率实在太低。4.2 优化过程分三步把时间压下来第一步我在脚本开头加了setEcoMode -modifyOnlyCell true -fixOverlap false -removeDummyCells false -summary eco_summary.txt同时把循环里的ecoPlace和check_drc全部去掉只保留纯粹的ecoAddRepeater。跑完发现时间从45分钟降到了18分钟效果立竿见影。这说明之前的耗时大头确实不在“加repeater”本身而是每轮循环附带的place和check操作。第二步我发现18分钟里仍然有一部分时间花在Tcl循环本身的解析和ecoAddRepeater每次调用的固定开销上。于是我干脆生成一个包含1200条ecoAddRepeater -cell BUF_X4 -net ...命令的脚本文件然后用source ./add_rep.tcl一次性灌进去。这个改动让时间从18分钟降到了11分钟左右。有人可能会问Tcl的foreach和source一个长脚本到底差在哪区别在于source一个文件时Innovus可以连续解析并执行命令省去了很多脚本解释层面的往返开销。另外我还把每条命令的反馈输出用redirect重定向到了文件里防止终端交互拖慢速度。第三步我在netlist里筛选了一遍把扇出特别大、单根repeater搞不定的net标记出来直接使用-num 2或-num 3一次插入多个buffer而不是把同一条net重复加多次。这步又把时间压缩到了6分钟左右。最终全部1200条net处理完毕耗时约6分20秒相比最初的45分钟提升了7倍左右。4.3 结果与质量检查优化后的流程跑完我做了完整的质量检查。setEcoMode -summary生成的摘要文件里1200条net中成功插入repeater的有1192条失败的8条主要是因为局部区域congestion太高没有足够的row空间。对于这8条我单独用ecoAddRepeater -cell BUF_X1换小尺寸buffer重新处理最后8条也全部搞定。overlap方面因为我批量阶段关闭了-fixOverlap所以跑完后确实出现了3处overlap集中在几个比较拥挤的局部区域。我在收尾阶段重新打开了setEcoMode -fixOverlap true执行了一次ecoPlace -noSeq3处overlap全部修复。DRC方面新增的violation只有寥寥几条都是间距问题简单shrink一下线宽或者绕一下就解决了。4.4 这么折腾值不值有朋友问过我实际开发时这种情况多吗说实话非常普遍。ECO阶段本来就是时序和DRC问题最多的时候加repeater是最常用的修复手段之一批量场景几乎天天遇到。45分钟和6分钟的差距在一天要迭代四五次的节奏下差距是“能不能在下班前跑完”级别的。当然我也要提醒一点不是所有场景都需要这么折腾。如果只有二三十条net需要加repeater默认ECO模式直接跑可能两三分钟就完事了没必要关掉-fixOverlap再开回来。优化的前提是“批量”足够大大到开销已经影响迭代效率。我的经验是net数量超过300条就值得用这套方法了。5. 常见问题与避坑指南5.1 问题速查表批量ECO加repeater的过程中有几类问题是高频出现的。我整理了一个速查表方便大家直接对照排查。现象可能原因解决方案设置了setEcoMode但没效果版本不支持某个选项或设置顺序不对先看setEcoMode -help把设置放到脚本最前面ecoAddRepeater报physical相关错误目标区域congestion高、row资源不够、cell与row类型不匹配换小尺寸cell关闭dontUse限制换个插入位置批量后overlap暴增批量阶段关闭了fixOverlap但没有统一收尾在循环后重新打开fixOverlap并执行ecoPlace添加的buffer带了PG pin导致PG short选中的cell带PG pinECO时没有正确连接PG net用不带PG pin的buffer/inverter或先用dbGet确认PG term脚本跑一半中断某条net失败导致Tcl报错退出用catch包住ecoAddRepeater记录失败并继续5.2 如何正确获取标准单元的PG term有朋友在交流群里问过Innovus里怎么选中标准单元名字为biasnw的pg term这个在批量加repeater时确实会遇到。比如你想检查某个库单元是否带PG pin或者在ECO后确认某个inst的PG连接是否正确就要用到dbGet。假设你要选中名字为biasnw的标准单元的PG term可以这样写# 先找到这个instance set instDb [dbGet -p top.insts.biasnw -if {.name biasnw}] # 再取它的所有PG term set pgTerms [dbGet -p $instDb.pgTerms.name] puts $pgTerms如果只想找VDD或者VSS这种特定PG term加上过滤条件set pgVdd [dbGet -p $instDb.pgTerms.name -if {name VDD}]为什么要关注这个因为批量加repeater的时候如果你选的库单元自带PG pin比如某些buffer标准单元工具在ECO放置时可能需要额外处理PG connection。如果PG net没有正确连接后面就会出现short或isolation violation。比较稳妥的做法是在批量操作前先用dbGet把目标库单元的PG term情况摸清楚如果不需要PG就尽量选不带PG pin的单元如果必须用带PG的单元那就要确保PG net存在且可连接。5.3 批量操作时怎么控制输出和日志批量跑几百上千条ECO命令时终端疯狂刷屏不仅看着烦还会拖慢运行速度。我通常会用redirect把输出重定向到日志文件同时打开setEcoMode -summary这样既能保留完整进度又不让交互输出拖慢速度。redirect -file eco_add_repeater.log { source ./add_rep.tcl }另外建议在脚本里多用puts打印阶段性进度但别在循环内打印太多细节。比如每处理50条net打印一次当前时间既能观察进度又不会产生大量IO开销。这个细节看似不起眼在1200条net的规模下能省下不少时间。5.4 最后一个坑别忘了恢复setEcoMode这是我特别想强调的一点。setEcoMode设置的是全局状态如果你在批量脚本里关闭了-fixOverlap跑完之后没有恢复后续其他ECO操作会继续沿用这个“只插入不修正”的模式很可能产生一堆意想不到的overlap和DRC问题。我的习惯是批量脚本的最后几行必须包含恢复配置setEcoMode -fixOverlap true -removeDummyCells true最好在验证收尾完成后再执行一次report_eco_mode或者直接查看当前设置确认已经恢复到常规状态。否则下次跑别的ECO脚本时很容易被这个“历史遗留模式”坑一把。最后再分享一个我自己的实际操作体会批量ECO这块最重要的不是把某个命令研究到极致而是建立起“批量模式”的思维方式。setEcoMode不是魔法它只是把工具的工作方式调到更适合批量处理的档位。先在小样本上试跑确认设置合理再铺开到全量netlist是我长期跑ECO流程养成的习惯。如果你现在正被批量ecoAddRepeater折磨不妨把今天的思路拿回去试一试时间上的惊喜大概率比我这个案例还明显。
返回列表