半夜十一点多群里突然甩过来一张截图Innovus的log停在一行已经快一个小时没动提问的人就一句话“place跑不下去了卡在这儿了咋整”这种场面我相信每个做数字后端的人都遇过。Innovus里的PRPlace and Route流程从floorplan到routeDesign任何一个环节都可能随时“跑不下去”。而且最折磨人的不是报ERROR而是那种log不更新、CPU还在转、你不知道它是在慢慢磨还是已经死透的状态。这篇东西我打算把这几年在现场排查过的PR卡死问题好好捋一遍从环境安装到place、CTS、route阶段分别会踩什么样的坑以及我手里比较管用的处理套路分享给正在被Innovus折磨的兄弟们。1. 先搞清楚“跑不下去”到底是哪种死法1.1 别盯着屏幕发呆先看log和进程状态很多人遇到卡住的第一反应是盯着innovus的窗口看盼着它下一秒就刷新一行。这没用。正确做法是打开另一个终端先看三样东西进程还在不在、CPU占用是多少、log最后几行说了什么。tail -n 50 innovus.log top -u 你的用户名 free -g df -h /tmp如果进程CPU占用一直在90%以上多半是还在算只是这一阶段特别耗时间你要做的是判断它是在正常慢跑还是死循环。如果CPU掉到0%那就是挂死了常见原因有license断连、远程X11卡死、内存交互不足、进程被系统kill。如果log最后一行出现ERROR、FATAL、Segmentation fault那就简单了直接按error信息去查。还有一个很多人忽略的/tmp满了。Innovus在跑global routing和timing opt的时候会在临时目录写大量文件磁盘满了以后进程不报错但就是写不动卡在那里。1.2 分辨五种常见的“卡死现场”我把这些年遇到的情况大致分成五类每类的处理优先级完全不一样。表现可能原因优先级直接报ERROR退出数据问题、命令参数错、license失效最高直接查loglog不动但CPU高place/CTS在正常计算但太慢高确认耗时合理性进程消失、log末尾无异常内存被OOM killer杀掉高查dmesglog卡住且CPU极低license等待、GUI显示卡死、磁盘写不进去中逐个排除跑完但结果完全不可用congestion爆炸、DRC大量违例中属于“跑完不算跑通”这里我想强调一个观念跑不下去不等于只有报错才算跑不下去。很多时候Innovus把整个流程“跑完”了但打开floorplan一看热点区域红得发紫timing path一查全是violation这种结果连做ECO的资格都没有。所以排查的首要思路是搞清楚它到底是哪一步、以什么方式“跑不下去”。1.3 分清楚卡在哪一个阶段Innovus里PR流程大致是init_design→floorPlan→placeDesign→ccopt_designCTS→routeDesign→addFiller→verify_drc。不同阶段卡住的原因天差地别floorplan卡通常是数据问题比如macro重叠、site定义不对、boundary尺寸异常。place卡congestion、floorplan不合理、约束矛盾是重灾区。CTS卡时钟定义有问题、时钟树spec不合理、skew group异常。route卡congestion、全局绕线overflow、电源网络stripe设置冲突。我排查时的第一个动作不是改参数而是翻log定位到它最后在做哪个命令。innovus.log里会记录当前正在执行的命令名比如placeDesign下面还有子阶段Global Place、Legalization、Clock Placement这些看到这一步就能缩小范围。2. 环境、安装和数据的坑很多人死在一开始2.1 CentOS 7上装Innovus的库依赖坑热词里有人在搜“centos 7 innovus安装”这个背景我也多说一句。很多人的PR不是项目中跑不下去而是软件压根起不来、一启动就报错或者是跑的过程中莫名崩溃。CentOS 7这种老系统上装Innovus最大的麻烦就是32位兼容库和老的X11/Motif图形库缺失。启动时如果报类似这样的错error while loading shared libraries: libXm.so.4: cannot open shared object file说明系统缺了openmotif。常规操作是把常用依赖一次性补齐yum install -y openmotif libXp libXrender mesa-libGLU libXss libXft fontconfig然后用ldd检查Innovus的可执行文件看还有哪些库是not foundldd /tools/cadence/innovus/bin/innovus | grep not found有一点要留意CentOS 7有些库被替换成了compat-前缀的版本装完以后用ln -s手动建个软链也是常有的事。这种环境问题看起来和“跑不下去”没关系但它会在你跑大规模设计到一半的时候突然崩掉而且崩溃前毫无预兆。我是建议在一开始就把环境彻底搞定别带病跑项目。2.2 license配置不对会让流程“卡死”Innovus在跑的过程中如果license断开很多时候不是直接报错而是停在那里反复重试。表现特征就是CPU很低、log最后一行停在某个命令上、进程也活着但就是不动。排查方面先看license环境变量是否正常echo $CDS_LIC_FILE echo $LM_LICENSE_FILE再用lmstat检查license server上Innovus的feature是否够用、有没有被其他用户占满。我记得有次项目组四个人同时跑大模块license的place feature只有两个结果后面启动的两个人就一直在排队等待。从log看就是“卡住”实际上是在等license。2.3 LEF/DEF/库/SDC数据一致性要提前检查很多时候PR跑不下去根源不在流程本身而是输入数据自相矛盾。LEF文件里macro的site和std cell的site不匹配place时会出现大量illegal placement。Liberty库里的power pin命名和LEF不一致CTS或addStripe阶段会找不到pg pin。SDC里时钟定义互相覆盖导致place阶段timing计算出现诡异结果。DEF里的boundary和floorplan设置冲突floorPlan命令直接报错。我的习惯是在init_design完成后、正式place之前先跑几个检查命令checkDesign、reportDesignStats、简单看一眼summaryReport。别嫌麻烦这几十秒的检查能省下后面几小时的排查。3. Placement与Congestion最常见的主战场3.1 placeDesign卡住的三个典型原因place阶段是大家喊“跑不下去”次数最多的。我总结下来九成以上出在下面这三类问题上。第一类floorplan物理不合理。比如hard macro重叠、macro和boundary之间没有留够绕线通道、memory block把std cell区域挤成一条缝。这种问题在place之前其实已经埋雷了Innovus在global placement阶段会遇到大量的overlap然后反复legalize表现出来就是log不动、CPU狂转。处理方法是回到floorplan阶段检查report_floorplan在GUI里打开floorplan视图直接看macro有没有叠在一起、periphery有没有明显不合理的窄通道。给macro加合适的halokeepout区域是标准操作很多团队会在init后先设好create_halo -all_blocks 20第二类利用率utilization虚高。不是所有cell面积都算utilization但很多人只看到core utilization 70%就觉得没问题却忽略了macro区域占掉的面积、电源stripe占掉的绕线资源、以及防盗走高扇出网high fanout net消耗的空间。实际有效利用率经常比报告里的高出一截其结果就是global placement阶段overflow降不下去place硬生生跑十几个小时。第三类约束和时钟域问题。SDC里如果存在互相矛盾的时钟定义或者某个时钟domain里有一堆没有约束的pathplace会一直在那里优化到“无法进一步优化”为止。排查方法是在place之前跑一遍report_clock_tree或者report_qor -preCTS先确认基础时序环境有没有明显问题。3.2 用cell padding缓解局部congestion关于热词里“innovus 加cell padding”这个技巧我在实际项目里用的频率非常高。所谓cell padding简单理解就是给某些std cell在物理上额外“增肥”——在cell的左右或上下加一段禁止放其他cell的空白区域。它不改变cell本身的逻辑功能但会在热点区域人为地拉开间距给绕线腾出空间。操作上很直接add_cell_padding -cell AND2X1 -left 1 -right 1 add_cell_padding -cell [dbget top.insts.cell.name -if .celltypestd] -left 2 -right 2第一行是给名称为AND2X1的cell左右各加1的padding第二行是给所有std cell统一加2。加完以后重新place即可。这里有几个经验只对特定cell加padding效果比全加好因为全加会明显抬高利用率反而加剧congestion。判断该对哪些cell加padding要看congestion分布图。GUI里打开Congestion图层看到哪个区域红了就对该区域里的高频cell类型加padding。padding的单位是site宽度或track间距加太狠会导致legalize失败Innovus会报Not enough space之类的错误。通常从1开始试不行再加到2。如果你用的是Innovus较新版本命令可能是set_cts_padding或者UI里的Placement Cell Padding入口同一目的在不同版本上入口有差异。先help add_cell_padding确认当前版本支持什么。3.3 addStripe电源网络跑不过去怎么处理另一个常见的“跑不下去”是addStripe阶段。听到有人说“innovus addstripe卡住”多半不是命令本身卡而是前一阶段的电源网络定义有问题。常见情况有这些层设置冲突在不对的layer上用-direction horizontal或者同一个layer上stripe的width和spacing组合违反design rule。处理方式是把addStripe的层单独拿出来report_design_rules看一眼最小width和间距。net名不对addStripe里指定的-nets名字没在LEF里定义成power/gnd或者名字大小写跟约束里不一致。先确认顶层电源地名字默认是VDD和VSS但如果设计里用的是VCCD1这种就必须对应改。和已有stripe打架如果之前手动画过一些stripe或者用了addRing新的stripe可能和旧的shape重合报Collision错误。一般加-overlap参数处理或者先把旧的重叠区域清掉。我自己写脚本的习惯是在addStripe之前先查当前的power net定义dbget top.pgNets.name dbget top.pgNets.pgType确认pgType是power还是ground再写addStripe就不会莫名其妙报错。而且我强烈建议把power stripe这一步单独放一个脚本文件跑别和place/CTS混在一个大脚本里出了问题也好定位。4. CTS和Routing从时钟到绕线的一地鸡毛4.1 ccopt_design悬而不决先查spec再查资源CTS阶段卡住基本都出在时钟定义没有整理干净。Innovus里的CTS已经不是以前那种简单的“插buffer”逻辑ccopt_design会做并发时钟树优化一旦时钟spec里存在不合理的exception、过大的skew group、或者clock root找不到它就可能长时间卡在优化循环里。跑CTS之前建议先干这几件事生成一次时钟树spec看看内容create_ccopt_clock_tree_spec -file ccopt_spec.tcl打开这个文件查一下root、sink、skew group是否合理。先做一个快速sanity checkreport_clock_tree -summary有些时钟树issue在summary里能直接看到比如某个时钟根本没有被CTS认到。注意ccopt_design对内存的消耗比place还要夸张。如果机器只有32G内存大设计跑CTS经常被OOM杀掉表现为日志最后一行停在Begin Clock Tree Routing之类的提示后进程就消失了。这时候先用dmesg | tail确认有没有Out of memory的记录。有的话要么换更大内存的机器要么用setMultiCpuUsage -localCpu把并发线程降下来减少峰值内存。4.2 routeDesign说挂就挂拆开跑是王道Routing阶段卡死congestion依然是第一大原因。Innovus的routeDesign本身包含global route和detail route理论上细节绕线之前会先做全局绕线评估如果overflow太多detail route就会非常痛苦。我在项目里养成了一个习惯把routeDesign拆开分步执行。routeDesign -global routeDesign -track routeDesign -detail每一步之间都看一眼结果。特别是-global跑完以后马上执行reportCongestion -overflow -verbose如果看到某个区域的overflow数量特别高比如超过总cell数量的2%到3%就不要硬着头皮跑detail了先回去处理congestion。处理热点区域的手段按性价比排序对热点里的cell类型加padding重新place这个前面说过。调整floorplan把macro位置挪一挪给热点区域腾出绕线通道。打开setNanoRouteMode里跟congestion相关的选项让route阶段更多考虑绕线拥挤度。不同版本参数名不同用help setNanoRouteMode查一下直接搜索congestion关键词。还有一点routeDesign阶段不要开太多线程。有人为了快setMultiCpuUsage -localCpu 16直接用满结果内存爆掉反而更慢。我一般控制在8个以内遇到大设计反而用4个线程更稳。4.3 “跑完”不等于“跑通”DRC和时序验证才是终点有些项目跑完routeDesign流程没有报任何errorlog结尾还给你个Normal Termination看起来好像皆大欢喜。结果一跑verify_drc出来几千个violation。这种状态我会认为它本质上也是“跑不下去”——因为结果不能用后面的ECO和signoff根本没法继续。verify_drcInnovus的DRC检查里最常见的是short和spacing violation。short多说明congestion没有真正解决spacing violation多说明绕线资源在某些层上确实不够。这时候我的建议是回到route阶段换策略而不是直接在ecoRoute里手动修。用手动修几千个DRC是地狱难度而且很容易修出新的违例。这个阶段也一定要看时序报告。如果postRoute timing大量violation先判断是结构性问题还是细节优化问题。结构性问题比如clock tree latency异常、某些path的skew大得离谱这种光靠optDesign -postRoute是救不回来的回到CTS甚至place重新跑才是对的。5. 现场排查速查表与我的实操习惯5.1 症状到解决一张表直接抄为了方便直接对照我把这些年最常见的场景整理成一个速查表。遇到问题先按行匹配能省掉大部分翻log的时间。症状现场排查动作实际解决手段place阶段log半小时不更新CPU高tail看子阶段名GUI看congestion检查macro halo降利用率对热点cell加padding进程消失log停在routeDesigndmesg看是否OOM降线程数加大内存拆步执行routeDesignlog停在等待licenselmstat查feature确认license余量释放其他人的licenseaddStripe报nets找不到dbget top.pgNets.name确认power/gnd命名统一VDD/VSSccopt_design长时间卡住检查时钟spec和skew group重设clock root简化exceptionroute后DRC上千条shortreportCongestion看热点加cell padding调floorplan换routing策略启动Innovus直接闪退ldd查缺库装openmotif、libXp等依赖跑着跑着GUI没响应但终端有输出远程X11卡死临时改用纯命令行batch模式或X11转发调优5.2 跑长流程前一定要有的“保命习惯”关于“跑不下去”我认为更值钱的不是事后troubleshooting而是事前预防。下面这些习惯是吃过多次亏以后养成的说实话每一条都是拿加班时间换来的。分段执行分文件记录log。不要一个大脚本从floorplan一路跑到verify_drc。至少拆成place、CTS、route、verify四个阶段每一段单独写log。谁出问题谁显形省得在一个几十万行的大log里大海捞针。关键节点saveDesign。在place完成、CTS完成、route完成这几个节点分别saveDesign一次。Innovus的saveDesign可以随时restore这意味着你不需要每次从头跑。比如CTS跑完觉得congestion不行restore到place节点改padding再跑比从init_design重来快太多。saveDesign checkpoint_place.enc restoreDesign checkpoint_place.enc资源提前监控。跑之前先free -g看内存df -h /tmp看磁盘。Innovus对大设计的峰值内存需求比你想象的高很多项目默认8个线程跑峰值内存直接翻到40G以上机器不够就跑不下去。用batch模式和GUI模式灵活切换。远程跑大流程的时候GUI模式很容易因为X11转发问题导致界面卡死视觉上就像“Innovus挂了”。其实后端还在跑。这种时候直接用命令行的batch方式跑脚本或者用innovus -batch不同版本入口略有差异跑完再打开GUI看结果。别让一个只是“看不清”的界面耽误你判断“死没死”。6. 一个让我印象深刻的实战复盘最后讲一个案例是我觉得特别典型的“跑不下去但根本不是设计问题”的情况。有个项目跑到placeDesignlog停在Begin Global Placement超过三个小时CPU只有5%。当时第一反应是congestion或者floorplan有问题于是restore到floorplan阶段调halo、调utilization、加padding来回折腾了两三轮重新跑place依旧卡住。后来实在没办法去翻进程状态发现Innovus进程其实在但CPU几乎为零并且进程处于T状态stopped。再追下去发现是机器上另一个管理员任务把进程挂起了还在等前面的job结束。说白了不是Innovus的问题是调度环境的问题。这个案例给我的教训很深刻排查顺序不能错。先查系统层进程、内存、磁盘、license再查设计层floorplan、congestion、约束最后才去动参数。很多人一上来就改place的effort level、改padding结果只是在自己吓自己真正的原因根本不在设计数据里。还有另外一个经验不要忽视innovus.log里出现的大量WARN。有些WARN看似无关紧要比如某条电源网络的pin缺失、某个时钟的source latency没有定义它们不会立刻让你跑不下去但会在后面某个阶段冷不丁变成ERROR或者让timing结果烂到没法收拾。跑流程的时候定期打开log看WARN的密度比跑完再看要有效得多。我个人现在遇到“跑不下去”的标准流程就是先确认进程和资源状态再看log最后200行然后按阶段定位、分段验证。大多数问题都能在半小时内找到方向。真到了要调floorplan和routing strategy的层面也已经有了足够的排查证据不会瞎试。Innovus这东西跑通一次不难难的是每次都知道它是怎么死的、死在哪儿。多一些这类排查记录大家都能少走点弯路。