本文如果有错,欢迎留言更正;此外,转载请标明出处 http://www.cnblogs.com/IClearner/  ,作者:IC_learner

  之前讲了基本的时序路径约束,现在我们来看一下其他的约束,然后通过实战来讲解一些其他的约束。实战中也没有前面的“理论”中的约束类型,但是可以通过实战来了解其他的约束。本文的具体内容是:

    ·多时钟同步约束

    ·门控时钟的约束

    (实战:)

    ·正负边沿触发器的约束

    ·输入输出延时的非默认约束

    ·输入输出有多个路径驱动(类似多时钟同步)

 

1、多时钟同步的时序约束

前面的讲了基本的时序路径约束,也就是那些约束是基于类似下面电路类型的:

                   

模块前后的时钟是同一个,因此输入输出逻辑的路径延时约束也变得简单。下面我们来对多时钟同步设计的时序路径进行约束,多时钟电路的模型如下所示:

                   

  我们要综合的模块的时钟是CLKC,但是前后模块的时钟不一定是CLKC,但是前后模块的时钟跟CLKC是来源于同一个时钟的,比如说经过锁相环分频或者倍频,这里拿分频来举例,比如说CLKA、 CLKB、CLKC、CLKD、CLKE都是由同一个时钟CLK经过分频得来,如下图所示:

             

  (虽然上面说是同步电路,但是在传统上看,上面的电路不算是同步时钟,因为他们的相位没有固定的关系;但是在这里,我们“假装”它们是同步时钟,因为理论上,是由同一个时钟分频得来的,在理想情况下,我们是可以知道它们的相位关系的)

  在我们要综合的电路中,只有一个时钟端口CLKC,即只有CLKC时钟驱动要综合电路中的寄存器。其他的时钟CLKA,CLKB,CLKD和CLKE在我们要综合的电路中并没有对应的时钟端口。因此,它们并不驱动要综合电路中的任何寄存器。它们主要用于为输入/输出端口延时作约束,可能会出现一个端口有多个约束的情况。

下面我们根据上面的例子作多时钟的同步设计约束,也就是为下面的电路类型做约束:

                     

CLKC在要综合的设计中有对应的输入端口,其定义与单时钟时一样,即:

              create_clock  -period  20  [get_ports CLKC]

  由于CLKA,CLKD和CLKE在要综合的设计中没有对应的输入端口,因此需要使用虚拟(virtual)时钟。虚拟时钟在设计里并不驱动触发任何的寄存器,它主要用于说明相对于时钟的I/O端口延迟,DC将根据这些约束,决定设计中最严格的约束。建立虚拟时钟的格式如下:

                       

上面定义了名字为VCLK的虚拟时钟,周期为20ns。因为虚拟时钟不驱动设计中的任何寄存器,设计中没有其对应的输入端口。所以定义中没有源端口或引脚。由于虚拟时钟没有对应的时钟端口,我们必须给它一个名字。与一般时钟一样,虚拟时钟是DC的内存里已定义的时钟物体(设计对象),它(们)不驱动(触发)当前设计中的任何寄存器。用作为输入/输出端口设置延迟

  例如,对于下面输入端口电路

                     

对应的约束为:

                   

由于是直接知道了外部的约束,因此可以直接约束。注意最后一条那里,这里的输入路径的对比时钟是CLKA,而不是我们要综合的模块时钟CLKC了,此外这里的路径约束是对于输入端口IN1而言,因此要具体给出输入端口的名字,而不能用[get_ports   $ALL_IN_EXCEPT_CLK]这样的了,而是要具体到某些端口了。

  其输入端口的时序关系如下图所示:

                  

如波形图所示,要综合电路的输入部分逻辑N的延时必须满足:

20 - 5.5 - Tsetup和10 -5.5 - Tsetup两个等式中最严格的情况,也就是满足:10 -5.5 - Tsetup

  (输入部分逻辑N的延时Tn满足:20ns = 5.5ns +  Tn  + Tsu +Tuncertainty和10ns =5.5ns + Tn + Tsu+Tuncertainty中最严格的,Tuncertainty在这里为0)由于是输入端口,数据是从CLKA时钟域传到CLKC时钟域,因此是从CLKA出发,也就是说数据从CLKA上升沿开始(时刻0),然后CLKC的下一个上升沿到来的时刻(时刻20)捕获数据,因此留给输入逻辑的延时是20 - 5.5 - Tsetup;CLKA下一个上升沿(时刻30ns处)又传输数据过来,而这时相对于CLKA的下一个CLKC上升沿在40ns处捕获数据,因此留给输入逻辑的延时是10 -5.5 - Tsetup;这两个延时必须同时满足,故满足10 -5.5 - Tsetup

 

  例如对于下面的输出端口电路:

                 

创建的虚拟时钟和对应的约束为:

                

第二条set_output_delay命令里,使用了-add_delay选项,意思时输出端口OUT1有多个约束,如果不加选项-add_delay,第二个set_output_delay命令将覆盖(取代)第一条set_output_delay命令,这时,输出端口OUT1只有一个约束,就达不到我们的预期要的约束了。

  时钟CLKD的频率为75MHz(300MHz/4),为了计算时钟周期,我们需要用实数来得到时钟的周期。要注意的是[expr  1/75*1000][expr  1.0/75*1000]得到的结果是不一样的,前者是0,后者不为0实数

  上面输出端口电路的约束对应的时序关系如下图所示:

                 

要综合电路的输出部分S必须满足:Ts<10-4.5Ts<6.7-2.5中最严格的要求,也就是Ts<6.7-2.5

  (Ts满足:10ns = Ts + Tuncertainty + 4.5ns和6.7ns=Ts+Tuncertainty+2.5ns中最严格的)

与前面的类似,只不过这里是数据输出端口,CLKC的上升沿是数据发送沿,CLKD和CLKE是数据接收端,因此都是从CLKC出发。比如CLKC分别从0时刻和20时刻出发,到CLKD或者CLKE的上升沿结束,跟前面同理,由此也可以得出最严格的延时约束是Ts<6.7-2.5。

由此可见,综合时,DC计算出所有时钟的公共基本周期(common base period),计算出每个可能的数据发送/数据接收时间,按最严格的情况对电路进行综合。这样可以保证得到的结果能满足所有的要求(约束),达到设计目标。

 

2、门控时钟的时序约束

门控时钟(gated clock)是进行低功耗电路设计的一种有效和常用方法。下图是门控时钟的一个例子:

                     

 

门控时钟有理想的,也有有问题的情况,如下图所示:

                 

从上面的电路图和波形图中,很容可以看出时钟的控制边沿为上升沿,门控使能信号在逻辑高电平起作用(被激活)。如果门控使能信号Cgate在时钟上升沿之前没有变化(从有效变成无效或者从无效变成有效),而是上升沿过后,门控信号才发生变化,这时门控电路的输出会产生毛刺(glitches)。

  关于门控制时钟的使能信号电路模型和时序关系图如下所示:

                     

对应的门控时钟约束为:

                      

需要说明的是,DC能自动辨认门控时钟电路。综合时,DC将根据上述的约束在门控时钟电路中增加/删除逻辑以满足门控使能信号的建立和保持时间要求。

  关于门控时钟,下面进行简单叙述。有两种门控时钟单元,一种是无锁存器(latch free)门控时钟单元,另一种是基于锁存器(latch based)门控时钟单元。前面的例子中的门控时钟单元是无锁存器的门控单元。基于锁存器门控时钟单元的结构如下图所示:

                       

这种电路结构的行为表现好像一个主从(master-slave)寄存器,它在时钟的上升沿捕获门控使能信号。这种结构的门控时钟单元的输出如下所示:

                   

 我们可以看到基于锁存器门控时钟单元不产生毛刺,因此我们建议大家使用这种门控时钟电路。但是无论使用哪种门控时钟,都会使其驱动的寄存器时钟引脚信号不能由输入端直接控制,从而降低了电路的测试覆盖率,这是要注意的(关于什么是测试覆盖率,请参考有关书籍)。

 

3、实战

本次的实战是进行其他选项的时序约束,下面直接来实战吧,不废话了:

设计原理图:

            

设计规范:

         

①准备还相关的设计源文件、编写.synopsys_dc.setu相关的配置文件

这一步跟前面章节的步骤类似,这里不再详述。

 

②在前面相关章节的约束基础上,根据设计规则进行书写相关的约束条件:

-->首先这个时钟名字为my_clk,占空比为40%(高电平占40%),没有偏移(这里的偏移是offset,而不是skew),因此之前创建时钟的约束可以改为:

  create_clock  -period  3.0  -name  my_clk  -waveform  {0 1.2}  [get_ports clk]

  其他的时钟约束需要把clk改成my_clk,然后在进行其他的输入输出等延时约束时,需要注意其对应的时钟改为my_clk。

 

 

-->附加的输入延时约束:

  这里的输入延时约束是在之前的输入延时约束的基础上附加的,我们先来看看这个约束的要求:

    1.sel端口的数据也由附加的寄存器F4提供,在F4的时钟下降沿触发之后,数据到达sel端口的时间不超过420ps。

    2.时钟信号从时钟源到F4的时钟端口有600ps的延时(包括外部的source 延时 和 内部的network延时)。

  根据上面两点,我们可以这么约束:

 set_input_delay  -max  1.02  -clock  my_clk  -add_delay  -clock_fall -network_latency_included  -source_latency_included  [get_ports  sel]

  怎么理解这句约束呢?我们先来看一下set_input_delay -max   这个命令的约束选项:

                  

                    

                                                        

                          

                          

首先是420ps的延时,这是直接给出了外部的延时;然后呢,又有时钟信号的延时600ps,因此我们这个附加的输入延时总量为420ps+600ps = 1.02ns。这里由于是附加的约束条件,因此需要加上-add_delay的选项;由于是下降沿触发,因此需要-clock_fall的选项;最后需要指明这延时不是添加在输入延时上面的,而是包含在本身的时钟延时上面的。

 

-->附加的输出延时约束:

  首先1.那里的意思是说输出端口out1的数据被F5寄存器捕获;在F5的下降沿到来之前,数据必须不晚于260ps到达out1端口,如下图所示:

                     

                                   情况a是符合要求的,而情况b是不符合要求的。

  然后是2.那里,意思是F5的network延时有500ps;当没有这个延时要求的时候,我们在下降沿附加的外部延时约束就是260ps,但是由于这500ps的延时,导致了下降沿推后,如下图所示:

                      

  这个时候,外部延时的约束就是260-500=240ps了,也就是说,模块内部的组合逻辑增加了240ps的时间延时余量,具体的约束如下所示:

 set_output_delay  -max -0.24 -clock my_clk -add_delay -clock_fall -network_latency_included  [get_ports out1]

 

-->最后是输入端负载的约束,每个输入端口都扇出到另外两个子模块(除了clk),每个子模块在内部驱动相当于3个bufbd1(输入引脚I)缓冲器,然后要求给输入端约束这个外部的电容负载;我们得到的约束如下所示:

      set all_in_ex_clk [remove_from_collection [all_inputs] [get_ports clk]]

      set_load [expr 6 * {[load_of cb13fs120_tsmc_max/bufbd1/I]}] $all_in_ex_clk

 

③启动DC,进行读入设计前的检查

  跟前面章节步骤一样,不再详述。

 

④读入设计与读入后的检查

  跟前面章节步骤一样,不再详述。

 

⑤进行约束设计与检查是否正确约束上

  跟前面章节步骤一样,不再详述。

 

⑥进行综合和综合后检查

  跟前面章节步骤一样,不再详述。

 

⑦写出相关的报告或者文件

  跟前面章节步骤一样,不再详述。

posted on 2017-04-02 13:20  IC_learner  阅读(16203)  评论(1编辑  收藏  举报