set_clock_groups/Logically Exclusive/Physically Exclusive Clocks/create_clock

目录

1.set_clock_groups 

1.1 有多个 -group

1.2 有单个 -group

1.3 多级使用set_clock_groups

1.4 asynchronous/logically_exclusive/physically_exclusive 三个参数区别

1.4.1 总结

1.5实例分析

方法一:

方法二:

补充说明:


1.set_clock_groups 

        在硬件设计中,没有设置clock groups前,综合工具是把所有的clk作为同步clk来处理,具体的表现是工具会分析所有任意两两clk的timing。所以应该理解为:增加group 是在原来同步的基础上增加异步描述,不在描述中的还保持同步关系【当然也可能是clk之间没有path】

        set_clock_groups 命令有三个选项:“-asynchronous”,“-logically_exclusive”,“-physically_exclusive”

        上面三个选项其实是为了不同场景下设置clock groups更容易理解,其实实际的作用是一样的。也就是让不同的clk groups之间不进行timing check。

        假设一个设计中有clk_a, clk_b, clk_c, clk_d, clk_e, clk_f共六个时钟。set_clock_groups有以下写法:

1.1 有多个 -group

set_clock_groups -asynchronous -name async_xxx0_group \
                     -group [list clk_a clk_b] \
                     -group [list clk_c clk_d]

set_clock_groups -logically_exclusive -name async_xxx1_group \
                     -group [list clk_a clk_b] \
                     -group [list clk_c clk_d]

set_clock_groups -physically_exclusive -name async_xxx1_group \
                     -group [list clk_a clk_b] \
                     -group [list clk_c clk_d]

上面三条语句其实都是一个效果:

from clk_a to clk_c/clk_d不check timing

from clk_b to clk_c/clk_d不check timing

from clk_c to clk_a/clk_b不check timing

from clk_d to clk_a/clk_b不check timing

其他clk之间都check timing【包括不在分组之内的clk_e和clk_f

套用同异步的概念,六个时钟,只有 clk_a and clk_b和clk_c and clk_d是异步的其他两两之间都是同步时钟。

从上面的效果来说,又可以等价为以下的语句

set_false_path -from [get_clocks [list clk_a clk_b]] -to \
[get_clocks [list clk_c clk_d]]

set_false_path -from [get_clocks [list clk_c clk_d]] -to \
[get_clocks [list clk_a clk_b]]

        虽然set_clock_groups的三种形式和set_false_path的作用效果是一样的 但是这些命令是各自用在不同的场景下,比如全部用set_false_path就体现不出clk group及同异步的概念。后续章节也会介绍set_clock_groups的三种形式的各自场景。

1.2 有单个 -group

set_clock_groups -asynchronous -name async_xxx0_group \
                     -group [list clk_a clk_b]

set_clock_groups -logically_exclusive -name async_xxx1_group \
                     -group [list clk_a clk_b]

set_clock_groups -physically_exclusive -name async_xxx1_group \
                     -group [list clk_a clk_b]

这种只有单-group的含义是

clk_a和clk_c, clk_d, clk_e, clk_f都不需要check timing

clk_b和clk_c, clk_d, clk_e, clk_f都不需要check timing

clk_a和clk_b需要check timing

clk_c, clk_d, clk_e, clk_f 相互之间需要check timing

或者套用同异步说法 clk_a和clk_b同步和其他clk都是异步

1.3 多级使用set_clock_groups

        在介绍“-asynchronous”,“-logically_exclusive”,“-physically_exclusive”三个参数区别之前,本节只用“-asynchronous”来举例,其他两个参数也是相同的用法。

        当 set_clock_groups 命令中多个 groups 被指定时,同一个时钟不能出现在不同的 group 中,但是可以存在于多次 set_clock_groups 命令使用。

例如:设计认为clk_a和clk_b是同步clk,clk_a和clk_d也同步,但是clk_b和clk_d异步,我们先写出下面的约束:

set_clock_groups -asynchronous \
        -group {Clk_a Clk_b} \
        -group {Clk_c} \
        -group {Clk_a Clk_d}

结果运行发现上面这种写法就是错的,这是因为工具无法实现clk_a自身clk domain内不check timing

但是我要怎么实现clk_b和clk_d之间不check timing呢?

实现方法如下:

set_clock_groups -asynchronous \
        -group {Clk_a Clk_b} \
        -group {Clk_c}

set_clock_groups -asynchronous \
        -group {Clk_a Clk_d} \
        -group {Clk_c}


set_clock_groups -asynchronous \
        -group {Clk_b} \
        -group {Clk_d}

1.4 asynchronous/logically_exclusive/physically_exclusive 三个参数区别

  • asynchronous

        多个时钟之间相位关系不确定,就可以将这两个(或多个)时钟是asynchronous,一般而言当时钟来自于不同的PLL或者晶振时,时钟之间的相位是不固定的。此时就用asynchronous来设置异步时钟分组。

  • logically_exclusive

        如果一个电路中有两个 clock, 但是有一个选择信号控制这两个 clock,那么在这个mux之后会存在两个clk,这两个clk就可以设置为logically_exclusive.

        set_clock_groups/Logically Exclusive/Physically Exclusive Clocks/create_clock_第1张图片

        设logically_exclusive一定要满足这两个clk在传播路径上没有相互的path,为了保证这一点,就需要在mux的两个输入端generated 新的clk,设新generated 的clk之间是logically_exclusive,那么路径上寄存器就不会检查这两个新的generated clk之间的timing。

        如上图可以在pin_2和pin_3 generated clk并设为logically_exclusive,而不能将pin_0和pin_1上的clk设为logically_exclusive。pin0clk和pin1clk是有path的,而且不是异步电路 是需要收timing的。

        需要注意的是上文中所说的mux是一种准静态或静态选择,在电路工作时只能选pin2clk或pin3clk。假如是个动态选择,比如上一拍选择pin2clk,下一拍选择pin3clk,这时就会出现B0寄存器用pin2clk launch ,B1寄存器用pin3clk capture的情况,这时是需要check timing的。

  • physically_exclusive

        如果两个 clock 定义在同一个端口上,那么这两个 clock 在物理层面就是不可能同时存在的,此时就需要声明成 physical exclusive.

        还是参考上图,pin4会流过两个clk,一个是clk0一个是clk0的二分频。这两个频率是准静态或静态切换的。那么可以在pin4上分别generated pin4clk0和pin4clk0_d2,把这两个clk设为physically_exclusive。

        还有一种情况某一个clk pin上在function mode是funClk在testMode是testCk,而且后端flow要求funMode和testMode一起收timing【大部分情况下是单独收timing】,那么funclk和testCk就可以在这个pin上设为physically_exclusive。

1.4.1 总结

总结起来:

asynchronous:就用在设置异步时钟分组

logically_exclusive:就是两个时钟同时存在,且有一个选择端控制这两个信号,后续clkpath在工作时只选择一个clk

physically_exclusive:两个 clock 不可能同时出现在电路中(比如定义在同一个点上)

        有前文说明 这三个参数的实际作用是一样的,我们不考虑asynchronous,因为这个场景很明确。logically_exclusive和physically_exclusive是否可以混用呢?

        答案是肯定的 【经过在dc工具上验证的结论】上图中我们可以把pin2clk和pin3clk 设为physically_exclusive。同样也可以把pin4clk0和pin4clk0_d2设为logically_exclusive。或者设计中我们只用physically_exclusive或只用logically_exclusive,更有甚者我们把pin2clk和pin3clk 设为asynchronous,把pin4clk0和pin4clk0_d2设为asynchronous,这些都没问题。

        但是既然工具区分了这三种应用场景,最好是按场景使用。以便于理解。

1.5实例分析

还是采用和1.4节相同的电路图:

set_clock_groups/Logically Exclusive/Physically Exclusive Clocks/create_clock_第2张图片

时钟mux是静态或准静态切换,A0--->AC0, B1--->BA0,B1--->BC0都是同步电路,需要check timing,那么我们该如何下sdc的约束呢?

方法一:

create_clock -name clk_0 -period ${CLK_PERIOD_XXX}       [get_ports pin_0]

create_generated_clock -name clk_0_d2 \
                       [get_pins div2_reg/D] \ #//pin_1
                       -master_clock clk_0 \
                       -divide_by 2 \
                       -source [get_ports pin_0] \
                       -add

create_generated_clock -name clk_0_pin_2 \
                       [get_pins pin_2] \
                       -master_clock clk_0 \
                       -divide_by 1 \
                       -source [get_ports pin_0] \
                       -add

create_generated_clock -name clk_0_d2_pin_3 \
                       [get_pins pin_3] \
                       -master_clock clk_0 \
                       -divide_by 1 \
                       -source [get_ports div2_reg/D] \ #//pin_1
                       -add



set_clock_groups -logically_exclusive  -name yyyy \
                                       -group [list clk_0_pin_2] \
                                       -group [list clk_0_d2_pin_3]

#set_clock_groups -physically_exclusive -name yyyy \
#                                       -group [list clk_0_pin_2] \
#                                       -group [list clk_0_d2_pin_3]

        其中line30--32的作用效果和line26---line28是一样的;但是line30--32写法不正规,也不容易理解。

        设logically_exclusive必须按照上面的约束,分别在pin_2和pin_3上generated clk,因为我们的目标是不检查B0和B1寄存器上传播的clk_0_d2_pin_3和clk_0_pin_2之间的timing,如果设置clk_0和clk_0_d2为logically_exclusive,那么BA0,BC0,AC0寄存器上clk_0和clk_0_d2就不会check timing,显然是不符合要求的。

方法二:

create_clock -name clk_0 -period ${CLK_PERIOD_XXX}       [get_ports pin_0]

create_generated_clock -name clk_0_d2 \
                       [get_pins div2_reg/D] \ #//pin_1
                       -master_clock clk_0 \
                       -divide_by 2 \
                       -source [get_ports pin_0] \
                       -add



create_generated_clock -name clk_pin_4_0 \
                       [get_pins pin_4] \
                       -master_clock clk_0_pin2 \
                       -divide_by 1 \
                       -source [get_ports pin_2] \
                       -add

create_generated_clock -name clk_pin_4_1 \
                       [get_pins pin_4] \
                       -master_clock clk_0_d2_pin3 \
                       -divide_by 1 \
                       -source [get_ports pin_3] \
                       -add



#create_generated_clock -name clk_0_pin_2 \
#                       [get_pins pin_2] \
#                       -master_clock clk_0 \
#                       -divide_by 1 \
#                       -source [get_ports pin_0] \
#                       -add
#
#
#create_generated_clock -name clk_0_d2_pin_3 \
#                       [get_pins pin_3] \
#                       -master_clock clk_0_d2 \
#                       -divide_by 1 \
#                       -source [get_pins div2_reg/D] \ #//pin_1
#                       -add
#
#create_generated_clock -name clk_pin_4_0 \
#                       [get_pins pin_4] \
#                       -master_clock clk_0_pin2 \
#                       -divide_by 1 \
#                       -source [get_pins pin_2] \
#                       -add
#
#create_generated_clock -name clk_pin_4_1 \
#                       [get_pins pin_4] \
#                       -master_clock clk_0_d2_pin3 \
#                       -divide_by 1 \
#                       -source [get_pins pin_3] \
#                       -add

set_clock_groups -physically_exclusive -name xxxx \
                                       -group [list clk_pin_4_0] \
                                       -group [list clk_pin_4_1]

#set_clock_groups -logically_exclusive -name xxxx \
#                                       -group [list clk_pin_4_0] \
#                                       -group [list clk_pin_4_1]

        其中line61---line63和line57---line59作用效果一样。但是line61---line63写法不正规,也不容易理解。

        无论采用line28---line55的方式generated  clk_pin_4_0和clk_pin_4_1还是采用line12---line24的方式generated clk_pin_4_0和clk_pin_4_1结果对于check timing来说都是一样的。      

补充说明:

  • 在create_clock或者create_generated_clock之后,原来在当前点传播的clk不在向后传播。
  • 在当前点create_clock或者create_generated_clock多个clk时要加上-add选项,否则在该点只有一个最后被create或generated的clk有效。

        比如说在pin_2点没有generated clk_0_pin_2之前,该点的clk属性时clk_0,generated clk_0_pin_2之后,该点及后面只有generated clk_0_pin_2在propagation而没有clk_0.

        同理在没有generated clk_pin_4_0和clk_pin_4_1之前 pin_4上传播的clk是clk_0_pin_2和clk_0_d2_pin_3,创建之后只有clk_pin_4_0和clk_pin_4_1。假如我在pin_4只创建了clk_pin_4_0,那么pin_4及以后clkTree就只有clk_pin_4_0.

        假如在pin_4 generated clk_pin_4_0和clk_pin_4_1时没有加-add,那么最终pin_4上只有clk_pin_4_1。

        create和generated clk相当于同时执行了set_sense  -type  clock -stop_propagation命令,比如在pin_2点,相当于同时执行:

set_sense  -type  clock -stop_propagation \
           -clocks [get_clocks clk_0] \
           get_pins pin_2

create_generated_clock -name clk_0_pin_2 \
                       [get_pins pin_2] \
                       -master_clock clk_0 \
                       -divide_by 1 \
                       -source [get_ports pin_0] \
                       -add

你可能感兴趣的:(芯片后端,soc,sta,set_clock_group)