相关阅读
静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm=1001.2014.3001.5482
目录
在一个设计中创建一个时钟对象的SDC命令是create_clock。该指令的BNF范式(有关BNF范式,可以参考以往文章)为:
create_clock
[-name clock_name] [-add] [source_objects] [-period period_value]
[-waveform edge_list ] [-comment comment_string]
//注:该命令的选项和参数顺序任意
定义时钟周期
-period选项用于定义时钟对象的周期,周期的单位由工艺库给出。下面的所有示例,默认是以纳秒(ns)为单位,时钟周期的值必须有意义即大于0。虽然set_units命令可以用来指定单位,但它不应该被主动使用,因为指定的单位不能与工艺库冲突。
标识时钟源
在创建一个时钟对象时,需要指定它的时钟源对象,简单来说就是时钟对象生成并开始传播的位置。源对象可以是,一个端口(port)或者是一个引脚(pin)。例如,对于图1,源对象可以是端口clk,与门U4的输出引脚Y,甚至U4的输入引脚B。
一个时钟对象可能有多个时钟源,当然一个时钟源上也可能有多个时钟。对于图1,假设驱动电路的时钟信号的周期是10ns。则该时钟对象的创建方式可以是:
#使用端口作为时钟源
create_clock -period 10 [get_port clk]
#使用输出引脚作为时钟源
create_clock -period 10 [get_port U4/Y]
#使用输入引脚作为时钟源
create_clock -period 10 [get_port U4/B]
图1 第一个例子
命名时钟
每一个时钟对象的创建都会给时钟命名,使用-name选项可以指定一个时钟名,当没有使用选项指定时,默认使用时钟源对象名字作为时钟名。对于前面的例子,时钟名分别是clk、U4/Y、U4/B。在SDC中,时钟对象的名字至关重要,因为所有依赖于此时钟对象的SDC命令可以通过名字引用它,而无需使用其他信息。在有些情况下,-name选项是必须的,比如当使用了-add选项时(用于在同一个时钟源上定义多个时钟),关于这点,将在后面进行介绍。最后顺带一提,如果定义个两个同名时钟,后定义的时钟也会覆盖先定义的时钟。
//在时钟端口定义了一个时钟
create_clock -period 10 [get_port clk]
//在时钟端口又定义了一个时钟,这会覆盖之前在端口定义的时钟
create_clock -period 20 [get_port clk]
//定义了一个叫clk1的时钟(这是不建议的,因为最好使时钟名与时钟端口名一致)
create_clock -period 10 -name clk1 [get_port clk_1]
//又定义了一个叫clk1的时钟,这覆盖了之前的定义(即使它们不在同一个端口上)
create_clock -period 10 -name clk1 [get_port clk_2]
指定波形
只指定时钟周期不足以完全描述一个时钟信号的特征,-waveform选项用于指定波形的形状。该选项的参数是一个正实数列表,依次表示出现时钟信号的第一个上升沿、下降沿、上升沿......出现的时间。例如,对于图2的波形,在t=5ns时出现上升沿,在t=10ns时出现下降沿。因此创建这个对象使用的命令是:
#假设在端口clk上创建时钟
create_clock -period 10 -waveform {5 10} [get_port clk]
#第二个上升沿出现在t=15ns时
注意,创建的波形在t=0ns时会有下降沿,因为t=10ns时有下降沿,周期为10ns则也代表t=0ns时也有下降沿,即会自动推理出完整波形。
图2 第二个例子
需要注意的是waveform列表中的数有一些限制:列表中的时间必须递增、时间个数必须是偶数个,即只能按一对上下沿给出 、跨度(即第一个和最后一个时间的差)必须小于时钟周期,例如下面给出了几个不合法的waveform格式。
create_clock -period 10 -waveform {5 6 7} [get_port clk]
create_clock -period 10 -waveform {5 4 3 2} [get_port clk]
create_clock -period 10 -waveform {5 4 16 18} [get_port clk]
下面的命令所创建的时钟拥有图3所示的波形,可以看出t=0ns时的下降沿,t=5ns时的上升沿,t=10ns时的下降沿被自动推理出来了。
create_clock -period 10 -waveform {15 20} [get_port clk]
图3 第三个例子
虽然存在时钟波形推理,但是使用report_clock命令时,报告中的waveform不会包含这些推断出来的沿,只是这些推断出来的沿会在时序分析计算时起作用,图4显示的就是使用report_clock命令报告的上面命令所创建时钟的waveform。在后面文章中,涉及到的有关边沿位置(例如第一个上升沿),是不包含自动推理的沿而指的是waveform中的沿。
图4 时钟报告
如果不指定-waveform选项,则时钟默认占空比50%,且在t=0时上升,在t=period/2 ns处下降。如下面的命令创建的时钟波形如图5所示。
create_clock -period 10 [get_port clk]
#等价于下面的命令
create_clock -period 10 -waveform {0 5} [get_port clk]
图5 第五个例子
现在考虑如图6所示的波形,注意到当t=0ns时,目标波形的初值即为1,因为必须从第一个上升沿开始指定,所以无法指定t=4ns时的下降沿,对于这种情况,我们只能使用如下命令,描述出第一个上升沿后的波形,然后让其自动推理。
create_clock -period 10 -waveform {5 14} [get_port clk]
图6 第六个例子
在一些应用中,比如像脉冲消隐,需要在触发器后指定的时间范围内删除数据,为了减少射频干扰。这时需要模拟复杂的波形,它可以使用有两个以上边沿的waveform列表来实现。考虑图7所示的周期为10ns的复杂时钟,它在一个周期中有两个脉冲,第一个脉冲在t=3ns时出现上升沿,在t=5ns时出现下降沿,第二个脉冲在t=8ns时出现上升沿,在t=9ns时出现下降沿,后面的波形会自动推理,使用下面的命令创建该时钟:
create_clock -period 10 -waveform {3 5 8 9} [get_port clk]
图7 第七个例子
同源多时钟
许多设计需要在一个时钟源指定多个时钟(注意区分这和一个时钟有多个时钟源的差别),从而满足多I/O速度协议的需求。考虑图8所示的电路单元。
假设通过一个多路选择器从两个时钟中选择一个驱动,而这两个时钟特征不同,为了模拟这种情况,设计者可能需要在相同的设计源对象中创建时钟。这可以使用以下的命令:
#在同一个源对象上定义时钟,需要使用-add选项并主动命名,否则后定义的时钟会覆盖之前定义时钟
create_clock -name clk1 -period 10 [get_pin U4/Y]
create_clock -name clk2 -period 10 [get_pin U4/Y] -add
#这种在两个端口定义时钟的方式也可以,因为时钟信号可以穿过组合逻辑传播
create_clock -name clk1 -period 10 [get_port clk1]
create_clock -name clk2 -period 10 [get_port clk2]
图8 有两个时钟驱动的电路单元
在同一个对象源定义多个时钟,可以让这两个时钟都参与进综合与静态时序分析中,如图9所示的报告中就包含了两个时序组,但是从图中可以看出,由于这两个时钟出现的交互,clk1时序组中的发射时钟可以是clk2(当然也可以是clk1,不过本图没有显示);同理clk2时序组中的发射时钟可以是clk1(当然也可以是clk2,不过本图没有显示),这不难解决,只需要分别在端口定义时钟,并使用set_case_analysis命令指定数据选择器的选择信号即可(或者使用set_disable_timing命令中断时序弧)。可以使用report_transitive_fanout -clock_tree -nosplit 命令报告设计中的时钟树情况,如图10所示。
图9 两个时钟时序报告
图10 报告时钟树情况
但是需要注意的是,如果不是将两个时钟定义在一个源对象上,而是将一个时钟定义在另一个时钟的传播路径上,则这个时钟会覆盖另一个时钟,例如使用如下的命令后得到的时钟树如图11所示,可以看到clk1和clk2两个时钟源并没有传播至寄存器的时钟端。
create_clock -name clk1 -period 10 [get_port clk1]
create_clock -name clk2 -period 10 [get_port clk2]
#覆盖时钟clk1和clk2,因为clk3所处的源对象在clk1和clk2的传播路径中
create_clock -name clk3 -period 20 [get_pin U4/Y]
图11 多个时钟的覆盖
注释时钟
从SDC1.9开始,包含create_clock在内的一些SDC命令增加了一个新的选项,-comment选项用一个字符串作为属性,用于显示时钟信号的文档信息,以帮助理解、复用、增强SDC的可移植性,并不影响综合与时序。例如:
create_clock -period 10 -name clk [get_port clk]\
-comment "Clock for USB block generated by PLL"
虚拟时钟
到目前为止,我们谈到的所有时钟信号都是有源对象的,换句话说,都是有时钟定义点的。然而在某些情况下,用户需要约束电路单元中的一些端口和引脚,这些端口和引脚在设计内并没有发射时钟与之对应,为了描述这些片外的时钟,设计者需要用到虚拟时钟的概念。虚拟时钟是指物理上不存在的时钟,没有定义时钟源,如下所示。
create_clock -period 10 -name v_clk -waveform {0 5}
写在最后
最后需要注意的是,使用create_clock命令创建的时钟对象是一个理想的(ideal)时钟,从图8的时序报告中可以清晰的看到这一点,理想的时钟代表着时钟路径上元器件带来的延迟(即时钟网络延迟)会被忽略,此时需要使用set_clock_latency命令指定网络延迟。这也代表着只能使用set_clock_transition命令指定时钟转换时间,而不能直接对时钟端口使用set_input_transition等命令。