时序例外约束是什么?时序例外约束指的是约束这些路径在综合时不让工具去分析它们。
时序例外约束包括:
set_max_delay/set_min_delay;
set_multicycle_path;
set_false_path ;
set_path_margin;
这类约束常见的形式如下图中所示:
优先级:
从图中可以看出,这类约束之间存在优先级的限制,同时约束本身也有优先级的存在。
比如:一次执行下面两条约束,尽管第二条执行较晚,但是工具还是会认定第一天约束设定的15为clk1到clk2之间路径的max delay值。
再比如:对图示路径一次进行如下四条时序例外约束,优胜者是第二条,但是如果再加最后一条约束false path的优先级最高,会取代之前所有的时序例外约束。
我们先学习一下set_max_delay/set_min_delay:
首先说明一下,这不是io约束,虽然好像有点像。
默认情况下,EDA工具会根据launch和capture时钟沿自动计算允许的最大和最小路径延迟,通过set_max_delay或者set_min_delay命令可以覆盖由EDA工具计算出的最大或者最小路径延迟。
例如,通过如下命令可以设置急促请你REG_A到REG_B之间的最大路径延迟为12ns
set_max_delay 12.0 -from [get_cells REGA] -to [get_cells REGB]
此时,当寄存器间的路径延时大于 "12-寄存器B的setup_time" 时发生timing violation
类似地,可以通过如下命令设置寄存器REGA到REGB之间的最小路径延时为2ns
set_min_delay 2.0 -from [get_cells REGA] -to [get_cells REGB]
此时,当寄存器间的路径延迟小于 “2+寄存器B的hold_time” 时发生hold violation
接下来重点看一下set_false_path的用法:
首先我们需要搞清楚的是什么路径我们要把它设置为false_path ?
通过这个文档描述可以得知,false_path是逻辑电路中实际存在的电路,但是要求它没有功能性,这个没有功能性如何理解?(其实就是数据bus路径,没有逻辑控制功能的path),所以,在时序分析的时候这些路径就可以被忽略。上面还举例说明了几种fasle_path的路径:跨时钟域逻辑,寄存器静态配置逻辑,resetn和test逻辑,异步fifo的读写逻辑。
下面分析说明上述false_path如何添加约束:
1:no_function_path如何添加false_path路径:
set_fasle_path -through cell1/pin1 -through cell2/pin2
set_false_path -through cell2/pin2 -through cell1/pin1
注意上面这两条约束是不一样的。
对于no_function path,还可以使用 -through 来代替 -from or -to ,使用-through选项可以避免选择start_point和end_point,而确保选择通过某个点的所有路径。
set_false_path -through [get_pins MUX1/a0] -through [get_pins MUX2/a1]
-through 选项的顺序非常关键,上面这句约束为例,路径约束先通过了pin MUX1/a0,然后通过pin MUX2/a1.
2:复位信号如何添加fasle_path路径:
set_false_path -from [get_port reset] -to [all_registers]
上述约束是添加从reset端口到所有寄存器的路径
3:跨时钟域路径如何添加约束:
set_false_path -from [get_clocks CLKA] -to [get_clocks CLKB]
set_false_path -from [get_clocks CLKB] -to [get_clocks CLKA]
在两个时钟域之间,设置false_path,应该是相互设置为false_path,所以是2条语句
4:异步双端口RAM或者异步FIFO,读写时钟为异步时钟,如何添加约束:
set_false_path -from [get_cells <write_register>] -to [get_cells <read_registers>]
然后我们看一看set_multicycle_path:
通常情况下,两个同步的reg进行timing_check时,组合逻辑的delay必须在一个时钟周期内到达,才能满足建立时间的要求,但是在某些情况下,从一个寄存器输出到另外一个寄存器的data端需要不止一个cycle的时间,而且这又不影响逻辑的功能。此时,我们可以把这样的path约束为multicycle path,下图中所示为一个3cycle的multicycle path的电路结构图和波形图。
对于上述path我们可以添加这样的约束:
create_clock -name CLKM -period 10 [get_ports CLKM]
set_multicycle_path 3 -setup -from [get_pins UFF/Q] -to [get_pins UFF1/D]
setup检查:
默认情况下,当UFF0/CK作为launch clock时(T=0ns时),在T=10ns时UFF1/CK采集到前一级过来的数据。
但是当我们通过上述约束设置以后,launch clk的沿推到了T=30ns,因此,两个寄存器之间的组合逻辑delay的要求就放松到了30ns,这样的状态下,Tsu是容易满足的。
hold检查:待补充!
我们再来看看set_path_margin:
通过set_path_margin命令,可以设置让某条路径的时序检查更为严格或者更为宽松。
set_path_margin 1.2 -from [get_cells FF4] -to [get_cells FF5]
上述命令使得信号在被寄存器FF5采样之前相对于原来的setup time提前1.2s到达稳定状态,当该命令所设置的值为正时,时序检查更为严格;当该命令所设置的值为负时,时序检查更为宽松。
如下图所示为设置set_path_margin 之后的时序报告,margin累计在data_required time中: