ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

数字IC后端层次化设计流程:从flat flow到hierarchical flow的工程实践

数字IC后端层次化设计流程:从flat flow到hierarchical flow的工程实践 数字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 flow2.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.2nstop走线预估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.3nstop就必须更新约束并重跑受影响区域的优化。所以top level的抽象模型也要跟着block版本及时更新这个工作很容易被低估却是hierarchical flow能否稳定推进的关键。3.3 资源消耗和并行度的直接对比用一个实际项目的数据来对比可能更有感知。同一个约8000万instance的设计项目flat flowhierarchical flow峰值内存250GB单block 30GBtop 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大概多少instanceblock的边界划在哪哪些逻辑必须放一起每个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功能边界必须同时考虑物理和实现约束。我一般按这个优先级来评估物理位置多个模块在floorplan上是否天然邻近邻近的尽量放一起连接密度参考pre-planning阶段的连接分析高连接密度逻辑尽量不切开时间预算跨block路径尽量少路径长度和级数尽量短时钟域一个block尽量覆盖一个或少量几个时钟域因为后续CTS在block内做时钟域太杂会大幅增加难度团队分工和人相关尽量让一个团队的代码落在一个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需要额外生成两种交付物给topabstract viewblock的物理抽象模型只包含pin位置、OBSobstruction区域、布线阻挡等物理信息不包含内部细节接口时序模型通常是ILMInterface Logic Model或ETMExtracted 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工具具备全局视野可以穿透所有cellhierarchical 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模型只在“对外接口有变化”时才重新生成内部优化几乎不更新abstractTop 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 tracktop走线绕过了某个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或者已经决定要拆但不知道第一刀切在哪里欢迎等下一篇应该能给到你一些可以直接上手的思路。
返回列表