☰
IC后端floorplan实战:面积估算、宏单元摆放与电源规划
2026/10/8 2:54:38 网站建设 项目流程

1. 从第一次被拥塞图打脸说起:为什么要认真学floorplan

我刚开始学IC后端时,对floorplan有个很天真的认知:觉得这步不就是画个框、把memory大概摆一摆、然后把电源网络铺上去嘛,真正难的应该在布线阶段。直到第一次负责一个中等规模模块,综合完直接跑自动布局,看到global routing之后满屏的红色拥塞热点,我才意识到自己省掉的那部分“看起来很简单”的功夫,后面全变成了加班修不完的线长违例和绕线拥塞。

floorplan,翻译成“布局规划”,是物理设计流程里真正意义上的第一道手工作业。前一步的综合拿到的是门级网表,里面是几十万个标准单元和若干个大模块的互联关系;后一步的布局布线要把这些单元真正落到硅片上。而floorplan恰恰是两者之间的“总设计图”:决定芯片面积多大、core边界在哪里、macro和IP摆在哪、IO和pin怎么分、电源网络怎么搭骨架。你可以把它类比成装修前先定户型:墙在哪儿决定了后面沙发怎么摆、水电怎么走,墙一旦砌错,家具摆得再整齐也白搭。

这篇笔记是我学习floorplan的完整复盘,讲的是这套方法背后的“为什么”,而不只是命令流程。我会从面积估算、宏单元摆放、电源规划、IO与拥塞预判这几条主线展开,最后把实际调试中踩过的坑和排查思路一并列出来。内容主要针对数字后端初学和中级工程师,如果你正准备从flow跑通阶段走向真正独立做floorplan,这篇应该能帮你避开不少弯路。

2. 面积估算与芯片尺寸:动手之前第一笔账得算明白

2.1 标准单元面积与utilization的基本关系

拿到综合后的门级网表,很多人第一反应是“先跑一遍流程看看”,但老手会先算一笔面积账。这笔账的起点,是网表里所有标准单元本身的物理面积总和。这个数字在看综合报告时一般能直接拿到,或者用工具读入网表后按instance面积累计也能得到。

光知道std cell总面积还不够,因为标准单元不可能像拼瓷砖那样严丝合缝地铺满整个core。单元之间要留布线通道,clock tree综合会插入大量buffer,后端优化会插hold buffer,ECO阶段还要有地方加逻辑。所以真正规划core面积时,需要先把“利用率”这个概念立起来:

[ utilization = \frac{std\ cell\ 总面积}{std\ cell\ 可用面积} ]

注意,这个utilization的分母通常是“core里可以摆放标准单元的区域”,不是整个die面积。业界比较常见的初版目标利用率在65%~75%左右,具体取决于设计规模、宏单元占比、性能要求。如果design里有大量SRAM或者有高频率模块,我会倾向留到60%~70%;如果纯标准单元逻辑、时序压力不大,75%以上也不一定出问题,但前提是通过后续拥塞分析验证过。

2.2 一个可复用的面积估算示例

举个例子。假设综合报告里标准单元总面积为200,000 (\mu m^2),还有两块SRAM,每块占15,000 (\mu m^2)。如果我把utilization设为70%,那么core里面留给标准单元区域的面积就是200,000 ÷ 0.7,约285,714 (\mu m^2)。再把两块SRAM的面积加进去,core的总需求大约在315,714 (\mu m^2) 左右。

然后看core的宽高比。如果封装或pad限定了die的shape,ratio就得跟着封装走;如果没有硬性限定,一般从1:1附近起步比较省心。按这个面积开平方,core边长大约在562 (\mu m) 左右。实际操作时我不会直接手算,而是先在工具里按这个估算值设置core,再读入所有单元,让工具报一个真实的core density,看是否落在65%~75%区间。

2.3 那些容易“偷走”面积的隐藏项

新手最容易忽视的是,core面积并不是“标准单元面积 + macro面积”这么简单。floorplan阶段就要考虑到好几类隐形占用:

  • endcap cells:为了防止well边缘的扩散和光刻效应,core边缘会放一排物理单元,这些不占逻辑却占面积。
  • well tap cells:提供衬底偏置连接,通常每隔一段距离放一个,密度不小。
  • power stripe和PG via:金属条带以及它们打孔占用的布线资源,不直接算进std cell面积,但会影响有效摆放区域。
  • CTS buffer的余量:高扇出时钟网络加进去后,面积利用率往往比floorplan阶段预估高2~5个点,且质量好的时钟树往往更耗buffer。

所以我的习惯是:floorplan预估利用率时,尽量取区间中间值偏保守。一旦发现某次设计估算utilization已经超过75%,我就不急着往下跑,优先把core放大,或者找架构同事讨论是否能够合并部分逻辑。这个习惯帮我省掉了后面无数次routing阶段的返工。

3. 宏单元摆放:不是“把方块放进框里”那么简单

3.1 数据流分析是宏摆放的第一原则

宏单元(SRAM、PLL、DAC/ADC、各种IP)是floorplan阶段最需要你花心思的对象,因为它们体积大、pin固定、移动成本极高。自动布局工具在placement阶段能优化标准单元位置,但macro一旦摆定,工具改动它的能力很弱。这意味着宏观布局的决策权必须留给人。

摆放宏单元的第一原则是顺着数据流走。比如一个模块从总线上收数据,解码后写入SRAM,又从SRAM读出处理后通过数据总线送出,那么SRAM就应放在总线和逻辑交汇的中心附近,而不是扔在core角落。宏单元离使用它的逻辑越远,数据线穿越的距离就越长,走线延迟和绕线资源都会显著恶化。

我记得有一次处理一个通信基带模块,两个SRAM分别挂在收发两条数据通路上,当时为了图省事,我把两个SRAM并排放在core下方的连续区域里。这样表面上整齐,结果收发逻辑被隔在芯片两侧,数据线全部横穿整个core,congestion从右侧一路红到左侧。后来把两个memory拆开放,各自贴近收发通路,问题立刻缓解了大半。所以判断宏放得好不好,第一眼永远看数据进出方向,而不是看摆放整齐不整齐。

3.2 摆完macro后,从三个视角复查好坏

宏单元摆完之后,我会习惯性地从三个视角过一遍:

  1. 通道视角:每个macro四周是否留有足够的“路”让标准单元和信号线经过。如果一个macro把core从边缘顶到另一边,中间不留缝隙,等于在芯片里砌了一堵墙,两侧逻辑的连线只能挤在有限缺口里绕行。
  2. pin access视角:macro pin所在的那一层和那一侧,有没有被旁边的macro或IO pad挡住。尤其要注意SRAM的pin通常集中在某几侧,假如pin朝外却被另一个macro贴在脸前,后续连接这个macro的信号就得费很大力气绕出来。
  3. 时钟与电源视角:macro是否给CTS buffer、电源strap留了位置。宏单元密集区往往也是时钟汇聚区,如果周边完全没有插buffer和走clock trunk的空间,后面CTS阶段会很难受。

3.3 一个务实的手动摆放调整套路

如果项目里macro数量不算太多(比如十个以内),我推荐手动摆放加工具辅助验证。大致套路是:

  • 在工具里打开版图,先把所有macro放在core外围,按面积从大到小排列。
  • 画一条粗略的数据流连线,观察哪些模块之间交互量大,把这些macro在空间上拉近。
  • 逐步把macro向core内部或边缘移动,每动一次就看一次周围的whitespace分布。
  • 摆完一遍后做一次place_opt的pre-CTS快速run,不要求它的timing优化得多好,只看congestion map和density map。

这个循环通常要重复两三轮。很多刚接触floorplan的人恨不得一轮就定型,但我的经验是,macro位置这种高杠杆决策,值得你花整个floorplan阶段一半的时间在上面。工具能帮你验证,但判断方向还是得靠人。

4. 电源网络规划:floorplan里最容易被看轻的基本盘

4.1 为什么电源规划必须从floorplan阶段就开始

很多人以为电源网络是后面power routing阶段才处理的事,实际完全不是。floorplan一旦把macro位置、core面积和引脚分布定了,电源网络的基本框架也就被约束了一半。尤其是宏单元的PG pin位置、power switch cell的摆放、不同电压域的划分,这些在floorplan阶段不规划清楚,后面想改等于重摆。

电源网络的目标非常直接:在最短路径上把电压均匀送到芯片每个角落,把IR drop控制在可接受范围,同时满足电迁移(EM)约束。如果电源网络密度不够,芯片跑高速负载时局部电压跌落,轻则时序变差,重则逻辑功能直接出错。

4.2 Pixel-level的电源骨架:ring、stripe和rail

通常的电源骨架由三层组成:

  • power ring:环绕core外围的环形电源走线,连接IO电源引脚和内部网络,是整个供电系统的主干道。
  • power stripe:横跨core内部的水平/垂直金属条带,把电源从ring送到内部模块。stripe方向和间距要根据金属层方向、电流需求、绕线资源综合决定。
  • standard cell rail:标准单元行上的电源轨道,通常由工具在布局阶段自动生成,但量级较小,必须接在stripe网络上才有意义。

做stripe规划时,我习惯先确认design的总电流需求,再估算金属层每微米宽度能承载多少电流。设总电流5A、电压1.0V,意味着总功耗5W;假设顶层金属每微米宽度可过1mA量级的电流(具体看工艺和金属层厚,这里只说思路),那么需要的总金属宽度就是5A÷对应电流密度。这只是粗略估算,实际还要乘以冗余系数,并把stripe的电阻、bump/pad位置等因素一并纳入。

这里得提醒一句:stripe不是越密越好。电源stripe配置得过于密集,会把大量走线资源占掉,后续信号绕线空间变小。我见过一个设计,为了把IR drop做到极致,在core里铺满了互相垂直的stripe,结果信号routing阶段几乎每层都被金属条带切得支离破碎,绕线严重超量。正确做法是先做一轮快速电源分析,把IR drop热点区域定位出来,再有针对性地在这些区域加密。

4.3 宏单元和电源规划之间的配合

宏单元对电源网络的影响容易被忽略。很多SRAM或IP的PG pin是沿着macro边缘排列的,当floorplan阶段摆放macro时,就要考虑你后续stripe的方向能否接到这些pin上。常见做法是让stripe方向与宏单元pin侧对齐,尽量让宏电源引脚直接搭在stripe上,避免全靠打孔绕线。

此外,如果设计里存在多个电压域(比如core 0.8V、IO 1.8V、模拟3.3V),不同域之间要靠level shifter和isolation cell衔接,这些cell的位置也必须在floorplan阶段提前规划。我的经验是,把电压域边界画得越简洁越好,最好让不同域的macro分区布置,而不是犬牙交错地混在一起。否则level shifter数量暴涨,面积和功耗同时失控。

5. IO与Pin规划:让信号走短而不是走远

5.1 IO pin布局与数据流方向对齐

IO pin的位置在floorplan阶段通常由封装或芯片整体规划给定,但对内部模块而言,我们真正要关注的是模块边界上的pin assignment,或者在die边缘的pad位置。

如果数据从芯片左侧进来,处理完后从右侧出去,那么宏观布局和IO排列就应该顺着“左进右出”或者“右进左出”的数据流方向。一个常见错误是,模块的输入输出pin被分在芯片两端,但模块内部的核心逻辑却放在中间偏下,导致所有信号进入模块后要绕一段很长的路才能碰到真正的逻辑。这种长绕线是最容易在时序报告里突然冒出大量setup违例的元凶。

在宏观布局时,我习惯把IO pin的位置和内部macro的逻辑位置放在同一张图上一起看。比如某个IO pin是SRAM地址输入,那么它对应的SRAM controller应该尽量靠近这个pin所在的方向。如果封装已经定死了pin位置,那floorplan调macro时就要反向适应pin的位置,而不是反过来让信号去迁就你摆的方案。

5.2 拥塞评估:怎么在floorplan阶段就判断“行不行”

floorplan做完之后,很多人直接一路自动跑到routing,直到看到congestion报告才慌。这其实错过了最好的验证窗口。现在主流后端工具都支持floorplan阶段做一次快速全局布线预估,用当时的物理信息和网表跑一遍global route,输出一份congestion map,颜色从绿到黄到红标出热点区域。

我每次floorplan结束、placement正式开跑之前,都会做一次这样的预检查。重点看三层信息:

  • hot spot分布:core里有没有大面积的红色区域。如果仅是局部两三个点,通过调macro或者加routing guide可以解决;如果大面积红色,那多半是utilization太高或macro布局有方向性问题。
  • overflow数值:报出来的total overflow和max overflow。不同工具、不同设计阈值不一样,不能只看绝对值,但横向对比调整前后的change很有意义。
  • pin density:macro、memory pin扎堆的地方,往往是拥塞的前兆。pin太密集说明周边标准单元太少或者走线资源不足,可以考虑把密集宏单元分散。

我特别想说一个经验:floorplan阶段花半小时调整一下macro位置,效果常常好过布线阶段花三天拆线。这不是夸张,我自己经历过太多次“布线跑不下去,回头改floorplan,重跑却一天就通了”的情况。早期多花时间在上游,是所有后端老手都认可的“慢即是快”。

5.3 给hold buffer和ECO留后手

floorplan时另一个容易被新手忽略的细节是给hold buffer留空间。芯片物理设计里,setup修复可以通过降低频率或调整逻辑,hold修不了,只能堆buffer修延迟。随着工艺演进,hold buffer的插入数量越来越多,动辄几千上万个。如果在floorplan阶段就把utilization顶到80%以上,这些buffer到后期根本没地方放,最后只能打乱布局或改floorplan。

我的处理方式是,在floorplan时就把目标利用率压低几个点,并且看报告时关注“自由摆放区域”的分布。如果某些模块周围几乎被macro全包围,这块区域的buffer容量就很小,后续hold修起来会非常痛苦。提前识别这些“口袋区域”,在floorplan阶段给它们留出缓冲空间,远比后期在CTS和hold修复阶段到处塞buffer靠谱。

6. 工具实操:一个最简floorplan流程和关键检查点

6.1 从数据准备到输出floorplan

以Innovus为例,跑一个最基础的floorplan大致需要这些输入:综合后的门级网表(.v)、时序约束(.sdc)、物理库(LEF/tech LEF)、时序库(.lib)、IO pin定义(tdf或io文件)。不同工具的数据格式有差异,但数据链条基本一致。

读入数据后,第一步是创建core,告诉工具面积和纵横比。比如估算出core边长约562 (\mu m),可以用类似下面的命令创建:

read_netlist $DESIGN.v read_physical -lef $LEF read_timing -lib $LIB read_sdc $DESIGN.sdc floorPlan -d 600 600 10 10 10 10

命令里的四个数字分别表示上下左右留出的core offset。设置好初始尺寸后,再读入IO pin分配,或者手动指定。接着把macro按前面的思路逐个摆放,摆放完成后创建电源环和stripe。一个极简的电源创建流程类似:

addRing -nets {VDD VSS} -layer {top M6 bottom M6 left M5 right M5} -width 2 -spacing 1 addStripe -nets {VDD VSS} -layer M4 -direction vertical -width 1 -spacing 1 -set_to_set_distance 100

注意,这里的金属层号、宽度、间距都只是示例,实际必须和工艺库、PG连接关系、IR drop目标匹配。如果这个设计有多个电压域,命令会复杂得多,还需要处理power switch cell和isolation cell的摆放。建议初学阶段先把单电压域流程跑通,再逐步加难度。

6.2 跑通之后,必看的三个检查点

floorplan工具输出之后,我一般不会立刻往下跑placement。先做三件事:

  1. 看density map:确认标准单元放置区域的平均密度是否在目标范围内,有没有局部过高或过低的区域。
  2. 跑快速global route预检:用globalRoute或者ecoRoute之类的方式做一次快速评估,看congestion map上有没有异常热点。
  3. 检查power network连接性:确认每条stripe都正确接到ring、macro的PG pin有没有遗漏连接,这一步可以用工具自带的pg check功能。

如果这三项都通过,这个floorplan才算是“可以见人”的状态。接下来再跑placement,后续的问题就会少很多。

6.3 推荐的学习路径和练习方式

如果你也想系统掌握floorplan,我最推荐的学习方式不是只看文档,而是拿一个开放或内部的简单模块,反复调参数试。具体来说,可以做一个对比实验:同一个设计,分别用utilization 65%、75%、85%各跑一轮完整流程,记录每一轮的congestion、routing时长和最终timing,你会对这个设计在面积与性能之间的敏感度有非常直观的认识。再做一个实验:把同一组macro分别按“集中堆放”“完全打散”“按数据流摆放”三种方式摆,观察全局布线的差异。这几个练习做完,你对floorplan的理解会比读十篇教程都深。

7. 复盘:那些让我交过学费的floorplan坑

7.1 利用率拍脑袋,布线阶段替你买单

我最早独立做floorplan时,为了把芯片面积压小,把utilization设到了85%。刚做完placement时一切正常,一跑route就开始大面积overflow,工具拆线拆到天亮也搞不定。最后trace下来,根因就是没有给布线通道和时钟buffer留余量。从那以后我把“utilization先取70%左右”当成默认值,除非有非常明确的面积压力,否则不轻易逼近80%。这个教训的本质是:floorplan阶段省下的每一分面积,都会在routing阶段以一倍甚至几倍的代价还回来。

7.2 macro把标准单元区域“切碎”

另一个常见坑是macro摆放时只想着把memory放得近一点,结果两个macro之间只留了一条极窄的通道,把标准单元区域切成几块孤岛。placement阶段工具还能把cell硬塞进去,但布线阶段这些区域就变成了涌堵入口。现在我做复查时,会专门测量macro之间的最小间距,并且会观察通道两端是否有较大的逻辑交互量。如果通道两侧都连着高交互逻辑,就说明通道宽度大概率不够,得重新调整。

7.3 只抱时序大腿,忘了电源这个隐形约束

还有一次设计,我把所有精力都放在给关键路径减短走线上,完全忽略了IR drop。后来做早期电源分析,发现某个远离stripe的memory供电电压已经跌到规格下限。没办法,只能在那片区域补stripe和bypass电容,又一次打乱了宏布局。这件事之后,我在每次floorplan启动时就把电源预算和数据一起加载进来,至少保证stripe主干一定经过所有高功耗宏单元,ir drop这类问题尽量不拖到后期。

7.4 我的快速复查清单

判断一个floorplan能不能继续往下走,我现在只凭一张清单:

检查项目标判断工具/方法
core面积utilization落在60%~75%density report
宏摆放方向顺着数据流,不阻断通道数据流图 + 版图目检
macro间距留足走线和时钟buffer通道测量工具计算间距
电源网络IR drop无热点,stripe与PG pin匹配快速电源分析
IO对齐pin方向与内部数据流方向一致IO pin图 + 连线预检
拥塞预检无大面积红色区域global route快速评估

把这些项逐条过完,floorplan就不会出太大问题。哪怕后面来了ECO,改动的范围也基本可控。

最后说一条我自己的体会:floorplan是IC后端里最“像建筑设计师”的工作,它要求你同时想清楚面积、时序、供电、可布线性这几件事,而且必须在信息不完整时就拍板。正因如此,它也是最值得花时间的一步。每次多思考十分钟的宏位置,后续很可能帮你省下一个通宵的布线返工。做后端越久,我越愿意把这步做扎实,而不是急着“先跑起来再说”。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询