FPGA设计时序约束二、输入延时与输出延时

目录

一、背景

二、set_input_delay

2.1 set_input_delay含义

2.2 set_input_delay参数说明

2.3 使用样例

三、set_output_delay

3.1 set_output_delay含义

3.2 set_output_delay参数说明

3.3 使用样例

四、样例工程

4.1 工程代码

4.2 时序报告

五、参考资料


一、背景

    为了在设计中准确的模拟信号从FPGA传输到外部或外部信号进入到FPGA端口的时序,在设计中需要给定输入端口和输出端口的延时信息,因为vivado仅仅能够识别边界内部的时序。

二、set_input_delay

    FPGA端口和外部的时延约束命令有两种,输入时延命令set_input_delay和输出时延命令set_output_delay。

2.1 set_input_delay含义

    输入时延约束指定了设计中输入时钟端口的输入时延,以应用板为例,输入时延表示在数据从外部芯片通过应用板到达FPGA的输入引脚和应用板的时钟相位存在差异。因此,输入时延值可以是正数也可以是复数,正负值取决于数据信号和时钟信号在外部芯片与FPGA接口处的相对相位。

    注:在Ultrascale系列的器件中,输入时延也可以设置到内部的数据引脚上。

2.2 set_input_delay参数说明

打开vivado中set input delay的设置窗口,有三种可选项:Rise/Fall,Min/Max,Add delay。

FPGA设计时序约束二、输入延时与输出延时_第1张图片

 

Clock:指定约束引脚的同步时钟,必须是事先定义的主时钟或虚拟时钟。

Objects:用于指定约束的目标端口。

Delay value:指定约束的时延值。

Delay value is relative to clock edge:指定输入时延值是相对于同步时钟的边沿,可以是上升沿rise或下降沿fall,默认值为上升沿

Delay value already includes latencies of the specified clock:设置延时值是否包含指定时钟(包括源时钟,网络时钟,源时钟/网络时钟)的潜在因素

Rise/Fall:指定约束信号相对时钟约束的延时边沿,可为上升沿rise或下降沿fall

Min/Max:Min为最小时延值,作用于hold/removal,Max为最大时延值,作用于setup/removal,如果Min/Max都未选择,表示最大时延和最小时延值相等

Add delay information to the existing delay:用于输入端口关联超过一个时钟沿的场景,例如,DDR接口。

2.3 使用样例

a) 设定一个输入延时,相对于时钟sysclk,最大时延和最小时延相等

 create_clock -name sysclk -period 10 [get_ports CLK0]
set_input_delay -clock sysclk 2 [get_ports DIN]

b)设定一个输入延时,同步时钟为虚拟时钟

create_clock -name clk_port_virt -period 10       #create_clock不指定object时创建的为虚拟时钟
set_input_delay -clock clk_port_virt 2 [get_ports DIN]

c)设定一个输入延时,同步时钟为sysclk,最大时延值和最小时延值不同

create_clock -name sysclk -period 10 [get_ports CLK0]
set_input_delay -clock sysclk -max 4 [get_ports DIN]
set_input_delay -clock sysclk -min 1 [get_ports DIN]

d)在两个IO端口间是纯组合逻辑,输入端口为DIN,同步时钟为虚拟时钟

create_clock -name sysClk -period 10
> set_input_delay -clock sysClk 4 [get_ports DIN]

 e)输入时延设置到DDR的数据输入引脚DDR_IN ,数据被clk_ddr的上升沿和下降沿触发,到FPGA内部FF的数据输入端口,对上升沿和下降沿都敏感                                                                                                                                            

create_clock -name clk_ddr -period 6 [get_ports DDR_CLK_IN]
set_input_delay -clock clk_ddr -max 2.1 [get_ports DDR_IN]
set_input_delay -clock clk_ddr -max 1.9 [get_ports DDR_IN] -clock_fall -
add_delay
set_input_delay -clock clk_ddr -min 0.9 [get_ports DDR_IN]
set_input_delay -clock clk_ddr -min 1.1 [get_ports DDR_IN] -clock_fall -
add_delay

f)设置输入时延到startupe3的内部引脚,时延路径从startupe3到组合逻辑单元(针对Ultrascale器件)

create_generated_clock -name clk_sck -source [get_pins -
hierarchical*axi_quad_spi_0/ext_spi_clk] [get_pins STARTUP/CCLK] -edges {3
5 7}
set_input_delay -clock clk_sck -max 7 [get_pins STARTUP/DATA_IN[*]] -
clock_fall
set_input_delay -clock clk_sck -min 1 [get_pins STARTUP/DATA_IN[*]] -
clock_fall

三、set_output_delay

3.1 set_output_delay含义

    ​set_output_delay约束指定了关联时钟沿的输出端口的输出路径时延,输出时延可理解为在数据从FPGA的输出端口到达其他芯片和关联的参考时钟间的相位差。输出时延值可以是正数也可以是复数,正负值取决于数据信号和时钟信号在外部芯片与FPGA接口处的相对相位。

3.2 set_output_delay参数说明

打开set_output_delay窗口,与set_input_delay窗口类似,相关配置项的作用也相同。

FPGA设计时序约束二、输入延时与输出延时_第2张图片

3.3 使用样例

a) 设定一个输出时延,同步时钟为sysClk,最大时延和最小时延值相同

create_clock -name sysClk -period 10 [get_ports CLK0]
set_output_delay -clock sysClk 6 [get_ports DOUT]

b) 设定输出时延,同步时钟为虚拟时钟

create_clock -name clk_port_virt -period 10    #创建虚拟时钟
set_output_delay -clock clk_port_virt 6 [get_ports DOUT]

c)设置输出时延,同步时钟为DDR时钟,最大时延和最小时延值有多个

create_clock -name clk_ddr -period 6 [get_ports DDR_CLK_IN]
set_output_delay -clock clk_ddr -max 2.1 [get_ports DDR_OUT]
set_output_delay -clock clk_ddr -max 1.9 [get_ports DDR_OUT] -clock_fall -add_delay
set_output_delay -clock clk_ddr -min 0.9 [get_ports DDR_OUT]
set_output_delay -clock clk_ddr -min 1.1 [get_ports DDR_OUT] -clock_fall -add_delay

上述约束的效果如下图,时钟上升沿的时延范围为0.9-2.1ns,下降沿的时延范围为1.1-1.9ns

FPGA设计时序约束二、输入延时与输出延时_第3张图片

 

d)设置输出时延到STARTUPE3(对于Ultrascale+器件)的pins,从逻辑单元到STARTUPE3

create_generated_clock -name clk_sck -source [get_pins -hierarchical axi_quad_spi_0/ext_spi_clk] [get_pins STARTUP/CCLK] -edges {3 5 7}  #创建生成时钟
set_output_delay -clock clk_sck -max 6 [get_pins STARTUP/DATA_OUT[*]]   #设置输出时延最大值
set_output_delay -clock clk_sck -min 1 [get_pins STARTUP/DATA_OUT[*]]	 #设置输出时延最小值

四、样例工程

4.1 工程代码

module timing(clk1,clk2,clk3,ce,d1,d2,out );
input clk1,clk2,clk3,ce,d1,d2;
output out;
reg ff1,ff2,ff3;
wire comb;
always@(posedge clk1,negedge ce)
begin
    if(!ce)
    ff1<=0;
    else begin
        ff1<=d1;
    end
end
always@(posedge clk2,negedge ce)
begin
    if(!ce)
    ff2<=0;
    else begin
        ff2<=d2;
    end
end
assign comb=ff1*ff2;
always@(posedge clk3,negedge ce)
begin
    if(!ce)
    ff3<=0;
    else begin
        ff3<=comb;
    end
end
assign out=ff3;
endmodule

约束文件,4、5、6为set_input_delay和set_output_delay

1、create_clock -period 10.000 -name create_clk1 -waveform {0.000 5.000} [get_ports clk1]  #创建主时钟create_clk1,约束到clk1
2、create_generated_clock -name gen_clk1 -source [get_ports clk1] -divide_by 2 -add -master_clock create_clk1 [get_pins ff2_reg/C]   #创建生成时钟gen_clk1,约束到FF2的clk端口
3、create_generated_clock -name gen_clk2 -source [get_ports clk1] -edges {1 3 5} -edge_shift {1.000 0.000 0.000} -add -master_clock create_clk1 [list [get_pins ff2_reg/C] [get_pins ff3_reg/C]] #创建生成时钟gen_clk2,约束到FF3的clk端口
4、set_input_delay -clock [get_clocks create_clk1] -rise -min 0.800 [get_ports d1] 
5、set_input_delay -clock [get_clocks create_clk1] -rise -max 1.200 [get_ports d1]#设置输入端口d1的输入时延最大值1.2ns和最小值0.8ns,
6、set_output_delay -clock [get_clocks create_clk1] -clock_fall -rise -max -add_delay 0.800 [get_ports out] #设置输出时延到输出端口out,同步时钟为create_clk1,输出延时0.8ns

网表连接图,FF1_reg和ff2_reg的输出经过LUT2输出到ff3_reg,对应的时钟分别为clk1,clk2,clk3。

FPGA设计时序约束二、输入延时与输出延时_第4张图片

4.2 时序报告

执行Flow Navigator中综合流程下的report timing summary查看时序报告

FPGA设计时序约束二、输入延时与输出延时_第5张图片

 

查看约束到create_clk1的input_delay

FPGA设计时序约束二、输入延时与输出延时_第6张图片

 

input_delay中min时延值对应hold路径

FPGA设计时序约束二、输入延时与输出延时_第7张图片

输出时延报告,设置的约束值为0.8ns,符合预期

FPGA设计时序约束二、输入延时与输出延时_第8张图片

 

五、参考资料

用户手册:ug903-vivado-using-constraints-en-us-2022.2.pdf

链接:https://pan.baidu.com/s/17AK_-J4wRXiFLtLTorlrwg?pwd=mylt 

提取码:mylt

你可能感兴趣的:(FPGA所知所见所解,fpga开发,时序约束,set_input_delay,set_outputdelay,vivado)