SDC命令详解:使用create_generated_clock命令进行约束(上)

张开发
2026/7/1 22:56:15 15 分钟阅读
SDC命令详解:使用create_generated_clock命令进行约束(上)
相关阅读SDC命令详解https://blog.csdn.net/weixin_45791458/category_12931432.html?spm1001.2014.3001.5482目录时钟分频器时钟倍频器时钟门控创建生成时钟命令的BNF范式标识生成时钟源指定生成时钟的源引脚生成时钟命名设定生成时钟特性有时候复杂的设计需要多个时钟来完成相应的操作当设计中有多个时钟存在时它们需要相互协作或各司其职。有几种时钟可能由其他时钟而派生或者说生成在定义这些时钟时需要使用创建生成时钟命令create_generated_clock。这类时钟可能是时钟分频器时钟倍频器和时钟门控。时钟分频器时钟分频器产生一个比原始时钟频率更低周期更长的时钟信号。典型的时钟分频器是由多个T触发器串联构成的异步计数器。异步计数器的电路如图1所示产生的时钟波形如图2所示。对于该电路如果输入的时钟周期是10ns则clk_1的时钟周期是20nsclk_2的时钟周期是40ns。图1 异步计数器图2 分频器电路时钟波形时钟倍频器时钟倍频器是一种通过增加时钟频率来获得更快时钟速度的电路。这种技术通常用于微处理器和内部总线并配合内部高速缓存以提高处理器的吞吐量。图3给出了一个简单的时钟倍频器电路电路利用延迟的时钟和原时钟异或产生更高的时钟频率延迟可以使用反相器或缓冲器得到产生的时钟波形如图4所示。在一般情况下通过PLL锁相环实现时钟倍频。图3 简单的时钟倍频器图4 倍频器电路时钟波形时钟门控自20世纪90年代中期以来时钟门控成为了一种非常流行的减少功耗的技术。当触发器或寄存器因时钟触发而翻转时会产生一定的动态功耗。然而某些情况下部分电路在特定时间无需工作此时禁用这些电路的时钟可以减少不必要的功耗这称为时钟门控。图5给出了门控时钟的一个简单实现更复杂的实现可以参考以往的文章。图5 门控时钟创建生成时钟命令的BNF范式SDC命令中用于创建生成时钟的命令是create_generated_clock。该命令的BNF为create_generated_clock [-name clock_name] [-add] [-master_clock clock] [-divide_by divide_factor | -multiply_by multiply_factor] [-duty_cycle percent] [-invert] [-preinvert] //该选项在SDC 2.2引入 [-edges edge_list] [-edge_shift edge_shift_list] [-combinational] [-comment comment_string] -source master_pin source_objects //注该命令的选项和参数顺序任意标识生成时钟源就像create_clock命令一样创建一个生成时钟同样需要它的时钟源对象简单来说就是生成时钟生成的位置源对象可以是一个端口(port)或者是一个引脚(pin)。一个生成时钟可能有多个时钟源当然一个时钟源上也可能有多个生成时钟。如果指定的对象是一个叶单元的引脚则该引脚所属的叶单元会被设置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属性的原因显式或隐式。指定生成时钟的源引脚指定生成时钟的源引脚可以使用-source选项。这个选项指明生成时钟是由哪个引脚或端口上的时钟派生的这个原时钟被称为master clock注意这里不一定要master clock的源对象是该引脚或端口该引脚或端口也不需要是生成时钟源的扇入只需要master clock能传播至该引脚或端口即可。例如在图1中可以定义两个生成时钟生成时钟源对象分别为clk_1和clk_2源引脚则定义为clk或者也可以是clk_1_reg/CK如果已在clk定义了时钟则会传播至clk_1_reg/CK需要注意的是时钟无法穿过寄存器传播。在这里需要搞清楚生成时钟源对象和生成时钟源引脚的区别生成时钟源对象指的是生成时钟定义在哪个位置而生成时钟源引脚指明了哪个是获得生成时钟的原时钟。如果一个引脚或端口上有多个时钟传播至此则无法推断出生成时钟属于哪个master clock需要显式指明。这可以使用-master_clock选项实现只需指定参数为master clock的名字即可。在创建了生成时钟后开发工具将基于master clock的属性派生生成时钟的属性如波形、周期等。指定生成时钟的源引脚只是用于确定master clock及其极性如果master clock传播至生成时钟源引脚时极性为负也就是反相的比如在时钟路径上存在奇数个反相器/与非/或非门则本文后面谈到的master clock的waveform指的是原waveform反相后的这将在讨论-preinvert选项时详细说明对于master clock为传播时钟的情况master clock到生成时钟的延迟并不依赖源引脚而是依赖master clock源对象到生成时钟源对象。在这里有必要说明一下定义生成时钟的必要性。有人可能会认为根据master clock定义生成时钟是不必要的可以让开发工具自行推断出最后生成的时钟而不去单独创建。但这是错误的比如对于图1的分频器如果只在clk处定义了时钟开发工具不会认为clk_1和clk_2处生成的是时钟信号因为所有时钟信号在传播到触发器的时钟端后即终止传播如图6的时钟树报告所示该报告使用report_transitive_fanout -clock_tree命令产生故不能用clk_1和clk_2信号去触发后面的触发器这导致了后面的触发器是无约束的。此时可以在clk_1和clk_2上定义生成时钟来约束分频时钟控制的触发器。图6 时钟树报告生成时钟命名和普通的时钟一样每一个生成时钟对象的创建都会给生成时钟命名使用-name选项可以指定一个生成时钟名当没有使用选项指定时默认使用生成时钟源名作为生成时钟名。在有些情况下-name选项是必须的比如当使用了-add选项时关于这点将在后面进行介绍。设定生成时钟特性设定生成时钟的特性可利用以下三个选项当中的一个-edges——选项的参数一个列表指明了生成时钟的边沿是如何与master clock的边沿对齐的。列表中的第1个数表示生成时钟的第1个上升沿对应master clock的第几个沿master clock的沿的编号是waveform开始从左到右从1开始依次增加第2个数表示生成时钟的第1个下降沿对应master clock的第几个沿第3个数表示生成时钟的第2个上升沿对应master clock的第几个沿以此类推。列表中需要至少有3个以上的奇数个沿表示一个完整的周期生成时钟的周期就是第1个上升沿到最后1个上升沿之间的时间上升沿-下降沿-上升沿...。-divide_by——选项的参数是一个除法因子表示分频倍数周期通过这个因子翻倍。-multiply_by——选项的参数是一个乘法因子表示倍频倍数周期要除以这个因子。需要注意的是尽管时钟是通过周期来定义的但divide_by和multiply_by是针对频率而言的。总的来说任何使用-divide_by或multiply_by选项来表示的生成时钟也可以使用-edges来表示反之则未必正确。参考图1假设在clk处定义时钟在clk_1和clk_2上定义生成时钟。使用-edges创建生成时钟参数{1 3 5}表示生成时钟的第1个上升沿对应master clock由的第1个沿上升沿生成时钟的第1个下降沿对应master clock的第3个沿下降沿生成时钟的第2个上升沿对应master clock的第5个沿上升沿生成时钟的周期是master clock由waveform开始计算的第1个沿到master clock由waveform开始计算的第5个沿的时间即20ns这里所指边沿的位置不考虑自动推理。需要注意的是使用-divide_by选项和-multiply_by选项创建的生成时钟的waveform中的边沿数与master clock相同而对于-edges选项则没有这个要求。create_clock -period 10 -waveform {10 15} [get_ports clk] ################################################################################ #可以使用-divide_by create_generated_clock -source [get_ports clk] -divide_by 2 [get_ports clk_1] create_generated_clock -source [get_ports clk] -divide_by 4 [get_ports clk_2] #下面的形式也可以有相同的效果即其中一种生成时钟的master clock是另一个生成时钟 create_generated_clock -source [get_ports clk] -divide_by 2 [get_ports clk_1] create_generated_clock -source [get_ports clk_1] -divide_by 2 [get_ports clk_2] ################################################################################ #使用-edges也可以 create_generated_clock -source [get_ports clk] -edges {1 3 5} [get_ports clk_1] create_generated_clock -source [get_ports clk] -edges {1 5 9} [get_ports clk_2] #下面的形式也可以有相同的效果即其中一种生成时钟的master clock是另一个生成时钟 create_generated_clock -source [get_ports clk] -edges {1 3 5} [get_ports clk_1] create_generated_clock -source [get_ports clk_1] -edges {1 3 5} [get_ports clk_2]下面展示了使用-divide_by选项创建生成时钟的情况可以使用report_clock报告设计中的各个时钟的情况如图7所示可以看到使用-divide_by选项生成的时钟的第一个上升沿与master clock的第一个上升沿是对齐的如果使用-edges选项则没有此要求生成的时钟的第一个上升沿可以与master clock的任何一个沿对齐。图7 时钟报告对于使用-divide_by选项的生成时钟除了周期有相应改变外其他性质有什么变化呢前面其实已经谈到了一个使用-divide_by选项分频得到的生成时钟的第一个上升沿与master clock的第一个上升沿对齐。对于其他上升下降沿Design Compiler的处理方式是将周期平均分给所有的上下脉冲也就是说无法保证占空比与分频前一致具体如下例所示。#定义了一个复杂的时钟波形 create_clock -period 20 -waveform {2 5 12 15} [get_ports clk] #根据这个时钟使用-divide_by创建分频时钟结果如图8所示 create_generated_clock -source [get_ports clk] -divide_by 2 [get_ports clk_0]图8 上升沿对齐周期在上下脉冲间均分对于使用-multiply_by选项的生成时钟无法保证倍频得到的生成时钟的第一个上升沿与master clock的第一个上升沿对齐。Design Compiler的处理方式是将所有沿的出现时间除以倍频因子这样能保证所有脉冲占空比与之前相同具体如下例所示。#定义了一个复杂的时钟波形 create_clock -period 20 -waveform {2 5 12 15} [get_ports clk] #根据这个时钟使用-multiply_by创建倍频时钟结果如图9所示 create_generated_clock -source [get_ports clk] -multiply_by 2 [get_ports clk_2]图9 倍频之后的waveform相当于之前的waveform除以倍频因子下一节SDC命令详解使用create_generated_clock命令进行约束下https://chenzhang.blog.csdn.net/article/details/134290809

更多文章