ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

数字后端布图规划实战:从面积估算到宏单元摆放的完整指南

数字后端布图规划实战:从面积估算到宏单元摆放的完整指南 数字后端这个坑我前前后后摸爬滚打了一阵子现在回头看最让我当初头疼的不是最后的物理验证而是整个流程的第一步——布图规划。你可能觉得奇怪布图规划不就是把宏单元往版图上摆一摆、把面积算一算吗真有那么难等你真的把Die尺寸拍小了、或者把一个Memory随手丢在角落里后面Place、CTS、Route轮番教做人你就明白这一步到底有多重要了。这篇学习笔记面向的是和我一样处于入门阶段、手里已经能跑起数字后端基本流程的工程师也适合刚接触物理设计的IC应届生。我梳理了一套从输入文件准备到面积估算、IO规划、宏单元摆放、电源网络设计的完整思路结合我在Innovus上实际跑过的流程来写尽量把原理和操作串起来。看完你应该能对“布图规划到底在做什么、为什么要这么做、怎么做才不会给自己埋雷”有一个比较系统的认识。1. 布图规划在数字后端流程中的坐标为什么它是第一个要拍板的环节1.1 从综合网表到物理版图布图规划承担了什么数字后端物理设计从拿到综合之后的门级网表开始。逻辑综合把RTL变成由标准单元和宏单元组成的网表但直到这一步所有单元都还只存在于“逻辑连接”层面没有一个物理位置。布图规划就是给这堆抽象的单元划定一片真实的物理区域芯片大小是多少输入输出Pad放在哪哪些宏单元放在哪个角落电源网络沿着什么路径铺进去标准单元在剩下的空间里怎么分布。一句话概括布图规划是整个物理世界里“定基调”的环节。它的输出是Die/Block的边界坐标、IO Pad的位置、所有宏单元的位置和朝向、电源网络的初步方案以及给标准单元留下的可摆放区域。这些信息直接决定了后面Placement和Routing能不能顺利走通。我在学习过程中习惯把它类比成装修前画户型图你买了一套毛坯房墙和承重柱是工艺决定的但卧室、厨房、客厅的位置是你自己定的。把客厅塞在最里面厨房门对着卫生间能住但每天生活都别扭。放到芯片上就是把频繁通信的两个模块隔了半个Die能布线吗能但是绕线长度暴涨时序全红。把高功耗模块放在一个供电偏远的角落能工作吗也许能但IR drop一查就是红线。1.2 布图规划直接决定的三个“致命指标”后端流程越往后走改动代价越高。布图规划阶段随手拍的一个决定到布线阶段可能变成需要重跑整个流程的大雷。我认为布图规划直接决定三个对芯片生死攸关的东西第一是面积。Die尺寸直接决定单片晶圆能切出多少裸片这是成本问题。但面积也不是越小越好核心区域塞得太满利用率高到离谱后面标准单元摆放和布线就会拥塞到爆。第二是时序。宏单元的位置决定了数据通路的物理长度而物理长度直接变成走线延迟。时钟频率越高关键路径越敏感。布图规划阶段把关键模块的物理距离缩到最短后面CTS和Route阶段才能喘口气。第三是布线的可完成性。芯片里的布线资源是用金属层撑起来的但任何一层金属的走线容量都有限。如果宏单元摆放把某些区域变成了绕线死角或者把布线通道堵死局部拥塞会让工具撒开大量短线甚至直接爆route overflow。1.3 Die尺寸、IO位置、宏摆放和电源网络都是它的输出每次打开Innovus做floorPlan之前我都会提醒自己现在定的这些参数后面每一步都在拿它们当边界条件。Die的宽高比和尺寸、IO Pad的具体坐标、每个Macro的起始位置和旋转方向、电源Ring和Strap的走向都属于布图规划的输出范围。实际项目中布图规划往往不是一次到位的。多数做法是先定一个大致的面积和宏单元布局跑一版快速place得到拥塞预估然后回来调宏位置、调利用率反复迭代几轮直到各个维度的预估数据都相对正常才进入正式的Place和后端全流程。这个“先粗后细、快速迭代”的思路才是工程师真正的工作方式。2. 布图规划前必须备齐的输入文件少一个都会翻车2.1 输入文件清单与各自角色布图规划不是凭空开始的它的输入文件基本决定了你能看到什么样的世界。先列一个我在实践中整理的最小输入清单文件类型作用常见格式门级网表描述标准单元和宏单元的连接关系Verilog、VHDL时序约束定义时钟周期、输入输出延迟、例外路径SDC物理库描述单元外形、引脚位置、布线阻挡LEF时序库提供单元时序、功耗、面积参数Liberty (.lib/.db)技术文件描述金属层、通孔、设计规则等工艺信息Techfile (tf)寄生参数文件RC提取用的工艺参数TluPlus、qrcTechFileIO约束/封装定义定义Pad和封装的映射关系DEF、io file电源意图文件定义多电压域、电源开关、隔离策略UPF/CPF这张表看起来平淡无奇实际项目里最容易翻车的恰恰是这些文件的版本对齐。比如综合用的Liberty库和物理实现用的LEF库不匹配或者顶层网表里的某个IP单元在LEF里找不到对应macro工具在init_design阶段就会报一堆warning严重的话直接读不进设计。2.2 库文件与约束选错后面全是白干这里有一个我在学习初期反复踩的坑时序库要分清corner。数字后端常用SS、TT、FF三个工艺角分别对应慢、典型、快条件布图规划阶段不需要把所有corner都读进来一般先用一两个典型corner做分析和拥塞预估但进入时序收敛阶段就必须把多corner配齐。如果你在布图规划阶段只读了FF库后面签核时换成SS库会发现面积评估和时序预估值都产生偏差前面的floorplan结论可能都要推翻。SDC约束里最容易漏的是false_path和multicycle_path的声明。布图规划虽然不像时序收敛那样逐条看SDC但时钟周期这个数字会影响你对面积和宏单元位置的判断——时钟越紧关键路径越需要缩短宏单元就越应该贴着相关的逻辑摆放。还有一个容易忽略的点IO约束。芯片不是设计完了才考虑引脚封装引脚分配大概率在项目启动阶段就定死了。布图规划前最好拿到封装或芯片架构侧给的IO assignment哪怕是一个Excel表格形式的引脚-信号对应关系也比自己拍脑袋排Pad靠谱得多。我甚至见过项目因为忽略IO约束导致后续的bonding和封装重做的案例。2.3 Innovus读入网表和库的基本流程以Innovus为例布图规划前的读入流程基本长这样set init_verilog ../rtl2gates/top.v set init_design_netlisttype Verilog set init_top_cell top set init_mmmc_file ../scripts/mmmc.tcl set init_lef_file {../tech/tech.lef ../stdcell/stdcell.lef ../memory/sram_512x32.lef} set init_gnd_net VSS set init_pwr_net VDD init_design这里init_mmc_file是MMMC视图文件里面配好各个corner的lib、cap table和RC工艺角。同时记得指定电源地网络名不然后面加电源环和Stripe的时候工具根本不知道该往哪个net上打。3. 面积估算与Die尺寸确定利用率到底怎么定3.1 芯片面积预算的计算方法布图规划的第一个核心问题是这块芯片要做多大。很多人觉得面积就是网表里所有cell面积加起来但实际上不是。你得在单元面积上叠加上电源网络的占用、布线通道的占用、时钟网络的占用以及给工程改动留的余量。先用量化的方式说面积预算标准单元面积来源于综合报告里的Total Cell Area或者Liberty库里每个cell的area字段累加。宏单元面积来源于Memory Compiler或第三方IP的datasheet/LEF规划时也算出每个宏的实际尺寸。目标利用率这是布图规划阶段人为控制的系数定义为标准单元面积 宏单元面积与核心区域面积之比。所以核心区域面积的经验公式是Core Area 标准单元总面积 宏单元总面积/ 目标利用率这里有个很多新手理解错的地方这个利用率不是把标准单元面积加起来除以Die面积那么简单而是在核心区域内、扣除IO和宏单元占位后给标准单元摆放和走线留出的密度上限。工具在Place阶段会把单元填满这个区域如果利用率给得太高标准单元之间几乎没有空隙布线器就无从下手。3.2 一个具体估算案例拿我之前做过的一个小规模设计举例。标准单元综合后的总面积大约是2.5mm²宏单元方面有6块SRAM每块约0.25mm²合计1.5mm²。这时候如果目标利用率定65%核心区域面积就是2.5 1.5/ 0.65 ≈ 6.15 mm²这个数字记住它已经是一个偏紧的预算。接下来还要考虑实战中的额外损耗电源网络和时钟网络要占据金属层资源IO区域和外围保护环会吃边界面积布线通道如果要穿越宏单元区域还得额外加余量。实际落地时我通常会在这个基础上再放宽5%到10%比如直接取核心区域6.5mm²以上然后再去反推Die的宽高比。利用率不是越高越好这是布图规划阶段最重要的尺度感。我自己的经验参考如下设计特征参考利用率逻辑简单、门数少、时序宽松70% ~ 80%一般SoC或ASIC模块60% ~ 70%宏单元多、数据通路密集、高频设计50% ~ 60%有大量Mega Cell或复杂时钟结构50%以下注意这只是一个起步参考。如果设计里含有大量寄存器堆、复杂的时钟门控结构CTS阶段会插入很多buffer利用率给到55%都可能嫌紧。3.3 Die形状对后端流程的蝴蝶效应面积定了紧接着就是形状。Die的宽高比不是随便拍的它对后端的后续流程影响非常直接。第一个影响是布线拥塞分布。方形Die在相同面积下任意两点之间的平均曼哈顿距离最短这对全局走线是最友好的。如果做成长条形Die数据通路从一个角落穿到另一个角落的距离就被拉长了拥塞很容易集中在中间区域。第二个影响是IO Pad的排列。IO Pad数量通常是固定的Die周长越短单位长度上要放的Pad越多Pad间距越小引脚扇出和封装的可行性就越紧张。Memory多的设计通常IO也比较多这时候Die的形状会反过来约束IO排布。第三个影响是电源网络的均匀性。方形的核心区域在供电时从Ring到中心区域的电阻差异相对均匀IR drop更容易控制。细长结构会让长边方向上的电流路径变长电阻压降更大。所以在面积允许的范围内我倾向于让Die的宽高比接近1:1最多做到1.2:1左右。只有在封装、引脚排列或系统层面有明确约束时才去接受明显的矩形方案。4. 宏单元摆放的实战策略位置、方向、间距都有讲究4.1 宏单元摆放的五个底层逻辑宏单元摆放可以说是布图规划最核心、最考验经验的部分。标准单元是工具自动摆放的但宏单元位置基本靠人定。宏单元摆得好Place和Route事半功倍摆得不好后面工具再怎么使劲也救不回来。我自己总结了五个底层逻辑每次摆Macro前都会过一遍第一就近原则。数据交互频繁的宏单元和逻辑模块之间不应该隔山跨海。Memory和它对应的数据通路逻辑应该尽量贴在一起PLL要靠近它的参考时钟输入复位模块要靠近各个触发器的集中区域。这个原则的本质是把关键路径的物理长度压到最短。第二对齐原则。多个同类型Memory宏单元尽量沿着同一方向对齐排列形成阵列。这样不仅版图整洁更重要的是方便电源网络和时钟树统一走线。如果一个Memory朝东一个朝西电源Strap和时钟树绕来绕去纯属给自己找麻烦。第三通道原则。宏单元之间、宏单元和IO之间、宏单元和核心区域边界之间必须预留出布线通道。通道宽度要看经过这里的信号数量来决定一般至少留出5到10倍标准单元高度的距离。高密度设计里这个通道宽度需要更保守。第四电源域一致性原则。在低功耗多电压域的设计里同一个电源域的宏单元和逻辑块要尽量放在同一个区域内。不同电源域的模块交错混放会造成电源网络极其复杂IR drop和EM风险都会大幅上升。第五保护原则。模拟IP、PLL、高精度比较器这些对噪声敏感的模块不应该被大堆翻转频繁的标准单元包围最好在规划阶段就避开留出隔离带甚至加保护环。数字逻辑的开关噪声和电源弹跳一旦耦合进模拟模块信号质量就没法看了。4.2 具体落点和方向的调整方法实际操作中我在Innovus里通常这样走流程先用floorPlan设定核心区域然后打开GUI里的Placement模式切换到Macro视面把所有宏单元选出来按照上面的原则一个个摆到合适的位置。如果用命令行方式核心就是placeInstance# 将sram实例摆到核心区域坐标(100, 200)不旋转 placeInstance tst_top/mem_wrap/sram_0 100 200 R0 # 将另一块sram旋转180度后放过去 placeInstance tst_top/mem_wrap/sram_1 300 200 R180这里的方向值R0/R90/R180/R270是四种正方向旋转MX/MY是镜像。Memory宏单元通常有固定的pin面摆放时要确保它的数据总线pin和时钟pin朝向数据流过来的方向这样后面的连接才能以最短路径走出去。方向这块有个常见误区以为所有宏单元方向统一就一定好。其实统一方向确实有利于对齐但也要看pin的位置。如果一块Memory的数据pin在右侧而相关逻辑在左侧硬要用R0方向摆放会导致大量信号从Memory右侧绕一个大弯到左侧绕线长度和拥塞都会增加。摆放间距方面宏单元与宏单元之间、宏单元与核心边界之间我一般至少留出1到2倍标准单元行的高度作为通道。如果两侧宏单元的pin都很密集间距要更大一些。另外宏单元的pin面上方尽量少放其他宏单元否则这个pin面会被物理遮挡后续信号根本逃不出去。4.3 摆完宏单元后的自查清单摆完宏单元后我每次都会按下面这个清单过一遍缺一项都不算完成所有宏单元是否在核心区域内是否存在与IO区域或边界重叠。同类型Memory是否对齐且方向尽量一致。关键数据通路上的宏单元和逻辑块之间是否存在物理遮挡。宏单元的pin面是否朝向预期方向pin面外侧是否有足够布线空间。是否有宏单元挡在了其他宏单元与IO Pad之间的直线通路上。高噪声和敏感模拟模块之间是否留了隔离空间。区域之间的布线通道是否足够当前的设计宽度是否足够容纳预计的信号数量。清单检查完我还会跑一版快速Placement用congestion map来验证。这一步很快但信息量很大——它能直观告诉你哪里绕线会挤爆哪里空闲得离谱。5. 电源规划布图阶段就要铺好的整片“电网”5.1 从Pad到标准单元电流是怎么流进芯片的很多刚入门的人不理解为什么电源规划是在布图阶段做的而不是等布线快完了再补。原因很简单电源网络从封装引脚到每个标准单元的供电Pin走的路径和占用的是金属资源。如果布图阶段不规划后面真正要布线的时候发现金属层全被信号线占了电源网络要么绕远路要么因为加宽金属而挤占大量布线资源。理解电源规划先理解电流的路径。以传统的Wire Bond封装为例电流从封装引脚进入芯片上的电源Pad然后通过电源Ring环绕芯片核心区域再由横向和纵向的Stripe电源条带像网格一样铺遍整个核心区域最后通过标准单元行内的Rail把电流分配到每个标准单元的供电Pin。这一路路径上每一段都是电阻都会产生压降。IR drop的目标通常是把电源电压和地之间的电压差控制在标称电压的5%以内。拿1.0V的核心电压来说各路加起来只能压掉50mV预算非常紧。5.2 电源环、Strap、Rail怎么设计电源环Power Ring是围绕核心区域的一圈宽金属它的作用是把从Pad进入的电流均匀扩散到核心区域的四周再通过Stripe向内部输送。电源环的宽度要根据电流大小估算一般要画多层金属叠加比如底层用一条宽的横向金属高层用另一条纵向金属形成低阻抗环路。电源Stripe是横向和纵向排布在核心区域上方的宽金属条一般选用高层金属M5、M6、M7等因为这些层的厚度更厚、方块电阻更小而且没有标准单元的Pin阻挡可以做得很宽。Stripe之间要按等间距排布间距需要考虑每段供电区域内标准单元的功耗和允许的IR drop。标准单元Rail是标准单元库自带的电源轨道通常在M1层内部集成好不需要我们手工设计。在Innovus里电源环和Stripe的生成命令长这样# 在核心区域周围生成电源环 addRing -nets {VDD VSS} -around core \ -width 8 -spacing 1.5 \ -layer {top metal5 bottom metal5 left metal6 right metal6} # 在核心区域上方生成横向电源条带 addStripe -nets {VDD VSS} -layer metal5 -width 2 \ -spacing 4 -set_to_set_distance 40 \ -direction horizontal这里-width是金属宽度-spacing是同一层两条线之间的距离-set_to_set_distance是同一组net相邻条带的重复间距。实际数值取决于工艺节点的电流密度、金属层厚度和功耗估算结果。如果Stripe间距太大中间的单元离电源来源太远IR drop会变大如果太密金属资源被大量消耗信号布线空间变小。布图阶段别指望电源规划一步到位。我自己的做法是先按功耗估算结果铺一套初步的Ring和Stripe等跑完Placement后用IR drop分析工具跑一遍看热点区域的电压降是否超标再决定要不要加宽Stripe或减小间距。这套“估算法加仿真修正”的流程比拍脑袋靠谱得多。5.3 多电源域与低功耗设计中布图阶段的额外工作如果你的设计用了UPF定义多电压域布图规划的电源工作要更早介入。不同电压域的模块在物理上最好分区放而不是打散混放。每个电压域需要有独立的电源Ring或者从主电源网络单独拉出的Stripe电源域之间的信号穿越还要加Level Shifter。Level Shifter的位置一般也是布图阶段定的。它属于需要在两个电源域边界摆放的特殊单元摆放得太远会导致跨域信号路径上出现电平转换不及时的问题。我在低功耗项目的布图规划阶段通常先把UPF读进去确认电源域边界和Level Shifter的期望位置再决定宏单元具体落点。另外电源开关单元Power Switch插入的位置也依赖布图规划。开关单元一般在电源Ring和标准单元区域之间成排放置布图规划时如果没给它们留地方后面插开关会把标准单元区域挤得不成样子。6. 布图规划的检查与避坑肉眼能看出来的门道6.1 可视化检查的几个维度布图规划做完了怎么判断做得好不好我的习惯是从三个维度看。第一个是面积利用率怎么看都舒服。打开Innovus的密度图Density Map如果标准单元区域整体颜色均匀没有出现某个区域特别深、某个区域特别浅的情况说明分配基本合理。特别深的区域意味着局部可能拥塞之后Place会把大量单元堆在这里。第二个是飞线图。GUI里把所有信号连接显示为flylines就能直观看到宏单元之间、宏单元与IO之间的连线是否横七竖八。如果出现大量长距离飞线从芯片一头到另一头说明摆放逻辑有问题应优先调整宏单元位置。第三个是拥塞预估。跑一版快速Place后看congestion map重点关注Transition区域和拥塞热点。拥塞严重的区域后续布线器会很难收场需要在布图阶段就通过调整宏单元、改变核心区域形状或者降低利用率来解决。6.2 我踩过的布图规划常见的坑我学习过程中踩过不少坑挑几个印象特别深的写出来你们看到类似苗头赶紧绕道。第一个坑是利用率卡得太死。以前我以为面积越省成本越低于是把利用率干到75%以上结果Place阶段工具疯狂报overflowRoute阶段更是走到哪里堵到哪里。后来回到布图阶段把利用率降到65%左右所有后续流程都顺了。经验是宁可Die稍微大一点也不要让后端流程走进死胡同。芯片成本不只是Die面积前端设计迭代、后端收敛时间、改版次数全部是钱。第二个坑是宏单元方向全部照搬库里的默认方向。默认方向R0在很多IP上没问题但Memory和某些带长总线的大IPpin面的位置决定了大量绕线方向。我后来养成习惯每摆一个宏单元都想一下“它的高频信号从哪来、要到哪去”而不是简单地铺一个MP。第三个坑是电源Stripe覆盖范围太粗心。曾经有一块小Memory的pin面正好被一条横向Stripe压住导致那组数据pin物理上被挡住信号根本走不出来最后必须手动绕开。解决办法是在布图阶段就检查Stripe和宏单元pin面的重叠情况。第四个坑是没给CTS留buffer空间。时钟树综合阶段要插入大量Buffer和Inverter这些单元没有额外的地方放只能见缝插针塞进标准单元区域。如果布图阶段把标准单元区域利用率排得太满CTS阶段会为了塞Buffer把区域挤变形导致时钟偏移和拥塞双双恶化。给CTS留缓冲空间这件事布图阶段就该做。第五个坑是低估了IO区域的影响。IO Pad和Core之间的环形区域不只是走线通道还要容纳ESD保护结构、IO逻辑和电源脚。这个区域太窄后面IO相关的时钟和信号布线会非常痛苦。我建议IO与核心边界之间至少留出多层金属可以顺畅通过的空间具体宽度根据IO数量和信号密度来定。6.3 布图规划通过的一个实用检查清单最后整理一份我在项目里实际使用的检查清单每次布图规划初版出来以后逐项打勾核心面积和Die尺寸已按目标利用率确认留有5%-10%的余量。所有宏单元都在核心区域内无重叠、无越界。宏单元方向已按pin面和数据流调整关键总线方向相对顺直。关键数据通路的宏单元和逻辑块之间没有被其他大单元阻断。IO Pad与对应宏单元/逻辑块之间不存在明显的物理障碍。各电压域的宏单元物理分区清晰Level Shifter和Power Switch位置已预留。电源Ring和Stripe已按功耗估算铺设IR drop预估在5%以内EM满足电流密度要求。电源Stripe没有遮挡任何宏单元pin面和标准单元pin区域。标准单元区域利用率合理为CTS预留了足够的缓冲空间。密度图和拥塞预估图上没有明显的局部热点全局布线通道看起来通畅。踩过几次坑之后现在我每个项目布图规划做完都会把这张清单晒在工位上从头到尾过一遍再往下走。也不知道是我运气好还是真管用大部分时候布图规划阶段多花两小时后面Place和Route能少加班两三天。这个习惯值。
返回列表