相关阅读
SDC命令详解https://blog.csdn.net/weixin_45791458/category_12931432.html?spm=1001.2014.3001.5482
目录
设定占空比
时钟沿偏移
生成时钟源引脚出现多个时钟
组合电路生成时钟
指定生成时钟反相
指定原时钟反相
Multicorner-Multimode支持
写在最后
设定占空比
前文的末尾提到,当使用-divide by或-multiply_by选项创建生成时钟时,会根据master clock的时钟周期派生出生成时钟的周期,但对于时钟边沿的处理,两者则不一致。但是,仍然有方法在一定程度上对占空比进行设定。现在拿图1中的时钟倍频器举例说明,图2是它的波形图,假设clk的周期是20ns。
图1 时钟倍频器
图2 倍频器电路时钟波形
对clk时钟和生成时钟clk_out的定义为:
create_clock -period 20 -waveform {5 15} [get_ports clk] create_generated_clock -source [get_ports clk] -multiply 2 [get_ports clk_out]而前文所说,生成时钟的周期变为10ns,而所有的沿出现的时间都除以2,如图3所示。
图3 生成倍频时钟
此时,可以通过-duty_cycle选项设定占空比,该选项只能和-multiply_by一起使用,用以表示时钟信号中占空比,继续拿图1举例,可以看出生成时钟和原时钟的占空比都为50%,如果想要一个占空比为30%的生成时钟,则可以使用下面的命令,生成时钟的占空比可以从图4中看出确实变为了30%。
create_generated_clock -source [get_ports clk] -multiply 2 [get_ports clk_out] -add -name test -duty_cycle 30图4 -duty_cycle选项改变倍频生成时钟占空比
如果存在不止一个高脉冲会怎么样,下面像前文一样定义一个复杂的时钟,拥有两个脉冲,占空比分别为20%和25%,并试图改变它的倍频生成时钟的占比,结果如图5所示,可以看到Design Compiler直接忽略了除第一个正脉冲之外的所有脉冲。
create_clock -period 20 -waveform {2 6 12 17} [get_ports clk] create_generated_clock -source [get_ports clk] -multiply 2 [get_ports clk_out] -duty_cycle 10图5 试图改变多脉冲生成时钟的占空比
时钟沿偏移
前文介绍的-divide by和-multiply_by在生成一些波形时无能为力,因为无法控制生成信号的占空比。但-edge_shift选项使得创建任意形状的生成时钟成为了可能,下面举例说明。假设要根据图6生成图7所示的波形。
图6 原时钟波形
图7 生成时钟波形
可以使用下面的命令,这意味对于生成时钟,第一个上升沿对齐原时钟的第一个上升沿,下一个下降沿出现在原时钟的第一个上升沿后2ns,第二个上升沿出现在原时钟的第二个上升沿(第三个沿)。时钟偏移可以是正向的,也可以是负向的,这使得用-edges和-edge_shift对任意复杂波形的建模成为了可能,结果如图8所示。
create_clock -period 10 -waveform {10 15} [get_ports clk] create_generated_clock -source [get_ports clk] -edges {1 1 3} -edge_shift {0 2 0} [get_ports clk_out]图8 -edge_shift选项设置生成时钟的时钟沿偏移
生成时钟源引脚出现多个时钟
正如前文所述,如果一个引脚或端口上有多个时钟传播至此,则无法推断出生成时钟属于哪个master clock,需要显式指明。这可以使用-master_clock选项实现,只需指定参数为master_clock的名字即可,下面我们用一个例子说明这一点,对于图9所示的电路,我们在U4的输出Y上定义了两个时钟,现在假设在输出c上定义两个生成时钟,它们分别基于clk1和clk2,结果如图10所示。
图9 多个生成时钟
create_clock -name clk1 -period 10 [get_pins U4/Y] create_clock -name clk2 -period 20 [get_pins U4/Y] -add create_generated_clock -source [get_ports U4/Y] -divide_by 1 -master_clock [get_clocks clk1] [get_ports c] -name clk1_ create_generated_clock -source [get_ports U4/Y] -divide_by 1 -master_clock [get_clocks clk2] [get_ports c] -add -name clk2_图10 指定生成时钟的主时钟
组合电路生成时钟
图11给出了一个源同步接口。在源同步接口中,时钟随着数据一起作为输出,这种结构的优点是结构时钟和数据的传输延迟相同,从而它们的延时大小不重要。接收设备可以根据输入时钟对输入数据进行采样。
图11 源同步接口
图中的输出端口data_out的输出延迟应该根据输出端口clk_out的时钟设定。这种情况下,生成时钟应该定义在clk_out上。这可以利用-combinational选项实现,设定了该选项后,生成时钟的周期与master clock相同,相当于-divide_by 1,这时不能用其他任何选项,结果如图12所示。
create_clock -period 10 [get_ports clk] create_generated_clock -combinational -source [get_ports clk] [get_ports clk_out]图12 组合电路生成时钟
指定生成时钟反相
-invert选项用于将生成时钟反相,该选项是在根据其它选项之后生效,即在创建生成时钟后再将其反相,下面是该选项的使用方式,结果如图13所示。
create_clock -period 10 [get_ports clk] create_generated_clock -source [get_ports clk] -divide_by 2 [get_ports clk_out] create_generated_clock -source [get_ports clk] -divide_by 2 [get_ports clk_out] -add -name clk_out1 -invert图13 反向生成时钟
指定原时钟反相
-preinvert选项用于指定先将生成时钟的源引脚的时钟极性反相后,再根据其创建生成时钟,图14给出了一个时钟路径上存在反相的情况。
图14 时钟路径上存在反相
下面分别以clk端口和U6/Y引脚为生成时钟的源引脚,以clk_1_reg/Q为源对象创建两个二分频生成时钟,图15是此时的时钟报告,可以看出其中一个生成时钟确实按照之前讨论-divide_by选项时那样,生成时钟的第一个上升沿与master clock的第一个上升沿是对齐的,而另一个则是先将master clock反相,即waveform变成{15 25}后再进行对齐。
create_clock -period 20 -waveform {5 15} [get_ports clk] create_generated_clock -source [get_ports clk] -divide_by 2 [get_pins clk_1_reg/Q] -name clk1 create_generated_clock -source [get_pins U6/Y] -divide_by 2 [get_pins clk_1_reg/Q] -add -name clk2图15 根据反相/非反相的master clock生成的时钟
如果此时使用-preinvert选项,则会颠倒这两种情况,即原本不反相变反相,而原本反相变不反相。在某些情况下,源引脚的时钟极性会导致出现警告或错误,此时-preinvert选项可以作为一个补救方式,但最好还是明确警告或错误出现的原因,详情可见下面的博客。
静态时序分析:无法满足的生成时钟(TIM-255警告、UITE-461或PTE-075错误)https://blog.csdn.net/weixin_45791458/article/details/146171761?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522a7daf53979fb584680838b779c4ca3eb%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=a7daf53979fb584680838b779c4ca3eb&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-146171761-null-null.nonecase&utm_term=%E6%BB%A1%E8%B6%B3&spm=1018.2226.3001.4450
Multicorner-Multimode支持
该命令仅对当前场景生效,换句话说只能在当前场景创建生成时钟对象。关于场景的更多介绍,可以参考下面的博客。
Design Compiler:多工艺角和多工作模式(Multicorner-Multimode, MCMM)https://blog.csdn.net/weixin_45791458/article/details/149578771?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522e3267dcc7cc26380435f53994dc8b9b8%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=e3267dcc7cc26380435f53994dc8b9b8&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-149578771-null-null.nonecase&utm_term=MCMM&spm=1018.2226.3001.4450
逻辑库中定义的生成时钟
除了使用create_generated_clock外,还可以在逻辑库建模时就定义生成时钟,这种方式通常用于宏单元或复杂时钟转换单元,使得工具在读取库时就能够识别时钟之间的派生关系,从而减少后续约束编写的复杂度。
例如在一个简单的二分频单元中,可以在库中直接定义生成时钟(使用库单元属性generated_clock),如下所示:
cell(div_cell) { pin(clk) { direction : input; clock : true; } pin(clk_div2) { direction : output; clock : true; } generated_clock(genclk_div2) { clock_pin : clk_div2; master_pin : clk; divided_by : 2; } }需要注意的是,只有时钟确实传播到了输出引脚clk_div2的master_pin即clk引脚,生成时钟才是正确定义的,否则将被视为无master clock的生成时钟。该生成时钟在使用report_clock进行报告时,会被标注为g-lib_generated_clock,与用户自己定义的G-generated_clock进行区分(对于Design Compiler)。
除此之外,当用户使用PrimeTime将层次设计导出为Extracted Timing Model(ETM)时,如果用户在设计内(非边界)定义了生成时钟,还会创建内部引脚(Internal Pin),并在该引脚上利用库单元属性generated_clock定义生成时钟。Design Compiler在链接这种存在内部引脚的单元时,会提示"Warning: Reference *** contains internal pins with clock attribute. (TIM-103)"。
逻辑库中定义的生成时钟与create_generated_clock命令定义的生成时钟不同,无法使用write_sdc和write_script等命令写出。
写在最后
如果希望删除已创建的生成时钟对象,可以使用remove_generated_clock命令。如果该命令删除了定义在逻辑库中的生成时钟,可以使用reset_design命令将它们恢复。