核心定义
扇出指的是:一个逻辑单元的输出信号,直接驱动多少个其他逻辑单元的输入。
简单来说,就是'一个输出能带多少个负载(输入)'。
一个生动的比喻
你可以把一个逻辑单元(比如一个触发器的输出)想象成一个音响,而把它要驱动的其他逻辑单元的输入想象成耳机。
- 低扇出:就像这个音响只连接了 2-3 个耳机。每个耳机都能获得清晰、强劲的声音(信号),而且音响本身很轻松。
- 高扇出:就像这个音响通过一大堆分线器,同时连接了 500 个耳机。这时,每个耳机听到的声音都会变得非常微弱(信号变差),而且音响可能会因为负载过重而发热、失真甚至损坏。
在 FPGA 中,'声音微弱和失真'对应的就是信号延迟增加和信号波形变差(斜率下降)。
为什么扇出在 FPGA 中如此重要?
在 FPGA 中,逻辑单元之间的连接是通过可编程的布线资源实现的。高扇出会带来几个主要问题:
时序问题(最主要的问题)
增加布线延迟:一个信号要驱动很多负载,意味着它需要在 FPGA 芯片上走很长的线路,连接到各个分散的目标点。这大大增加了信号在布线上的传播时间。
导致建立时间/保持时间违例:这个增加的延迟可能会使信号无法在下一个时钟周期到来之前,稳定地传递到所有目标寄存器,从而导致时序违规,电路无法在指定频率下正常工作。
功耗问题
高扇出意味着一个信号需要切换(充放电)非常大的电容负载(所有负载输入电容和布线电容的总和)。根据公式
P = CV²f,动态功耗与电容C成正比,所以高扇出会显著增加功耗。拥塞问题
一个高扇出的信号会占用大量的布线资源,可能会导致 FPGA 局部区域布线资源紧张,从而影响布局布线工具的工作,甚至导致布线失败。
FPGA 与 ASIC 在扇出处理上的区别
这一点很重要:
在 ASIC 中:扇出是一个固定的电气特性。一个标准单元(如反相器)的驱动能力是有限的,其最大扇出数有严格限制,否则电路根本无法工作。
在 FPGA 中:扇出更多地是一个性能和资源问题。因为 FPGA 内部的布线资源是预先制造好的,它有足够的驱动能力来连接非常多的点(即扇出可以非常高,理论上可达数万)。问题不在于'能不能连',而在于'连了之后速度有多慢,功耗有多大'。
如何优化高扇出?
当设计出现高扇出网络时(综合或布局布线工具会给出警告),常用的优化方法有:
寄存器复制
这是最有效、最常用的方法。原理是:不使用一个寄存器驱动所有负载,而是复制多个相同的寄存器,每个寄存器驱动一部分负载。
例如:原来是一个寄存器驱动 500 个负载。现在可以复制成 5 个相同的寄存器,每个寄存器只驱动 100 个负载。这样,每个寄存器的扇出从 500 降到了 100,时序和负载能力都得到了极大改善。
使用全局时钟网络
对于像时钟信号这种天然就是极高扇出(几乎驱动所有触发器)的信号,FPGA 提供了专用的低偏移、高驱动能力的全局时钟网络。你必须通过实例化时钟缓冲器(如 BUFG)来使用这个网络,而不能使用普通布线。
优化代码结构
在编写 HDL 代码时,避免产生巨大的控制信号。例如,一个使能信号
en控制一个非常大的模块,就容易产生高扇出。可以考虑分层、分模块地生成使能信号。依靠工具的自动优化
现代 FPGA 综合和实现工具(如 Vivado, Quartus)都具备自动寄存器复制的功能。你可以在工具设置中打开相关选项,工具会尝试在满足时序的前提下自动进行优化。


