3、拥塞的电路根源:高扇出网络、多bit总线聚集、时钟网络局部集中
各位工程师朋友,咱们接着聊拥塞。上一节我们看了物理层面的表现,这一节我带你挖一挖电路设计本身的问题。说白了,很多拥塞不是工具笨,是你写代码的时候埋下的雷。
我个人习惯,拿到一个拥塞严重的模块,第一件事不是看布局,而是打开网表,查三类东西:高扇出网络、多bit总线、时钟网络。这三样东西,是拥塞的三大“元凶”。
3.1 高扇出网络:一根线带太多负载
什么叫高扇出?就是一根信号线,后面接了成百上千个负载。比如全局复位信号、扫描使能信号、一些控制信号。你想想看,一根线要驱动几百个标准单元,每个单元都要从这根线上拉电流。结果是什么?
- 驱动强度不够:工具会自动插入多级缓冲器(Buffer)来增强驱动。这些Buffer会占用大量绕线资源。
- 绕线资源被挤占:一根高扇出网络,往往需要走很宽的金属线,或者走多个分支。这些线把通道堵死了,其他信号就过不去。
- 动态功耗飙升:高扇出网络翻转时,大量负载同时充放电,局部电流密度大,IR Drop也跟着来。
避坑指南:我曾经接手一个项目,后端跑完布局后,发现某个区域拥塞到爆。查了半天,是一个全局复位信号扇出了8000多个负载。工具自动插了200多个Buffer,把那一块绕线层全占满了。后来我手动做了复位树综合,把扇出降到每级200以内,拥塞立刻缓解。
怎么处理?我建议你在综合阶段就做扇出约束。比如设置 set_max_fanout 32,让工具提前插入Buffer树。或者在后端用 clock_opt -high_fanout_net 这类命令专门处理。
# 综合阶段约束高扇出网络
set_max_fanout 32 [current_design]
# 后端处理高扇出网络
create_buffer_tree -net reset_n -max_fanout 32 -buffer_list {BUFX8 BUFX16}
3.2 多bit总线聚集:一群信号挤在一起
多bit总线,比如数据总线、地址总线,动辄64位、128位甚至更宽。这些总线在布局时,如果所有bit都挤在同一个区域,那绕线资源就是灾难性的。
为什么会这样?因为总线信号往往需要走相同的路径,从发送端到接收端。如果发送端和接收端距离很近,那还好。但如果它们分布在芯片两端,总线就要穿过整个芯片。你想想看,128根线并排走,每根线还要保持等长、控制串扰,这得占多少绕线通道?
| 总线宽度 | 绕线层需求 | 拥塞风险 |
|---|---|---|
| 32位 | 2-3层 | 低 |
| 64位 | 3-4层 | 中 |
| 128位 | 4-6层 | 高 |
| 256位及以上 | 6层以上 | 极高 |
我在项目中遇到过最夸张的一次,是一个256位的AXI总线,所有bit的发送端集中在同一个宏单元附近。布局时,工具把256个发送寄存器堆在一起,结果那一块绕线资源直接爆掉,绕线完成率只有60%。
怎么破?我建议做总线分散布局。把总线的不同bit分散到不同区域,或者用 set_bus_spreading 这类命令让工具自动分散。另外,如果总线宽度太大,考虑用SerDes或者分时复用,减少物理连线数量。
小技巧:对于超宽总线,可以在综合阶段插入寄存器切片(Register Slice),把长总线打断成多段。这样每段的负载和绕线长度都变小,拥塞自然缓解。
3.3 时钟网络局部集中:时钟树扎堆
时钟网络,说白了就是芯片的“心跳”。但心跳太强,也会出问题。时钟树综合(CTS)时,工具会在时钟源附近插入大量时钟Buffer,形成一棵巨大的树。如果这棵树的所有分支都集中在某个区域,那这个区域的绕线资源就会被时钟Buffer和时钟线占满。
我记得有一次,一个模块的时钟频率是1GHz,时钟树用了3000多个Buffer。这些Buffer全部集中在模块的左上角,因为时钟源在那里。结果左上角的绕线密度达到95%,其他信号根本走不过去。
时钟网络局部集中,通常有几种表现:
- 时钟Buffer聚集:大量Buffer堆在时钟源附近,形成“Buffer岛”。
- 时钟线拥挤:时钟树的分支线为了等长,绕来绕去,占满绕线层。
- 时钟屏蔽线:为了抗干扰,时钟线旁边要加屏蔽地线,进一步占用资源。
注意:时钟网络拥塞最麻烦的地方在于,你不能随便动它。时钟树的skew、latency、功耗都是严格约束的。我曾经试过强行把时钟Buffer分散,结果skew从50ps飙到200ps,时序直接崩了。
怎么处理?我建议从源头入手:
- 时钟源位置优化:把时钟源放在模块中心,而不是角落,让时钟树均匀分布。
- 时钟树层级控制:用
set_clock_tree_options -max_levels 8限制时钟树深度,避免Buffer过多。 - 时钟网格(Clock Mesh):对于高频设计,用时钟网格代替时钟树,减少Buffer数量。
- 时钟门控:在不需要时钟的区域插入门控,减少时钟Buffer的负载。
# 时钟树约束示例
set_clock_tree_options -max_levels 8 -max_fanout 64
set_clock_tree_exceptions -dont_buffer_leaf_pins [get_pins -hier *clk_gate*]
3.4 三者叠加:拥塞的“完美风暴”
实际项目中,高扇出网络、多bit总线、时钟网络往往同时出现。比如一个高性能CPU核心,既有高扇出的控制信号,又有128位的数据总线,还有1GHz的时钟树。这三样东西挤在一起,就是拥塞的“完美风暴”。
我做过一个AI加速器芯片,就是这种情况。控制逻辑、数据通路、时钟树全部集中在核心区域。布局后,那一块的绕线密度达到98%,工具绕了三天三夜都没绕通。后来我们花了整整两周,手动调整布局、分散总线、优化时钟树,才把拥塞降下来。
核心思路:遇到拥塞,先查电路根源。不要一上来就调布局、改绕线策略。先看看是不是高扇出、总线聚集、时钟集中这三个问题。把电路层面的问题解决了,物理层面的问题往往迎刃而解。
下面这张图,是我总结的拥塞电路根源分析流程,你可以参考一下:
嗯,总结一下。高扇出网络、多bit总线、时钟网络,这三样是拥塞的电路根源。遇到拥塞,先别急着调工具参数,打开网表看看这三类信号。把电路层面的问题解决了,物理实现才会顺利。
可可精品资料库