优化扇出

Note:文章内容以 Xilinx 系列 FPGA 进行讲解

1、生成扇出报告

高扇出网线会增加布局布线 的压力,很容易导致时序为例。这是因为在布局时过高的扇出使得工具很难将扇出的驱动(源端)与所有的负载(目的端)放置得比较紧凑,从而使有些负载距离驱动比较远,导致线延迟比较大。

那么多高的扇出才算高扇出呢?对于7系列FPGA而言,可根据下表进行判断:

这是一个指导性的标准 ,在实际工程中需要灵活运用。而对于UltraScale/UltraScale+ FPGA 而言,并没有给出这样的标准,而是需要根据时序进行判断。可能会出现扇出位十几或几十的情况,只要其成为时序违例的主要因素,就可尝试从降低扇出的角度优化时序。

Vivado提供了一个非常好用的命令report_high_fanout_nets ,用于生成高扇出网线报告。该命令有很多选项,以下是几个主要的选项:

需要注意的是,-load_types-clock_regions-slr两两互斥的,只可以使用其中的一个选项。在设计开发中,对综合后的设计就要开始进行扇出分析,以尽早发现高扇出的网线,并评估其可能对涉及造成的影响。

report_high_fanout_nets命令具体用法如下图所示:

如果使用**-load_types选项**,相应的Tcl命令如下图所示:

使用该选项生成的报告样例如下图所示:

从此报告中可以看到rectify_reset的扇出位10239,是由触发器驱动 的(对应Driver Type 列),其负载由两部分构成:

① 触发器的复位/置位(对应Set/Reset Slice 列)

② BRAM/DSP/OTHER的复位/置位(对应Set/Reset BRAM/DSP/OTHER 列)。

如果需要进一步获取网线rectify_reset的所有负载 以便分析,可以先在上图报告选中该网线,然后再执行如下的Tcl命令:


如果使用**-timing选项**,相应的Tcl命令如下图所示:

使用该选项生成的报告如下图所示:

该选项生成的报告相比-load_types选项,增加Worst Slack (ns)和Worst Delay (ns)两个信息,这有助于判断该网线是否对时序收敛构成威胁。如果需要查看穿过报告中某个网线的时序路径的时序信息,如这里的usbEngine 1/u1/u3/O3,可先在此报告中选中该网线,再执行下述Tcl命令,即可生成对应的时序报告:

从报告中可以看到,Slack为3.998、Net Delay为5.562,与前面生成的报告数据是吻合的。

综合后 的设计进行扇出分析时,在扇出报告里要特别关注由LUT驱动高扇出网线 ,尽管Vivado也会对LUT进行复制以降低扇出,但是毕竟FPGA芯片中LUT的个数远远小于 FF的个数,且这种复制很难对时序有显著改善。因此,一旦在此阶段发现LUT驱动的网线扇出较高,就应从代码层面看是否可以将其修改为由触发器驱动


2、降低扇出的几种方法

方法一:利用设计流程降低扇出

Vivado提供了不同粒度的扇出优化。

opt_design阶段,可以通过添加选项-hier_fanout_limit 来降低扇出。对于每个层次内 的高扇出网线,如果其扇出大于 -hier_fanout_limit指定值 ,那么工具就会对该网线的驱动进行复制 ,并将复制版本的驱动放置在该网线所在的层级内。显然,这是一种模块级的粗粒度的优化方法。同时,在opt_design阶段,对于扇出大于25000 的网线,如果设计中仍然有未用的全局时钟缓冲器(如BUFG),那么工具会根据时序需求自动将该网线通过BUFG引入全局时钟网络。
布局(place_design)阶段,对于扇出大于1000 且建立时间裕量小于2.0 的网线,如果该网线由寄存器驱动 ,那么工具会自动对寄存器进行复制,以降低扇出。对于扇出大于10000的网线,如果设计中仍有未用的全局时钟缓冲器(如BUFG),那么工具也会自动将其通过BUFG引入全局时钟网络。
在布局后的物理优化(phys_opt_design)阶段,工具会根据时序裕量布局信息 自动对高扇出网线的驱动进行复制,通常会对时序有较大改善。这里需要注意 的是确保设计中的高扇出网线是由寄存器驱动的 ,这样便于工具复制和重新布局。在某些情况下,工具并不会对所有关键的高扇出网线的驱动进行复制 ,此时可以尝试将phys_opt_desig n的**-directive** 值修改为ExploreAggressiveExploreAggressiveFanoutOpt

如果在布线阶段发现某些网线因为扇出较高而成为时序收敛的瓶颈,那么可将该网线标注 ,在布线之前执行如下Tcl命令:

选项**-force_replication_on_nets** 后跟的是高扇出网线的名称。

Vivado Project模式下,可将该脚本存储在一个.tcl文件中,并在如下图所示的界面方框任选一个浏览到该文件即可:

Vivado Non-Project模式下,则可以将其放置在route_design 命令之前,Tcl代码如下图所示:

对于IP中 的高扇出网线,因为IP通常源代码不可见及IP本身的加密特性,所以采用phys_opt_design 的选项**-force_replication_on_nets**将非常有效。

方法二:利用约束降低扇出

综合阶段 ,Vivado提供了综合属性MAX_FANOUT ,该属性可指导Vivado在综合 时对指定网线的驱动进行复制,但要求驱动触发器查找表。可以在RTL代码中使用该属性:

(* max_fanout=<number> *) wire signal;

也可以在XDC约束文件中使用,Tcl命令如下所示:

set_property MAX_FANOUT number [get_cells cellA]

set_property MAX_FANOUT number [get_netsnetB]

MAX_FANOUT的施加对象可以是get_cells 获取的单元,也可以是get_nets获取的网线。从工程实践的角度而言,建议采用上述Tcl命令的方式进行约束。因为这样不仅避免了对RTL代码的"污染",而且更为精确。

不过建议仅对局部扇出相对较低 的信号施加MAX_FANOUT属性,避免全局高扇出 网线(如全局复位信号)使用MAX_FANOUT,否则会导致大量的寄存器复制,同时会增加控制集。同时在使用MAX_FANOUT时,要注意其施加对象的驱动负载 是否在同一层次 内,同时要注意综合设置选项**-flatten_hierarchy**的值,有些场合,其值会导致MAX_FANOUT无法生效,如下图所示:

除了-flatten_hierarchy会导致MAX_FANOUT无法生效,还有一些MAX_FANOUT的无效场景,如下表所示:

布局阶段 ,属性FORCE_MAX_FANOUT 限制指定网线扇出的最大值 ,该属性通常结合另一个属性MAX_FANOUT_MODE 使用。MAX_FANOUT_MODE用于限定 降低扇出的方式 ,其取 值包括CLOCK_REGIONSLRMACRO(指BRAM、UltraRAM和DSP)。以下图为例:

左侧 为触发器FF作为驱动,其输出网线(名为sig1)的扇出为4。图右侧为使用下列Tcl约束命令后的效果:

该约束命令就是将网线的扇出约束为1,但是只针对负载为MACRO的。

FORCE_MAX_FANOUT和MAX_FANOUT_MODE是非常好用的降低扇出的方式,如对于SSI芯片,如果需要控制指定网线在每个SLR内的扇出,就可以将MAX_FANOUT_MODE值设置为SLR。对于任何设计,如果需要确保关键位置的每个BRAM的读/写使能是由独立的触发器 驱动的,就可以将MAX_FANOUT_MODE值设置为MACRO

对于高扇出网线,也可以将其引入全局时钟网络 ,只需要将其连接到全局时钟缓冲器上即可。这可以在RTL代码 中通过实例化全局时钟缓冲器的方式实现,也可以在XDC约束文件 中通过CLOCK_BUFFER_TYP E实现。从工程实践的角度而言,使用属性CLOCK_BUFFER_TYPE更为实用,因为这避免了对RTL代码的修改,同时如果不需要插入BUFG,则只需要将其值设置为NONE。具体约束命令如下:

方法三:从代码层面降低扇出

通常在设计中,除了时钟信号的扇出较高,全局复位信号的扇出也较高。时钟由于有全局时钟网络的支持,是完全允许高扇出的。因此,我们需要关注的是非时钟的高扇出信号。

首先,对于全局复位信号的使用,我们可以从以下3个角度进行审视

(1)复位信号驱动的负载是否都是必须复位的?

例如,流水线寄存器是不需要复位的,只需要做好初始化就可以,因为旧数据总会被新数据"冲走"。

(2)是上电复位还是系统正常工作时也需要复位?

有些复位仅仅是执行系统上电复位,需要将触发器复位到期望值(通常为0),这实际上完成的是触发器的初始化。这种复位实际上是不需要的,可直接通过触发器初始化操作完成。但如果在系统工作过程中仍需要复位,那么这种复位是不能移除的。

(3)复位信号的极性是否一致?

在设计中要保持复位极性一致,即当同一复位信号驱动不同负载时,这些负载的复位信号都是高电平有效或都是低电平有效,避免既有高电平有效又有低电平有效,这无形中增加了触发器控制集。

其次,对于局部控制信号 ,要从电路结构上管理好扇出,这在高速设计中尤为重要。例如,对于BRAM和UltraRAM的读/写地址端口读/写使能端口 ,应尽可能使扇出低一些,且确保其驱动为触发器而非查找表。

最后,我们也可以在代码中通过手工复制寄存器 的方式降低扇出。只是需要注意,确保复制的寄存器不会被工具优化掉,因为复制的寄存器和原始寄存器被认为是等效寄存器 。因此,可对这些寄存器添加综合属性KEEPDONT_TOUCH (建议直接在RTL代码中使用),也可使用模块化综合方式 ,即对这些触发器所在层次 设置KEEP_EQUIVALENT_REGISTER属性,将其值设置为1,具体Tcl约束命令如下所示:


3、改善扇出的正确流程

降低扇出有多种方法,可以从设计流程 的角度入手,也可以从约束属性 的角度入手,还可以从代码层面入手。那么优先选择哪种方式呢?这里建议以设计流程为主,以约束属性为辅,如果两者均未奏效,就需要从代码层面进行人工干预了,形成的流程如下图所示:

之所以将设计流程作为首选方案,是因为无论是布局还是布局后的物理优化,都是受时序需求驱动的,工具会据此决定是否对高扇出网线的驱动进行复制及复制多少份,这比人工复制更具有针对性。


~End~

相关推荐
jjjxxxhhh1231 小时前
FPGA,使用场景,相比于单片机的优势
单片机·嵌入式硬件·fpga开发
诚实可靠小郎君95276 小时前
FPGA高速设计之Aurora64B/66B的应用与不足的修正
fpga开发·aurora·高速通信
百锦再6 小时前
基于Zynq FPGA对雷龙SD NAND的测试
fpga开发
∑狸猫不是猫18 小时前
HDLBIts习题(4):边沿检测、分频计数器、多位BCD计数器
fpga开发
黑旋风大李逵1 天前
FPGA使用Verilog实现CAN通信
fpga开发·can通信·sja1000t·fpga实现can通信
hi941 天前
PYNQ 框架 - 中断(INTR)驱动
嵌入式硬件·fpga开发·zynq·pynq
transfer_ICer2 天前
Vscode搭建verilog开发环境
vscode·fpga开发·编辑器
沐欣工作室_lvyiyi3 天前
汽车牌照识别系统的设计与仿真(论文+源码)
人工智能·单片机·fpga开发·汽车·单片机毕业设计·matlab车牌识别
绅士羊OuO3 天前
FPGA学习笔记#5 Vitis HLS For循环的优化(1)
c++·笔记·嵌入式硬件·学习·fpga开发
Panda 皮3 天前
FPGA时钟之时钟偏移
fpga开发