☰
数字IC后端层次化设计流程:从flat flow到hierarchical flow的工程实践
2026/10/5 4:38:13 网站建设 项目流程

数字IC后端跑过的项目一多,就会意识到一个问题:规模一旦上去,平整化流程(flat flow)就跑不动了。我指的是物理上那种“跑不动”,综合几个小时、布局布线一个循环三五天、时序收敛反复折腾好几轮,整个项目卡在迭代里出不来。这时候就得把设计拆开,分而治之,这就是hierarchical flow(层次化设计实现流程)存在的意义。

这一篇是这个系列的第一篇,先把最核心的东西讲透:hierarchical flow是什么、解决什么问题、和flat flow比到底差在哪、整个流程怎么搭。后面几篇会再深入partition切分细节、pin assignment策略、abstract模型生成、block级收敛与top级集成这些实操话题。

适合谁看?刚接触后端实现、对hierarchical flow只有概念没有全貌的工程师,以及正在纠结“我的项目要不要拆 hierarchical”的从业者。看完你至少能判断自己的项目该不该走这条线,走的话第一步该做什么。

1. hierarchical flow到底是什么

1.1 一个不算严谨但很好懂的定义

所谓hierarchical flow,就是在一个大规模芯片的后端实现过程中,不把整个设计当成一个整体去跑place和route,而是先把设计按功能或物理边界切成若干个子模块(block),每个子模块像一个小芯片一样独立完成从综合后网表到布局布线、时序收敛的全过程,最后再把所有已经实现好的子模块在一个top level(顶层)里拼装、绕线、收敛。

这个过程听起来像“先单独装修每个房间,再把房间拼成整栋楼”,实际上后端做的事情也确实如此。

但要注意,hierarchical flow不是简单的“并行跑几个block”。它真正的技术难点在于三个地方:

  • 怎么切分:哪些逻辑放一起、切多大、端口怎么定义。
  • 怎么约束:top和block之间时钟、时序budget怎么分配,接口时序怎么对齐。
  • 怎么集成:block出什么样的abstract模型、顶层用什么方式绕线和连接,最终时序怎么收敛。

这三件事贯穿整个flow的始终,任何一个环节没想清楚,后面都会炸。

1.2 它是怎么在一颗大芯片里工作的

拿一颗典型的大型SoC来说,芯片里可能有CPU簇、GPU、NPU、各种高速接口IP、内存控制器、大量模拟前端和数字后端模块。如果整个芯片用flat flow来跑,首先memory instance数量可能就有几千上万个,标准单元数量奔着几千万甚至上亿去。这个规模下,就算机器内存够,一次placement的runtime可能就要好几周,而且未必能收敛。

hierarchical flow的做法是把芯片按模块边界切出来。切分依据通常是:

  • 已有的IP或子系统的物理边界;
  • 时钟域划分(一个block尽量落在单一或少数时钟域);
  • 团队分工边界(多人或小组并行负责不同block)。

每个block单独做floorplan、摆放、时钟树综合、布线、时序收敛,然后生成一个简化版的“抽象视图”(abstract view)交给top。top只负责把各个block拼接起来,处理block之间的连线、I/O pad逻辑和顶层时钟网络。

这样做的好处很直接:block之间天然并行,整个设计从“一次处理整颗芯片”变成“多个小项目同时推进+一个相对轻量的top集成”,时间和机器压力都大幅下降。

1.3 系列文章会覆盖什么范围

既然标了“系列(一)”,我得先把定位说清楚。这一篇重点在概念建立和全流程打底,包括:

  • 什么情况下必须用hierarchical flow;
  • 它和flat flow的本质区别在哪里;
  • 完整流程从planning到top integration的骨架;
  • 每个关键环节的输入输出是什么,怎么串起来。

后面的系列会依次展开partition怎么做、pin assignment和budget怎么切、abstract view怎么生成和验证、block内部要不要保留hierarchical结构、top集成时用何种routing模式,以及时序不收敛时在hierarchical flow里怎么定位和解决。每篇都能单独看,但串起来才是完整的方法论。

2. 什么情况下必须用hierarchical flow

2.1 设计规模已经超出了工具和平行的极限

这是最直接、最刚性的驱动因素。数字后端工具在place和route阶段需要把整个设计加载进内存,综合后的网表规模直接决定内存和runtime。

我举一个实际感受过的例子:一个大约1.2亿instance级别的AI加速芯片,纯flat跑placement阶段,内存峰值大概要到500GB以上,单次placement运行时间超过12天。这还只是placement,后面CTS、routing、时序优化每一步都是这个级别的开销。整个流程跑完一轮可能要一个月。而项目组根本不可能接受一个月才看到一版结果。

换成hierarchical flow之后,把设计切成9个block,每个block大概1300万instance,单block的placement只需要1到2天,top level因为只处理block抽象模型和少量顶层逻辑,整个集成流程也能控制在几天内。更重要的是,9个block可以同时跑在同一台机器或集群上,时间从“串行的几十天”变成“并行的两三天”。

所以很多人问“到底多少规模才需要拆hierarchical”,业内没有一个绝对的数字,但我的经验是:标准单元加宏单元总数超过3000万到5000万级别,或者单个设计后端实现一轮周期超过一个半星期的时候,就值得认真评估hierarchical flow了。这个阈值也跟机器配置、工具版本、是否有cluster环境有关系,不是死的。

2.2 多团队并行开发的协作需求

规模只是一个维度,团队协作是另一个更微妙的维度。

一颗大芯片通常由多个设计团队共同完成,每个团队负责一个或几个功能模块。如果整体用flat flow,所有团队的工作成果必须全部集成到一个统一的网表里才能跑实现,这意味着:

  • 任何团队一块代码延迟交付,其他人全部阻塞;
  • 任何一个模块修改,全芯片的重新实现代价巨大;
  • 团队成员之间互相影响,排错和定位问题极其痛苦。

hierarchical flow天然适配这种多人协作模式。每个block可以由独立团队独立推进,只要block之间定义好接口、budget和交付格式,大家各干各的,最后在top统一集成。

实际项目中,很多设计团队甚至是在不同国家、不同时区并行工作,hierarchical flow让这种协作成为可能。接口协议和抽象模型是唯一的“语言”,只要两边说得通,物理上在哪台机器上跑都无所谓。

2.3 混合信号芯片和大型IP集成的特殊需求

还有一类设计,即使规模不算特别大,也不得不走hierarchical:混合信号(mixed-signal)芯片。

这类芯片里通常包含模拟前端、PLL、ADC/DAC、RF前端等模拟模块,这些模块有自己的版图,需要被当作hard macro放进数字后端流程。如果整个芯片跑flat,每个模拟模块都要被当成特殊的macro处理,宏多了以后placement、routing的复杂度会急剧上升,而且模拟模块之间的相对位置、屏蔽要求、噪声隔离都是全局约束,flat flow很难处理干净。

把数字部分切成若干blocks、把模拟部分作为corner block或者特殊约束的hard macro,放在top level固定好位置,数字blocks只和它们通过固定pin连接,整个实现的确定性就高多了。这类设计在FMCW雷达芯片、SerDes收发机、生物电信号处理芯片里都很常见。

3. 与flat flow的对比:核心差异和取舍逻辑

3.1 时序收敛方式的根本不同

flat flow的时序收敛思路是“全局最优”。工具把所有路径放在一起考虑,你有完整的时钟树信息、完整的物理信息,工具可以通过调整cell位置、插入buffer、改变net topology来优化任意一条路径。所有路径都在一个统一的时序预算下工作。

hierarchical flow则完全不同。每个block内部的时序在block阶段收敛,但block的输入输出路径分成三段:

  • 源block内部路径;
  • top level走线路径;
  • 目的block内部路径。

这三段分别在不同时间、不同工具下收敛,中间靠“budget”(时序预算)来串联。也就是说,block在收敛自己内部时序时,必须给top level的走线预留足够的时间裕量;top在集成时必须使用block给出的接口时序约束,确保跨block路径在三个区域都能满足。

这里面最大的坑是budget分配不合理。比如一个跨block路径总共需要3ns的周期,源block内部逻辑已经用了1.2ns,top走线预估0.6ns,那目的block内部就只能用1.2ns。如果block实现后发现内部路径需要1.5ns,那整条路径在top集成后必然violation。所以hierarchical flow里,每个block的时序目标不是“自己舒服”,而是“严格按预算来”,内部越紧,后面越安全。

3.2 物理实现的迭代模式差异

flat flow的迭代模式是“全局小步走”——每次改动栅极级别的微小位置,反复调整直到满足约束。好处是每一步都能看到全局结果,坏处是设计一大,每一步都要带动全局算一遍。

hierarchical flow的迭代模式更接近“局部大步走+全局周期性整合”。block内部可以快速反复迭代place和route,因为范围小、路径少、工具反应快。top level则不需要频繁重跑,只要block的abstract model和时序budget不变,top可以不关心block内部每次微调。

但要注意,这里的“不变”是理想状态。实际项目中block接口时序经常会变,比如某条输出路径延迟从2ns变成2.3ns,top就必须更新约束并重跑受影响区域的优化。所以top level的抽象模型也要跟着block版本及时更新,这个工作很容易被低估,却是hierarchical flow能否稳定推进的关键。

3.3 资源消耗和并行度的直接对比

用一个实际项目的数据来对比可能更有感知。同一个约8000万instance的设计:

项目flat flowhierarchical flow
峰值内存250GB+单block 30GB,top 50GB
单轮完整runtime14~20天block并行4~6天+top集成2~3天
收敛迭代周期3周以上1周以内
需要机器配置大型内存服务器普通服务器集群

数据虽然不是绝对精确,但趋势非常明确。hierarchical flow用多一些流程管理复杂度,换来了数量级的资源消耗下降和迭代速度提升。对于大项目来说,这笔账怎么算都是划算的。

当然,hierarchical flow也有代价。最明显的是“看不到全局”——block阶段做的时序优化、congestion优化都只基于局部信息,某些在flat flow里可以提前预判的风险,在hierarchical里往往到top集成阶段才会暴露出来。这也解释了为什么hierarchical flow对前期planning的质量要求远高于flat flow。

4. 核心流程拆解:从partition到top集成

4.1 第一步:Pre-planning,想清楚再动手

hierarchical flow开始前有一个极其重要的阶段叫pre-planning。这个阶段的输入是综合后的门级网表、约束文件、库文件和芯片的整体floorplan思路,输出则是一份详细的partition方案和设计实现计划。

这个阶段要回答的关键问题包括:

  • 要切几个block?每个block大概多少instance?
  • block的边界划在哪?哪些逻辑必须放一起?
  • 每个block用的时钟域是什么,跨时钟域(CDC)路径怎么处理?
  • block的三星(电源规划)怎么跟top衔接?
  • 哪些block需要额外做IP级别的特殊处理(比如hard macro隔离、模拟IP屏蔽)?

很多刚上手hierarchical flow的团队容易在这个阶段偷懒,觉得差不多能分开就行。结果后面发现某个block里时钟树复杂度爆炸,或者两个block之间的连接密度过高导致top routing严重拥塞,这种问题在pre-planning阶段是可以通过合理的partition优化避免的。

我自己的习惯是,在做正式partition之前,先会用工具里的一些快速分析功能(比如connectivity分析、拥塞预估)把整个设计跑一遍quick global route,找到连接密度最高的区域,再决定要不要把这些区域内部化到同一个block里。连接密度高的地方被切开,基本等于给自己挖坑。

4.2 第二步:partition切分和budget分配

partition是hierarchical flow的地基,也是最考验经验的一步。

切分的基本单位是hierarchy,也就是RTL代码模块层次。但切分的时候不能只看RTL功能边界,必须同时考虑物理和实现约束。我一般按这个优先级来评估:

  1. 物理位置:多个模块在floorplan上是否天然邻近,邻近的尽量放一起;
  2. 连接密度:参考pre-planning阶段的连接分析,高连接密度逻辑尽量不切开;
  3. 时间预算:跨block路径尽量少,路径长度和级数尽量短;
  4. 时钟域:一个block尽量覆盖一个或少量几个时钟域,因为后续CTS在block内做,时钟域太杂会大幅增加难度;
  5. 团队分工:和人相关,尽量让一个团队的代码落在一个block里,避免跨团队改接口。

切完partition之后,紧接着就是budget分配。这一步的目标是给每个block定义输入输出路径的时序约束。

我实际用的方法是:

  • 先做一版全芯片的quick timing analysis(可以用逻辑综合后的网表做,也可以先做一个近似floorplan的快速布局);
  • 提取所有跨block路径的时序信息,得到每条路径的总延迟和各个block的贡献占比;
  • 按贡献占比和物理距离给每个block分配时序预算;
  • 预算+buffer delay和clock skew预留,得到每个block接口路径的input/output delay约束;
  • 生成每个block的独立约束文件。

Budget分配没有统一公式,但有一个原则可以参考:总共3ns的周期,如果你发现跨block路径源端逻辑已经用了1.5ns,目的端还要0.9ns,那留给top走线和skew的只有0.6ns,这通常已经非常紧了。这时候要么调整partition让路径不跨越block,要么在顶层加一级寄存器重新切path,要么增加pipeline。我见过太多项目因为省着几个周期不愿意加pipeline,结果整个后端多走了三轮迭代。

所以,budget分配阶段如果发现某条关键路径的预算已经紧张到不合理,不要硬扛,往回看partition方案是不是该调整。这个来回在项目初期做非常便宜,越往后越贵。

4.3 第三步:Block实现和abstract model生成

Partition和budget确定之后,所有block就可以并行推进实现了。

每个block内部的流程和flat flow基本一致:读入自己的网表和约束、做floorplan、摆放、时钟树综合、布线、时序收敛、物理验证。唯一的不同是,block需要额外生成两种交付物给top:

  • abstract view:block的物理抽象模型,只包含pin位置、OBS(obstruction)区域、布线阻挡等物理信息,不包含内部细节;
  • 接口时序模型:通常是ILM(Interface Logic Model)或ETM(Extracted Timing Model),描述block外部接口路径的时序行为。

这两个交付物是整个hierarchical flow的灵魂。top level不需要知道block内部长什么样,只需要知道“在顶层这个位置有个模块,pin在这个位置,外部路径的时序特性是这样的”,就能完成整个顶层的实现。

生成abstract model的时候有一个经常被忽略的细节:pin的物理位置和金属层设置。如果block的pin拍在M3,但block内部已经把这个区域全占满了,top的走线就只能绕行,会造成congestion。所以block实现时,pin assignment要在block的详细布线阶段同步验证,确保pin周围有足够的布线资源给top使用。

4.4 第四步:Top集成和最终收敛

Block全部完成或者大部分完成后,top level集成就会启动。这个阶段要做的事情包括:

  • 读入所有block的abstract view和时序模型;
  • 读入top level自己的网表和约束(主要由IO pad、block实例、顶层逻辑组成);
  • 在top floorplan里摆放各个block的物理位置;
  • 处理top level时钟网络(通常是给每个block的时钟pin做clock mesh或clock tree);
  • 绕top level信号线;
  • 时序收敛验证。

Top level的routing策略通常是hierarchical routing或者区域routing,工具只会对有信号的区域进行优化,而不会穿透block内部。这一点和flat flow有本质区别:flat flow工具具备全局视野,可以穿透所有cell;hierarchical flow的top只能看到abstract的边界。

所以top集成阶段最常出现的问题就是:跨block路径在top阶段时序变差。原因通常是:

  • top走线延迟预估偏低;
  • block接口时序模型过度乐观;
  • 顶层时钟偏斜没控制好;
  • 顶层绕线时没有足够空间加buffer。

这些问题最终的解决手段无非几种:调整top floorplan、优化budget分配、要求某个block重新调节内部时序、加顶层寄存器。真正到了这一步,任何大的改动代价都是巨大的,所以再次强调前期planning的重要性。

我在top集成时有一个习惯:在所有block中选一个代表模块,等它一版abstract稳定下来之后,先把top的完整流程空跑一遍。这样能提前暴露顶层floorplan的问题、走线资源的问题、时钟网络设计的问题,而不用等所有block都完成才开始。这个“早期top验证”的做法能帮大项目省下至少两周时间。

4.5 补充分享:block和top的版本管理

hierarchical flow项目里,block的版本和top的版本之间是强关联的。Block每次更新abstract模型和时序模型,top都需要重新评估受影响区域。

我们实际使用的策略是:

  • Block的abstract模型只在“对外接口有变化”时才重新生成,内部优化几乎不更新abstract;
  • Top level只在关键里程碑点(比如tapeout前每两周)统一更新所有block的模型;
  • 每个block维护独立的版本号,top的run目录里记录使用的block版本组合;
  • 每次top跑完整流程后,对跨block路径做一次diff,与上一次结果对比,偏差超过阈值就要检查是哪个block的模型变化导致。

这套版本管理虽然听起来繁琐,但如果没有它,出了问题你根本不知道是哪个block的改动导致的top路径恶化。尤其是团队分散的情况下,这个问题会被放大很多倍。

5. 常见问题与排查技巧实录

5.1 问题一:partition之后发现某个block拥塞严重

现象:某block内部std cell density明明不高,routing时却出现大量short和detour,整体congestion报告非常难看。

排查:这种情况大概率是partition的物理边界不合理。典型场景:两个功能模块在RTL层级上是分开的,但它们在物理位置上交叉咬合,强行按RTL边界切开后,连接路径在block边缘大量汇聚,形成局部拥塞。

解法:回到pre-planning阶段,检查block的RTL边界是否和物理连接密度匹配。常见优化手段是允许在block内跨RTL边界做局部逻辑合并,或者在边界附近加一些“软边界”,让工具可以把少量逻辑跨边界移动。这种逻辑搬移在hierarchical flow里通常通过逻辑partition工具自动完成,但需要人工设定允许程度和范围。

5.2 问题二:top level绕线后跨block路径延迟暴涨

现象:top集成后,某条跨block路径比预算消费的延迟大了0.5ns以上,直接导致setup violation。

排查:先把路径拆开看三段的实际延迟。通常是top走线延迟远超预估,原因可能是:

  • top floorplan上两个block摆得太远;
  • 顶层该走的line没有预留足够的routing track;
  • top走线绕过了某个block的OBS区域,路径物理长度翻倍。

解法:对症下药。太远就调整floorplan;布线资源不够就调整block pin位置和方向,减少某一边的pin密度;绕线严重就检查block的OBS设置是否太保守,有没有可能放出一些低层金属区域给top走线。

我在一个项目里遇到的情况是:某个block的OBS把整个M5层都禁掉了,而top恰好需要横向穿过多条M5信号,结果所有走线只能去挤M6和M7,顶层直接拥塞。最后让block方重新梳理OBS,只禁掉内部真正使用的区域,问题立刻缓解。

5.3 问题三:block内部时序收敛了,但top集成后整体时序变差

现象:每个block单独检查时都满足时序约束,但放到top里跑一遍完整时序分析,发现很多路径出现新violation,而且分布没有明显规律。

排查:这类问题通常是接口时序模型和真实拓扑不一致导致的。Block内部时序分析时看的是理想接口模型,top集成时看到的是真实负载、真实走线,两者之间如果有偏差,violation就会出现。

解法:

  • 先检查block的接口时序模型是否用了过紧或过松的budget,过松会让block内部实现时低估最终负载,过紧则会浪费block性能;
  • 再看block的时钟pin的latency模型设置是否合理,top集成的时钟树和block内部CTS假设是否一致;
  • 最后看block输出的驱动能力是否足够,某些低驱动强度的cell到了真实负载下延迟暴涨。

这个问题的本质是“接口模型准确度”问题。在hierarchical flow里,接口模型越保守,top集成越安全,但block内部就越难收敛;接口模型越乐观,block越好做,但top集成风险越高。找到一个合理的平衡,是这个flow里最考验功力的事情之一。

我的做法是:在top集成的早期阶段就把真实负载反馈给block。具体方式是,top跑完routing后,提取所有跨block接口的实际net capacitance和transition时间,回注到block的接口约束里再做一次signoff检查。这样能提前发现接口模型偏差,而不是等到最后全芯片验证时才暴露。

5.4 问题四:多个block并行推进,但节奏不齐导致top阻塞

现象:project计划里top集成在某个时间点启动,但总有一两个block因为各种原因没完成abstract生成,top被迫等待。

排查:这更多是项目管理问题,但从技术上也有些手段可以缓解。

解法:

  • 对block按风险等级分类,高风险block优先启动、优先交付abstract;
  • 对没有final abstract的block,先用上一个版本的abstract或一个早期简化模型占位,top先跑主流程,等block版本更新后再局部重跑受影响区域;
  • 将top集成流程分成多个阶段,比如先做floorplan验证、再做时钟分析、最后做详细routing,确保每个阶段不因为个别block缺失而完全卡死。

从实际操作角度说,早期的placeholder模型和最终模型之间误差不能太大,否则前期做的top布局可能白做。所以placeholder模型不是随便拉一个方块,它至少需要包含正确的pin位置、大致正确的OBS范围和合理的接口时序——这些信息在block早期和block owner沟通后就能拿到。

5.5 常见问题速查表

现象可能原因排查优先级常见解法
Block内部拥塞严重Partition边界和物理连接密度不匹配高调整partition边界、允许局部逻辑搬移
Top走线延迟大涨Floorplan位置差、OBS过严、布线资源不足高调整floorplan、精简OBS、均衡pin分布
Top集成后新violation接口时序模型不准确高反馈真实负载给block、重新生成abstract模型
Block之间时序budget频繁变化Budget分配时预留不足中早期多做全局时序分析、预留更多top余量
Abstract模型和block实际不一致Block内部修改后未同步更新模型中建立版本管理机制、强制abstract版本对照表
Top时序收敛但物理验证失败Top走线间距问题、block边界DRC冲突中提前做block边界和顶层DRC检查、统一定义边界禁区

这张表覆盖了hierarchical flow里我遇到过的绝大多数典型问题。排查的顺序通常是从最快确认的问题开始,因为跨环节问题往往涉及多个owner,先把单点原因排除掉,才能定位到最后的多方交叉问题。

6. 最后一个实用心得

回头看这个flow,我最想多说一句的是:hierarchical flow真正的技术难点几乎都不在工具操作上,而是在前期决策和接口管理上。partition怎么切、budget怎么分配、abstract怎么生成、block和top之间怎么协同——这些想得越清楚,后面的实现就越顺。

我在前面提到的“早期做一版top验证”这个方法,几乎在每一个大项目里都帮我们提前暴露了风险。哪怕所有block都还只有一个粗略的floorplan信息,也值得先把top流程空跑一遍。这一步能让你在项目早期就知道:顶层clock mesh合不合理、block之间走线够不够用、floorplan需不需要调整。等到所有block都完成再发现问题,代价已经完全不同。

下一篇文章会专门展开partition切分的具体方法,包括逻辑和物理边界的匹配策略、如何分析跨模块连接矩阵、以及几种典型切分场景的对比。如果你正在纠结自己的项目该不该拆hierarchical,或者已经决定要拆但不知道第一刀切在哪里,欢迎等下一篇,应该能给到你一些可以直接上手的思路。

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

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

立即咨询