SDC命令详解:使用create_clock命令进行约束
相关阅读SDC命令详解https://blog.csdn.net/weixin_45791458/category_12931432.html?spm1001.2014.3001.5482目录定义时钟周期标识时钟源命名时钟指定波形同源多时钟注释时钟虚拟时钟Multicorner-Multimode支持写在最后在当前设计中创建一个时钟对象的SDC命令是create_clock。本文针对Design Compiler但该命令同样存在于PrimeTime、IC Compiler等工具中它们大致相同略有差别。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_ports clk] #使用输出引脚作为时钟源 create_clock -period 10 [get_pins U4/Y] #使用输入引脚作为时钟源 create_clock -period 10 [get_pins U4/B]图1 第一个例子如果指定的对象是一个叶单元的引脚则该引脚所属的叶单元会被设置size only属性确保其不会在综合过程中被优化掉需要注意的是此时的size_only属性是隐式设置的这与使用set_size_only命令显式设置不同无法使用report_attribute命令或get_attribute命令直接查看而只能使用report_cell命令或report_size_only命令间接查看隐式size_only属性的优先级高于显式size_only属性使用list_size_only_types命令可以列出叶单元被设置size_only属性的原因显式或隐式。如果指定的对象是一个层次单元的引脚则层次单元引脚扇出的第一个组合逻辑叶单元会被设置size only属性确保其不会在综合过程中被优化掉需要注意的是此时的size_only属性是隐式设置的这与使用set_size_only命令显式设置不同无法使用report_attribute命令或get_attribute命令直接查看而只能使用report_cell命令或report_size_only命令间接查看隐式size_only属性的优先级高于显式size_only属性使用list_size_only_types命令可以列出叶单元被设置size_only属性的原因显式或隐式。命名时钟每一个时钟对象的创建都会给时钟命名使用-name选项可以指定一个时钟名当没有使用选项指定时默认使用时钟源对象名字作为时钟名。对于前面的例子时钟名分别是clk、U4/Y、U4/B。在SDC中时钟对象的名字至关重要因为所有依赖于此时钟对象的SDC命令可以通过名字引用它而无需使用其他信息。在有些情况下-name选项是必须的比如当使用了-add选项时用于在同一个时钟源上定义多个时钟关于这点将在后面进行介绍。最后顺带一提如果定义个两个同名时钟后定义的时钟也会覆盖先定义的时钟。//在时钟端口定义了一个时钟名为clk create_clock -period 10 [get_ports clk] //在时钟端口又定义了一个时钟名为clk这会覆盖之前在端口定义的时钟 create_clock -period 20 [get_ports clk] //定义了一个名为clk1的时钟这是不建议的因为最好使时钟名与时钟端口名一致 create_clock -period 10 -name clk1 [get_ports clk_1] //又定义了一个叫clk1的时钟这覆盖了之前的定义即使它们没有定义在同一个端口上 create_clock -period 10 -name clk1 [get_ports clk_2]指定波形只指定时钟周期不足以完全描述一个时钟信号的特征-waveform选项用于指定波形的形状。该选项的参数是一个正实数列表依次表示出现时钟信号的第一个上升沿、下降沿、上升沿......出现的时间。例如对于图2的波形在t5ns时出现上升沿在t10ns时出现下降沿。因此创建这个对象使用的命令是#假设在端口clk上创建时钟 create_clock -period 10 -waveform {5 10} [get_ports clk] #第二个上升沿出现在t15ns时注意创建的波形在t0ns时会有下降沿因为t10ns时有下降沿周期为10ns则也代表t0ns时也有下降沿即会自动推理出完整波形。图2 第二个例子需要注意的是waveform列表中的数有一些限制列表中的时间必须递增、时间个数必须是偶数个即只能按一对上下沿给出 、跨度即第一个和最后一个时间的差必须小于时钟周期例如下面给出了几个不合法的waveform格式。create_clock -period 10 -waveform {5 6 7} [get_ports clk] create_clock -period 10 -waveform {5 4 3 2} [get_ports clk] create_clock -period 10 -waveform {5 4 16 18} [get_ports clk]下面的命令所创建的时钟拥有图3所示的波形可以看出t0ns时的下降沿t5ns时的上升沿t10ns时的下降沿被自动推理出来了。create_clock -period 10 -waveform {15 20} [get_ports clk]图3 第三个例子虽然存在时钟波形推理但是使用report_clock命令时报告中的waveform不会包含这些推断出来的沿只是这些推断出来的沿会在时序分析计算时起作用图4显示的就是使用report_clock命令报告的上面命令所创建时钟的waveform。在后面文章中涉及到的有关边沿位置例如第一个上升沿是不包含自动推理的沿而指的是waveform中的沿。图4 时钟报告如果不指定-waveform选项则时钟默认占空比50%且在t0时上升在tperiod/2 ns处下降。如下面的命令创建的时钟波形如图5所示。create_clock -period 10 [get_ports clk] #等价于下面的命令 create_clock -period 10 -waveform {0 5} [get_ports clk]图5 第五个例子现在考虑如图6所示的波形注意到当t0ns时目标波形的初值即为1因为必须从第一个上升沿开始指定所以无法指定t4ns时的下降沿对于这种情况我们只能使用如下命令描述出第一个上升沿后的波形然后让其自动推理。create_clock -period 10 -waveform {5 14} [get_ports clk]图6 第六个例子在一些应用中比如像脉冲消隐需要在触发器后指定的时间范围内删除数据为了减少射频干扰。这时需要模拟复杂的波形它可以使用有两个以上边沿的waveform列表来实现。考虑图7所示的周期为10ns的复杂时钟它在一个周期中有两个脉冲第一个脉冲在t3ns时出现上升沿在t5ns时出现下降沿第二个脉冲在t8ns时出现上升沿在t9ns时出现下降沿后面的波形会自动推理使用下面的命令创建该时钟create_clock -period 10 -waveform {3 5 8 9} [get_ports clk]图7 第七个例子同源多时钟许多设计需要在一个时钟源指定多个时钟注意区分这和一个时钟有多个时钟源的差别从而满足多I/O速度协议的需求。考虑图8所示的电路单元。假设通过一个多路选择器从两个时钟中选择一个驱动而这两个时钟特征不同为了模拟这种情况设计者可能需要在相同的设计源对象中创建时钟。这可以使用以下的命令#在同一个源对象上定义时钟需要使用-add选项并主动命名否则后定义的时钟会覆盖之前定义时钟 create_clock -name clk1 -period 10 [get_pins U4/Y] create_clock -name clk2 -period 10 [get_pins U4/Y] -add #这种在两个端口定义时钟的方式也可以因为时钟信号可以穿过组合逻辑传播 create_clock -name clk1 -period 10 [get_ports clk1] create_clock -name clk2 -period 10 [get_ports clk2]图8 有两个时钟驱动的电路单元在同一个对象源定义多个时钟可以让这两个时钟都参与进综合与静态时序分析中如图9所示的报告中就包含了两个时序组但是从图中可以看出由于这两个时钟出现的交互clk1时序组中的发射时钟可以是clk2当然也可以是clk1不过本图没有显示同理clk2时序组中的发射时钟可以是clk1当然也可以是clk2不过本图没有显示这不难解决只需要分别在端口定义时钟并使用set_case_analysis命令指定数据选择器的选择信号即可或者使用set_disable_timing命令中断时序弧但这些方法只能同时分析单个时钟下的情况如果需要同时考虑设计在多个时钟下的情况使用set_false_path命令或者set_clock_group命令即可。可以使用report_transitive_fanout -clock_tree -nosplit命令报告设计中的时钟树情况如图10所示。图9 两个时钟时序报告图10 报告时钟树情况但是需要注意的是如果不是将两个时钟定义在一个源对象上而是将一个时钟定义在另一个时钟的传播路径上则这个时钟会覆盖另一个时钟例如使用如下的命令后得到的时钟树如图11所示可以看到clk1和clk2两个时钟源并没有传播至触发器的时钟端。create_clock -name clk1 -period 10 [get_ports clk1] create_clock -name clk2 -period 10 [get_ports clk2] #覆盖时钟clk1和clk2因为clk3所处的源对象在clk1和clk2的传播路径中 create_clock -name clk3 -period 20 [get_pins U4/Y]图11 多个时钟的覆盖使用check_timing -override_defaults create_clock命令可以报告那些定义在另一个时钟传播路径上的时钟。注释时钟从SDC1.9开始包含create_clock在内的一些SDC命令增加了一个新的选项-comment选项用一个字符串作为属性用于显示时钟信号的文档信息以帮助理解、复用、增强SDC的可移植性并不影响综合与时序。例如create_clock -period 10 -name clk [get_ports clk]\ -comment Clock for USB block generated by PLL虚拟时钟到目前为止我们谈到的所有时钟信号都是有源对象的换句话说都是有时钟定义点的。然而在某些情况下用户需要约束电路单元中的一些端口和引脚这些端口和引脚在设计内并没有发射时钟与之对应为了描述这些片外的时钟设计者需要用到虚拟时钟的概念。虚拟时钟是指物理上不存在的时钟没有定义时钟源如下所示。create_clock -period 10 -name v_clk -waveform {0 5}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%257Drequest_ide3267dcc7cc26380435f53994dc8b9b8biz_id0utm_mediumdistribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-149578771-null-null.nonecaseutm_termMCMMspm1018.2226.3001.4450写在最后如果希望删除已创建的时钟对象可以使用remove_clock命令。最后需要注意的是使用create_clock命令创建的时钟对象是一个理想的(ideal)时钟从图8的时序报告中可以清晰的看到这一点理想的时钟代表着时钟路径上元器件带来的延迟即时钟网络延迟会被忽略此时需要使用set_clock_latency命令指定网络延迟。这也代表着只能使用set_clock_transition命令指定时钟转换时间而不能直接对时钟端口使用set_input_transition等命令。