ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Innovus手工布线实战:核心命令与DRC修复全流程指南

Innovus手工布线实战:核心命令与DRC修复全流程指南 开头部分先跟同行聊两句。做数字后端的都知道Innovus的自动布线nanoroute已经很强了但凡是跑过几个项目的人都会承认完全依赖自动布线在真实项目里根本行不通。高层走线的Power规划、特殊宽度的关键信号、绕不开的congestion死点、ECO阶段新加的那几根线——这些场景十有八九得靠手工布线兜底。再加上流片前那场让人又爱又恨的DRC signoff修不好就是返工、加cycle、烧钱。这篇东西我打算用项目实战的视角把Innovus手工布线里最常用的场景、命令、参数选择逻辑以及DRC修复时的判断思路和操作顺序完整梳理一遍。内容主要面向刚接触数字后端的学生、刚入职的后端工程师也欢迎有经验的老手直接看后面的排错实录看有没有踩过你也在踩的坑。1. 为什么自动布线时代手工布线依然是后端基本功1.1 自动布线解决不了的几个“死角”先明确一个观点Innovus的NanoRoute在处理大规模、规则化布线时效率确实无可替代但自动布线本质上是一个“基于全局权衡”的算法过程它在乎的是整体收敛而不是某一条线的最优。所以实际项目里会频繁遇到几种自动布线搞不定的情况——不是跑不通而是跑不出“能signoff”的结果。一是电源网络相关的绕线。芯片内部高层的VDD/VSS走线通常有固定的宽度和间距要求自动布线器对特殊宽度的金属线处理比较保守绕线路径一旦复杂就容易出现大段金属缺失、Via堆积、甚至电源网络短路。这种情况在floorplan阶段要是没预留好通道到了布线后期必然后悔。二是congestion死区。有些模块之间的通道窄到可怕自动布线器在局部区域来回尝试后可能会“妥协”——把线绕得非常远导致延迟暴增或者直接留下一堆没有布通的pin。这种时候靠调floorplan已经不现实唯一可靠的办法就是手工把几条关键的线从外围绕过去给自动布线器腾出空间。三是ECO阶段的临时新增。芯片演进到post-mask ECO阶段metal fix是家常便饭。改一条标准单元的输出路径、补一个buffer、拉一根新线这些改动如果全量重新跑一遍自动布线可能引发无法预估的时序和物理扰动。而手工布线可以做到精准、局部、可控——只动该动的线。1.2 手工布线在项目流程里的真实定位做后端这么多年我觉得手工布线与其说是一项“技能”不如说是一种“风险兜底手段”。它渗透在floorplan早期的高压线规划、CTS阶段的关键clock绕线、布线后期的metal fix、以及ECO阶段的各种补救中。数据上一份成熟的Innovus布线结果里手工布线的数量可能只占全部net的百分之几但这百分之几往往决定整个项目能不能按时signoff。更重要的一点是掌握手工布线能让你真正读得懂工具的报错。很多做后端的同学遇到DRC violation就傻眼不知道怎么改本质原因就是他们脑子里没有“线应该怎么走”的空间概念。工具报的一条spacing violation在GUI里看是一条红色的形状但只有你理解它本应该怎么绕、绕的时候应该隔多远、Via应该放在什么位置你才能在两分钟内给出修复方案。手工布线训练出来的就是这种“布线空间直觉”。2. 手工布线的核心场景与动手前检查2.1 常见的四类手工布线场景实操中我遇到最多的手工布线需求基本可以归为四类。第一类是电源与特殊宽度的走线。包括从VDD/VSS pad到power ring的接入、IR drop热点区域的电源加固、以及对ESD和latch-up敏感的I/O相关走线。这类线通常有明确的宽度和层数要求用自动布线跑反而不靠谱。第二类是高速或敏感信号的专用走线。比如clock tree的主干走线、高倍频的clock net、以及某些对串扰和delay匹配要求极高的数据线。这类线需要在设计中就规定好shielding、width和spacing手工布线可以确保每段路径都符合约束。第三类是穿越congestion区域的“绕行线”。这类线不是非走不可而是因为整体拥挤导致自动布线无法收敛需要工程师手工制定一条阻力最小的路径把线从外围带过去缓解局部的溢出。第四类是ECO新增/改动的功能线。例如一个功能ECO需要新增两个标准单元之间的连接或者需要把某条线从原来的buffer tree上摘下来接到新的路径上。用ecoRoute加手工修线是最高效可靠的方案。2.2 动手前必须做的三个检查不管哪类场景我强烈建议在实际走线之前先花几分钟把下面三件事确认清楚。省这几分钟后面可能要花几个小时擦屁股。第一个检查是读GuIde布线引导。Innovus在place之后会自动为每个net生成GuIde代表工具推荐的布线路径范围。手工布线时核心原则是尽量让你的线待在GuIde范围内或者贴着它走。因为GuIde之外的区域可能就是其他net的资源你强行占用DRC可能过了但route congestion和时序会变差。用命令report_guides -net $net_name可以在文本界面看到GuIde的坐标也可以在GUI里通过“Display Show Guides”打开可视化视图。第二个检查是看Congestion图。在动手前用report_congestion或者GUI的Congestion Map把当前层级的congestion分布调出来。如果你要手工在某个区域走线先确认这片区域是不是本身已经“红得发紫”。如果太拥挤哪怕你把这条线布通了后续自动布线也容易在其他地方产生新violation。通常我在这种区域会反向考虑先在周边区域给这条线规划一条“绕过”的路径而不是硬往里挤。第三个检查是确认Pin Access。手工布线的起点和终点通常是标准单元的pin或者macro的pin。这些pin所在的层、出口方向、阻挡情况决定了你线怎么出、要不要用via换层。在Innovus中选中pin后按“P”键可以查看pin属性和坐标也可以在命令窗口用report_net -net $net_name看所有pin的连接层和位置。这个步骤看起来不起眼但很多人布线失败就是栽在“起点/终点的pin其实是在被blockage挡住的方向”这种细枝末节上。补充一个实操习惯动手前我会先把当前cell的所有layer的obstruction显示打开菜单Display Obstruction再叠加一个Congestion Map图层。这样看的时候就能直观看到哪些地方是“物理不可走线”的避免在blockage上反复报错。3. Innovus手工布线核心命令与操作技巧3.1 addRoute最常用的手工布线命令Innovus手工布线的核心命令是addRoute它的语法灵活用途也广。我日常用得最多的几种形式如下# 最简单用法指定net自动找路径 addRoute -net VDD_MAIN -layer M4 # 带起点和终点的精确路径 addRoute -net sig_data -begin {12.34 56.78 M3} -end {23.45 67.89 M4} # 指定路径走线先手动定义路径点 addRoute -net sig_ctl -path {{10.0 20.0 M3} {10.0 25.0 M3} {15.0 25.0 M4} {15.0 30.0 M4}}addRoute的search-and-repair能力也比较可靠你给它一个net名它会基于现有GuIde自动找出一条可达路径并把线生成在指定的layer上。最精髓的是-path参数它可以让你手工指定每一个拐点的坐标和层实现对线的完全控制。这在绕congestion区域时是无可替代的。另外一个很常用的选项是-width和-spacingaddRoute -net VDD_NET -layer M5 -width 1.2 -spacing 0.6用了这两个参数后工具会按你指定的物理尺寸生成走线并在周边留出相应间距。注意这里的-spacing不是全局的约束而是这条net自身的spacing要求。如果你的设计里已经对net设置了non-default ruleNDR则必须用NDR方式赋值不能在这里手动指定。NDR的优先级更高手动指定的width可能被覆盖。3.2 路径编辑和删除操作手工布线的另一半工作在于修线。在Innovus里编辑线路径可以用editRoute命令也可以直接在GUI中操作——按下ShiftF2可以进入“Route Edit”模式然后用鼠标点选路径段拖动非常直观。删除某条线或者某一段时用deleteRoute# 删除整条net的物理连线 deleteRoute -net sig_ctl # 只删除某一段路径 deleteRoute -net sig_ctl -begin {10.0 20.0 M3} -end {15.0 30.0 M4}这里有个容易犯的坑直接deleteRoute -net xxx删除后会连带删掉这条net的物理连接关系如果有必要应该在删除后重新用addRoute或者ecoRoute把线补上。不要觉得删了就完了等DRC检查完才发现这块net还是断的又得花时间重新连。3.3 Via的设置与处理手工布线时Via的管理特别重要。在Innovus里换层时工具会自动生成via但在下面的情况下你需要手动指定via的类型电源网络从高层转低层时一般要求使用多个via并联降低电阻默认的单via可能IR drop不满足要求。高密度区域空间有限可能必须使用“stacked via”这种占面积更小的via。需要避开某些层的blockage时必须通过指定via的坐标来借用旁边的空间。# 在指定坐标处放via addVpg -via VIA45 -net VDD_NET -at {12.34 56.78} # 手动指定路径并自动带via addRoute -net sig_ctl -path {{10.0 20.0 M3} {10.0 25.0 M3} {10.0 25.0 M4}}在GUI里选中一条线后右键选择“Add Via”工具会弹出一系列的via候选。这里要留意一个细节默认的via不一定是最优的。在via table里通常会有多种不同尺寸的via有的via覆盖面积大但电阻小有的via小但多几个并联也能满足需求。看实际场景选择不要一直默许默认值。3.4 手工布线的常见GUI操作路径如果你是在图形界面下工作下面这几条快捷键和菜单路径值得记住Route Edit模式ShiftF2进入后可手动点击拖动走线。Show Guides菜单Display Show Guides切换是否显示net的GuIde。Toggle Segment选择一条线后按S可以分段高亮便于单独操作某一段。Delete Segment选中线后按ShiftD删除整条或当前选中段。Property窗口选中一条线后按CtrlP可以查看/修改线宽、层、间距等属性。有一说一GUI操作在初期很好用因为它给了你视觉反馈。但做大批量ECO修线时我建议尽量还是用命令脚本。理由很简单——可复现、可提交、不会因为误操作把线动坏。好的做法是先用GUI理顺一条线的路径然后把addRoute命令记录下来写进脚本里批量执行。提示Innovus的命令行历史会自动记录GUI操作生成的命令直接history查看或导出即可。这招在写ECO脚本时非常省力。4. 三类典型手工布线任务的完整实操流程4.1 任务一电源网络的加固与修补电源线的手工布线不是随便拉一根线它的本质是“用最低的电阻把电流送到最需要的地方”。我一般遵循这样的流程第一步先用report_power -outfile power.rpt或者直接在GUI里打开IR drop热力图找到电压降最严重的区域。一般这种区域集中在远离power pad的角落或者标准单元密度极高的区域。第二步分析这些区域的供电路径。如果当前路径上的metal宽度太窄或者via数量不够就会表现为局部IR drop超标。比如某条VSS路径在M5上只有2um宽而这条路径要带的电流可能已经超过5mA/um的安全值这时需要手工增加一条相同层或相邻层的并联走线。第三步实施修补。我常用的做法如下# 假设我要给某个区域加一条M6的VDD强化线 set net_name VDD_MAIN set width 3.0 # 先计算合适的线宽按照该层金属的电流密度上限以及预估电流值 # 假如电流为30mA该层允许电流密度为0.6mA/um则最小宽度为50um # 但由于是局部并联宽度可以根据空间调整不一定严格按最大电流来 addRoute -net $net_name -layer M6 -width $width \ -begin {100.5 200.3 M6} -end {130.5 200.3 M6}需要注意电源线手工补完后一定要顺手检查via的连接。一根很粗的M6走线如果只在两个端点各放一个via中间一大段的电流只能靠着细的via孔慢慢往下渗IR drop还是会超标。正确的做法是在线上均匀打多个via。实用技巧选中新加的M6线段然后依次在几个关键位置用addVpg补via。4.2 任务二绕开高密度区域的“阻力最小路径”这种场景经常出现在两个宏单元夹缝、或者拥塞最严重的区域。传统思路是“让自动布线去绕”但很多情况下自动布线会在高压区域反复试探最后给你留下一堆伤害时序的“之字形”走线。我的做法是先打开Congestion Map用色块看清楚哪儿是真正过不去的地方然后在周围找出一条“压力小”的环形路径手工把线引过去。举个实际例子某项目里一条clock net的GuIde横穿了一个标准单元密度爆表的区域。自动布线之后线的延迟比预估翻了几乎一倍。我在GUI里调出congestion图发现区域右上角还有一条M5的通道基本是空的于是下了这条命令addRoute -net clk_phy -path { {85.0 100.0 M4} {85.0 130.0 M4} {96.0 130.0 M5} {96.0 166.0 M5} {130.0 166.0 M4} {130.0 178.0 M4} }官方说法这叫“pre-route addRoute”就是在自动布线之前人工占住那条通道。这样做的好处是后续NanoRoute运行时会自动避开这片已被占用的区域从而在整体规划上把拥塞分摊到外围。这条手工线几乎没增加delay区域内的自动布线也顺利收敛了。这里分享一个判断标准绕行路径的长度不要超过原路径长度的1.5倍否则即使DRC没问题时序也可能hold不住。如果绕行距离过长宁可把这条net做中继buffer也不要硬跨半个芯片。4.3 任务三ECO场景下的手动补线与改线ECOEngineering Change Order是后端工程师最常遇到的手工布线需求。post-mask ECO的金属层通常有限定只能改M1到M5之类的上层金属底层Diffusion和Poly不允许动。Innovus里针对ECO有一个专门的命令族ecoRoute。典型操作流程是先用ecoDesign或者直接对netlist做修改把新增的逻辑单元加入设计。用ecoPlace对新单元做placement一般工具会自动就近放置。用ecoRoute做初始布线。最后对手工不满意的部分用addRoute修正。# 假设ECO后新增了一个inv和一个buffer需要连线 ecoRoute -net new_net1 -fix # 如果ecoRoute没有走好可以删除后手工加 deleteRoute -net new_net1 addRoute -net new_net1 -begin {50.0 80.0 M3} -end {78.0 80.0 M3}还有一个高频场景是插入buffer。Innovus里的ecoAddRepeater -buffer可以根据预设的buffer cell自动在路径上插入buffer并自动连接线网。但是自动插完后通常会出现若干DRC问题因为工具的默认目标只是“逻辑正确”对物理间距、绕线方向考虑得不够细致。所以插完buffer后我基本都会再手动调一遍线。# 插入buffer示例 ecoAddRepeater -buffer BUF_X12 -net clk_net -numStages 3 # 然后手动调整buffer周围的走线 addRoute -net clk_net -path {{...} {...}}需要特别注意的是ECO补线后一定要跑一遍verifyConnectivity确认所有连接关系都成立。无数惨痛教训证明ECO改线最容易出现“看起来连上了其实开路/短路”的情况。5. DRC修复全流程与经验5.1 DRC违规的常见类型与成因做数字后端不可能不遇见DRC violation。常见类型我整理成一个速查表方便第一眼就能粗略判断问题性质违规类型一般成因修复思路Spacing violation两条线之间的距离小于最小间距拉开间距或把一条线绕到其他层Width violation线宽低于该层最小宽度要求加宽到合规值注意是否影响邻近线间距Area violation金属面积不满足最小面积要求在与该线相连的端点处“扩展”一小块金属Via spacing/enclosureVia与Via之间距离不足或Via周围金属包裹面积不够移动Via位置或在Via周围补一圈金属Antenna violation长金属线上积累的电荷可能击穿栅氧化层跳层布线打断长线或插入diodeShort violation两条不同net的金属重叠删掉其中一段并另选路径5.2 DRC修复的操作顺序修复DRC的顺序直接决定了你的效率。如果乱修一会儿改这条线一会儿调那个via很容易出现“按下葫芦浮起瓢”——修完一个又冒出两个新的来。我个人的顺序是第一步先修Short。这是最优先的因为short可能会导致信号短路严重程度最高。用DRC Viewer打开short类violation逐一处理。这类问题一般就是两条线碰一起了删掉其中一条重新绕即可。第二步修Antenna。这类问题往往牵涉到长走线越早修后面布线时越容易避开。修法也很简单——把长线分段跳层。每跳一次层积累了电荷的金属段就被断开一次天线效应就会减弱很多。# 找到antenna violation后可以在violation点附近加一个跳层via # 假设在坐标(40,50)处本来是一条M3长线改成从M3跳到M4再跳回M3 addRoute -net sig_1 -path {{40.0 45.0 M3} {40.0 50.0 M3} {40.0 50.0 M4} {45.0 50.0 M4} {45.0 50.0 M3} {45.0 55.0 M3}}第三步修Spacing和Width。这两类问题通常可以一起处理因为把线重新走了之后往往间距和宽度问题会一起消失。第四步修Area。单独的小面积metal缺失是最容易修的只需要在线的端点“加一个补丁”。在Innovus里可以在GUI中右键选择“Add Patch”或者用命令手动加一块小金属。# 在指定点加一块面积为2um x 2um的金属补丁 createRoute -layer M2 -point {30.0 60.0} -width 2.0 -ext 1.0这里要提醒一下加补丁的时候不要把补丁加得太远补丁要跟原violation的金属有物理接触最好覆盖到它。另外补丁不要太大能过area规则就行否则反而会引入新的spacing问题。5.3 用DRC Debugger做高效定位Innovus的DRC Viewer 3.0很好用它能自动把violation按照类型、坐标、layer分组显示并且可以高亮对应的网络。每次修完一条线之后建议在DRC Viewer里立即“update”重新运行一次该net的DRC看是否新增了violation。有时候在GUI里操作不直观也可以直接用命令查询# 查看当前所有open的DRC report_drc -all -no_display # 针对特定net查看 report_drc -net sig_1 # 查看某个坐标附近的violation report_drc -box {45 45 55 55}在实际项目中我一般是在跑完verify_drc之后先导出一份完整的violation列表按照坐标排序然后从芯片角落开始按顺序逐一修。这么做的好处是效率高不重不漏。6. 高频问题与排查思路实录6.1 手工布线后DRC反而更多了有段时间我手工补了几条线一跑DRC新增了七八个spacing和area violation当时人都麻了。后来定位问题发现是我没有考虑好“via跳层处的金属外扩”。比如M4的线要换到M5层Via45附近M4和M5的金属各需要一定的enclosure而我只按M4的宽度拉了线M5段却用了M4的线宽标准导致M5段宽度不够直接报了一堆area violation。对策每条手工走线结束后立刻在GUI里选中线段用属性查看器检查宽度是否匹配当前层的工艺要求。好的工艺库中每一层的最小线宽并不一致换层后务必检查。6.2 手工绕线的时序更差了这个问题一般出在信号线上。手工绕线本质上会改变线的寄生电容和电阻从而导致延迟变长。特别是时钟线上的绕线哪怕只多几微米也可能造成不小的时钟skew。对策手工布线完成后不要急着直接流片先把ECO net标记为“fixed”然后跑一遍timing。如果延迟明显变大就需要考虑在绕线的同时引入一段shielding或者干脆换一层低阻的金属来走。M7/M8这类高层金属的R/C通常比M1/M2小很多所以对时序敏感的信号线尽量往上走。6.3 Via打不上工具一直报错Via打不上的本质原因通常是下方或上方的金属层在该位置已经有blockage或其他net占用。很多人这会儿还在反复调整坐标浪费时间。对策换一个思路先在GUI里打开所有层和obstruction显示用鼠标点击目标位置看看当前坐标下方是什么。如果被blockage挡死就直接换个位置打via不要死磕一个点。另外也可以考虑用不同尺寸的via比如VIA45不行试试VIAX45有时候就是大一个size的via刚好能塞进去。6.4 修完DRC后天线效应又冒出来了这类问题集中在长线fix过程中。你为了修一个spacing把一根线绕得更长了结果引发了antenna violation。对策修线时每一次改变路径都要在脑内预估一下线长增量。如果路径加长很明显建议在路径中间插一个跳层via把天线效应的风险前置拆掉。这个习惯能避免DEADLOCK式的反复修复。6.5 命令执行后没有效果有些新手在命令行输入addRoute后发现GUI里没有任何反应第一反应是命令写错了。实际上可能是这条net已经被设为fixed或者你指定的layer在该区域没有合法的routing resource。对策检查一下net状态。可以先用report_net -net $net_name查看physical status看是不是locked/fixed。如果确实fixed用editSelect -net $net_name然后右键“Unfix”解掉。另一种情况是该层在当前区域被hold了需要用globalSetNanoRouteMode -holdNet之类的命令解除控制。7. 写在最后一点个人实操体会老话说“自动布线99%手工布线1%”但实际做项目的时候那1%的活儿往往决定了剩下99%能不能过。你负责的那条关键路径如果布得绕、布得慢整个die size都要变大功耗和时序双双受影响。我自己刚开始学Innovus手工布线时也是靠一遍遍试错过来的。第一次看到DRC的几十个violation脑子里全是“这怎么可能修得完”。后来慢慢总结出几个原则动手前想清楚路径动手时盯紧via和width动手后必须跑verify_drc验证修时优先short其次是antenna最后才是那些零星的spacing和area。最后分享一个实用小技巧给关键net的GuIde加“anchor”可以在addRoute命令里用-anchor指定关键绑定坐标这样即使后续整条route重跑工具也会优先保证经过你指定的点。这算是我在项目里最常用的“软手工”技巧了——既保持了手工的精确意图又把重复性的绕线工作交还给自动布线器去完成。
返回列表