一.基础知识
需要作为区分的情况是,建立时间和保持时间是针对同步电路而言的,而这篇总结的是恢复时间和移除时间,这是针对异步电路的复位信号的释放过程。同步和异步的区别就在于所使用的时钟是否为同源时钟(可以理解为FPGA实验板上的晶振),如果晶振不同,那么即使频率相同的两个时钟信号也是异步的。
恢复时间(Recovery Time):撤销复位信号时,恢复到非复位状态的电平必须在时钟有效沿来临前的一小段时间到来。
移除时间(Removal Time):在时钟有效沿来临之后复位信号还需要保持的最小时间。
二.时序分析
1.时序引擎如何进行Recovery检查?
Required Time = destination clock edge start time + destination clock path delay - clock uncertainty - recovery time
Arrival Time = source clock edge start time + source clock path delay + datapath delay
Slack(recovery) = Required Time - Arrival Time
注意:写数据一般不推荐进行复位,可能会导致复位信号的扇出很大,推荐复位一些控制信号:比如写使能信号,读使能信号等。
2.时序引擎如何进行Removal检查?
Required Time(removal) = destination clock edge start time + destination clock path delay + clock uncertainty +removal time
Arrival Time(removal) = source clock edge start time + source clock path delay + datapath delay
Slack (removal) = Arrival Time - Required Time
三.时钟约束具体操作
时序引擎能够正确分析四种时序路径的前提是,用户已经进行了正确的时序约束。时序约束本质上就是告知时序引擎一些进行时序分析所必要的信息,这些信息只能由用户主动告知,时序引擎对有些信息可以自动推断,但是不一定准确。
- 第一种时序路径需要约束Input-delay
- 第二种时序路径需要约束时钟
- 第三种时序路径需要约束output-delay
- 第四种时序路径需要约束Max_delay/Min_delay
1.时钟约束
用户约束时钟时,一般两种类型的时钟需要约束
1.主时钟(primary clock)
主时钟可以分为两种类型:
第一种是从FPGA的全局时钟输入引脚输入的时钟。
具体方法:create_clock -period 10 [get_ports sysclk]
解释:10:这里指时钟周期为10ns,默认占空比为50%,sysclk:全局时钟输入引脚
create_clk -name devclk -period 10 -waveform {2.5,5} [get_ports ClkIn]
devclk:这只是一个名字,只在时序分析中起作用 -waveform{2.5,5} 2.5:时钟第一个上升沿
5:时钟第一个下降沿 ClkIn:全局时钟引脚
第二种时从高速收发器输出给用户的恢复时钟。
具体方法:create_clock -name rxclk -period 3.33 [get_pins gt0/RXOUTCLK]
解释:注意这里是get_pins,ports代表FPGA板子上的引脚端口,pins则代表是内部模块的输入输出
这里默认占空比也为50%
2.生成时钟(Generated clock)
生成时钟分为两种类型:第一种是由FPGA的专用时钟管理模块(PLL/MMCM)产生的时钟(这种时钟时序引擎可以自动推断);第二种是由用户可以通过LUT或寄存器产生的时钟(这种时钟必须由用户自行手动约束)。
每个生成时钟都会对应一个时钟源,这个时钟源可以是primary clock或者另外一个Generated Clock。在约束生成时钟的死后,用户不需要描述生成时钟的周期和波形,只需要描述由master_clk经过怎样的变化而产生的生成时钟即可。比如:分频(_divide_by),倍频(_multiply_by),反相(_invert),相移(-edge_shift)等操作。
在约束生成时钟之前一定要先约束master_clock。
具体方法:
create_clock -name clkin -period 10 [get_ports clkin]
#option 1:master clock是primary clock
create_generated_clock -name clkdiv2 -source [get_ports clkin] -divide_by 2 \ [get_pins REGA/Q]
#option 2:master clock 是模块中的时钟输出(比如PLL/MMCM输出)
create_generated_clock -name clkdiv2 -source [get_pins REGA/C] -divide_by 2 \ [get_pins REGA/Q]
#通过描述波形代替描述变化
create_generated_clock -name clkdiv2 -source [get_pins REGA/C] -edges {1,3,5} \ [get_pins REGA/Q]
1,3,5:指的是以master clock为基准,1ns:第一个时钟上升沿,3:第一个时钟下降沿,5:第二个时钟上升沿
#当生成时钟需要相移时,使用-edge shift选项,注意:-edge shift不能与-divide_by/-multipl/-invert同时使用
create_clock -name clkin -period 10 [get_ports clkin]
create_generated_clock -name clkshift -source [get_pins mmcm0/CLKIN] -edges {1 2 3} \ -edge_shift {2.5 0 2.5}
第一个上升沿:0+2.5=2.5ns
第一个下降沿:5+0 = 5ns
第二个上升沿:10+2.5 = 12.5ns
2.关闭异步路径
时序引擎默认情况下会分析所有时钟之间的时序路径,用户可以通过时序分组(set_clock_group)命令或伪路径(set_false_path)命令来关闭异步路径的时序分析。
- 使用set_clock_group命令,时钟引擎会将不同分组的时钟之间的路径分析关闭,相同分组的时钟之间路径仍然存在。
- 使用set_flase_path命令,时序引擎会忽略两个时钟的双向路径
被忽略的路径不一定可以正常工作,需要用户确保该路径使用了两级触发器或按照异步数据传输方式传输数据。用户负责保证这些被忽略的路径可以正常工作。
两个时钟之间的关系:同步时钟,异步时钟,一级不可扩宽的时钟。
- 同步时钟:两个时钟之间的相对相位关系是固定的(两个时钟来源于同一个primary clock),并且这两个时钟的频率的最小公共周期是个整数。属于同步时钟关系的两个时钟之间的路径是可以进行时序分析的。
- 异步时钟:两个时钟之间的相对相位关系不确定。一般情况下,不同的primary clock之间都属于异步时钟,它们产生的生成时钟也属于异步时钟关系。属于异步时钟关系的两个时钟之间的路径是无法进行正确的时序分析的。如果用户不对所有的时钟之间的关系进行约束,时序引擎会默认所有的时钟之间都属于同步时钟关系。
- 不可扩宽的时钟。对于这类时钟,时序引擎无法在1000个周期内找到两个时钟的公共周期,时序引擎就会从这1000个时钟周期中找到建立时间需求最差的情况,然后进行时序分析。
具体方法:
#option1:直接对于所有时钟进行分类
set_clock_groups -name async_clk0_clk1 -asynchronous -group {clk0 usrclk itfclk} \ -group {clk1 gtclkrx gtclktx}
#option2: 只对master clock进行分类
set_clock——groups -name async_clk0_clk1 -asynchronous
\ -group [get_clocks -include_generated_clock clk0]
\ -group []get_clocks -include_generated_clock clk1
3.三种时序路径的约束
第一种时序路径:input delay用于约束输入端口和FPGA中第一级触发器之间的时序关系。
Max Input Delay = (MAX)+
(MAX)+clk skew(min)
一般情况下如果不知道的话,上值去时钟周期的60%
Min Input Delay = (Min)+
(Min)+clk skew(MAX)
约束Input delay的方法:
- #option1:默认设置一个值
create_clock -name sysClk -period 10 [get_ports CLK0]
set_input_delay -clock sysClk 2 [get_pins DIN]
sysClk为参考时钟
- #option2:设置一个最大值和最小值
create_clock -name sysClk -period 10 [get_ports CLK0]
set_input_delay -clock sysClk -max 4 [get_pins DIN]
set_input_delay -clock sysClk -min 2 [get_pins DIN]
- #option3:同时设置上升沿和下降沿
create_clock -name sysClk -period 6 [get_ports DDR_CLK_IN]
set_input_delay -clock sysClk -max 2.1 [get_pins DDR_IN]
set_input_delay -clock sysClk -max 1.9 [get_pins DDR_IN] -clock_fall -add_delay
set_input_delay -clock sysClk -min 0.9 [get_pins DIN]
set_input_delay -clock sysClk -min 1.1 [get_pins DIN] -clock_fall -add_delay
第二种时序路径:正常进行建立时间和保持时间约束
第三种时序路径:outputdelay用于约束最后一级触发器与FPGA输出端口之间的时序关系。默认情况下设置为时钟周期的60%。
Max Output Delay = (MAX)+
- Clk skew(Min)
Min Output Delay = (Min)+
- Clk skew(Max)
具体方法:
- #option1:默认设置一个值
create_clock -name sysClk -period 10 [get_ports CLK0]
set_output_delay -clock sysClk 6 [get_ports DOUT]
- #option2:设置上升沿和下降沿
create_clock -name clk_addr -period 6 [get_ports CLK0]
set_output_delay -clock clk_addr -max 2.1 [get_ports DOUT]
set_output_delay -clock clk_addr -max 1.9 [get_ports DOUT] -clock_fall
set_output_delay -clock clk_addr -min 0.9 [get_ports DOUT]
set_output_delay -clock clk_addr -min 1.1 [get_ports DOUT] -clock_fall
4.multicycle约束
1.为什么要进行multicycle约束?
- 时序引擎默认情况下会在建立时间/保持时间需求最差的情况下进行时序分析,而时序引擎选择的这种需求不一定是用户真正希望的,而且时序引擎默认选择的这种需求是非常严苛的,甚至有时候根本无法满足。此时需要用户进行多周期约束,手动修改建立时间需求/保持时间需求。
- 用户希望放松某些路径的约束力度,就可以通过多周期约束调整建立时间/保持时间需求。
- 使用set_multicycle_path命令进行约束
set_multicycle_path <path_multiplier> [-setup|-hold] [-start|-end] [-from <.startpoints>] [-to <endpoints>] [-through <pins|cells|nets>]
path_multiplier:指的是调整时钟周期的个数
-setup|hold:调整的是建立时间还是保持时间
-start:指的是发起沿(如果是建立时间就向左,保持时间就向右)
-end:指的是捕获沿(如果是建立时间就向右,保持时间就向左)
默认不指定发起沿还是捕获沿的情况下,如果是建立时间默认调整捕获沿,如果是保持时间的话默认调整发起沿。
Source Clock (-start) Moves the launch edge | Destination Clock (-end) Moves the capture edge | |
Setup | <----(backward) | ---->(forward)(default) |
Hold | ---->(forward)(default) | <----(backward) |
2.如何进行multicycle约束?
- 在源时钟和目的时钟相同的情况下进行multicycle约束(每两个时钟周期发起一次数据,每两个时钟周期捕获一次数据)
先调整建立时间,再回调保持时间
set_multicycle_path 2 -setup from [get_pins data0_reg/C] -to [get_pins data1_reg/D]
from:可以是FPGA输入端或时钟输入端
to:可以是FPGA输出端或数据输出端
set_multicyle_path 1 -hold -end -from [get_pins data0_reg/C] -to [get_pins data1_reg/D]
- 在源时钟和目的时钟相同的情况下进行Multicycle约束下(每四个周期发起一次数据,每四个周期捕获一次数据)
与第一种情况类似
set_multicycle_path 4 -setup -from [get-pins data0_reg/C] -to [get_pins data1_reg/D]
set_multicycle_path 3 -hold -end from [get_pins data0_reg/C] -to [get_pins data1_reg/D]
- 在源时钟和目的时钟相同的情况下进行Multicycle约束下(每五个周期发起一次数据,每五个周期捕获一次数据)
set_multicycle_path 4 -setup -from [get-pins data0_reg/C] -to [get_pins data1_reg/D]
set_multicycle_path 3 -hold -end from [get_pins data0_reg/C] -to [get_pins data1_reg/D]
- 在原时钟和目的时钟频率相同且有正向偏移的情况下(正向偏移为0.3ns)
set_multicycle_path 2 -setup -from [get_clocks CLK1] -to [get_clocks CLK2]
- 在原时钟和目的时钟频率相同且有负向偏移的情况下(负向偏移0.3ns)
发生负向偏移时,通常不需要进行Multicycle的约束,除非负向偏移过大
- 在源时钟和目的时钟频率不同的情况下(源时钟慢,目的时钟快)
也可以使用异步FIFO作异步跨时钟域处理,但是影响性能
调整setup需求(只能用-end,不能用-start),再进一步调整holdup要求
- 在源时钟和目的时钟频率不同的情况下(源时钟快,目的时钟慢)
调整setup需求(只能用-start,不能用-end)和holdup要求(只能用-start,不能用-end)
5.falsepath约束
1.为什么要使用伪路径约束?
第一种情况是:在实际运行过程中,该路径不工作
第二种情况是:该路径不需要时序分析。比如:已经做了两级触发器同步的跨时钟域路径,只在商店时工作一次的寄存器,异步复位路径或用于测试的路径
注意:如果用户的目的只是放松某条路径的约束,可以使用set_multicycle_path命令,不要使用伪路径约束
设置伪路径约束的好处:减少综合/实现/时序分析的时间;极大地提升工具对设计的综合/实现/优化的结果。
具体实现方法:ser_false_path [-setup] [-hold] [-from <node_list>] [-to <node_list>] \ [-through <node_list>]
注意:如果不指明具体是setup还是holdup,则默认都不会进行分析。另外,from...to...是单项路径
2.falsepath约束举例?
- 将异步复位信号设置为伪路径
set_false_path -from [get_port reset] -to [all_registers]
- 将CLKA到CLKB的单向路径设置为伪路径
set_false_path -from [get_clocks CLKA] -to [get_clocks CLKB]
- 将CLKA到CLKB以及CLKB到CLKA的双向路径设置为伪路径
set_false_path -from [get_clocks CLKA] -to [get_clocks CLKB]
set_false_path -from [get_clocks CLKB] -to [get_clocks CLKA]
注意:如果多个异步时钟之间的路径需要设置为伪路径的时候,推荐使用set_clock_group命令
6.Maxdelay约束
1.什么情况下使用Maxdelay约束
- 它可以带multicycle约束,调整建立时间需求,而且set_max_delay约束的优先级比Multicycle约束要高
- 对于两个异步时钟域之间的异步信号不需要进行时序分析,但是用户对路径延时有一定的要求时,可以使用set_max_delay -datapath only进行约束,-datapath only用于忽略时钟歪斜,只考虑数据路径的延时
2.怎么使用?
set_max_delay -from [get_clks GCB0[*]] -to [get_clks GCB a[*]] -datapath_only 5(具体延时大小一般不超过目的时钟的时钟周期)