一、时序引擎是如何进行建立时间和保持时间分析的
-
setup检查
时序引擎会找出发起时钟和捕获时钟的最小公共周期,然后在最小公共周期内找到所有发起时钟沿和捕获时钟沿的所有可能情况,并在所有情况中挑选出最严苛的情况确定launch edge 和capture edge. -
hold time检查
保持时间要求是以建立时间要求为基准的。
有两种保持时间发起沿和捕获沿确定方法:
a.当前建立时间发起沿产生的数据不能被当前建立时间捕获沿的前一个时钟沿捕获;
b.当前建立时间发起沿的下一个有效沿产生的数据不能被当前建立时间的捕获沿捕获。
从两种状况中确定所有的保持时间需求(可正可负),并以最大的保持时间需求来确定保持时间发起沿和捕获沿的位置。
二、Multicycle约束
- 为什么要进行Multilcycle约束
时序引擎默认情况下会分析建立时间/保持时间需求最严苛的情况,而这不一定与实际需要相符。实际情狂可能并不需要这么严格的时序,因此用户可以借用set_multicycle_path命令来放松某些路径的约束力度。 - tcl命令格式
set_multicycle_path <path_multiplier> [setup|hold] [-start|-end] [-from] [-to] [-through<pins|cells|nets>] - 调整规则
a.[setup|hold]:选择调整建立时间约束还是保持时间约束;
b. [-start|-end]:选择调整的时钟沿是发起时钟沿还是捕获时钟沿。调整setup时,默认调整时钟的捕获沿(-end),调整hold时,默认调整时钟的发起沿(-start)。调整规则见下表:
默认规则下,setup的path_multiplier的值为1,hold的path_multiplier的值为2 - 约束实例
情况a.源时钟和目的时钟相同
默认情况如下:
现在如果想放松setup的约束,发送沿每三个时钟周期发起一次数据,则可以将建立时间的捕获沿向后挪两个捕获沿周期:
set_multicycle_path 3 -setup -from[get_pins data0_reg/C] -to[get_pins data1_reg/D]
此时分析模型如下:
建立时间的约束是放松了,但是相应的保持时间的位置也随着建立时间捕获沿的变化而变化,此时保持时间需求过于严苛,需要再加一句tcl将保持时间的捕获沿前移:
可以右两次移发起沿:
set_multicycle_path 2 -hold -start -from[get_pins data0_reg/C] -to[get_pins data1_reg/D]
也可以左移两次捕获沿:
set_multicycle_path 2 -hold -end -from[get_pins data0_reg/C] -to[get_pins data1_reg/D]
情况b:源时钟和目的时钟相同且有正向偏移的情况下(正向偏移0.3s):
很明显,这里setup的要求过于严苛,因此将setup的检测沿向后移一个周期:
set_multicycle_path 2 -setup -from[get_clocks clk1] -to [get_clocks clk2]
约束后hold的需求也发生变化,变化结果正确,所以不需要再做hold的约束
情况c:源时钟比目的时钟慢
set_multicycle_path 2 -setup -end -from[get_clocks clk1] -to[get_clocks clk2]
这会将setup的捕获沿向后移动一个时钟周期:
hold的检测边沿也会随之移动,如果做如下约束:
set_multicycle_path 1 -hold -from[get_clocks clk1] -to[get_clocks clk2]
则会将hold的发起沿向后移一个周期,因为hold默认是移动发起沿的
这样保持时间未免过于宽松,调整捕获沿的位置,加上-end
set_multicycle_path 1 -hold -end -from[get_clocks clk1] -to[get_clocks clk2]
这就是我们想要的约束了
情况d:源时钟比目的时钟快,默认如下:
放松建立时间需求:
set_multicycle_path 3 -setup -start -from[[get_clocks clk1] -to[get_clocks clk2],得到如下结果:
因为保持时间分析是以建立时间分析为基础的,当建立时间的发起沿移动后,保持时间有两种情况:
这里很明显hold_b的约束更严苛,所以会以hold_b来分析建立时间,为了放松建立时间约束:
set_multicycle_path 2 -hold -from[[get_clocks clk1] -to[get_clocks clk2]
这样就是我们想要的约束了