Vivado从此开始(进阶篇)读书笔记——综合阶段相关知识点

本文转载自:十年老鸟的CSDN博客

计算控制集

对控制集百分比的说明(适用于7系列FPGA和UltraScale FPGA)如下表。可以看出:当控制集的百分比超过15%时,需要降低控制集。

1.png

计算控制集百分比的步骤如下:
1、 打开综合阶段或实现阶段生成的DCP,通过

report_control_sets –verbose

命令获取unique_ctrl_set,即unique control sets值

2.png

2、 通过两条命令获取当前芯片中SLICE的个数slice_num:

set part [get_property PART [current_design]]
set slice_num [get_property SLICES [get_parts $part]]

3、 计算控制集百分比,即unique_ctrl_set/ set slice_num*100%

(* keep = “true” *)

例如

(* keep = “true” *)reg rst_rep1;
(* keep = “true” *)reg rst_rep2;

使用keep,使得寄存器不会被综合器优化,用于复制寄存器,降低扇出,优化时序,尤其对于全局复位或全局使能信号而言,是一种行之有效的方式。

-shreg_min_size

用于管理移位寄存器是否映射为LUT,默认值为3。通过实验可以得到如图所示的结论:当移位寄存器的深度小于等于-shreg_min_size时,最终的实现方式为触发器级联的形式;当其深度大于-shreg_min_size时,实现方式则为FF+LUT+FF的形式。

3.png

注意 –no_srlextract用于组织工具将移位寄存器映射为LUT。(不要勾选)

SRL_STYLE

SRL_STYLE用于指导Vivado将SRL映射为何种形式

SRL_STYLE有6个可选值,分别为register、srl、srl_reg、reg_srl、reg_srl_reg和block

用法:

(* SRL_STYLE  = “reg_srl_reg”*) reg [DEPTH-1:0]shreg;

从时序角度而言,不建议时序路径的终点是移位寄存器。因此,对于“FF+组合逻辑+SRL”的路径,可优化为“FF+组合逻辑+FF”的路径,最后的FF是从移位寄存器中提取出来的。

对于较大深度的移位寄存器,可以将其映射为Block RAM,也就是SRL_STYLE的值为block,否则会消耗过多的LUT

USE_DSP

默认情况下,用HDL描述的乘法、乘加、乘减、乘累加,以及预加相乘运算,最终都会映射到DSP48中,但是加法、减法和累加运算则会利用常规的逻辑资源,即查找表、进位链等实现。相比于LUT,DSP48在功耗和速度上都有优势。如果希望加法运算能映射到DSP48中,那么就要用到综合属性USE_DSP。

该综合属性有4个值,分别是simd,logic、yes和no。这里重点介绍simd值。当属性值为simd时,对应SIMD(single instruction multiple data)模式。实际上SIMD模式是DSP48的一个特征。它使得位宽为48bit的ALU可配置为4个位宽为12bit的ALU(执行加法、减法或位逻辑运算)或者2个位宽为24bit的ALU。此时DSP48内部的乘法器是无法使用的

模板中SIMD的实现方式:

(* use_dsp = "simd" *)
module dsp_simd  # ( 
                      parameter N = 4,  // Number of Adders
                                W = 10  // Width of the Adders
                    )
                    (
                     // Clock 
                     input clk,
                     // First input
                     input [W-1:0] a [N-1:0],
                     // Second input
                     input [W-1:0] b [N-1:0],
                     // Output
                     output logic [W-1:0] out [N-1:0]
                    );
     
integer i;
logic [W-1:0] a_r [N-1:0];     
logic [W-1:0] b_r [N-1:0];

always @ (posedge clk)
begin
 for(i=0;i<N;i=i+1)
 begin
  a_r[i] <= a[i];
  b_r[i] <= b[i];
  out[i] <= a_r[i] + b_r[i];
 end 
end

endmodule


最新文章