之前写过一篇跟CTS相关的文章《从时钟结构上解决multi clock之间的balance矛盾》,今天来讲讲我对分频器做CTS的一些理解。
相信对分频器有了解,特别是在项目中接触过时钟复位框图的同学对下面的电路并不陌生。
clk0和clk1经过MUX后,经过任意分频器得到clk_div,clk_div驱动后面的逻辑。其中clk_cnt是根据分频系数计数的一个逻辑。
对于这种电路,我们在CTS前后的约束会有稍微不一样。在CTS后(用于PR和signoff),我们通常会约成下面的样子。这也是我们平时见得最多也最好理解的约束。
create_clock clk0 [get_pins clk0]
create_clcok clk1 [get_pins clk1]
create_generated_clock clk_div [get_pinsreg1/Q]
但是在CTS时,如果使用上面同样的约束,那么工具在做时钟树综合时,因为看到在reg1/Q处generate了一个时钟,所以会将reg1/CK设成non stop pin。也就是只在reg0和reg2之间做balance(把它们的clock skew尽可能做小),reg1却不会参与balance。这样的后果是,在signoff时,reg0和reg1由于clockskew,可能会导致违例比较大。
因此,在CTS阶段,我们惯用的做法是,将约束改成下面的样子:
create_clock source_clk [get_pins 2mux1/o]
create_clock clk_div [get_pins reg1/Q]
由于工具在做CTS时,是以create_clock分group的。所以这时工具会把reg0和reg1看作是source clk域的,在他们之间做balance。而clk_div后面的负载作为一个group去做balance。这样就能很好的解决了上面的问题。
从上面的分析可以看出,使用CTS阶段的约束,source clk和clk_div之间是不会做balance的,所以如果他们之间有路径,那这些路径的clock skew可能会比较大。所以我们在设计中就要避免这种情况的出现;如果实在避免不了,就要根据实际情况调整约束了。
举个例子:
如下面的电路。假如reg0/1/2的复位都是经过clk_div做异步复位同步释放的。
那么在CTS时,工具会在reg0/1之间做balance;reg2/3/4之间做balance。这时reg0/4的skew可能会比较大,从而会导致违例。如下图:
为了避免上面的情况,可以修改设计,把reg0和reg1的复位改成使用source clk同步。这样工具就会在reg0/1/3/4之间做balance了。
暂无评论哦,快来评论一下吧!