
做数字IC后端的人应该都听过这句话floorplan定生死powerplan定成败。夸张吗一点都不夸张。我接手过不少复杂模块有些项目看起来代码逻辑没什么问题综合出来时序也还凑合结果一到后端floorplan没做好后面place和route全是坑修congestion修到怀疑人生甚至最后为了收时序把整颗芯片的频率都拉低。而这一切往往在最初定floorplan的那两天就已经埋下了。今天这篇就围绕ICCSynopsys IC Compiler这个工具聊聊复杂模块的floorplan和powerplan到底该怎么做。文章不会去重复那些已经写烂了的工具手册内容而是把我实际跑过项目后的思考、计算方式、命令用法以及踩过的坑尽量完整地记录下来。适合正在做数字后端、准备入门后端的工程师还有那些从模拟后端转数字后端的同学参考。如果你已经在用Innovus很多思路同样是通用的工具只是实现手段。1. floorplan设计思路从die area到macro摆放的全局拆解1.1 为什么floorplan决定后端成败很多人刚做后端时会把floorplan简单理解为“把memory和大模块摆一摆”。实际远不止这些。floorplan的核心任务是在物理层面上还原设计的数据流和控制流让信号走的路径尽量短、相互干扰尽量小同时为时钟树、电源网络留出足够的空间。我做复杂模块时有个很深的体会floorplan真正难的地方在于平衡。你要同时照顾时序、拥塞、电源完整性、可布线性、甚至后端之后的物理验证。这些指标之间经常相互打架。举个最直白的例子macro摆得太集中短距离绕线方便了但局部congestion会直接爆掉CTS阶段插完buffer之后更是雪上加霜macro摆得太散看起来每个区域都宽松了但关键路径的net长度变长时序收不回来。所以floorplan从来不追求某一个指标做到极致而是追求整体不出大问题。还有一点必须提醒floorplan阶段的设计决策后期改起来成本极高。我也见过有同事过了placement才发现某个memory放歪了想挪一下位置结果动一个macro周边几百条net全部重绕一连串的时序violation冒出来白白浪费两三周时间。所以在floorplan阶段宁可多花两天仔细推敲也不要赶进度。1.2 拿到复杂模块后我的第一轮布局思路拿到一个复杂模块的netlist我先不看具体逻辑而是做三件事看数据流方向、看memory分布、看关键路径约束。这三件事的输出直接决定我下面怎么定core面积和macro摆放。数据流方向怎么看一般是从综合后的sdc和网表中提取模块间的连接关系复杂设计也可以看设计文档里的block diagram。把数据通路的方向标出来后macro摆放就有一个基本逻辑了一组有大量数据交互的macro它们在floorplan上应该尽量靠近且数据的入口和出口要对齐到对应的IO端口方向。举个例子一个通信基带模块通常包含多个FIFO、几块大SRAM、一些乘加运算单元。FIFO往往是数据缓冲SRAM是中间结果存储乘加单元是计算核心。数据流一般是从接口进来进FIFO然后给到运算单元中间结果写SRAM最后再出去。那我在摆macro时会让FIFO靠近输入端口SRAM放在运算单元附近避免数据在芯片上“绕远路”。EMElectromigration电迁移和IR drop是powerplan的关注点但floorplan阶段就要提前考虑。macro多、面积大、功耗高的模块电源网络必须足够密。所以我定macro位置的时候会顺手看一下每个macro的功耗估算通过之前的功耗分析报告把功耗高的区域空出足够的power stripe通道避免后期这里电压降得厉害。核心的摆放原则可以先归纳成几句话数据流方向贯穿整个floorplan高交互模块就近摆放SM标准单元区域保持相对完整连续时钟敏感模块避开电磁干扰源。1.3 用congestion评估反馈闭环来打磨方案摆完第一版macro之后我习惯尽快跑一个快速placementICC里就是create_placement之类的流程可以先做congestion map哪怕时序还没有优化也先把congestion看一遍。这一步非常有用它能把“我感觉这样摆挺好”变成“实际绕线资源吃不吃紧”。怎么读congestion map重点关注三类区域macro之间的channel、macro与block边界之间的区域、以及标准单元密集区。这些地方如果出现大片红色说明绕线资源可能不够要么增加channel宽度要么调整macro的相对位置。注意congestion map有方向性竖着走线的层和横着走线的层拥塞程度不一样要结合工艺的金属层方向和pin density一起看。ICC里可以直接生成congestion report和map。我一般看两个值全局拥塞度和局部拥塞度。如果某个局部区域超过105%甚至110%就说明这个区域很可能成为后期的瓶颈一定要在floorplan阶段处理掉。我曾经遇到过一个模块全局拥塞度只有92%看起来很不错但实际上chip corner附近一块很小的区域拥塞度到了120%结果route阶段在那里浪费了整整四天。从那以后我每个floorplan都会专门检查“局部热点”而不是只盯着平均指标。2. powerplan设计电源环、stripe与std cell供电的完整推导2.1 电源环宽度计算与金属层选择powerplan很多人觉得就是把VDD和VSS铺上去没什么技术含量。这是大错特错。powerplan设计的目标是在芯片工作的所有工况下每个标准单元的供电电压都落在允许范围内同时电源网络本身的电流密度不超出金属层的可靠性上限。这里面的每一步都是计算出来的不是拍脑袋决定的。先讲core ring电源环。core ring是围绕core区域的一圈环形电源走线作用是把外部供电导入core内部的power stripe网络中。计算core ring总宽度时最基础的方法是先估算整个模块的平均电流和峰值电流再根据目标IR drop和金属层方阻算出所需的总电阻进而推算出金属宽度。打个比方模块峰值电流I_peak假设为5A允许的IR drop是30mV那core ring本身的等效电阻就应该控制在6mΩ以下R V / I 0.03V / 5A。金属的方块电阻和厚度、宽度有关如果用的是顶层厚金属M9方块电阻可能在0.1Ω/sq量级那么选择合适的宽度和层数让总电阻满足要求。还需要注意EM的影响。金属在过高电流密度下会发生电迁移时间长了会断路。这个在powerplan设计时就需要用电流密度上限来约束宽度的选择必须同时满足IR drop和EM两个约束取两者中更大的那个宽度。很多人在这一步只算IR drop项目后期EM signoff不过回来改powerplan代价非常大。2.2 mesh与stripe的规划EM、IR drop与绕线资源平衡core ring只是第一步真正给标准单元供电的是power stripe网络也叫电源rail或电源mesh。stripe的间距、宽度、层数直接影响IR drop和绕线资源之间的平衡。stripe太密电源网络好看了但信号绕线资源被大量占用congestion出问题stripe太疏IR drop超标标准单元供电不足时序直接恶化。业界一般怎么定先根据功耗和电压降目标做一次粗略的IR drop分析看需要多密的网络再结合信号绕线资源做折中。比如在7nm工艺下M4/M5作为局部电源层M6/M7作为中层stripe顶层M8/M9作为全局电源层每一层stripe的间距从几十微米到一两百微米不等需要根据block大小和功耗密度具体算。这里我分享一个我的经验值参考表注意这只是参考具体工艺和库需要重新算标准单元功耗密度较低的设计stripe间距取40μm~60μmM4/M5即可功耗密度中等stripe间距取30μm~40μmM4/M5加M6/M7双层高功耗密度stripe间距20μm~30μm配合顶层厚金属M8/M9做电源主干ICC里相关的命令是create_power_stripes需要在定义好power network之后执行。这个命令的参数很多包括layer、width、pitch、direction、nets等我后面实操部分会给出一个可参考的脚本。再补充一个mesh的细节电源网络最好做成格状结构也就是横向和纵向都有stripe连接。格状结构的好处是电流可以从多个路径流向负载点降低等效电阻提高EM容限。哪怕某个局部区域有一个stripe断了电流也能从旁边绕过去不至于立刻出问题。这就像城市路网有横有纵单条路堵了还能绕行如果只有一条主干道一旦出事就整片瘫痪。2.3 PG connection与follow pin的落实细节power网络规划好了之后还要把它真正连接到标准单元上。这里涉及两个概念follow pin和PG connection。Follow pin是标准单元行上的电源轨一般由工艺库自动连接。在ICC里通过derive_pg_connection命令工具会自动把std cell的VDD/VSS连接到对应的power stripe网络上。这里有个细节如果你的设计有多个电压域比如VDD和VDD_SRAM一定要确保derive_pg_connection的-power_net、-ground_net参数设置正确。我曾经见过一种情况两个电压域的名字写错导致SRAM的cell被接到了错误的电源网络上虽然LVS没报问题因为PG属性还在但实际仿真时SRAM供电电压不对功能直接错误。另外还有一类特殊cellendcap cell和welltap cell。Endcap是放在标准单元行两端、用来满足工艺规则比如N-well边界要求的单元welltap是提供衬底偏置连接的单元。这些cell的PG连接容易被忽略但它们如果不接好DRC会报出一堆问题LVS也会出错。所以在floorplan之后一定要先加endcap和welltap再做电源网络连接顺序搞反了后面检查很麻烦。3. 实操过程ICC命令级流程与关键检查点3.1 初始化数据与design planning的启动ICC操作的起点是准备好所有输入数据netlist、SDC约束、LEF/Milkyway reference library、TLU寄生参数文件、以及IO约束文件如果模块有IO pin。在启动ICC之前我习惯把数据清单列出来逐项确认少任何一个文件后面都有可能卡住。启动ICC有两种方式图形界面和tcl shell。实际做复杂模块我更多用tcl脚本跑流程图形界面主要用于看congestion map和macro位置。用命令行跑的好处是可重复、可回归改一个参数重跑一遍非常方便。进入工具后第一步是读入库和设计。ICC里一般用Milkyway格式的物理库通过set_mw_cel_ref_library和open_mw_lib来指定。读入netlist后需要做elaborate和link把设计和库关联起来。这个阶段如果报出unresolved reference说明netlist里有些instance引用的cell在库里找不到一定要先解决不能带着错误往下走。初始化完成后我会用report_design和report_power先看一下设计的基本情况总cell数量、macro数量、功耗估算。这些数字帮助我在后面做面积估算和powerplan参数选择时有个底。3.2 macro placement与pin assignment的操作要点复杂模块的macro placement我建议用“手动初摆工具自动摆放辅助验证”的方式而不是完全依赖工具的自动macro摆放功能。手动摆放时参考线guideline用得上可以先把数据流方向用虚拟的矩形框画出来再把macro放进对应的框内。ICC里调整macro位置可以用move_placement或set_macro_pin_connection等命令。实际操作中我一般这样操作先把所有macro按理想位置放好用refine_placement或create_placement跑一遍快速placement看一下congestion map然后根据热点反复微调macro位置。这个过程可能要迭代好几轮。Pin assignmentIO pin分配也很关键。复杂模块通常有几百甚至上千个IO pin它们的顺序和位置会影响整个block的绕线难度。ICC里可以用edit_pad或者place_pins命令来摆pin。一个原则是先满足时序关键信号的路径最优再考虑非关键信号。实际中pin的位置需要和顶层top level的规划对齐不能只顾着模块内部绕线方便结果到了顶层发现连线交叉严重。如果模块有pin的relative order约束比如总线pin要连续排列需要在floorplan阶段就和前端/架构确认清楚避免后面改pin位置引发大面积重绕。3.3 powerplan创建create_rect_rings与create_power_stripes实战命令接下来是powerplan的落地环节。先创建core ring再打stripe最后做std cell区域内的PG连接。创建一个core ring的ICC命令示范具体参数以你的工艺和设计为准create_rect_rings \ -nets {VDD VSS} \ -left_offset 2 \ -right_offset 2 \ -top_offset 2 \ -bottom_offset 2 \ -left_segment_layer M9 \ -right_segment_layer M9 \ -top_segment_layer M8 \ -bottom_segment_layer M8 \ -width 4 \ -spacing 0.2这条命令的意思是在core的四周创建VDD和VSS的电源环宽度4μmM9走左右两边M8走上两边距离core边界2μm。这里width和spacing怎么定我在前面已经讲过了一定要结合IR drop和EM计算。注意左右两边的M9宽度和上下两边的M8宽度可以不同因为不同层的电流承载能力不一样。创建power stripe的命令示范create_power_stripes \ -nets {VDD VSS} \ -layer M6 \ -direction vertical \ -width 1.2 \ -pitch 40 \ -set_to_set_distance 20 \ -extend_to_boundary这条命令会在M6层上沿垂直方向创建VDD/VSS交替排列的stripe宽度1.2μm间距40μm。set_to_set_distance表示VDD与VSS stripe之间的距离。这里我要特别提醒stripe的起点和终点设置。很多新人用create_power_stripes时stripe延伸到了core ring外面结果DRC报出一堆short问题。最好用-extend_to_boundary把stripe限定在core区域内或者手动指定-延伸范围。为了让VDD和VSS在多个金属层之间形成完整的电源mesh还需要在横向的M8、M9层上也打stripe或ring。各层之间通过via阵列连接via的数量要足够承载电流否则会在via处形成EM热点。via密度不够是非常常见的EM问题来源。接下来是standard cell的PG连接ICC里用derive_pg_connectionderive_pg_connection \ -power_net VDD \ -power_pin VDD \ -ground_net VSS \ -ground_pin VSS \ -create_ports top如果设计里有多个电源域需要分别为每个域执行derive_pg_connection并指定对应的power pin。执行完以后用report_pg_pin或check_pg_power_structure检查有没有漏接的pin。3.4 用check_pg和编译前检查堵住时间炸弹电源网络创建完不代表就结束了必须要做检查。ICC里有专门的检查命令check_pg_power_structure、check_pg_connectivity等。我每次跑完powerplan都会认真过一遍这些检查哪怕报出来全是WARNING也要一条条看。常见的检查结果有几种某些instance没有连接到电源网络VDD和VSS网络之间有short某些层的stripe断开形成浮空网络多电压域之间的isolation cell缺少PG连接这些问题在powerplan阶段发现改起来几分钟如果等到place之后才发现可能要把整个PG网络重做代价完全不同。除了PG检查还要跑一个快速placement验证congestion是否在预期范围内。我的习惯是floorplan和powerplan做完后先跑一个只含placement的阶段不做时钟树看congestion和时序大概情况。这一步能花半天时间但能提前发现50%以上的后期问题。4. 常见问题与排查技巧congestion、IR drop、DRC的连环坑4.1 congestion爆掉时先别急着调floorplan很多工程师一看到congestion map上一片红第一反应就是挪macro。这个反应不一定对。congestion高有两种原因一种是macro布局不合理另一种是标准单元的摆放密度在某个区域过高还有可能是pin access问题。排查时我会先用report_congestion看具体是哪些层、哪些区域拥塞。如果是局部区域标准单元太多可以考虑调整utilization给这个区域留出更多空白如果是pin access导致绕线资源被blockage占用需要检查是不是macro的pin朝向了错误的方向。还有一种特殊原因module的端口位置和macro的pin位置冲突。数据从macro的pin出来要走很长一段才能绕到block的边界port这段路径如果经过标准单元密集区congestion就会很高。这时候与其挪macro不如调整pin assignment把block的IO pin放在更靠近对应macro的方向让数据流少穿越标准单元区域。另外一个容易被忽视的角度SDC约束太乐观或太悲观会导致工具在优化时过度修时序插入大量buffer间接推高congestion。如果congestion高同时时序violation也多可以试着放宽不关键路径的约束让工具别在这条路径上浪费资源。4.2 IR drop与EM仿真不过的定位方法IR drop问题在静态分析阶段往往不会暴露因为早期功耗估算不够准确。等做完signoff IR分析时发现电压降超标已经进入了项目的后半段。这时候定位问题我一般按照从全局到局部的思路来第一先看全局IR drop map判断是整体压降大还是局部热点。整体压降大说明power stripe网络整体偏稀疏或者core ring宽度不够需要加密全局电源网络。局部热点一般集中在功耗密度高的macro附近尤其是一些高频翻转的SRAM、register file周围。第二看EM检查结果。EM问题经常出现在via阵列和stripe拐角位置。如果某个via array报EM violation不要只是增大via数量还要看金属宽度是否足够因为电流瓶颈在窄金属段和via上。第三结合功耗分析报告确认高峰值电流窗口。有些IR drop问题只在特定测试向量下有如果向量覆盖不到静态分析可能永远发现不了。这时候需要跑动态IR分析比如RedHawk/Voltus把峰值电流窗口找出来再针对性地加强相应区域的电源网络。4.3 实际流片案例中的经验教训分享一个我早期踩过的真实教训。当时做的模块有十几个macro我为了追求congestion数字好看把所有macro摆放得很“整齐”memory全部对齐到一个方向。表面上看模块内部通道很宽裕congestion也很好。结果在CTS阶段发现时钟网络要穿过好几块memory之间的窄通道好几条clock path因为绕线距离过长latency差异巨大setup和hold同时出问题。后来我在floorplan评审时被资深工程师一句话点醒“你摆的是memory不是士兵列队。对齐是好看但数据和时钟不会因为你对齐就走直线。”从那以后我摆macro不再追求视觉上的整齐而是尽量让每一组高交互的module之间的物理距离最短。有些地方看起来歪歪扭扭但实际绕线反而短、拥塞也低。还有一个关于powerplan的教训有一次为了节约绕线资源把M6的stripe间距从默认的30μm拉大到了60μm。结果功耗分析的时候IR drop直接从3%飙到了8%标准单元供电不足时序大面积violation。后来不得不增加一层M7的stripe把M6抽掉的部分补回来前后折腾了一周多。这件事让我明白了一个道理powerplan的参数不是拍脑袋定的要用数据说话。省这一点点绕线资源远远不够弥补IR drop带来的损失。5. 避坑指南从工具脚本到团队协作的工程素养5.1 ICC使用中的脚本规范与版本差异ICC的命令在不同版本之间差别比较大尤其是从ICC到ICC2现在叫Fusion Compiler的迁移过程。如果你的项目还在用老版本的ICC需要特别注意create_rect_rings和create_power_stripes这类命令的参数在ICC2中已经变了。如果是新项目建议直接用Fusion Compiler的流程别在新项目上继续用旧版本的脚本否则工具迟早要逼你升级到时候全部脚本重写成本和风险都不小。脚本管理上我强烈建议把floorplan和powerplan的脚本做成参数化、模块化的结构。比如统一使用变量定义所有macro的名字、位置、尺寸用变量定义stripe的层、宽、间距。这样换一个模块或者改一版floorplan的时候只需要修改参数区不需要动核心代码逻辑。另外ICC的脚本一定要用tcl的source方式逐段执行不要一次性把上千行脚本全部跑完。每一段脚本之间加report和checkpoint方便定位是哪一步出了问题。我的习惯是每完成一个阶段就存一个milkyway library的cell view比如fp_start、fp_macro_placed、pg_created、place_done这样随时可以回滚到任意阶段。5.2 复杂模块floorplan评审清单一份好的floorplan方案不应该只存在于EDA工具里还应该能通过团队评审。我每次做复杂模块floorplan都会准备一份简短的评审清单在评审会议上逐项过模块面积和utilization是否留有足够缓冲能否应对后端优化带来的面积增加Macro摆放vs数据流/时钟路径关键路径是否会被迫绕远路Congestion热点是否存在局部拥塞超过100%的区域电源网络IR drop目标、EM裕量、多电压域连接方式IO pin分配是否和顶层规划对齐differential pair、bus pin是否成组特殊单元endcap、welltap、decap的初步规划DRC风险比如macro间的间距是否满足最小channel宽度、N-well边界规则评审清单看似繁琐但它的价值在于倒逼你把每一步都想过、算过。很多floorplan的后期问题在评审阶段就能被提前发现。工具脚本写得再漂亮也只是执行你的思路。真正的后端功力体现在你是否理解设计数据流的本质、是否摸清了工艺和库的特性、是否愿意在前期多花时间推敲每一步决策。5.3 新人上手ICC的3个实操建议最后给刚接触ICC做floorplan的新人三个实操建议。第一找一个已有的项目脚本作为起点不要从零开始写。很多公司内部都有可复用的floorplan模板脚本这些脚本经过了流片验证里面的参数和检查点比工具默认设置更贴近实际需求。照着模板改比自己在man page里翻命令高效得多。第二养成随手截图和记录的习惯。每次调整一个参数记录下调整前后的congestion、timing、IR drop数据。时间久了你会积累出一套属于自己团队的“参数经验表”而不是每次遇到问题都从头试。第三遇到问题先看log文件。我见过太多人在群里问“congestion为什么爆了”实际上log文件里已经清清楚楚写着哪个区域、哪一层资源不够。学会读log、读report是后端工程师的基本功别让工具替你思考工具只是把你的思考变成物理实现。做floorplan和powerplan这件事我一直觉得它很像城市规划。路网怎么留、水电怎么铺、商业区居住区怎么摆都会影响一座城市未来几十年的运转效率。放在芯片上这些决定会在后面place、CTS、route的每个阶段加倍奉还。前期想得越细后期越省心。希望这篇关于ICC复杂模块floorplan与powerplan的实操记录能给正在做后端或者准备入行后端的你一些参考。