做数字后端的人,几乎都经历过这种心梗时刻:Innovus里Floorplan、Place、CTS、Route一路绿灯,时序也收敛了,高高兴兴把GDS导出来,丢进Calibre跑LVS,满屏红色,而且报错的位置完全不在你预期的地方。我这些年Debug过的LVS问题少说也有几十个,从最初对着错误列表一头雾水,到现在能根据报错类型和RVE高亮快速定位问题源头,最大的感触是——LVS从来不是最后那台“验证工具”,它更像是整个版图数据质量的照妖镜。
这篇文章不讲教科书里的概念定义,只讲从Innovus到GDS这条路上哪些设置容易埋雷,LVS报错后应该按什么顺序排查,以及短路、开路、器件不匹配这几类最常见错误背后到底是什么原因。适合刚入门的数字后端工程师,也适合被LVS折磨了一整天想找排查思路的朋友。
1. GDS导出这一步:Layer Map和文本标签的坑
1.1 导出选项看起来简单,但Layer Map文件经常错得无声无息
Innovus里导出GDS,界面上的选项并不多,File → Export → GDS(或者旧版本里常见的streamOut命令),选好文件名、库文件、映射文件就能跑。但真正决定LVS死活的是那个不怎么起眼的Layer Map文件。它负责把Innovus内部数据库里的routing layer、via layer、PG layer、text label映射到GDSII的layer number和datatype。映射错了,后面的DRC/LVS全都会跟着错。
很多公司的flow里会固定放一个map文件,新人直接拿来用,跑完发现Calibre里所有层的属性都是乱的——M1画到了GDS layer 0、via层全都缺了、pin text干脆没写进去。这类问题最坑的地方在于它不报错,它就是让LVS结果变得莫名其妙。我拿到一个陌生flow,第一件事一定是打开map文件看一眼,哪怕不看内容也要确认它的修订时间和PDK版本对得上。
map文件的格式各家略有不同,核心就是一行一条映射。不贴具体PDK的层号了,因为每家的号都不一样,给个格式参考:
metal1 31 0 drawing metal1 31 1 text via1 40 0 drawing pg 54 0 drawing重点看三处:金属层有没有把drawing和text分开映射(一大类坑就是text和drawing合并)、via层有没有单独条目、PG相关的特殊层有没有被漏掉。有的PDK会同时提供streamOut.map和streamOut.map.pinOnly这类变体,后者通常只在某些pin-only导出场景里用,拿它导整芯片,pin text大概率写不出去。这个细节特别容易踩。
1.2 Pin Text和PG Terminal:最容易漏的隐性连接
版图里画了金属图形还不算完,Calibre LVS还需要文本标签告诉它“这块金属叫VDDnet”。所以GDS里必须有pin name的text,而且要放在PDK规定的层上。Innovus导出GDS时有单独的选项控制text输出,有些map文件也会单独给text分配GDS层。这两处只要有一个不对,Calibre就会把带标签的pin识别成“不知道叫什么名字的图形”,紧接着报出一堆unmatched net或者missing pin。
数字版图里大家的重心都放在信号布线上,但LVS眼睛死死盯着PG。标准单元里有些PG term不经过任何MOS管,直接是阱偏置,比如很多库里常见的biasnw,就是N阱的偏置端。这个term如果在GDS里没有被正确保留,PMOS的body就会在LVS眼里变成悬空,报出来就是成片的device mismatch,甚至一排PMOS都“消失”。
那怎么提前检查这类term?在Innovus里,Edit → Select by Name,Object Type切到PG Terminal,名称填完整的实例路径加term名(例如U_IO/biasnw),点Select就能选中。选中之后看它的Net属性,直接确认这个PG term连到了VDD还是别的电源。如果你只记得term名不记得实例路径,直接输入biasnw,界面上一般会列出所有匹配项,勾选后批量检查。我每次place完做PG完整性检查都会来这么一轮,比最后到Calibre里去翻报告快得多。
1.3 GDS导出后的三分钟快速自检
导出GDS之后我不会立刻跑LVS,先用KLayout或者Calibre自带的layout viewer打开GDS,花三分钟做三件事:
- 看关键金属层的图形数量是否合理,M1/M2有没有异常多出来的零散图形;
- 看text层数量,pin text是不是接近设计里IO和PG pin的数量级;
- 看有没有图层被映射到layer 0的默认层,有的话几乎可以断定map文件漏了条目。
这三件事全部通过,再进Calibre跑LVS。别觉得这是多此一举,很多“跑完才后悔”的LVS问题,在这个环节就能拦住。
2. 跑LVS前的规则文件确认:版本、Option和Soft Connect
2.1 Rule Deck版本和Calibre版本别凑合
Calibre LVS的第一步永远是确认rule deck版本和Calibre软件版本的兼容性。比如你现在用的Calibre 3.48这个版本周期,对应比较新的SVRF语义,而PDK的rule deck通常会在头部注释里写明“tested with Calibre某版本”。版本太老,解析器可能不认识deck里新加的SVRF语句,直接报一个很莫名的语法错误;版本太新,某些deprecated的命令可能被静默跳过,LVS结果不对但没有任何红色报错提示。
我见过最坑的一次,是rule deck里用了LVS SOFT CONNECT的新参数,老版本Calibre把这整条命令当注释跳过,所有soft connect都没被过滤,报告里凭空多出一堆奇怪的short。后来查了fab的支持矩阵才发现版本差了两个release。所以跑之前先看清楚,比对着报告猜半天靠谱得多。
另外,跑LVS我强烈建议用命令行而不是图形界面。图形界面适合看结果,不适合做flow。脚本里把rule deck路径、option文件路径、GDS路径、输出目录全部固定下来,这样每次跑的结果才可复现。命令行大概长这样:
calibre -lvs -hier -turbo 8 -spice out.net rule_deck.lvs-hier是层次化LVS,-turbo开多线程加速,-spice指定输出网表文件。具体参数以你环境里的脚本为准,但原则是:所有东西固定,不要每次手动点来点去。
2.2 SOFT CONNECT到底是什么问题
半导体工艺里,NMOS的bulk通过P衬底天然连在一起,PMOS的bulk通过N阱连在一起。LVS工具把“金属层连接”叫硬连接,把“通过衬底/阱形成的连接”叫软连接(soft connect)。rule deck里的LVS SOFT CONNECT相关配置,决定了这类软连接在多大程度上被当作有效电气连接。
数字后端最常见的问题是:两个不同的电源域(比如VDD和VDDPLL)分别布完线,看起来毫无交叉,但Calibre报short。你沿RVE高亮的路径看,怎么都找不到金属连接,实际原因往往是两个域的阱/衬底接触通过同一块P衬底形成了软连接,被工具当成了短路。
处理方式有两种。第一种是在LVS option文件里调soft connect参数,让工具不再把bulk到源的连接当成合并网络的依据;第二种是回版图检查两个电源域之间的isolation ring和tap cell是否真的按PDK要求放置。我的结论是:绝大多数情况下问题出在版图侧,是隔离结构没做对,而不是Calibre误报。只有在确认isolation结构完全没问题之后,才应该去动option文件。一上来就关soft connect,等于把设计里真实的可靠性问题盖住了。下面这个表是我自己总结的判断参考:
| 现象 | 优先检查 | 是否动option |
|---|---|---|
| 两个独立电源域报short | 阱、衬底接触、isolation ring | 先修版图再复跑 |
| 同一电源域内部报short | 金属图形、via、text层 | 不需要 |
| block级LVS干净、fullchip级报soft short | 顶层tap cell、seal ring | 确认无误再调参数 |
2.3 跑LVS前先跑一次DRC
这条建议我说给每个带过的新人:GDS导出来后,先跑Calibre DRC,再跑LVS,不要直接蹦到LVS。原因很简单,DRC违规是LVS错误的高频噪声源。金属间距不够导致意外桥接,在LVS里就是short;via的enclosure不够导致上下层没实际接触,在LVS里就是open。DRC清了,LVS的报错口径会干净得多。
尤其从Innovus导出的GDS,如果导出选项里没有处理好fill cell、pin shadow这类中间数据,DRC阶段能看到一大片本不该有的违规。先把这些清掉再debug LVS,省下来的时间非常可观。
3. 短路、开路、器件不匹配:三类报错的排查链路与实战案例
3.1 短路:先看报错网络名,再逐层关图形
拿到short错误,第一件事是看RVE里两个网络的名称,而不是直接去点高亮。这两个名字决定了排查方向:
- 不同电源域之间的short,优先怀疑阱/衬底软连接和tap cell位置;
- 电源与信号net之间的short,优先怀疑pin text层、金属残留;
- 同一条net内部出现异常合并,优先怀疑layer map。
定方向之后,在layout viewer里把除M1之外的所有层都关掉,只看M1图形。绝大多数short都是同层金属图形在物理上重叠或间距不够导致的。看完M1再看M2,逐层往上,重点看via孔附近有没有“不该出现的桥接”。这一招很笨,但几乎不会漏。
另外注意,RVE高亮的short路径不一定就是短路的物理位置。它画的是两个net之间的一条反馈路径,短路点往往藏在路径中间的某个via或者某段并行走线里。看到高亮区域很长时,别只盯着两端看。
3.2 开路:文本标签层和Via是两大雷区
Open错误在RVE里表现为一段“断头路”,预期相连但实际没接上。常见根因有三个:
- via缺失或者via尺寸不对,导致上下两层金属没真正接触;
- pin的text层被错误映射成金属drawing层,Calibre认为text所在区域有额外连接,把连续走线逻辑上劈开;
- 层次化LVS里,某个子模块被
LVS BOX替代,但box定义的端口名和顶层pin text对不上,导致顶层看不到这个端口。
排查时用RVE的高亮路径,从一端往另一端追踪,每一步只保留一层金属加相邻via层,直到找到断层。这种方法听起来土,但确实是处理open最有效的路径。逐层看的时候记得把text层也打开,很多时候所谓的“开路”只是text层没有落在预期位置。
3.3 器件不匹配:从数量对不上到W/L不合适
器件不匹配的类型五花八门,但排查思路是固定的。先看数量还是一致。数量不一致,绝大多数是器件识别层被污染:GT(poly)上有不属于poly的图形重叠、OD有源区被text层覆盖、M1 text落在了diffusion上被当成连接金属。这时候把识别层单独显示,和rule deck里定义的识别层做对比,往往一眼就能看出问题。
数量一致但W/L对不上,大概率是Calibre的器件合并方式和source netlist风格不一致。比如并联的MOS在版图里被merge成一个W加倍的器件,而source netlist里还保留着多条并联。这属于LVS REDUCE PARALLEL或类似选项的作用范围,需要跟PDK期望的网表风格对齐。
还有一种很隐蔽的情况是器件类型识别错误。P衬底/N阱识别层的处理顺序如果和rule deck定义不一致,或者LVS RECOGNIZE GATES的设置不对,普通走线可能被当成晶体管栅极。这种情况通常在IP边界上特别明显,因为IP内部和外部的阱/有源区连接规则不同。
3.4 Pin label和Missing Net:端口层面的隐藏问题
除了器件,LVS还专门比较端口网络。常见报错是“layout里有pin_X但source里没有”,或者反过来。这类问题往往是文本标签的锅:要么是Innovus导出时pin text没写全,要么是map文件里pin text的datatype和rule deck里定义的label层不一致。
还有一类是“missing net”,版图里某个金属图形没有连接到任何pin text,Calibre不知道它属于哪个net。此时它会自动按图形归类,如果一条独立走线两端都有via但没有任何label,就可能被归到错误的net里,连带报出一串device mismatch。所以遇到成片报错的场景,先查一下独立金属图形是不是缺label,比一个个怀疑器件靠谱。
3.5 一个真实Case:87个VDD到VSS的Short,最后只改了一行Layer Map
前阵子接手一个block,Innovus跑完P&R,导出GDS,Calibre LVS一打开,Error列表里87条short,全是VDD和VSS之间。第一反应是PG问题,于是我把两个电源域的图形在RVE里分别高亮,看高亮层叠面积。结果发现很多short点都落在有文本标签的金属图形附近,而且标签文本本身就处在两个金属图形之间的间距里。
再用KLayout打开GDS查层,发现M1的text和M1 drawing被映射到了同一个layer/datatype。在Calibre的rule deck里,这个层被定义成“drawing+label”性质,text形状虽然很小,但被当成了一块金属图形,直接把本来应该断开的两块M1桥接起来,于是成片short。
根因就是Innovus导出时的map文件把text与drawing合并了。修正map,把M1 text单独映射到一个独立layer/datatype,重新导出,原地复跑,87个short全部消失。这个案例我印象特别深:LVS报错的位置,不一定是问题根源的位置。数据流上游的层映射错误,会在版图层面制造出大量假short。这也是为什么我一直强调,导完GDS先检查map和图层。
4. Calibre RVE的使用:从报错坐标快速定位到Innovus版图
4.1 别只盯着Error列表:RVE三大面板这样配合
Calibre RVE(Results Viewing Environment)打开结果后,屏幕通常分成三块:左边是错误/警告列表,中间是版图区域,右边是所选器件的属性或网表对照。
新手最容易犯的错是只看左边列表,一条条读描述,不去点中间的版图高亮。实际debug的正确顺序是:先在列表里点中一条error,切到版图区看高亮位置,再在右边看两个net或device的详细属性,确认后再决定往哪查。
RVE的错误列表支持按类型过滤,只看shorts、只看opens、只看unmatched device,能极大减少噪音。拿到一个乱糟糟的报告,不要从第一个error开始一路向下,先按类型分组,看哪种类型数量最多,那往往就是主要矛盾。
4.2 层次化显示:不展开子Cell会让你误判
层次化LVS跑完,RVE默认可能在顶层显示错误。一个藏在标准单元内部的short,在顶层看会被压成很大一块高亮区域,看起来像整个cell都有问题。这时候需要把显示模式切到层次化,展开到错误所在的那个cell,才能看到真正的症结。
我踩过这种坑:一开始在顶层看到一个大面积高亮,以为是两条power stripe短路,花了半天在顶层找原因,最后展开才发现是某个cell内部M1多出了一块金属。所以看到错误面积大得离谱时,第一反应应该是:展开层级看。
4.3 从RVE坐标跳回Innovus的两个方法
方法一:在RVE的版图区鼠标悬停,状态栏会显示当前坐标。记下坐标,回到Innovus,在GUI左下角坐标框输入这些数字,或者用命令缩放到该坐标。这个方法最通用,不需要任何额外脚本。
方法二:如果RVE里错误关联的是某个instance,列表里会显示instance路径,直接回Innovus里用instance名去select,选中后高亮,再和RVE里看到的高亮图形对照。
我个人用得最多的是“先看instance路径,再坐标跳转”的组合动作。见到一个error,先确认它在哪个cell里,然后在Innovus里选中这个cell,再填入坐标缩放。整个循环下来,平均一条error两分钟能定位到具体物理位置,比在版图里瞎翻效率高很多。
5. 调试沉淀下来的避坑清单与个人习惯
5.1 常见“误报”其实是Rule Deck选项没选对
有一种情况要特别小心:rule deck或option文件里带有针对不同场景的开关,比如面向不同电源域、不同器件类型(IO、DTMOS、analog)的开关。PDK默认的calibre.lvs未必适合你当前模块,数字block和fullchip的LVS option就往往不一样。用错option的典型症状是:同一个GDS,不同人跑出来的LVS结果一个clean一个满屏报错。
项目里应该至少维护两套LVS runset,一套给block级,一套给chip级。block级可以开LVS REDUCE PARALLEL,关闭某些全局soft connect检查;chip级则要保留更完整的顶层连接语义。不要图省事一套runset跑到底,后面PEX阶段你会后悔的。
5.2 顶层悬空PG管脚的处理顺序
顶层LVS报“有几个PG terminal没接到任何net”,先别急着把pin豁免掉。先检查corner cell和power cell的物理连接是否完整,PG ring是否闭合,然后看IO power cell的供电连接有没有遗漏。这些都没问题,才能判断是“真的悬空”还是顶层文本标签缺失。
还有一个实际经验:处理顺序上,先修short,再修open,最后处理device mismatch。因为short往往会连带产生一堆unmatched device,short清掉后很多device mismatch会自动消失。反过来做,你会在别人的错误上白费力气。
5.3 LVS Clean之后别急着庆祝:ERC和PEX前还有事
LVS clean只能代表“连线关系一致”,不代表版图没有可靠性问题。floating well、antenna、latch-up风险都要靠ERC或专门的检查项把关。很多fab的rule deck里,LVS和ERC在同一套SVRF里实现,只是运行脚本不同,记得把ERC开关打开跑一遍。
另外,如果下一步要跑PEX寄生提取,务必用同版本同option的LVS结果作为输入。PEX阶段对器件识别、网络合并的方式完全继承LVS阶段,前后不一致会导致提取出的寄生根本不能反映真实物理情况。到时候后仿不过再回头排查,才是真的折腾。
5.4 Debug日志是给自己省时间的最好投资
每次LVS debug完,花五分钟把三样东西记录下来:报错类型、根因、修改点。做得多了之后你会发现,数字后端LVS的坑高度重复,翻自己的历史笔记比翻rule deck文档快得多。如果是团队项目,这个文档还能帮同事少踩一个下午的坑。
我自己现在专门有一个wiki页面记录这些case,包括这次的87个short案例也在里面。下次再有人跑来问“为什么我的VDD和VSS又short了”,把链接丢过去,比从头讲一遍省事太多。