周期为10ns的基础时钟
create_clock -period 10 [get_ports sys_clk]
生成时钟为通过组合逻辑自己生成的时钟驱动。(MMCM、PLL、BUFR输出的时钟不是生成时钟,vivado会自动识别,不需要额外约束)。
如图是经典二分频生成时钟,其输出的时钟约束应当为:
create_generated_clock -name clkdiv2 -source [get_ports clkin] -divide_by 2 [get_pins REGA/Q]
-name为该输出时钟的命名;-source为源时钟;-divide_by 2表示二分频;之后为生成时钟的输出端口。
当两个异步时钟生成各自的相关时钟后,若不加约束,vivado会认为所有时钟都是相关的。
set_clock_groups -name async_clk0_clk1 -asynchronous \
-group [get_clocks -include_generated_clocks clk0] \
-group [get_clocks -include_generated_clocks clk1]
-nama为所有时钟组命名;-asynchronous表示以下时钟组为异步;-group表示一个时钟组;-include_generated_clocks表示包含该时钟及该始终的生成时钟。
当两个时钟同一时刻有且只能有一个时钟工作时,这两个时钟相互独立,例如正常工作时钟和DFT时钟。
set_clock_groups -name exclusive_clk0_clk1 -physically_exclusive -group clk0 -group clk1
当外部芯片向FPGA发送数据时,从时钟上升沿到有效数据进入FPGA端口之间的延迟为输入延迟。
计算方法:
input delay_max = Tco_max + TD_max
input delay_min = Tco_min + TD_min
set_input_delay -clock sysclk -max 4 [get_ports din]
set_input_delay -clock sysclk -min 2 [get_ports din]
-clock为参考时钟;-min,-max为输入延迟范围。
set_input_delay -min 1 -clock clk [get_ports data_in]
set_input_delay -max 2 -clock clk [get_ports data_in]
set_input_delay -min 1 -clock clk [get_ports data_in] -clock_fall -add_delay
set_input_delay -max 2 -clock clk [get_ports data_in] -clock_fall -add_delay
在正常上升沿时钟输入时延约束后,-clock_fall表示在下降沿约束;-add_delay为避免下降沿约束覆盖上升沿约束。
当FPGA向外部芯片发送数据时,从时钟上升沿有效数据进入下游芯片寄存器之间的延迟为输出延迟。(即在下游芯片寄存器时钟上升沿之前x时间内数据应当稳定存在)
计算方法:
output delay_max = TD_max + Tsu
output delay_min = TD_min - Th
set_output_delay -clock sysclk - max 2 [get_ports dout]
set_output_delay -clock sysclk - min -1 [get_ports dout]
set_output_delay -min -1 -clock clk [get_ports data_in]
set_output_delay -max 3 -clock clk [get_ports data_in]
set_output_delay -min -1 -clock clk [get_ports data_in] -clock_fall -add_delay
set_output_delay -max 3 -clock clk [get_ports data_in] -clock_fall -add_delay
FPGA从入口到出口只有纯组合逻辑时,也需要对延迟进行约束。
set_max_delay 15 -from [get_ports din] -to [get_ports dout]
只有在FPGA输入、输出(IO)时才会用到虚拟时钟。
create_clock -name sysclk -period 10 [get_ports clkin]
create_clock -name vclk -period 5
set_input_delay 6 -clock clk [get_ports dina]
set_input_delay 6 -clock vclk [get_ports dinb]
可见,虚拟时钟与普通时钟约束时唯一不同是没有给定端口。
create_clock -name sysclk -period 10 [get_ports clkin]
create_clock -name vclk -period 10
set_clock_latency -source 1 [get_clocks vclk] //此处-source指延迟来自于时钟源端
set_input_delay -clock vclk -max 4 [get_ports ain]
set_input_delay -clock vclk -min 2 [get_ports ain]
set_multicycle_path -from[get_cells rega] -to [get_cells rega] -setup/hold -end/start 2
分为发送时钟和接收时钟,EDA在不约束时都默认为最差情况。
end以发送边沿作为参考,计算接收时钟落后的于参考的边沿,setup默认为接受时钟第一个落后于参考边沿的时钟边沿,hold为setup边沿回退一个,即默认情况下为:-setup -end 1 和 -hold -end 0。
start以接收边沿作为参考,计算发送时钟先的于参考的边沿,setup默认为发送时钟第一个领先于参考边沿的时钟边沿,hold为setup边沿回退一个,即默认情况下为:-setup -start 1 和 -hold -start 0。
多时钟周期约束主要包含以下几种情况:
当接收寄存器接收数据变化频率不大时,与发送寄存器之间的组合逻辑约束可以放宽,以减少综合时间。
在上图情况中,接收寄存器在发送寄存器变化后的第2周期接收。
set_multicycle_path -from[get_cells rega] -to [get_cells rega] -setup -end 2
set_multicycle_path -from[get_cells regb] -to [get_cells regb] -hold -end 1
语句中数字的含义:
-setup:表示该多周期路径所需要的时钟周期个数;
-hold:表示相对于缺省的捕获沿(图中的dufault hold),实际捕获沿(图中new hold)应回调的时钟周期个数;
参数时钟周期的选取:
-end表示参数时钟为收端时钟,对于-setup缺省为-end;
-start表示参数时钟为发端时钟,对于-hold缺省为-start;
此时,建立时间仍是在发送寄存器发送上升沿后接收时钟第二个接收上升沿;保持时间为发送寄存器发送上升沿后接收时钟第一个上升沿;与同频同相情况约束相同。
set_multicycle_path -from[get_clocks clk1] -to[get_clocks clk2] -setup -end 2
set_multicycle_path -from[get_clocks clk1] -to[get_clocks clk2] -hold -end 1
此时,建立时间仍为发送寄存器发送上升沿后接收时钟第一个接收上升沿;保持时间一定满足(为什么?);与正常周期情况情况约束相同,不再添加额外约束。
当发接收时钟频率是发送时钟整数倍时(此处以2倍为例),建立时间为接收时钟上升沿2,建立时间为接收时钟上升沿0。
set_multicycle_path -from[get_clocks clk1] -to[get_clocks clk2] -setup -end 2
set_multicycle_path -from[get_clocks clk1] -to[get_clocks clk2] -hold -end 1
set_multicycle_path -from[get_clocks clk1] -to[get_clocks clk2] -setup -start 2
set_multicycle_path -from[get_clocks clk1] -to[get_clocks clk2] -hold -start 1
set_false_path -from -through -to