create_clock
create_clock用于创建时钟,
source_objects用于定义时钟源的位置,通常是一个输入port或者pll的输出pin。如果没有source_objects,则定义了一个虚拟时钟,虚拟时钟不存在与芯片当中,通常作为参考用来设置input/output delay。
-period用来定义时钟的周期。
默认情况下,时钟有50%的占空比,在0时刻是上升沿,在一半周期处是下降沿。可以使用-waveform更改这个默认设定。例如:
第一条命令定义了周期为5,占空比为50%的时钟。第二条命令则定义了在1.0时刻为上升沿,2.0时刻为下降沿,周期为5的时钟。如下图所示:
-name选项能为时钟定义一个名字,如果不定义则默认以source object为名字
-add支持给设计中的同一source object添加多个时钟。
non-ideal时钟
set_clock_latency
使用create_clock创建的时钟默认情况下是理想的,但是真实的时钟有delay,transition,skew,uncertainty等。
set_clock_latency命令可以定义时钟的source latency与network latency之和。source latency指的是理想波形的起点到时钟定义点的delay,network latency指的是从时钟定义点到各个寄存器时钟pin口的延时,如下图所示。这个命令一般在propagated clock没有生成前使用。
或者使用命令set_propagated_clock使能传播延时(propagated delay)的计算。这是在时钟network和寄生参数确定之后进行的。
set_clock_latency命令如下:
-rise/fall分别定义上升和下降时的延时,不设定则默认为一样。
-source则只定义source latency,不包括network latency。
-early/late则会指定一个延时的范围,工具会根据需要去选择更保守的值来分析。
remove_clock_latency会删除点用户已经定义了的clock latency信息。
关于source latency,在ideal clock和propagated clock两种情况下都可以定义。当来自外部的时钟source latency不确定时,可以使用-early/late。例如source latency在1.5到2.5ns之间。
命令用了-source,则只定义source latency。并使用-early和-late分别定义了latency的范围。
set_clock_uncertainty
set_clock_uncertainty命令可以定义时钟的uncertainty和skew。
set_clock_transition
set_clock_transition命令可以定义时钟的上升和下降时间。
使用-rise/fall可以分别定义上升时间和下降时间。-min/max可以定义两种极端condition下的上升和下降时间。
report_clock
使用remove_clock,可以删除一个已经定义了的时钟。使用reset_design则会删除所有时钟和其他设计信息。
report_clock可以报告设计中已经定义好的时钟。get_clocks和all_clocks可以得到相关的时钟。例如:
命令可以找到以PHI1开头的,周期小于或等于5.0的时钟,并给出它们的报告。
多时钟约束
默认情况下,当多个时钟到达同一个寄存器的时钟pin,工具会同时考虑所有的时钟,例如寄存器被一个时钟驱动,被另一个时钟采样。
两个时钟有可能有三种关系,同步的,异步的,互斥的。如下图所示:
set_clock_groups有三个选项,-asynchronous/logic_exclusive/physical_exclusive,可以覆盖异步和互斥的情况。
同步时钟
两个时钟来自于同一个源且相位关系固定时,可以认为是同步时钟。如果不做额外的定义,工具认为时钟都是同步的,在zero时刻同步。例如,定义了如下三个时钟:
工具会取三个周期的最小公倍数12,然后分析12里面的每一个时钟沿。
使用report_interclock_relation可以报告这种时钟关系。
异步时钟
两个时钟在设计中不直接交互时可以认为是异步的。定义两个时钟为异步的,工具则不会检查它们之间的时序路径,等于是在它们之间定义了false path。定义异步时钟使用命令set_clock_groups -asynchronous
用set_clock_groups -asynchronous比设置false path效率更高,互相异步的情况下,false path需要分别使用-from,-to设置两遍
而set_clock_groups只需要一遍。
当后面只接一组group时,表示这组时钟和其他所有的时钟都是异步的,这是一种高效的设置方式。
互斥时钟
两个时钟不会同时出现,则认为是互斥的。为了使工具避免分析这种情况,可以定义false path,或者使用命令set_clock_groups -logically_exclusive定义它们为互斥的,或者使用case analysis来关闭不想分析的时钟。定义互斥的情况如下:
也可以在group中定义多个时钟。
如果只定义一个group,那它跟其他所有的时钟都互斥。
也可以给clock group定义一个名字,方便后面remove掉。
时钟互斥除了逻辑互斥,还有物理互斥,物理互斥使用set_clock_groups -physical_exclusive。逻辑互斥只会屏蔽逻辑上的交互,但工具还是会计算两个时钟间的cross talk,但物理互斥会将两者都屏蔽。
定义互斥的时候要注意,group仅限于mux之后的时钟,mux之前的时钟有可能在其他地方是不互斥的,或者只是逻辑互斥,有可能同时存在且有串扰的。
在上图中,由于F3到F4还有时序路径要check,所以不能直接给C1,C2设置physical exclusive,必须定义派生时钟GC1,GC2,给GC1和GC2设置physical exclusive。派生时钟定义的分频数为1,加上-combinatioal和-add选项,后面会对选项有详细介绍。
create_clock -period 10 -name C1 -waveform {0 5 } [get_ports C1]
create_clock -period 20 -name C2 -waveform {0 12} [get_ports C2]
create_generated_clock -name GC1 -divide_by 1 -source [get_pins mux1/A] [get_pins mux1/Z] -combinational
create_generated_clock -name GC2 -divide_by 1 -source [get_pins mux1/B] [get_pins mux1/Z] -combinational -add
set_clock_groups -physically_exclusive -group GC1 -group GC2
generated clock
如果一个时钟通过片上的逻辑从另一个时钟生成出来,那么生成出来的时钟称为派生时钟,即generated clock。
定义派生时钟使用命令create_generated_clock,工具不会分析派生的具体功能逻辑,只是计算timing delay,因此分频和倍频信息需要约束指定。当主时钟的延时和周期变化时,派生时钟也会跟随变化。例如,
注意,派生时钟的边沿都是基于主时钟的上升沿来的,如果派生时钟需要在主时钟的下降沿变化,则需要使用-edges,而不是-divide_by。例如以下波形:
对与DIV2A,以下两种写法都可以
对于DIV2B,则只能使用-edge
-combinational选项用于派生时钟中source latency的计算。
一般情况下,工具计算source latency时会计算从主时钟pin到派生时钟pin之间的组合与时序路径。有时候需要工具去忽略时序路径的计算,这时候就得加上选项-combinational。
如图所示的情况,如果想忽略sequential path,则得使用
当定义这个选项时,派生时钟和主时钟的周期一样,它只用在分频或倍频系数为1时。所以,它通常用在没有分频或倍频功能的其他派生时钟案例中。