3. 层次化设计与扁平化设计:两种设计范式的对比、优缺点分析、如何选择

做数字后端,第一个要面对的选择就是:这芯片,我到底要不要做层次化?

我刚入行那会儿,带我的老工程师丢给我一个两千万门的模块,说「你把它平了」。我当时连「平了」是什么意思都没搞懂,就硬着头皮把整个网表拍平成一个巨大的 netlist,然后跑综合、布局、绕线。结果呢?跑了三天,工具崩了三次。后来我才明白,有些设计,你非得给它切几刀不可。

今天我们就来聊聊这两种设计范式——层次化设计(Hierarchical Design)和扁平化设计(Flat Design)。它们没有的好坏,但选错了,项目周期可能直接翻倍。

3.1 两种范式,到底在说什么?

先给个最直白的定义。

  • 扁平化设计:把整个芯片的所有标准单元、宏单元、IO pad,全部放在一个 level 里。没有子模块,没有边界,工具看到的就是一张巨大的、扁平的网表。
  • 层次化设计:把芯片按功能或物理区域切分成若干子模块。每个子模块独立做 P&R,最后在顶层做集成和连线。

你想想看,这就像做一顿大餐。扁平化就是你把所有食材倒进一口锅里,一次性炖熟;层次化就是你先分别炒好配菜,最后再拼盘上桌。哪个好?看情况。

核心区别一句话:扁平化让工具全局优化,层次化让人类分而治之。

3.2 扁平化设计:优点与痛点

扁平化设计最大的好处,就是没有边界约束。工具可以自由地跨模块移动单元、优化时序、调整面积。理论上,它能达到最好的 QoR(Quality of Results)。

我记得有一次做一个中小规模的 AI 加速器,大概五百万门。我用了扁平化流程,从综合到 signoff,整个周期只用了两周。时序收敛得非常漂亮,因为工具没有任何「墙」挡着它。

但扁平化的缺点也很明显:

  • 容量瓶颈:工具一次要处理整个设计。超过一千万门,内存占用和运行时间会指数级增长。
  • 调试困难:出了问题,你很难定位是哪个功能块的问题。因为所有单元都混在一起。
  • 增量迭代慢:改一个小模块,整个设计要重新跑一遍。

我曾经踩过的坑:一个两千万门的芯片,我坚持用扁平化。结果综合跑了 72 小时,布局布线直接 OOM(内存溢出)。最后不得不临时切回层次化,白白浪费了一周。所以,容量是硬门槛,别硬撑。

3.3 层次化设计:优点与痛点

层次化设计的核心优势,就是可管理性。

你可以把一个大芯片切成若干个子模块,每个模块几百到几百万门。团队可以并行工作:A 组做 CPU 核,B 组做 GPU 核,C 组做 IO 子系统。最后在顶层做集成。

这样做的好处:

  • 并行开发:多个模块同时做 P&R,项目周期大幅缩短。
  • 容量可控:每个模块的大小都在工具的能力范围内。
  • 增量修改:改一个模块,只需要重新跑那个模块,顶层只做 ECO。

但层次化也有代价:

  • 边界时序损失:模块之间的接口需要预留 timing margin,这通常会牺牲一些性能。
  • 顶层集成复杂:顶层绕线、电源规划、时钟树同步,都是麻烦事。
  • 管理开销:你需要定义接口约束、时序预算、物理边界,这些都需要额外的人力。

我的个人习惯:对于超过一千万门的设计,我默认走层次化。但我会在顶层留一个「扁平化试跑」的脚本,用来快速验证关键路径。说白了,层次化是管理手段,扁平化是优化手段,两者可以结合。

3.4 对比表格:一张图看懂差异

对比维度 扁平化设计 层次化设计
适用规模 ≤ 500 万门 ≥ 1000 万门
时序收敛 容易,全局优化 较难,边界有损耗
运行时间 单次长,但无集成步骤 单次短,但需多次迭代
内存占用 高,与门数成正比 低,每个模块独立
团队协作 困难,只能串行 容易,可并行
增量修改 全量重跑 局部重跑
调试难度 高,全局混杂 低,模块隔离
顶层风险 无 有,集成阶段可能出问题

3.5 如何选择?我的决策框架

这个问题没有标准答案,但我有一套自己的判断逻辑。你可以把它当成一个 checklist:

  1. 看规模:门数超过 1000 万?直接走层次化。低于 500 万?扁平化更省事。中间地带?看团队能力。
  2. 看团队:你只有一个人?扁平化可能更可控。你有 5 个以上后端工程师?层次化能发挥并行优势。
  3. 看频率:设计中有多个独立时钟域?层次化更容易管理时钟树。
  4. 看迭代次数:项目还在频繁改 RTL?层次化的增量修改优势巨大。
  5. 看工具:你的 EDA 工具对层次化支持好吗?有些老版本工具,层次化流程 bug 很多,我建议你提前做 POC。

我的经验法则:如果你不确定,先做一个小规模的层次化原型。跑通一个子模块的完整流程,评估一下边界时序损耗和集成工作量。这比直接拍脑袋决定要靠谱得多。

3.6 层次化 vs 扁平化:决策流程图

下面这张图是我自己项目里常用的决策流程。你可以把它贴在工位上。

层次化 vs 扁平化决策流程图 设计范式决策流程图 开始评估 设计规模是否 > 1000 万门? 是 否 团队人数 > 3 人? 是 否 RTL 迭代频繁? 是 否 层次化设计 扁平化设计 说明: • 规模是硬门槛:超过 1000 万门,工具容量和运行时间会急剧恶化。 • 团队和迭代是软因素:人少、迭代少,扁平化更高效;反之,层次化更灵活。 • 最终决策可以混合:顶层扁平化 + 关键模块层次化,也是一种常见策略。

3.7 混合策略:我常用的「中间路线」

说实话,现实项目里很少有人走极端。我大部分项目用的都是混合策略。

举个例子:一个 3000 万门的 SoC。我会把 CPU 核、GPU 核、NPU 这些大模块做成层次化子模块,每个模块独立 P&R。但顶层总线、IO 接口、时钟生成这些逻辑,我会留在顶层做扁平化处理。

这样做的好处是:

  • 大模块各自为政,互不干扰
  • 顶层逻辑简单,扁平化跑得快
  • 关键路径(比如跨模块的 data path)可以在顶层统一优化

一个小技巧:在层次化流程中,我会给每个子模块留 5%-10% 的时序裕量。这听起来很浪费,但实际做顶层集成时,这些裕量会救你一命。我曾经因为只留了 2% 的裕量,结果顶层绕线后时序全线飘红,最后不得不重新调整 floorplan,多花了三周。

3.8 避坑指南:我踩过的几个雷

  • 边界时序预算给太少:模块内部时序很好,但顶层一接就崩。原因就是边界时序预算不够。我建议至少留 200ps 的 margin。
  • 顶层电源规划被忽略:层次化设计里,每个子模块的电源网络在顶层可能对接不上。我吃过一次亏,模块内部 IR drop 没问题,但顶层电源环太细,导致模块供电不足。从那以后,我每次做层次化都会先跑顶层电源分析。
  • 接口约束不一致:模块 A 的输出 delay 和模块 B 的输入 delay 对不上。这种问题在扁平化里不存在,但在层次化里很常见。我的做法是:统一用一个脚本生成所有模块的接口约束,避免人工手写。

最后提醒一句:不管你选哪种范式,一定要在项目早期做一次完整的流程验证。别等到最后一个月才发现工具不支持你的层次化策略。嗯,我见过太多这样的悲剧了。