这一篇在干嘛?
第 14 章的物理综合只解决了底层逻辑结构的优化,本章的**布局规划(floorplanning)**是更高层的手段:在布局布线之前,人工划定各功能模块在芯片上的物理区域。用得好能显著提速、缩短编译时间、降低功耗;用得不好会让性能断崖式下跌。本章讲什么时候该做、怎么做、怎么避坑。
15.1 设计分区(Design Partitioning)
当器件密度达到百万门级,“撒一把门让工具自己摆”的做法撑不住了——布局工具需要帮助。布局规划就是在布局(placement)之前为设计分区,典型流程如图:
图 15.1 标准流程 vs 物理综合流程:布局规划始终在布局之前
无论哪种流程,布局规划必须发生在布局操作之前(物理综合流程中甚至要在综合之前创建 floorplan)。floorplan 一旦固定,就成为所有逻辑单元物理位置的”分区指南”。
高层次的 floorplan 捕捉设计中所有主要功能块,并把这些块抽象化——不需要指明块内的具体逻辑。举例:设计有三个主要功能块 A、B、C,组成流水线:
图 15.2 接口良好定义的流水线:三个功能块各由一位设计师负责
这种分区的关键前提:
- 每块分配给独立设计师,块间只在系统设计师预先定义的接口处交互;
- 接口时序由时序预算(timing budget)明确约定;
- 接口 I/O 大概率都已寄存,关键路径落在各块内部——不会跨过功能块边界。
于是时序合规可以按块逐个考虑,不必面对一整片门海。这能大幅加速大型器件的实现:
图 15.3 Spartan-3 5000 上的分区布局规划示例:三个块各占一个区域
收益清单:
- 编译时间:Spartan-3 5000 这个规模的器件,门海式布局布线要好几个小时;分区后变成三次较小、更可控的布局布线,时间锐减。
- 时序风险:接口边界都寄存了,块之间留较大的”空隙”不会引起时序问题。
- 增量设计:某一块的结构或布局改动不影响其他块——分区方法与增量设计流程(incremental flow)天然配合。
启发:按主要功能边界做布局规划分区,时序就能逐块收敛。
15.2 关键路径布局规划
floorplan 的另一大用途:死磕关键路径。流程是迭代的:
图 15.4 关键路径布局规划的设计流程:floorplan 是时序收敛循环的枢纽
- 跑完最终实现,拿到关键路径报告;
- 把路径信息后向标注到布局规划器;
- 设计师手动为关键逻辑单元定义位置约束;
- 约束前向标注给布局布线工具;
- 重新实现,看结果,回到第 1 步。
与设计分区那种”一次定好就不动”的 floorplan 不同,关键路径 floorplan 是时序收敛循环中的活跃环节——每一轮迭代都可能修改。
启发:做关键路径布局规划时,floorplan 是迭代时序收敛循环的关键一环。
与图 15.3 的大区域分区不同,这种 floorplan 由若干临时的小区域组成——每个区域收紧一条关键路径,基于时序反馈信息临时创建、每轮迭代更新:
图 15.5 关键路径约束示例:两个小区域分别收紧两条关键路径
15.3 布局规划的危险
先说最刺眼的一句话:
坏的 floorplan 会显著降低设计性能。
逻辑链条:好的布局 ↔ 性能好;坏的布局 ↔ 性能差;坏的 floorplan 必然产生坏的布局。所以 floorplan 对性能的影响绝不是”不增不减”——做错了是负分。
不是所有设计都适合布局规划:
- 适合:流水线化、数据流规则的设计(如流水线微处理器)——结构清晰、天然分区;
- 不适合:主要是控制逻辑或胶合逻辑(glue logic)、没有明确数据通路的设计——本质就是门海,那就让综合和布局布线工具把它当门海对待,别强加人工约束。
一个实用的判断启发式:看关键路径中布线延时占比。
- 布线延时占关键路径延时的绝大部分 → floorplan 可能把结构拉近、优化布线资源,值得做;
- 布线延时占比不高、又没有明确数据通路 → 不是好候选。
启发:布局规划适合高度流水化的设计,或布线延时主导的布局。
15.4 最优布局规划的四个要点
最优 floorplan 的总原则:把直接互连的逻辑放在一起,绝不人为拆散关键路径上的单元。具体从四个角度入手。
15.4.1 数据通路优先
数据通路中心的设计相对好分。高速应用中要分区的流水线通常就是数据通路——它承载被处理的信息,速度要求最高(常常连续运行),先给它做 floorplan:
图 15.6 数据通路布局规划:只框住主流水线和相关逻辑
floorplan 只包含数据通路(主流水线级 + 相关逻辑);控制结构和胶合逻辑不在主数据通路上,交给后端工具自动摆放。
启发:floorplan 通常只包含数据通路,不包含控制或胶合逻辑。
15.4.2 高扇出网络
高扇出(high fan-out)网络——一个驱动器带一大堆负载——是布局规划的好候选。如果负载散布在驱动器周围的大片区域,驱动器输出处的布线资源会被大量占用,造成拥塞,殃及周边其他布线:
图 15.7 负载离驱动器太远:局部布线资源被占满,其他路由被挤长
图 15.8 把高扇出负载约束在小区域内:对其他布线的干扰最小化
把高扇出负载圈进一个紧凑区域后:布线工具运行更快,实现性能也更高(布线延时最小化)。
15.4.3 器件固定结构
FPGA 里有大量搬不动的内建结构:存储器(block RAM)、DSP、硬 PCI 接口、硬微处理器、进位链(carry chain)等。floorplan 不仅要让各模块彼此相对最优,还要围绕这些固定资源摆放,把到自定义逻辑的布线降到最短。
启发:floorplan 必须考虑内建资源(存储器、进位链、DSP 等)的固定位置。
例如 RAM 接口相关的输入输出逻辑,应该贴着固定 RAM 资源摆放——大块 RAM 应该用 FPGA 内固定的 block RAM 资源,而不是在芯片各处凑一堆分布式小 RAM:
图 15.9 固定的 FPGA 资源:RAM 列等内建结构位置不可移动
图 15.10 围绕固定 FPGA 资源规划区域
15.4.4 可复用性(屏蔽布局改动的影响)
门海设计的一个经典痛点:改动设计里毫不相干的角落,另一处却冒出时序问题。原因是不受约束的布局算法具有渐进性——“混沌效应”:芯片一侧的小布局变化挤走旁边的逻辑,旁边的又挤走更旁边的……最后整个芯片重新布局,时序全变。
好的 floorplan 是解药:关键逻辑被约束在 floorplan 区域内,周围布局怎么变,区域内部的相对时序纹丝不动,后续改动只能在区域外围”绕着走”:
图 15.11 关键逻辑被约束在区域内,外部布局变化不影响内部
这也让模块和模块组可以原样复用而不掉性能。
15.5 降低动态功耗
布局规划还有一个容易忽略的用途:降低动态功耗。回顾动态功耗公式 P = CV²f(第 11 章讲过),其中 C 是驱动器必须充放电的电容。
看一条从逻辑单元 A 到 B 的布线:
图 15.12 走线的 LC 寄生参数
布线走线的电容 C_trace 正比于走线面积;FPGA 布线资源的线宽固定,所以电容正比于走线长度——驱动器与接收器距离越远,每次翻转要充放电的电容越大,功耗越高。
于是降功耗的思路:在功能固定、各信号活跃度(activity)不可改变的前提下,缩短高活跃度(high-activity)网络的布线长度。
微妙之处在于:关键路径 ≠ 高活跃度网络。时序驱动的布局只会把关键路径组件拉近(这是它的本职),但关键路径上可能翻转率很低;而一个轻松满足时序的自由计数器可能翻转率极高。看这个场景:
图 15.13 关键路径已约束,但高活跃度电路被撒在四周,长布线拉高功耗
关键路径已约束、时钟频率已拉满,但布局工具没把高活跃度电路当回事,随手把它撒在关键路径四周——长布线让动态功耗居高不下。解法:给高活跃度电路单独加一个布局区域,强制其互连最短化。如果高活跃度电路与关键路径相互独立,这么做对时序几乎没有影响。
启发:以缩短高活跃度网络走线为目标的 floorplan 可以降低动态功耗。
15.6 本章要点回顾
- 按主要功能边界做 floorplan 分区 → 时序按块收敛;
- 关键路径 floorplan → floorplan 是迭代时序收敛循环的活跃环节;
- 坏的 floorplan 显著降低性能——floorplan 不是”无害尝试”;
- 高度流水化设计、或布线延时主导的布局才适合 floorplan;
- floorplan 通常只框数据通路,不框控制和胶合逻辑;
- floorplan 要围绕内建固定资源(RAM、进位链、DSP)规划;
- 缩短高活跃度网络走线的 floorplan 能降低动态功耗。
常见坑
最常见的错误是给不适合的设计强加 floorplan:控制/胶合逻辑为主、没有明确数据通路的设计,本来就是门海,画几个区域反而把布局工具的手脚捆住,性能断崖下跌。判断标准先看关键路径的布线延时占比——占比不高就别做。第二个坑是 floorplan 里漏掉对内建固定资源的考虑:block RAM、DSP、进位链的位置搬不动,模块区域画得再漂亮,如果和 RAM 列相距甚远,接口布线照样拖垮时序。第三个坑:改一版 RTL 就让 floorplan 失效——floorplan 要随设计演进维护,否则约束和逻辑对不上,效果全无。
通关标准:
学完本篇你应该能做到:
- 画出含 floorplan 的实现流程,说清它为什么必须发生在布局之前;
- 用”接口寄存化 + 时序预算”的分区方法把大设计拆成可独立收敛的块,并说出对编译时间和增量设计的收益;
- 用关键路径布线延时占比判断设计是否适合 floorplan;
- 掌握四个规划要点:数据通路优先、高扇出圈紧、围绕内建固定资源、保护关键区域屏蔽混沌效应;
- 解释 P = CV²f 中 C 与走线长度的关系,并对高活跃度(而非关键路径)网络单独布局降功耗。
自测:为什么按功能边界分区后,块与块之间留较大空隙不会引发时序问题?
因为良好的设计分区保证所有跨块接口的 I/O 都已寄存——寄存器到寄存器的时序路径完全落在各功能块内部,不跨越块边界。块间走线长短只影响跨块信号的全局延迟预算(已由时序预算约定),不参与块内关键路径的建立/保持检查。
自测:设计分区型 floorplan 和关键路径型 floorplan 在流程中的角色有何不同?
设计分区型:floorplan 在布局之前一次性创建并固定,作为所有逻辑物理位置的分区指南,之后不随迭代修改。关键路径型:floorplan 在拿到实现结果和关键路径报告后才创建,每次时序收敛迭代都会更新,是迭代循环中的活跃环节,由临时的小区域收紧个别关键路径。
自测:如何判断一个设计是否适合布局规划?
两个条件满足其一:设计高度流水化、数据流规则(有清晰数据通路可分区);或关键路径延时中布线延时占绝大部分(floorplan 能把逻辑拉近、优化布线)。反过来,若布线延时占比不高、又主要是控制/胶合逻辑没有明确数据通路,就不适合——强加 floorplan 只会束缚布局工具、降低性能。
自测:为什么关键路径区域约束好了,动态功耗还是降不下来?
因为时序驱动布局只优化关键路径,而关键路径和”高活跃度网络”是两个概念:关键路径上翻转率可能很低,翻转率极高的自由计数器等逻辑反而轻松满足时序、被随手撒在芯片各处,长布线让 P = CV²f 中的 C(正比于走线长度)变大。解法是给高活跃度电路单独划一个布局区域缩短其互连,前提是它与关键路径独立、不受时序影响。
自测:门海设计里"改一个角落、另一处时序崩了"的混沌效应是怎么发生的?floorplan 如何屏蔽它?
不受约束的布局算法是渐进的:芯片一侧的小布局变化挤占邻近逻辑的空间,被挤的逻辑又挤走更远的逻辑,级联传导直到整个芯片重新布局,时序全面变化。floorplan 把关键逻辑约束在固定区域内,区域内相对时序锁定不变,任何后续布局改动只能绕着区域边界进行,模块得以原样复用。