优化移位寄存器
Note:文章内容以 Xilinx 7系列 FPGA 进行讲解
1、FPGA中移位寄存器资源(7系列)
7系列FPGA中的SLICE分为两大类:SLICEL和SLICEM。每个SLICE内都有4个查找表(Look-Up Table,LUT)。其中,SLICEL中的LUT仅可用作逻辑函数发生器,而SLICEM中的LUT不仅可以用作逻辑函数发生器,还可以用作存储器,这也是SLICEM名称的由来(M表示Memory)。对比SLICEL和SLICEM中的LUT,如图下图所示(左侧为SLICEL中的LUT,右侧为SLICEM中的LUT):
不难看出,SLICEL和SLICEM中的LUT的输入/输出端口存在明显差异。
因为移位寄存器是存储器中的一种,所以如果想用LUT来实现移位寄存器,那么只能用SLICEM中的LUT资源。
SLICEM中的每个LUT可实现深度为32的移位寄存器(等效于32个寄存器级联),意味着可将一位数据延迟32个时钟周期。
同一个SLICEM中的LUT又可通过专用级联走线构成深度更大的移位寄存器,最大可构成深度为128(32×4)的移位寄存器,这意味着可将一位数据延迟128个时钟周期。这4个LUT的级联方向是由上至下。
如果需要更大深度(深度大于128)的移位寄存器,就不得不将不同SLICEM中的LUT级联起来,这时跨越SLICEM之间的走线不是专用走线。(不是专用走线,势必对时序收敛有影响)
同时由上图可以看出,LUT并没有置位/复位端口,因此,不管是同步还是异步,将LUT用作移位寄存器时都不支持置位/复位。所以用RTL代码描述移位寄存器时,如果期望其映射为SLICEM中的LUT,则不能添加置位/复位功能。
2、时序路径上的移位寄存器管理
在综合阶段,Vivado提供了两个选项用于指导工具如何处理移位寄存器,如下图所示:
-no_srlextract用于阻止工具将移位寄存器映射为LUT,则意味着所有的移位寄存器都将被综合为级联的寄存器,也就是以寄存器链的形式实现移位寄存器。
-shreg_min_size决定了移位寄存器被映射为SRL的最小深度。当移位寄存器的深度小于-shreg_min_size时,最终的实现方式为触发器级联的形式,即FF+FF或FF+FF+FF;当其深度大于等于-shreg_min_size时,实现方式则为FF+LUT+FF的形式(SRL一般都是由LUT生成)。
-no_srlextract和-shreg_min_size是全局选项,意味着对设计中的所有模块均适用(-no_srlextract 优先级高于-shreg_min_size)。因此,通常情况下不会手工修改这两项,而是由综合策略决定其具体设置情况,如下图所示:
可以看到, 较大的-shreg_min_size可以改善布线拥塞。
除此之外,Vivado还提供了综合属性shreg_extract和srl_style(具体用法见Vivado综合设置与综合属性-CSDN博客)。
Vivado还支持模块化综合技术,这使得对综合的管理粒度更加精细。其中,和移位寄存器相关的属性有两个:SHREG_MIN_SIZE和SRL_STYLE,具体使用方法如下图所示:
无论是综合选项还是综合属性,或者模块化综合技术,使用的前提是RTL代码对用户是可见的。若已到了设计实现阶段或用户仅可见综合后的网表文件,则需要使用其他方法对移位寄存器进行优化。此时就需要先找到网表中的移位寄存器。 具体Tcl命令如下:
这三类移位寄存器正是设计中需要格外关注的,尤其是当它们是时序路径终点单元时。因为这三类移位寄存器的深度较浅,所以可考虑是否将其替换为触发器更为合适。
上表中的约束属性可以在opt_design阶段使用,具体用法如下图所示:
① 若SRL是时序路径的终点单元 ,可借助约束属性SRL_STAGES_TO_REG_INPUT在移位寄存器输入端提取出一个寄存器,从而有利于工具改善布线延迟或降低逻辑级数。
② 若SRL是时序路径的起点单元 ,可借助约束属性SRL_STAGES_TO_REG_OUTPUT在移位寄存器输出端提取出一个寄存器,从而有利于改善时序。
~End~