ARTICLE DETAIL

资讯详情

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

数字后端PR阶段short修复:自动化脚本方案与实操

数字后端PR阶段short修复:自动化脚本方案与实操 1. 数字后端PR阶段short修复的底层逻辑1.1 为什么short是PR阶段最让人头疼的问题做数字后端物理实现的人都有一个共识timing违例可以慢慢调DRC可以逐条清但short这个东西一旦在PR阶段后期冒出来尤其是那种零星的、藏在密集标准单元阵列里的short排查起来能把人逼疯。我在多个先进工艺节点从40nm到7nm的项目中几乎每个项目都会在routing之后的verify阶段遇到short问题少则几十个多则上千个。short的本质是什么就是两条本不该连接的net在物理空间上发生了电气连接。在PR工具Innovus或ICC2的语境下short通常分为几类信号线对信号线的short、信号线对power/ground的short、power对ground的short。其中最常见也最麻烦的是信号线对PGPower/Ground的short因为PG网络遍布整个芯片标准单元的rail、follow pin、power mesh到处都是信号线稍微走偏一点就可能搭上去。为什么PR阶段特别容易出short原因很多。绕线拥塞congestion导致工具被迫走非常规路径、cell pin access不好导致via打偏、手工ECO时没注意避让、metal layer的min spacing规则在先进节点越来越复杂、double pattern coloring冲突等等。这些问题在40nm以上可能还不明显到了16nm以下尤其是7nm、5nmshort的数量和修复难度都是指数级上升。1.2 三大工具修复short的通用思路不管是Innovus还是ICC/ICC2修复short的核心思路其实就三条路挪线、改via、调cell位置。听起来简单但实际操作中你需要一个高效的脚本来批量处理否则手动一个一个修一个千级short的design能让你修到怀疑人生。挪线是最直接的方式。工具通常提供了editMoveWire、editMoveWireShape之类的命令可以把某段走线整体平移或者改变拐点位置。ICC2里对应的是move_objects配合reshape操作。挪线的关键在于你得知道往哪个方向挪、挪多少。挪多了可能碰到别的线产生新short挪少了原来的short没解决。改via是另一种常见手段。有时候short不是wire本身搭上了而是via打错了位置比如via enclosure不够导致和旁边的net短路。这时候你需要删掉旧via、在正确位置重新打via。Innovus里用editDeleteVia和editAddViaICC2里用remove_vias和create_via。调cell位置适用于short发生在cell pin附近的情况。有时候std cell的pin和旁边的wire靠得太近DRC报short这时候把cell稍微挪一点点几十纳米short就没了。Innovus里用editMoveInstICC2里用move_objects。但问题是当你面对几百上千个short的时候你怎么知道哪个short该用哪种方法怎么批量执行怎么保证修完不引入新问题这就是脚本的价值所在。1.3 脚本方案的整体设计考量我写这个脚本的初衷很简单把short修复的流程标准化、自动化。核心设计原则有四条第一先分类再修复。不同原因的short用不同策略不能一刀切。脚本首先要做的是parse工具的short report把short按类型signal-to-signal、signal-to-PG、PG-to-PG、按metal layer、按位置聚类。第二优先用工具原生命令。Innovus和ICC2都提供了丰富的edit命令脚本要做的是把这些命令串起来而不是自己去操作DEF。工具原生命令的好处是它会自动做DRC check避免你修完引入新违例。第三迭代修复。一轮修不完就多修几轮每轮修完重新verify直到short数量收敛到零或者不再下降。这个思路跟timing ECO很像都是迭代收敛的过程。第四可回滚。每轮修复前保存design snapshot万一修出问题了可以回退。这个在实际项目中太重要了我见过太多次脚本跑飞了把design搞烂的情况。2. 脚本核心模块拆解与关键实现2.1 short report的解析与分类不管你用Innovus还是ICC2verify之后都会生成short report。Innovus的report通常是verifyConnectivity或者verifyGeometry的输出ICC2则是check_routes或者verify_zrt_route的结果。格式略有不同但核心信息都包含short涉及的两个net名字、short发生的坐标、涉及的metal layer。脚本的第一步就是parse这个report。我用的是Tcl脚本因为Innovus和ICC2都原生支持Tcl。解析逻辑大概是这样的# 以Innovus为例解析short report set fp [open short.rpt r] set short_list {} while {[gets $fp line] 0} { if {[regexp {Short between net (\S) and net (\S) at location \((\S) (\S)\) on layer (\S)} $line match net1 net2 x y layer]} { lappend short_list [list $net1 $net2 $x $y $layer] } } close $fp解析完之后要做分类。分类的依据主要是net的类型。怎么判断一个net是PG还是signalInnovus里可以用dbGet查net的属性ICC2里用get_attribute。如果net名字里包含VDD、VSS、GND之类的关键词大概率是PG net。更准确的方法是查net的netType属性或者看它连的是不是tie cell。分类之后我会把short按metal layer排序。低层metalM1、M2的short通常跟cell pin access有关修复策略偏向挪cell或者改pin access。高层metalM5以上的short通常是绕线问题挪线或者改via更有效。2.2 挪线修复模块的实现细节挪线是修复short最常用的手段。Innovus里核心命令是editMoveWireICC2里是move_objects -reshape。但直接用这些命令有个问题你得指定挪动的方向和距离。脚本怎么自动决定这些参数我的做法是先分析short点附近的绕线情况找到一条安全通道。具体来说脚本会查询short点周围一定范围内的所有wire和via计算哪个方向有足够的space可以挪过去。这个space的计算要考虑min spacing规则、wire的width、以及周围其他net的分布。# Innovus挪线示例把指定坐标附近的wire往右挪0.02um proc moveWireAtPoint {x y layer direction distance} { set wires [dbGetTop.objs -objType wire -layer $layer -within [list $x $y]] foreach wire $wires { editMoveWire $wire $direction $distance } }这里有个关键点挪线之后一定要做DRC check。Innovus的editMoveWire命令有个-checkDRC选项建议打开。ICC2的move_objects之后要用check_routes验证。我一般会在脚本里每修100个short就做一次局部DRC check避免问题累积。挪线的距离怎么定我的经验是从min spacing的1.5倍开始试不行就逐步加大。比如min spacing是0.04um那就先试0.06um不行试0.08um、0.1um。但也不能无限加大超过0.2um的挪动基本就意味着绕线拓扑要大改了这时候不如直接删掉重绕。2.3 via替换与修复模块via相关的short通常有两种情况一种是via打在了错误的位置另一种是via的enclosure不够导致和旁边的net短路。前者需要删掉重打后者需要换更大enclosure的via。Innovus里删除via用editDeleteVia添加via用editAddVia。ICC2里用remove_vias和create_via。脚本的逻辑是先找到short点附近的via判断这个via是不是导致short的元凶如果是就删掉然后在合法位置重新打一个。# Innovus via替换示例 proc fixViaShort {x y layer} { set vias [dbGetTop.objs -objType via -layer $layer -within [list $x $y]] foreach via $vias { set viaName [dbGet $via.name] editDeleteVia $via # 在偏移位置重新打via editAddVia -via $viaName -at [list [expr $x0.01] [expr $y0.01]] } }via替换的注意事项新via的位置一定要做DRC check尤其是via的enclosure规则。先进节点里via enclosure的规则非常复杂不同metal layer、不同via type的enclosure要求都不一样。我一般会查一下tech LEF里的via定义确认新位置的enclosure满足要求。2.4 cell位置微调模块有些short是因为std cell的pin和旁边的wire靠太近导致的。这种情况下把cell挪一点点就能解决。Innovus里用editMoveInstICC2里用move_objects。但挪cell有个风险可能影响timing。所以脚本在挪cell之前要先check这个cell是不是timing critical的。怎么check可以查cell的slack如果slack小于某个阈值比如0.1ns就不挪改用其他方法修short。# Innovus挪cell示例 proc moveCellForShort {instName direction distance} { set slack [get_attribute $instName slack] if {$slack 0.1} { editMoveInst $instName $direction $distance } else { puts Skip moving $instName due to tight timing } }挪cell的距离一般很小几十纳米就够了。挪完之后要重新做DRC和timing check。我一般会在脚本里设置一个最大挪动次数比如一个cell最多挪3次超过3次还修不好就放弃改用其他方法。3. 完整实操流程与参数配置3.1 环境准备与脚本部署先说环境。Innovus我用的是20.10以上的版本ICC2用的是2019.03以上。这两个版本对edit命令的支持比较完善尤其是批量操作的性能优化做得不错。脚本文件我一般放在项目目录的scripts/fix_short/下面主脚本叫fix_short.tcl配置文件叫fix_short.cfg。配置文件里主要放这些参数min spacing的值从tech LEF里读、最大挪线距离、最大挪cell次数、DRC check的频率、每轮修复的最大short数量。这些参数因工艺节点而异7nm的min spacing可能是0.04um40nm可能是0.1um不能写死。# fix_short.cfg 示例 set MIN_SPACING 0.04 set MAX_MOVE_DIST 0.2 set MAX_CELL_MOVE 3 set DRC_CHECK_INTERVAL 100 set MAX_SHORT_PER_ROUND 500 set TIMING_SLACK_THRESHOLD 0.1部署的时候有个小技巧先把脚本source到工具里然后用fix_short_main命令启动。不要直接跑先跑一个dry run模式看看脚本parse出来的short list对不对分类对不对。dry run模式就是只打印不执行确认无误再真正跑。3.2 第一轮修复批量挪线第一轮修复我一般只做挪线因为挪线风险最小、速度最快。脚本会遍历short list对每个short尝试挪线。挪线的方向优先级是先试水平方向左或右不行再试垂直方向上或下。为什么因为水平挪线对timing的影响通常比垂直挪线小而且水平方向的space通常更多。# 第一轮修复主逻辑 proc fixShortRound1 {short_list} { set fixed_count 0 set fail_count 0 foreach short $short_list { set net1 [lindex $short 0] set net2 [lindex $short 1] set x [lindex $short 2] set y [lindex $short 3] set layer [lindex $short 4] set result [tryMoveWire $x $y $layer] if {$result 1} { incr fixed_count } else { incr fail_count } if {[expr $fixed_count % $DRC_CHECK_INTERVAL] 0} { verifyGeometry } } puts Round 1: fixed $fixed_count, failed $fail_count }第一轮跑完一般能修掉60%到70%的short。剩下的30%到40%通常是挪线解决不了的需要进入第二轮。3.3 第二轮修复via替换与cell微调第二轮针对第一轮没修好的short尝试via替换和cell微调。脚本会先判断short点附近有没有via如果有就优先试via替换。如果没有via就找附近的cell尝试微调cell位置。# 第二轮修复主逻辑 proc fixShortRound2 {short_list} { foreach short $short_list { set x [lindex $short 2] set y [lindex $short 3] set layer [lindex $short 4] set vias [dbGetTop.objs -objType via -layer $layer -within [list $x $y]] if {[llength $vias] 0} { fixViaShort $x $y $layer } else { set insts [dbGetTop.objs -objType inst -within [list $x $y]] foreach inst $insts { moveCellForShort $inst.name right 0.02 } } } }第二轮跑完short数量应该能降到个位数或者零。如果还有剩那就进入第三轮手工介入。脚本会把剩余的short输出成一个report包含坐标、net名字、layer、以及脚本尝试过的修复方法。你拿着这个report去Innovus的GUI里手动修效率会高很多。3.4 修复后的验证与收敛判断每轮修复之后都要做verify。Innovus里用verifyConnectivity和verifyGeometryICC2里用check_routes和verify_zrt_route。verify之后重新parse short report看short数量有没有下降。收敛判断的标准是short数量降到零或者连续两轮short数量不再下降。如果是后者说明剩下的short用脚本搞不定了需要手工介入。# 收敛判断逻辑 set prev_count [llength $short_list] set curr_count [llength [parseShortReport short_new.rpt]] if {$curr_count 0} { puts All shorts fixed! } elseif {$curr_count $prev_count} { puts Short count not decreasing, manual intervention needed } else { puts Short count reduced from $prev_count to $curr_count, continue... }4. 常见问题与排查技巧实录4.1 脚本跑完short反而变多了怎么办这是最让人崩溃的情况。脚本跑完short数量不降反升。原因通常有三个一是挪线挪过头了把原来的short修好了但引入了新的short二是via替换时新via的位置不合法产生了新的DRC违例三是cell微调影响了周围的绕线导致连锁反应。排查方法先看新产生的short在什么位置。如果集中在某几个区域说明是局部操作引起的。把脚本的日志打开看这些区域执行了什么操作。如果是挪线引起的把挪线距离调小如果是via替换引起的检查新via的enclosure如果是cell微调引起的把微调距离调小或者干脆禁用cell微调。我的经验是挪线距离宁小勿大从min spacing的1.2倍开始试不行再逐步加大。via替换一定要做DRC check不要嫌慢。cell微调能不用就不用除非实在没别的办法。4.2 先进节点下short修复的特殊考量7nm以下的节点short修复有几个特殊点。第一double pattern coloring的影响。有些short是因为coloring冲突导致的这时候光挪线没用得重新color。Innovus里可以用setNanoRouteMode -drouteColor相关的选项来调整coloring策略。第二via的enclosure规则极其复杂。7nm的via enclosure可能有几十条规则不同metal layer、不同via type、不同width的wireenclosure要求都不一样。脚本里一定要从tech LEF里动态读取这些规则不要写死。第三min spacing规则不是单一的。先进节点有multiple patterning同color和不同color的min spacing不一样。脚本里要区分处理不能一刀切。4.3 常见问题速查表问题现象可能原因排查方法解决方案脚本跑完short变多挪线过头或via位置不合法查看新short的位置分布调小挪线距离检查via enclosure某区域short反复修不好该区域congestion严重查看congestion map先做局部congestion优化再修short挪cell后timing变差cell是timing critical的查cell的slack设置slack阈值低于阈值不挪via替换后DRC报错新via enclosure不够查tech LEF的via规则换更大enclosure的via或调整位置脚本跑得特别慢short数量太多或DRC check太频繁看脚本日志减少DRC check频率分批处理4.4 几个我踩过的坑第一个坑没做dry run就直接跑。有一次我写了个新脚本没做dry run就直接在项目上跑结果parse short report的正则写错了把所有的short都parse成了同一个坐标脚本对着一个点疯狂挪线把那个区域搞得一团糟。从那以后我每次跑新脚本都先做dry run。第二个坑忘了保存snapshot。有一次脚本跑了一半我发现short数量在上升想回退结果发现没保存snapshot只能从头再来。现在我的脚本里强制在每轮修复前保存snapshot用saveDesign或者save_block。第三个坑DRC check太频繁导致脚本跑得极慢。一开始我设置每修10个short就做一次DRC check结果一个千级short的design跑了整整一天。后来改成每100个check一次速度快了10倍效果也没差多少。第四个坑没考虑multi-patterning的coloring。在7nm项目上我一开始没考虑coloring挪线之后short是没了但coloring冲突导致DRC爆了。后来在脚本里加了coloring check挪线之后先check coloring不合法就换个方向挪。5. 脚本的扩展与自动化集成5.1 与PR flow的集成方式这个脚本最好集成到PR flow里在route之后的verify阶段自动触发。Innovus里可以在flow script里加一个hookroute完成之后自动source这个脚本。ICC2里类似在route_opt之后加一个fix_short的step。集成的时候要注意脚本跑完之后要重新做timing signoff。因为挪线和挪cell都可能影响timing虽然影响通常很小但signoff之前一定要重新跑STA确认。# Innovus flow集成示例 routeDesign verifyConnectivity if {[llength [parseShortReport short.rpt]] 0} { source scripts/fix_short/fix_short.tcl fix_short_main verifyConnectivity verifyGeometry } extractRC reportTiming5.2 批量处理多个block的技巧如果是大型SoC通常分多个block做PR。每个block都会有short问题。这时候可以用一个顶层脚本批量调用fix_short脚本依次处理每个block。顶层脚本负责切换design、调用fix_short、收集结果。# 批量处理多个block set blocks {block_a block_b block_c} foreach blk $blocks { puts Processing $blk... source scripts/fix_short/fix_short.tcl fix_short_main -block $blk puts $blk done, remaining shorts: [llength [parseShortReport ${blk}_short.rpt]] }批量处理的时候要注意内存管理。每个block处理完之后要释放内存不然跑几个block之后工具就卡死了。Innovus里用freeDesignICC2里用remove_design。5.3 脚本的维护与版本管理这种脚本是要长期维护的因为工艺节点在变、工具版本在变、项目需求在变。我一般用git做版本管理每个项目开一个branch公共部分放在master上。脚本里的参数尽量做成可配置的不要写死。另外脚本的日志要详细。每次跑完日志里要记录parse了多少个short、分类结果、每轮修复了多少个、失败了多少个、失败的原因是什么。这些日志在项目review的时候非常有用可以拿来分析short的分布规律反过来优化PR的绕线策略。6. 个人实操体会与建议这个脚本我在多个项目上用过从40nm到7nm都有。实测下来对于signal-to-signal的short修复率能到95%以上对于signal-to-PG的short修复率大概80%左右因为PG网络的绕线通常更密集挪线空间更小PG-to-PG的short基本修不了那种通常是power mesh的设计问题得从power plan阶段解决。脚本不是万能的它解决的是批量、重复、有规律的short。对于那些特别复杂的short比如涉及多个net、多个layer的还是得手工修。但脚本能帮你把80%的简单short快速清掉让你有精力去处理那20%的硬骨头这本身就是巨大的效率提升。最后分享一个小技巧修short的时候先修高层metal的short再修低层metal的。因为高层metal的short通常影响范围大修好之后可能会顺带解决一些低层metal的short。反过来先修低层的话高层short还在低层修了也白修。这个顺序在实际项目中能省不少时间。
返回列表