数字IC后端PR阶段short自动化修复实战:Innovus与ICC2流程解析
干了这么多年数字IC后端PR阶段最磨人的问题之一就是short。尤其到了28nm以下工艺节点几百条short的DRC报告摆在眼前靠手工一条一条去绕线画routing blockage再ecoRoute效率低到怀疑人生。Innovus和ICC2两套工具我都长期用过老实说它们修short的底层逻辑有差异命令体系更是完全不同。这篇文章我就把两套环境下自动化修复short的实战经验摊开讲从short的物理成因、报告解析、脚本思路到参数调节再到修不掉时的硬核解法整理成一套可以直接参考的流程。1. short问题定位先搞清楚它在物理上到底发生了什么1.1 一颗芯片的short是怎么“长”出来的很多人一看到short就觉得是工具布线布坏了其实大多数short是多个环节叠加出来的结果。PR流程里从global routing到detail routing再到CTS、hold fixing、ECO每一步都可能引入short。最常见的一种情况是布线资源评估不准确某个区域congestion热点比预期严重detail routing时同层金属的两条net在track上发生了重叠工具在search-and-repair循环里没来得及清干净short就留下了。还有一类典型场景是ECO改逻辑。比如你原来的ECO只是把某个buffer挪个位置或者加个inverter工具做ecoRoute时只改了局部连接却残留了旧的via或者多余的metal segment。这些残留金属正好和附近信号线在同层搭上短路就诞生了。finFET节点下的via结构尤其敏感via pillar和via switching设置如果不当时钟net在往上跳层时很容易和旁边的数据net碰上。所以修short之前先得搞清楚它到底是怎么来的才能决定用轻量级修复还是推倒重来。1.2 为什么short总是拖到后期才爆发很多项目前期跑route_opt顺风顺水DRC一片绿一到hold fixing阶段short突然冒出来几十条。原因在于hold fix的buffer insertion会改变局部cell密度和绕线需求工具为了满足时序目标临时调节走线路径原本不拥挤的区域突然被塞进去几条绕道线冲突就出现了。另外CTS之后时钟树上的buffer/inverter也是一堆新增的pin这些pin的出pin位置如果和信号线在同层非常容易形成short。还有一个现实问题很多团队在PR过程中并不会每个iteration都跑全量DRC检查。往往到了signoff前才统一跑physical verification这时看到的short数量可能已经被放大很多倍——因为中间好几个版本的历史问题累积在一起了。所以我一直建议在route_opt过程中定期做增量DRC检查尤其是ecoRoute之后至少要跑一个quick DRC把short扼杀在早期。1.3 Innovus与ICC2对short的“账本”差异两个工具对short的报告格式和内部定义不完全一样。Innovus在verify_drc之后会把short归类为不同的DRC type比如short、short (metal)、short (via)、short (std cell pin)报告里会给坐标、layer、涉及net等信息。ICC2则主要是report_drc -type short来抓取它的short对象可以精确到具体net和坐标点而且有get_drc_nets这样的Tcl API可以直接拿去做自动化。这里有个很实际的坑因为报告文本格式不同从Innovus切到ICC2或者反过来原来写好的short解析脚本基本作废需要重新适配。我的建议是不要过度依赖报告文本解析尽量用工具原生的Tcl API拿结构化数据这样脚本的鲁棒性会好很多。2. 自动化修复前的“清场”工作不整理战场就开脚本是白干2.1 数据检查和环境确认很多人一拿到DRC报告就急着写修复脚本这是大忌。short修复本质是动布线如果数据库本身还有大量未提交的ECO、不完整的电源网络定义、或者routing blockage状态混乱你跑任何修复脚本都是在沙地上盖楼。我自己的固定流程是先做一轮基本检查确认database的version和ECO记录一致确认没跑过不完整的routing确认power/ground stripes都已经route干净。还有一个容易忽略的点——metal fill在PR阶段不能开否则会自动加上的dummy metal会干扰short的识别修出来的结果也不干净。另外跑short修复前留意一下当前design的floorplan是否已经lock过macro如果macro位置还有浮动后面修好的short很可能因为floorplan微调而复发。2.2 量化short分布不要一上来就全跑修复拿到short报告之后不要急着执行任何修复命令。先量化分析short集中在哪一层集中在哪个区域涉及的net是signal还是clock还是power。这一步做得好可以帮你决定用局部修复还是全局重新routing。我在实际项目里通常会把short报告导出来用脚本按layer和坐标binning一下。如果short集中在一个很小的区域比如某条macro通道附近那大概率是congestion问题直接对该区域做局部布线修复即可。如果short遍布全芯片那就不能一个个修而是要考虑是routing resource整体不足或者某个routing layer的pitch设置有问题需要回头查floorplan和route configuration。2.3 设定修复目标和优先级不是所有short都需要同一时间修掉。我的经验是把short分成三类第一类是LVS层面的硬short就是两条不同net的金属直接相连必须修第二类是同一net内部的冗余连接有些工具会识别为short虽然对LVS没影响但会造成DRC问题也要处理第三类是和clock net相关的short这类最麻烦因为牵一发动全身修完可能影响时钟树延迟。所以我会在脚本里做优先级过滤先修blocking的、影响LVS判断的short再处理clock相关的short最后统一处理零星散落的。顺序搞反了很容易出现修了一堆低优先级short结果把时序搞得稀烂的情况。3. Innovus环境下的short自动化修复实战3.1 单条短路的手工修复逻辑先学会手动再自动化在Innovus里修short我通常先定位坐标再手动确认问题然后选择修法。这里涉及几个常用命令report_net查net连接关系summaryReport -no_design看DRC汇总verify_drc跑检查。如果已经确认某条short在某块区域可以用图形界面定位或者直接在命令行用get_db拿到坐标。单条short的手工修复一般有两个方向如果短路处空间够直接addRoutingBlk加一块routing blockage然后ecoRoute让相邻net绕走如果空间不够就要考虑切开附近的走线把某条线引到更高或更低的金属层再绕回来。这里有一个重要细节——加的blockage不要一次性盖太大尤其是不能挡住没有short的net的正常通路否则修完这条short周边会冒出一堆新的routing violation。3.2 Innovus自动化修复脚本框架当我们把单条short的修复逻辑搞清楚之后就可以做自动化了。Innovus的Tcl API里get_db对象体系提供了DRC信息查询能力。一个常见的自动化修复思路是先把所有short对象拿出来过滤出坐标和layer信息然后对每个short区域生成一个局部的routing blockage再触发ecoRoute来重新走线。脚本逻辑示意大致是这样# 获取当前design的所有short DRC对象 set short_list [get_db [get_db current_design] .drc_shorts -type short] foreach short $short_list { # 取short所在layer和坐标范围 set layer [get_db $short .layer] set bbox [get_db $short .bbox] set x1 [lindex $bbox 0] set y1 [lindex $bbox 1] set x2 [lindex $bbox 2] set y2 [lindex $bbox 3] # 在short区域加一个小范围routing blockage局部逼走线 addRoutingBlk -box [list $x1 $y1 $x2 $y2] -layer $layer -type blockage } # 触发ecoRoute重新绕线 setNanoRouteMode -routeWithEco true setNanoRouteMode -routeWithTimingDriven true ecoRoute这里要说明一下不同版本的Innovus对drc_shorts对象的属性命名有差异脚本在具体项目里要做适配。核心思想是“定位short - 局部阻断问题区域 - 让工具重新绕线”。但这个方法只适合处理局部short如果short非常多一定不能靠逐条打blockage解决而要考虑区域级routing重置。3.3 关键参数和经验值Innovus里影响short修复质量的核心参数是setNanoRouteMode下的一些开关和ecoRoute的搜索空间设置。我常用的组合是-routeWithTimingDriven true保持时序驱动-routeWithEco true允许ECO-routeSearchEffort high让工具做一个更充分的搜索。经验上search effort调到high之后修复率会明显提升但运行时间也会涨大概多20%到30%的runtime。对几千条net的模块来说这个代价可以接受。另外还要关注ecoRoute迭代次数设置太低的话工具可能修一版就停了。我自己通常允许至少两轮iteration第一轮把明显的short清掉第二轮处理边界情况。有一个特别容易踩的坑是blockage layer的选择。如果short发生在M4你只在M4加blockage工具很可能把M4上面的M5走线也全部拉低或者推高导致新的short。我倾向于在同一坐标范围的相邻层也加一个临时blockage范围比原short略大一点让工具有一个buffer去调整。4. ICC2环境下的short自动化修复实战4.1 ICC2修short的命令脉络ICC2里处理short和Innovus的思路不太一样。它更倾向于让工具自己来做DRC修复而不是通过大量routing blockage去“逼”线。核心命令有几个report_drc -type short查看short列表get_drc_nets拿到short相关的net对象然后通过route_opt来修复DRC问题。值得注意的一点是route_opt在修DRC时会尝试同时保持时序所以比Innovus的ecoRoute要更“全局”一些。如果你的short只局限在某个小区域可以先用create_route_guide给工具一个引导告诉它哪些区域不应该走线再跑局部的route_opt。create_route_guide像是给工具画了一个“红线区”比直接加blockage更灵活因为它可以指定layer和方向。4.2 ICC2自动修复脚本实践ICC2的Tcl API在DRC处理上比较成熟。自动化脚本可以把short的坐标、layer、所在net都抓出来然后批量生成route guide再做ECO routing。我这里给一个示意脚本逻辑和Innovus版本类似但使用的是ICC2的API体系# 获取所有short DRC的net set short_nets [get_drc_nets -type short] foreach net $short_nets { # 拿到short相关DRC对象 set drc_list [get_drc -net $net -type short] foreach drc $drc_list { set layer [get_attribute $drc layer] set bbox [get_attribute $drc bbox] set x1 [lindex $bbox 0] set y1 [lindex $bbox 1] set x2 [lindex $bbox 2] set y2 [lindex $bbox 3] # 在short位置创建route_guide不允许该层走线 create_route_guide -box [list $x1 $y1 $x2 $y2] \ -layers $layer -type exclude } } # 做ECO routing修复 route_opt -eco_route -fix_drc这个脚本的核心思想是“把short点标记为不可走线区域然后让工具重新绕”。实际使用时route guide的范围同样不能太苛刻留一点余量反而修复效果更好。4.3 两个工具流程对照做了这么多项目我的体感是Innovus在局部ECO修short时更快因为它可以只对某条net做局部reroute而ICC2的route_opt即使加了-eco_route影响范围还是更大一些runtime更重。反过来说ICC2对全局DRC的修复更充分跑完一轮之后剩余short往往更少。从脚本维护角度看ICC2的get_drc_nets体系更贴近对象化思考适合做复杂逻辑Innovus的get_db也可以用但DRC对象和net的关联需要自己多做几步查询。另外ICC2的create_route_guide比Innovus的addRoutingBlk更精细可以按层、按方向写而Innovus的routing blockage相对粗放。5. 自动化之外几种“修不掉”short的硬核解法5.1 布线资源彻底不足要先给short区域“减负”自动化脚本修short本质是把线从这个地方挪到另一个地方。但如果一个区域的整体布线资源已经枯竭了挪来挪去只会导致short在附近区域不断转移。这种情况下你再怎么优化脚本都没用必须回到floorplan层面去“减负”。我遇到过的一个典型案例某个模块的M4和M5层在局部区域track utilization超过95%short报告密密麻麻集中在那个区域。当时我尝试了各种blockage和ecoRoute组合修一轮掉一批下一轮又冒出来。后来把附近一个macro整体往右挪了大概5微米给这片区域腾出了两条完整track的空间再用脚本跑一轮short几乎全清。所以自动化修复要建立在一个基本判断之上——如果short密度过高先检查congestion map别在资源耗尽的地方硬修。5.2 通孔引发的短路via pillar和via switchingfinFET节点下很多short和via相关。一种常见情况是via pillar太密导致信号线在换层时把同层的其他net也“带”上了还有via enclosure和layer extension设置不当让via周围的金属超出了预期范围。这类short用routing blockage去修很痛苦因为问题根源在制造规则层面。处理办法是调整via相关属性比如做via switching或者改变via pillar的尺寸。自动化脚本可以做一层预处理——把short高发区域的via统一替换成更紧凑或者更稀疏的via形式给旁边net腾出空间。这个操作在Innovus里可以用editVia系列命令ICC2里可以用edit_via或者通过修改via master的方式实现。但要注意via替换会影响电阻电容因此做之前要评估对时序的影响。5.3 和时钟树绑定的short如果short出现在clock net上情况就比较棘手了。时钟树上的buffer/inverter位置一旦变化就意味着clock latency变化后续所有时序约束都要重新评估。有些工程师在修clock short时直接把clock buffer挪开或者用blockage把周围清空结果时钟延迟变了setup和hold全乱了。我的建议是clock short先看能不能在不移动cell的前提下绕线解决。如果无法绕线要修clock tree的placement一定用ECO形式保留clock tree原本的结构和延迟预期修完立刻重跑时钟树分析。自动化脚本在处理clock相关short时要加一个保护机制——比如在脚本中过滤掉clock net或者对clock net使用单独的修复策略绝不能和signal net混在同一批处理里。6. 常见问题与排查技巧实录6.1 修复后short数量反而增加处理short时最容易遇到的现象是脚本跑完原先的一批short消失了但同时新增了一倍的short。这个问题多半出在routing blockage或route guide设置范围过大把short点附近的正常走线全赶走了。新增的short往往出现在blockage的边缘——线被逼到边界在那里和其他net挤在一起。排查思路是先看新增short的坐标和原short坐标的距离关系。如果新增short大多聚集在blockage边界那就缩小blockage范围或者只在原short点周围留一个很小的空白区。另外一个技巧是不要一次性对全部short加blockage而是先对前20%的short做修复验证无副作用后再扩大范围。6.2 修复short导致时序违例变多修short本质上是改变局部绕线绕线长度一变RC延迟就会漂移。有些自动化脚本为了修复short让工具走了很长的绕道路径虽然short没了但那条net的时序从满足变成了违例。我的做法是修复时给工具一个“时序底线”比如在Innovus里用setNanoRouteMode -routeWithTimingDriven true让工具在ECO路由时考虑到时序目标ICC2里则是在route_opt -eco_route时加上-keep_timing选项或者保持约束完整。跑完修复后不要只看DRC还要对比一下修复前后的时序报告尤其是靠近short区域的敏感net。6.3 short定位坐标与实际版图对不上有时候DRC报告里给出的short坐标在GUI里定位过去却找不到任何异常。这种情况通常不是因为工具报告错了而是因为数据库经过了多轮edit操作ECO记录和当前图形状态不同步。在Innovus里可以尝试reset_eco或重新读入一个干净的database再执行verify_drc坐标就会准确。ICC2里则要注意数据库的version如果中间有commit_eco或者save_block的过程坐标基准可能发生偏移。经验上如果short坐标频繁对不上不要去硬追坐标直接根据report里的net名字去report_net然后高亮那条net的所有metal再用图形界面去检查net的实际走线位置。这样比纠结坐标靠谱得多。6.4 经验速查表我把修short的常见场景和推荐方案整理成一个表方便大家在项目里快速对照场景推荐解法注意事项少量short散落分布脚本定位局部blockage/route guideecoRouteblockage范围宁小勿大short集中在某区域先查congestion map考虑加routing resource或调整floorplan别在资源耗尽区域反复修via相关short密集调整via pillar或做via switching注意RC变化对时序影响clock net上的short单独处理尽量不移动clock cell修完立即重跑时钟树分析修复后新增short缩小blockage/guide范围分批次处理验证前一20%修复无副作用修short导致时序违例开启timing driven的ECO路由修复前后对比时序报告这套判断框架我用了很久基本可以覆盖90%以上的short场景。遇到实在修不干净的大概率是floorplan或routing resource的底层问题自动化脚本解决不了需要回到设计层面调整。最后再分享一个习惯我在跑任何short自动化修复脚本之前都会先做一个database归档确保修复失败可以回退。脚本里面加一个“打印short总数”的log节点每轮修复前后对比一次数量而不是等到最后才看结果。这个习惯帮我少踩了很多坑。自动化修复不是把脚本丢给工具跑就完事它需要你不停观察、调整、验证才能真正在项目里落地。