做数字后端的朋友应该都有同感布图规划Floorplan是整个物理设计流程里第一个要面对的门槛也是最容易让人心里没底的一步。拿到门级网表之后不是立刻就让工具去摆标准单元而是要先回答一个更宏观的问题这块芯片到底长什么样、模块放在哪、电源怎么走、数据流怎么安排。布图规划就是回答这些问题的环节它决定了后续布局、CTS、布线的成败。这篇笔记我会结合自己用Innovus做项目的实际经验把布图规划这一站在做什么、怎么落地、有哪些坑一次性讲清楚适合刚接触数字IC后端、正在啃物理设计概念的同学参考。1. 布图规划在数字后端流程中的定位与核心价值1.1 数字后端全流程布图规划在最前端数字后端物理设计从综合后的门级网表开始大致流程是布图规划Floorplan、标准单元摆放Placement、时钟树综合CTS、布线Routing、物理验证DRC/LVS/DFM以及Signoff检查。布图规划是整个链条的起点这一步做得好不好直接影响后面所有流程能不能顺利收敛。说得直白点floorplan就是给这棵“数字大树”选地基和画树干地基歪了、树干分叉了后面枝叶长得多茂盛都白搭。很多人第一次接触floorplan会觉得它不像Placement和Routing那样有明确的自动化流程反而更像“体力活经验活”。但其实它是最考验全局观的一步。你需要同时考虑面积、时序、功耗、电源完整性、信号完整性、可制造性甚至封装设计。任何一个维度出了问题后面等着你的就是无穷无尽的ECOEngineering Change Order和返工。在Innovus这类工具里布图规划阶段最终产出的是一份带物理信息的floorplan DEF文件里面定义了芯片核心区core的大小、IO单元的位置、宏单元macro的坐标、电源网络拓扑、行row方向和site类型。这些信息一旦定下来后面的Placement和Routing基本就是在这样一个框架内做局部优化。所以行业里有个说法floorplan定案的时候这个项目的成败已经定了七成。1.2 布图规划到底在“规划”什么布图规划的核心任务可以拆成四块面积规划、IO规划、宏单元摆放、电源网络规划。面积规划是回答“芯片做多大”。你需要根据网表里标准单元和宏单元的面积总和结合预估的布线拥塞程度给出一个带冗余的core面积。不是说把单元面积相加然后除以利用率就是最终答案布线的难度、时钟网络的资源占用、电源网络的空间占用都要在面积里留出余量。IO规划是回答“输入输出怎么排”。芯片和外部世界的连接通道边界条件很硬因为IO必须和封装基板的ball map对上。有些IP对供电数量、地引脚数量有明确要求你需要先满足这些硬性条件再考虑信号顺序和走线方向。宏单元摆放是回答“大模块放哪”。比如SRAM、PLL、ADC/DAC这类硬核宏单元它们的引脚位置和形状是固定死的你必须把它们放到合理的位置让它们和数据流方向一致同时避免挡住标准单元的布线通道。电源网络规划是回答“电怎么送进去”。就是在core内部构建横平竖直的电源环ring和电源条带stripe让每个标准单元都能就近用电。这里要兼顾IR drop、电迁移EM和布线资源占用。这四块是互相耦合的。比如宏单元摆放挪了位置可能就影响了这一片的电源网络密度IO pin顺序变了可能又让某块宏单元的数据流方向变成“反着走”。所以布图规划是一个典型的权衡过程不是一次性拿到最优解而是不断调整、评估、再调整。1.3 布图规划的输入与输出先把家底理清楚布图规划不是凭空产生的东西它吃进来的输入有几个比较关键综合后的门级网表gate-level netlist、SDC时序约束、工艺库LEF/Techfile、宏单元的LEF和LIB、IO单元的库文件以及如果存在芯片级约束的话还会有chip-level DEF或MIG文件。这些输入决定了你手上有什么牌可打。输出则是一整套物理规划结果最核心的是带完整物理信息的DEF文件里面记录core边界、row配置、macro坐标、IO位置、placement blockage和初版PG网络。另外还会输出一个手工或脚本整理的floorplan约束文件以后每次从RTL开始重新做后端都能复用这套约束确保不同版本之间的物理规划一致性。初学者容易犯的一个错误是拿到网表和约束就开始跑工具结果工具报出一堆面积异常或者利用率负数的问题才回头去查输入。我自己的习惯是先把所有库、LEF、网表、约束的版本号核对一遍再用工具读入后跑一个简短的summary检查确认没有缺失和版本冲突再进入真正的floorplan初始化。前面省几分钟后面可能省几天。2. 布图规划的关键参数与决策逻辑2.1 芯片面积与利用率为什么不是简单相加面积估算最基础的做法是把所有标准单元的area相加加上所有宏单元的area再除以一个目标利用率。但这里有个容易忽略的问题标准单元库里的area是单元的物理尺寸不是实际布局后的占用面积。布局时单元之间要留出走线空间时钟树综合要插buffer电源网络要占金属层资源这些都不会体现在单元面积里所以核心区的实际长宽往往比“总面积/利用率”要更大些。利用率的选取和项目类型强相关。比如逻辑占比高、总线多的设计利用率通常不敢设太高因为绕线资源紧张后期routing congestion会很严重。我做过的一个MCU项目logic density大概在60%左右初始利用率设到70%跑完放置直接局部拥塞爆红后来调整到68%以下才压住。而纯memory为主的SoC因为宏单元内部走线基本不占core资源利用率可以放到75%甚至更高。利用率的本质是给后续优化“留白”。设置太低浪费面积成本上去了设置太高后面布线拥塞时序无法收敛代价更大。一个相对稳妥的起步值是65%到70%具体还得靠跑一版试flux看congestion map再回调。这里提一个我常用的判断方法把初始floorplan做完后先不急着摆放的标准单元完整布局而是直接跑一次全局布线快速评估看congestion map的红色区域面积占比如果超过一定比例就直接回头改面积。2.2 IO规划与Pad布局封装约束是硬边界IO规划的根基是封装方案。如果你用的是BGA封装那么芯片顶层信号IO的分布必须和封装基板的ball map一一对应否则后面封装走线根本出不来。IO planning做得好不好不是看单个pin的位置而是看整圈IO的排布能不能自然地适配内部数据流。我一般会按这样几步来做IO规划先读封装文件确定IO总数和电源地IO数量然后把高速接口和时钟这类敏感性IO单独标记出来接着按照数据流方向把逻辑相关的IO集中在相邻区域最后再检查一遍整圈IO有没有跨分割区域、有没有顺序交叉。宏单元和IO的协同也很重要。比如某块数字信号处理逻辑需要跟一组高速IO直连那这组IO附近的core区域就该留给相关宏单元和逻辑而不是摆一个完全无关的模拟IP。IO规划其实就是在“封装硬约束”和“内部数据流合理性”之间找平衡。还有一类特殊IO容易被忽略就是boundary scanJTAG或者debug相关IO。这类IO数量不多但分布随意经常会被工具自动放到很尴尬的位置。我建议针对这类调试IO手工指定位置尽量集中到一个角落方便调试器物理走线。2.3 宏单元摆放原则跟着数据流走宏单元摆放是布图规划里门道最深的一部分。大块头的静态存储器SRAM有固定的shape和pin位置模拟IP更是不能随便动所以宏单元摆放的核心不是“摆哪”而是“为什么摆这”。业内最通用的思路是沿着数据流data flow摆放。比如CPU子系统里指令从ITCM读出来进入流水线数据从总线接口进来进入DTCM那么ITCM和DTCM就应该放在靠近总线接口和流水线逻辑的一侧而不是跟缓存堆在一起。顺着数据流摆走线自然流畅时序和拥塞都会好做很多。宏单元摆放还有一些机械性的规则同类宏单元尽量成组排列方便电源网络和地网络的统一规划大宏单元之间要留出走线通道不能让所有走线都挤在一个窄口宏单元的pin方向要朝向自己的逻辑避免翻转之后pin朝外导致走线绕远。这些规则听起来简单做起来到处是取舍。还有一个经常被新手忽略的点就是宏单元下面的电源网络供给。大型SRAM的功耗其实不小如果floorplan阶段没给它预留足够的电源stripe和decap空间后面做IR drop分析时经常爆红。我习惯在摆完宏单元后会单独检查每个宏单元的IR drop热区不给它留到后面再补救的机会。2.4 电源网络拓扑规划别让“干线”堵车电源网络规划在floorplan阶段就要定下骨架。最基本的配置是IO ring连接封装电源core内部用Power Ring把整个core围一圈然后用同层或上下层的Stripe做纵横交织的网络把电从ring送进core内部最终通过标准单元Row上的VDD/VSS pin完成供电。Stripe的宽度、间距和层数选择没有统一标准需要根据功耗密度和金属层资源来算。一个粗略的估算方法是先根据功耗和供电电压估算平均电流再结合允许的IR drop和金属层电阻率去算需要多少条Stripe、每条要多宽。这个计算不用特别精确因为后面signoff阶段还会做动态IR drop分析但floorplan阶段至少要保证方向正确、密度合理别等到ECO才来改。另外电源网络规划还要考虑电压域voltage domain的问题。多电压设计里有多个VDD不同电压域的电源网络物理上要隔离但又不能完全割裂因为信号跨越电压域的时候还需要level shifter。这些都在floorplan阶段要规划清楚工具不会自动帮你区分。我个人的经验是电源条带宁可多给不可少给。TSMC N7以下的工艺低层金属电阻率越来越高IR drop压力比重越来越大电源网络占掉的绕线资源是可以接受的但IR drop violations带来的时序ECO成本是完全不可接受的。3. 基于Innovus的布图规划实操从数据准备到面积估算3.1 数据准备与库检查在Innovus里做布图规划之前先把输入数据准备利索。要读入的文件包括综合后网表verilog或SDC格式、SDC约束、标准单元LEF、宏单元LEF、Tech LEF、IO库LEF以及时序库和物理库。如果你有上一级芯片的DEF或者partition floorplan也一并准备好。数据读入阶段最常遇到的问题是LEF版本和工具版本不匹配或者宏单元LEF缺少必要的pin方向和site定义。这些错误通常在init_design阶段就会暴露但是报错信息有时候比较隐晦。我习惯在读入后先跑一步report_units和checkDesign确认所有库的instance都能对应上物理信息再往下走。数据干净是floorplan顺利的一大半保证。检查项检查内容常见问题库文件LEF/TechLEF版本、site定义Macrosite后缀不一致导致unitTile无法对齐网表连接关系完整性、undriven port忘接信号的net导致io pin缺失约束SDC时钟定义、端口负载约束过紧导致后续放置面积虚高封装IO ball map与pin name匹配pin alias不匹配导致IO assignment错乱3.2 初始化floorplan面积、长宽比、row配置Innovus初始化floorplan最常用的命令是floorPlan。最简形式是指定core的长宽和四周的core margin。比如floorPlan -site core -d 400 400 5 5 5 5意思是die尺寸为400x400um周边core margin各5um。实际项目中你很少直接这么用一般会先让工具根据netlist面积算一个建议值再人工微调。工具给出的默认core长宽通常基于标准单元总面积和宏单元面积之和除以目标利用率。你可以通过report_config -floorplan或者解读log来看这个估算过程。我通常会把工具估算的利用率写下来对比自己的手工估算相差超过3个点就去看网表里是不是有重复面积统计或者大块IP没有被识别。Row方向row direction也要在初始化阶段确认。大部分设计用horizontal rows也就是row direction是horizontal标准单元行从左往右排row和row之间间隔为site高度。如果你的设计里混合了不同高度的标准单元那么row高度问题会更加敏感。Innovus里设置row方向的参数是setFPlanRowSpacing和addHaloToInst等辅助命令具体功能上相当于定义走线通道宽度不是直接画row本身。设置好初始core之后建议先做一次report_utilization看当前面积下的标准单元利用率和总利用率。如果总利用率超过预设值太多说明core面积给少了趁早扩大如果太低说明面积浪费后续相同性能下成本偏高可以适当缩小。3.3 IO配置与宏单元摆放操作IO配置在Innovus里的手动操作其实就是两件事设置IO方向和位置。批量IO的pin name和位置可以直接通过脚本或者GUI的IO editor拖动完成。实际操作时我不建议靠肉眼看GUI一个一个拖而是先维护一份IO mapping文件把pin name、net name、坐标、旋转方向都整理好再通过Tcl脚本一次性设置可追溯、可复用。宏单元摆放也可以用GUI拖动但更规范的做法是写Tcl脚本。比如setObjFPlanBox $macro_inst [list $x $y]可以直接把宏单元放到目标坐标。摆放过程中要看三个维度宏单元之间不能重叠、宏单元不能压住标准单元区域、宏单元的pin方向要对准数据流下游逻辑。前两个是硬性DRC第三个是软性时序考虑。我特别想强调一点宏单元摆放完以后一定要加上合适的Halo和Blockage。Halo是宏单元周边的禁摆区域给后续走线留空间Blockage是禁止标准单元放置的区域避免标准单元挡在宏单元门口。这两个东西不加后面的Placement一定会把标准单元塞得满地都是然后CTS和Routing就开始连锁爆炸。3.4 布局合理性的快速评估方法floorplan做完不等于万事大吉快速做一轮合理性评估是必须的。Innovus里最简单有效的办法是check_floorplan会检查IO合法性、宏单元重叠、row方向冲突等基础问题。但这只是及格线真正的高手会进一步做拥塞预评估。我常用的手段是先把floorplan保存为def然后临时跑一次快速全局布线fast global route出一个congestion report和热图。如果某个区域expanded net数量异常或者congestion hotspot面积偏大就说明这个区域的宏单元摆放或者blockage设置不合理趁早期调整代价很小。另外还要看floorplan与约束的匹配度。比如SDC里定义了某个模块的时钟频率特别高那么这个模块在floorplan里就应当有相对紧凑的布局和充足的低层布线资源如果被安排到了core边缘又远离自己相关逻辑后面时序很难收敛。这一项工具不一定会报错要靠人对设计的理解来判断。4. 布图规划阶段的高频问题与排查技巧4.1 利用率设置过高导致布线拥塞现象是Placement之后查看congestion map某一片区域红得刺眼Routing阶段涌现大量detour绕线部分net延迟显著超标。很多人的第一反应是让布线工具怎么优化但根本原因在floorplan阶段利用率就定太高了布线通道不足。排查时可以翻这一步在floorplan初始化的log里找到工具报告的总利用率再看看core面积中已经配给宏单元和blockage的面积占比。如果标准单元实际可用区域远小于理论core面积那么利用率数字是虚高的。对应处理方式不是缩小面积而是要么扩大core面积要么减少blockage区域给standard cell留出更多空间。4.2 数据流与宏单元摆放方向矛盾如果出现“某模块的数据从core左边进来但是相关宏单元被放到了右边”那不用等到Routing就能预测到这条路线的net会绕一大圈。这种问题在排IO顺序和宏单元位置时最容易发生因为IO顺序常被封装约束锁死宏单元摆放只能妥协。排查时建议画一张简单数据流图从每个IO区域出发把信号走向用箭头标出来再看看宏单元的实际位置是否与箭头方向大致一致。如果发现某几个宏单元与数据流方向几乎垂直趁早挪。别指望Placement自动帮忙解决它只能在给定的宏单元位置基础上做局部优化不可能从根本上改变宏观layout的质量。4.3 电源网络不足导致的IR drop风险早期IR drop问题不一定在floorplan阶段立刻暴露要么是用faulty分析跑出来的结果在后期才翻车要么是signoff阶段动态IR drop爆红。但根源经常可以追溯到floorplan阶段Stripe数量和宽度就没给够。我的处理经验是不要在floorplan阶段追求“刚刚好”。Stripe宽度和数量宁多勿少尤其对于高频、高翻转率的逻辑区域。如果Stripe多了导致标准单元可用面积紧张可以通过适当降低利用率和增大core面积来补偿。这个策略至少让你在后端后期少被IR drop问题折磨。4.4 版本迭代中的floorplan漂移项目迭代过程中网表和约束经常变化floorplan不是一成不变的。最常见的坑是改版时只改了RTL和综合脚本没有同步更新floorplan约束文件结果工具重新初始化后宏单元完全换了个位置所有前期规划作废。做法是每次floorplan确认后生成一份固定格式的floorplan约束文件Tcl或者def放入版本管理并和综合版本号、库版本号绑定记录。任何一次网表或约束更新都要用diff工具对比floorplan约束的差异确认哪些宏单元需要微调、哪些完全不用动。这样能避免很多莫名其妙的后端问题。5. 布图规划的个人实操心得与避坑经验5.1 先画纸面草图再操作工具做了几个项目之后我越来越觉得布图规划与其说是在用工具调坐标不如说是在纸上把数据流画明白。每次拿到新项目的网表分析完我都会先在白纸上按模块画一版“数据流方向和宏单元大致位置”标出每个模块之间数据量大致比例再打开工具去落实。这个过程看起来原始但特别管用能逼你在动手前想清楚宏观布局。有一回我在纸上画的方案当时觉得coordinated摆放很顺结果工具里一摆发现IO方向跟封装ball map冲突只能回头调整。但就算这样纸面上也帮我节省了在GUI里反复试错的时间。这个方法现在几乎成了我做项目的默认流程。5.2 养成快照习惯改动作操作前先存档布图规划是高度反复调整的环节一次大改动可能让整个floorplan的面貌完全变化。我强烈建议在每次重大改动前用defOut和addToShelf保存当前状态并顺手截一张当前floorplan的图片这样出了问题能快速回滚也能直观对比不同版本的优劣。我踩过最疼的一次坑是连续调了好几个宏单元位置之后引发congestion大爆发想回到上一版又找不到当时的具体坐标只能靠记忆手动挪回去白白浪费了大半天。后来我养成了改一步存一步的好习惯这种惨剧再没发生过。5.3 预留一点冗余向signoff风险学习布图规划是整个后端流程里容错空间最大的环节后面每一步的麻烦几乎都能在floorplan里找到“预根”。所以做floorplan时不能只看眼前能不能跑通还要想清楚后面CTS、Routing、IR drop的signoff要求。比如电源网络给足余量、布线通道留宽、宏单元周围Halo给够这些“冗余”短期看起来浪费面积长期来看都是在给你后续的ECO和收敛风险做保险。我记得一个老后端前辈说过一句话floorplan做得好的人不是他每个参数都选得最完美而是他有预留容错空间的意识。一个floorplan能顺利从Placement一路走到Signoff中间ECO越少说明之前的取舍越合理。这个经验可能比任何一条命令都值钱分享给大家共勉。