相关阅读

静态时序分析icon-default.png?t=N7T8https://blog.csdn.net/weixin_45791458/category_12567571.html?spm=1001.2014.3001.5482


目录

时钟分频器

时钟倍频器

时钟门控

创建生成时钟指令的BNF范式

标识生成时钟源

指定生成时钟的源引脚

生成时钟命名

设定生成时钟特性


        有时候,复杂的设计需要多个时钟来完成相应的操作,当设计中有多个时钟存在时,它们需要相互协作或各司其职。有几种时钟可能由其他时钟而派生或者说生成,在定义这些时钟时需要使用创建生成时钟命令create_generated_clock。这类时钟可能是时钟分频器,时钟倍频器和时钟门控。

时钟分频器

        时钟分频器产生一个比原始时钟频率更低(周期更长)的时钟信号。典型的时钟分频器是由多个T触发器串联构成的异步计数器。异步计数器的电路如图1所示,产生的时钟波形如图2所示。对于该电路,如果输入的时钟周期是10ns,则在clk_1的时钟周期是20ns,clk_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]
    [-edges edge_list] [-edge_shift edge_shift_list]
    [-combinational] [-comment comment_string]
    -source master_pin source_objects
    //注:该命令的选项和参数顺序任意

标识生成时钟源

        就像create_clock指令一样,创建一个生成时钟同样需要它的时钟源对象,简单来说就是生成时钟生成的位置,源对象可以是一个端口(port)或者是一个引脚(pin)。一个生成时钟可能有多个时钟源,当然一个时钟源上也可能有多个生成时钟。

指定生成时钟的源引脚

        指定生成时钟的源引脚可以使用-source选项。这个选项指明生成时钟是由哪个引脚或端口上的时钟派生的,这个原时钟被称为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定义生成时钟是不必要的,可以让开发工具自行推断出最后生成的时钟而不去单独创建。但这是错误的,比如对于图1的分频器,如果只在clk处定义了时钟,开发工具不会认为clk_1和clk_2处生成的是时钟信号,因为所有时钟信号在传播到触发器的时钟端后即终止传播,如图6的时钟树报告所示,故不能用clk_1和clk_2信号去触发后面的触发器,这导致了后面的触发器是无约束的。此时可以在clk_1和clk_2上定义生成时钟,来约束分频时钟控制的触发器。

图6 时钟树报告

生成时钟命名

        和普通的时钟一样,每一个生成时钟对象的创建都会给生成时钟命名,使用-name选项可以指定一个生成时钟名,当没有使用选项指定时,默认使用生成时钟源名作为生成时钟名。在有些情况下,-name选项是必须的,比如当使用了-add选项时,关于这点,将在后面进行介绍。

设定生成时钟特性

        设定生成时钟的特性可利用以下三个选项当中的一个:

  1. -edges——选项的参数一个列表,指明了生成时钟的边沿是如何与master_clock的边沿对齐的。列表中的第1个数表示生成时钟的第1个上升沿对应master clock的第几个沿(master clock的沿的编号是waveform开始从左到右,从1开始依次增加),第2个数表示生成时钟的第1个下降沿对应master clock的第几个沿,第3个数表示生成时钟的第2个上升沿对应master clock的第几个沿,以此类推。列表中需要至少有3个以上的奇数个沿表示一个完整的周期,生成时钟的周期就是第1个上升沿到最后1个上升沿之间的时间(上升沿-下降沿-上升沿...)。
  2. -divide by——选项的参数是一个除法因子,表示分频倍数,周期通过这个因子翻倍。
  3. -multiply_by——选项的参数是一个乘法因子,表示倍频倍数,周期要除以这个因子。

        需要注意的是,尽管时钟是通过周期来定义的,但divide by和multiply_by是针对频率而言的。

        总的来说,任何使用-divide_by或multiply_by选项来表示的生成时钟,也可以使用-edges来表示,反之则未必正确。参考图1,假设在clk处定义时钟,在clk_1和clk_2上定义生成时钟。

create_clock -period 10 -waveform {10 15} [get_port clk]

################################################################################
#可以使用-divide_by
create_generated_clock -source [get_port clk] 
    -divide_by 2 [get_port clk_1]
create_generated_clock -source [get_port clk] 
    -divide_by 4 [get_port clk_2]

#下面的形式也可以,即其中一种生成时钟的master_clock是另一个生成时钟
create_generated_clock -source [get_port clk] 
    -divide_by 2 [get_port clk_1]
create_generated_clock -source [get_port clk_1] 
    -divide_by 2 [get_port clk_2]

################################################################################
#使用-edges也可以
create_generated_clock -source [get_port clk] 
    -edges {1 3 5} [get_port clk_1]
create_generated_clock -source [get_port clk]
    -edges {1 5 9} [get_port clk_2]

#下面的形式也可以,即其中一种生成时钟的master_clock是另一个生成时钟
create_generated_clock -source [get_port clk] 
    -edges {1 3 5} [get_port clk_1]
create_generated_clock -source [get_port clk_1]
    -edges {1 3 5} [get_port clk_2]

        首先可以使用-edges创建生成时钟,{1 3 5}表示生成时钟的第1个上升沿,对应源时钟由的第1个沿(上升沿),生成时钟的第1个下降沿,对应源时钟的第3个沿(下降沿),生成时钟的第2个上升沿,对应源时钟的第5个沿(上升沿),生成时钟的周期是源时钟由waveform开始计算的第1个沿到源时钟由waveform开始计算的第5个沿的时间,即20ns(本段所指边沿的位置,不考虑自动推理)

        下面使用-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_port clk]

#根据这个时钟使用-divide_by创建分频时钟,结果如图8所示
create_generated_clock -source [get_port clk] -divide_by 2 [get_port clk_0]

图8 上升沿对齐,周期在上下脉冲间均分

         对于使用-multiply_by的生成时钟,无法保证倍频得到的生成时钟的第一个上升沿与master clock的第一个上升沿对齐。Design Compiler的处理方式是将所有沿的出现时间除以倍频因子,这样能保证所有脉冲占空比与之前相同,具体如下例所示。

#定义了一个复杂的时钟波形
create_clock -period 20 -waveform {2 5 12 15} [get_port clk]

#根据这个时钟使用-multiply_by创建分频时钟,结果如图9所示
create_generated_clock -source [get_port clk] -multiply_by 2 [get_port clk_0]

图9 倍频之后的waveform相当于之前的waveform除以倍频因子

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐