系列文章目录
FPGA时序约束(一)基本概念入门及简单语法
FPGA时序约束(二)利用Quartus18对Altera进行时序约束
FPGA时序约束(三)时序约束基本路径的深入分析
FPGA时序约束(四)主时钟、虚拟时钟和时钟特性的约束
文章目录
- 系列文章目录
- 衍生时钟
- 约束语法
- I/O接口约束
- 输入接口约束语法
- 语法实例
- 应用实例
- 输出接口约束语法
- 应用实例
衍生时钟
衍生时钟约束必须指定时钟源,可以是一个已经约束好的主时钟或另一个衍生时钟。
衍生时钟定义其与时钟源的相对关系,如分频系数、倍频系数、相移差值、占空比差值等。在做衍生时钟约束前,要求先做好其时钟源的约束定义。
一般Vivado自动约束,通过check_timing检查,如果没有生成,就手动约束。
约束语法
create_generated_clock -name <generated_clock_name > \
-source <master_clock_source_pin_or_port > \
-multiply_by <mult_factor> \
-divide_by <div_factor> \
<pin_or_port >
- \是换行符号,无实际含义。
- -name后的 generated_clock_name用于指定衍生时钟名称。若不指定将自动以pin_or_port 指定的物理节点作为该衍生时钟的名称。
- -source后的 master_clock_source_pin_or_port指定衍生时钟的源时钟引脚或端口,源时钟可以是一个已经定义过的主时钟、虚拟时钟或衍生时钟。
- -multiply_by后的< mult_factor >用于指定衍生时钟相对于源时钟的倍频系数,取值必须大于或等于1.0。
- -divide_by后的< div_factor >用于指定衍生时钟相对于源时钟的分频系数,取值必须大于或等于1.0。
- < pin_or_port >用于指定衍生时钟的物理节点﹑引脚或端口名称。
例如:
首先对主时钟进行约束:
create_clock -name clkin -period 10 [get_ports clkin]
有两种约束方法;
create_generated_clock -name clkdiv2 -source [get_ports clkin] -divide_by 2 [ get_pintREGA/Q]
也可以将REGA作为时钟源对clkdiv2做衍生时钟约束:
create_generated_clock -name clkdiv2 -source [get_pintREGA/C] -divide_by 2 [ get_pintREGA/Q]
I/O接口约束
输入接口约束语法
set_input_delay用于输人数据引脚相对于其时钟沿的路径延时。可以是正值,也可以是负值。
set_input_delay应用于FPGA器件的输入数据引脚或双向数据引脚,但不适用于FPGA内部信号或时钟输入引脚。set_input_delay 有-max和-min, 最大值用于建立时间检查,最小值用于保持时间检查。
set_input_delay -clock <args> -reference_pin <args> -clock_fall -rise -max -add_delay<delay><objects>
- -clock用于指定约束引脚的同步时钟(源时钟),可以是设计中事先定义的主时钟或虚拟时钟。
- -reference_pin用于指定延时值< delay >的参考时钟。不指定该选项,则指定延时值< delay >的参考时钟就是-clock。
- -clock_fall 指定输入延时约束取值相对于同步时钟的下降沿。若不指定默认为-clock_rise。
- -rise指定约束信号相对时钟的边沿关系是上升沿,也可以用-fall指定为下降沿。(没理解,也没实例)
- -max表示设定最大延时值,也可以使用-min设定最小延时值。若不指定同时用于最大和最小。
- < delay >用于指定将应用到目标输入引脚的延时值。有效值为大于或等于0的浮点数,1.0为默认值。
- < objects >用于指定约束的目标输入引脚名称。
语法实例
//约束输入CLK0的主时钟sysClk
create_clock -name sysClk -period 10 [get_ports CLK0 ]
//约束了数据引脚DIN相对于输入引脚为CLK0的主时钟sysClk,-max和-min值为2ns的输入延时约束。
set_input_delay -clock sysClk 2 [get_ports DIN]
//上面的还可以分开写
set_input_delay -clock sysClk -max 2 [get_ports DIN]
set_input_delay -clock sysClk -min 2 [get_ports DIN]
//定义输入端口reset相对于wbClk_IBUF_BUFG_inst/O输出的时钟的输入延迟为2ns,其中wbClk_IBUF_BUFG_inst/O输出时钟的时钟源为wbClk
set_input_delay -clock wbClk 2 -reference_pin [get_pin wbClk_IBUF_BUFG_inst/O] reset
//DDR数据约束,为啥要加add_delay:与端口上已定义的任何其他 set_input_delay 约束共存。
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 //上一行定义过max了,虽然是上升沿
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
应用实例
以此为例:
可以把该图抽象成之前学过的:(在之前的系列文章里面)
推导出建立时间余量公式:(这里和上面一样,对公式Tc2j_pcb进行了变换)
set_input_delay(max)=Tco( max)+Td_pcb( max)-Tc2j_pcb( min)
保持时间余量公式:
set_input_delay(min)=Tco(min)+Td_pcb(min)-Tc2j_pcb(max)
数据和时钟在PCB板上的延时值Td_pcb和Tc2j_pcb 可以通过PCB的走线测量即可算出。PCB板级走线延时可以按照0.17ns/in进行换算。
假设Td_pcb ( max)=0.5ns,Td_pcb( min)=0ns
Tc2j_pcb( max)=0.5ns,Tc2j_pcb(min)=0ns。
根据MT9V034芯片手册:参数tp,表示数据变化相对于其同步时钟PIXCLK下降沿的延时,最大值为3ns,最小值为一3ns。
可以映射到数据输出相对于时钟上升沿的延时。(已知同步时钟PIXCLK的时钟周期为40ns,相当于时钟沿左移20ns),那么可以得到Tco( max)=23ns,Tco(min)=17ns。
最后可以得到:
set_input_delay(max)=-ons+23ns+0.5ns=23.5ns
set_input_delay(min)=-0.5ns+17ns+0ns=16.5ns
(当然也可以不变换Tco的值,直接在约束的时候指定-fall)
输出接口约束语法
set_output_delay用于指定输出数据引脚相对于其时钟沿的路径延时。通常输出延时值包括了数据信号从FPGA引脚到外部芯片的板级延时,外部芯片的建立时间和保持时间等。输出延时值可以是正值,也可以是负值。
set_output_delay命令可以应用于FPGA 器件的输出数据引脚或双向数据引脚,但不适用于FPGA内部信号或时钟输出引脚。
set_output_delay约束命令的语法格式与set_input_delay一样。
应用实例
以FPGA到A/D芯片ADV7123的输出接口为例。ADV7123是一颗3路并行高速A/D芯片,用于驱动VGA接口的显示器。
抽象成之前介绍过的:
set_output_delay( max)=Td_pcb ( max)+Tsu-Tc2j_pcb(min)
set_output_delay( min)=Td_pcb (min)-Th-Tc2j_pcb(max)
还是假设Td_pcb (max)=0.5ns,Td_pcb (min)=0ns,Tc2j_pcb (max)=0.5ns,Tc2j_pcb(min)=0ns。
在ADV7123的芯片手册中,可以找到两个参数,分别为数据采样的建立时间和保持时间,即Tsu=0.2ns,Th=1.5ns。
set_output_delay(max)=0.5ns-0ns+1.5ns=2ns
set_output_delay(min)=0ns-0.5ns-0.2ns= -0.7ns