1问题
在做模块级约束的时候,外部的真实IO delay是还不知道的。为了让模块综合结果尽可能满足外部苛刻的条件,经验值是将IO delay设置为相关联的驱动时钟周期的60%,给模块内部的路径留下40%的时钟周期,这适用于
1.INPUT->REG路径
2.REG->OUTPUT路径
而对于INPUT->OUTPUT的路径(feedthrough),如果按照这样的设置,因为端口输入和输出延时已经占了60%+60%=120%的时钟周期,超过一个周期,这是不可能实现的约束,一般会把IO delay调节成IO 相关联的驱动时钟周期的40%,给模块内部的路径留下20%的时钟周期
但是对于下面这样一种电路,情况有些特殊,这也是实际设计中经常出现的电路:
注意到这个电路的不同之处在于,INPUT不仅连接了INPUT->REG的路径,同时另一分支连接到OUTPUT。而OUTPUT也同时被COMBO-A和REG->OUTPUT的逻辑所驱动。对于这样的结构,
1.对于INPUT->REG,和REG->OUTPUT,总是希望IO delay是60%的时钟周期的
2.INPUT->OUTPUT的feedthrough约束为20%的时钟周期。
要怎样才能同时满足这两个需求呢?
2结论与解决方案
1. 在做模块级综合的时候,对于IO路径一般会使用60%的端口时钟进行约束,如果这样的路径涉及到feedthrough path,也就是INPUT->REG的路径同时有分支到INPUT->OUTPUT的路径,并且该OUTPUT同时被这段feedthroughlogic以及REG驱动,全部按照端口60%驱动时钟的IO约束会造成无法优化的路径,也就是infeasible path
2. 对于infeasible path,dc不会做任何优化,如果不解决这样的问题,综合结果不是最优解
3. set_max_delay=input delay(60%CLK_V)+comb delay+output delay(60%CLK_V)可以解决这个问题,但当端口情况复杂的时候约束数量会很多,并且约束本身不便于理解
4.在同一个端口既定义了专门使用于INPUT->REG和REG->OUTPUT的CLK_V,同时定义了专门使用于INPUT->OUTPUT的CLK_V_FEED,并设置相应的CLOCK GROUP或者false_path可以最好地满足这个需求。
3测试与实验
以下面RTL为例:
这样一个电路经过翻译之后(综合优化之前)大概是以下的电路,INPUT->OUTPUT的路径组合逻辑部分是两个乘法器,而INPUT->REG的组合逻辑部分是两个加法器(这里不过多关注具体的功能):
假设:
1.周期设为2ns,500MHz的频率
2.整个设计只有一个时钟
3.每条路径都是单周期路径
4.IO的相关寄存器都存在于block之外,需要设置Virtual clock
5. INPUT端口(除去CLOCK)驱动为一个X1的buffer,OUTPUT端口的负载均为3个X1的buffer
如果我们按照传统的约束方法,将IOdelay设置为60%的时钟周期:
经过DC综合之后,可以看到电路被优化成了以下结构,蓝圈部分是input port->reg的路径,以寄存器为终点。红圈部分是我们要重点关注的input port->output port的路径,也就是feedthrough path:
我们使用report_timing看一下结果。
可以看到input port->reg(蓝)的路径主要是两个加法器,重点关注input delay的设置,成功地被设置成60%的时钟周期(2*0.6=1.2),这是符合预期的。并且这条路径满足时序要求:
然后我们再看下input port->output port的路径(红)。这块主要是两级乘法器的逻辑。因为这块逻辑包含了不止一条的路径,report_timing默认情况下选择最差的一条(in_3[0]->out_comb[1]):
可以看到这条路径被映射成了AND2X1->AND3X1->INVX1->AND3X1->XOR2X1,单就这一段组合逻辑的延时(算上端口上的延时)是0.59。因为input delay和output delay已经超过了一个时钟周期(6+6=12>10),所以无论这段逻辑如何优化,都会是违例路径。
另外我们注意到在使用report_timing的时候,DC显示了如下warning:
这里infeasible的意思为“不可实行的”,查看该warning的详细信息:
这段描述的重点在红线部分。Infeasible path指的是那些无论如何都不可能满足约束的路径,也就是我们这个例子中Input port->output port的这条路径。如果不加以处理,综合器对这种路径是不会做任何优化的,会影响到最后的QoR。
按照manpage中的WHAT NEXT的方法,使用report_timing -attribute可以看到这段路径是infeasible的:
既然问题是由于约束过紧导致,那么只要相应的放宽对这条路径的约束就可以了。之所以这个例子比较复杂,是因为我们如果不做特殊设置的话,无法兼顾到同时满足
1.对于INPUT->REG,和REG->OUTPUT,总是希望IO delay是60%的时钟周期的
2.INPUT->OUTPUT的feedthrough约束为20%的时钟周期。
为了解决这个问题,我们必须对此类路径做特殊设置。
方法1:
在约束中有一类特殊的约束叫exception,就是为了特殊情况而存在的。
可以使用set_max_delay的方法来对这样的路径进行单独约束,因为set_max_delay是一种exception,它可以覆盖原有的约束。举个例子,如果这条feedthrough path你所期望的延时是DELAY_COMB,并且端口的IO delay还是想保持原先的60%的时钟周期,那么可以通过设置max_delay=DELAY_COMB+0.6*P_VCLK*2。
这里可以看到这段INPUT->OUTPUT的max_delay被设置成了1.2倍的时钟周期外加一段延时的时间,这在现实中是不可能存在的路径。但这么设置并不意味着这条路径从外部起始寄存器->INPUT->COMB->OUTPUT->外部终点寄存器真的有超过一个时钟周期那么长(假设整个设计只存在一个时钟)。这样设置只是因为set_max_delay这个约束在进行分析的时候会天然考虑到input delay和output delay,而在这个方法中,并没有对端口的input delay和output delay进行改动,他们还是60%的时钟周期。这个约束的关键在于给予了中间这段从INPUT->OUTPUT的路径一段额外的DELAY_COMB的时间,而这个值是可以自己确定的。假设留给这段逻辑20%的时钟周期,也就是0.2*2=0.4,在约束中加入以下设置:
综合之后的report_timing -from in_3[0] -to out_comb[1] -attribute结果:
根据这个新的结果,我们可以看到
1.之前的约束违例问这条路径不再是infeasible path
2.之前这条路径是AND2X1->AND3X1->INVX1->AND3X1->XOR2X1,总的延时是0.59。DC没有做任何的优化。而在增加了max delay的约束之后,DC重新将这段路径优化成了NAND2X0->OR2X2->NBUFFX2->NAND2X0->XOR2X2,总的延时是0.5,以此来满足20%的时钟周期也就是0.4的约束。 虽然仍然有违例,但比起之前infeasible path没有得到优化,这段路径的在优化后延时减小了。
方法2
方法1使用set_max_delay来给这段INPUT->OUTPUT路径设置20%的时钟周期,对于一组的INPUT->OUTPUT,约束只需要加三行。
但实际上在综合之前,是不知道哪些INPUT->OUTPUT会存在这样的feedthrough的情况,因而为了保证结果,对于所有这样的路径都要进行max delay的设置来防止infeasible path的出现。实际的设计中端口不全是由是一样的外部时钟驱动,对于不同外部时钟驱动的端口,都要分别进行max delay的约束。假设这样的INPUT->OUTPUT组数特别多,方法1实际上是很繁琐的。比如如果有3个输入都是不同时钟驱动的,3个输出也都是不同时钟驱动的,那么一共有3*3=9组max_delay需要设置。
并且使用max delay的设置,从直观上并不利于理解。因为max delay设置的值实际上超过了一个时钟周期。
那么是否可以对feedthrough的IO端口额外做如下设置?
通过使用set_input_delay -add,在IO端口额外加上一个40%VCLK的时钟。这样对于上述场景(3个输入都是不同时钟驱动的,3个输出也都是不同时钟驱动),只需要6条设置input delay和output delay的命令,不需要对于每一组可能情况都去进行设置。
并且这样对于INPUT->REG的路径,还是会使用60%VCLK的约束,满足需求。但是对于feedthrough path,因为IO同时存在40%VCLK和60%VCLK的约束,他们都是基于同一个时钟VCLK,实际上还是会使用更紧的60%VCLK-60%VCLK的约束,而忽略了40%VCLK的约束,问题还是没有得到解决。使用report_timing -from in_3[0] -to out_comb[1] -attribute观察路径:
为了将feedthrough的路径和INPUT->REG/REG->OUTPUT的路径区分开来,需要在端口专门设置虚拟时钟CLK_V_FEED来进行约束:
重新综合,使用report_timing -from in_3[0] -to out_comb[1] -attribute观察路径:
可以看到这个infeasible的约束依然存在。
不同的地方在于,此时我们通过命令report_timing-from [get_clocks CLK_V_FEED] -to [get_clocks CLK_V_FEED] 观察同样的路径,可以看到相新设置的CLK_V_FEED已经设置到端口上了:
如果能有一个办法来取消CLK_V到CLK_V的约束就好了。
在exception中,false path可以实现类似功能,在这里可以使用false path设置:
重新综合,使用report_timing -from in_3[0] -to out_comb[1] -attribute观察综合后路径:
可以看到这个时候这条路径的结果已经好于加false_path之前的结果。这是因为如果没有设置false_path,更紧的feedthrough约束60%CLK_V->60%CLK_V会占主导作用,DC发现有infeasible的约束时便不做任何优化,即便合理的约束也同时存在。而false path可以解决这个问题。
但使用false path与之前set_max_delay类似,因为必须是每组clock一一对应,当端口clock数量繁多的时候,会有设置繁琐的问题。
与false path相类似功能的,有另外一个命令是set_clock_groups,实现起来比较简单。被设置到同一个group的时钟之间存在约束,而被设置到不同group的时钟之间不存在约束。如果通过set_clock_groups将驱动INPUT的CLK_V时钟和OUTPUT驱动的寄存器CLK_V时钟分到不同的clock group,那么这个问题就能得到解决。
但由于这里驱动INPUT的CLK_V和OUTPUT驱动的寄存器的CLK_V是同一个时钟,一个时钟没法被分到不同的group,必须将CLK_V分为CLK_V_I和CLK_V_O:
设置CLK_V_I和CLK_V_O到不同的clock group,可以取消CLK_V_I和CLK_V_O之间的约束,但在这一步之前,需要先确定好CLK_V_I/CLK_V_O和CLK以及CLK_V_FEED之间的关系。CLK_V_I/CLK_V_O与CLK之间的约束是需要的,这是INPUT->REG和REG->OUTPUT的关系,要把他们归到一个group。而CLK_V_I/CLK_V_O与CLK_V_FEED之间的关系是不需要的,因为这里只需要40%CLK_V_FEED->40%CLK_V_FEED的feedthrough约束,而不需要类似60%CLK_V_I->40%CLK_V_FEED这样的关系。
可以通过以下设置,其中第二个set_clock_group用于取消第一个set_clock_group里的CLK_V_I和CLK_V_O之间的关系:
这样一来,CLK_V_I和CLK_V_O之间就不会存在约束。再次综合,使用report_timing -from [get_clocks CLK_V_I] -to [get_clocks CLK_V_O]:
可以看到原先存在的60%CLK_V-60%CLK_V路径因为clock group的原因已经不存在了。
使用report_clock -groups来观察当前的clock group和false path情况,符合预期:
最后使用report_timing -from in_3[0] -to out_comb[1] -attribute观察综合后路径:
1. 使用virtual clock的约束和之前使用set_max_delay的约束实现了同样的目标,给feedthrough path留下了2-0.8-0.8=0.4的时间,达到了目的。(注意到这和set_max_delay的综合结果并不一致,但路径都得到了优化)。
2.相比于set_max_delay,使用virtual clock约束更便于理解,当端口时钟情况复杂的时候设置起来更加便利。
3.false path 和 set_clock_group都能实现需求,但当外部clock数目很多的时候使用set_clock_group来定义clock之间的关系比set_false_path更为简洁明朗
4. false path只针对STA,set_clock_group可以选择logically exclusive, phisically exclusive。在后端做信号完整性分析的时候有区别。使用set_clock_group会更合理一些。
4补充
最后完整的sdc如下:
这里提供了两种参考方法,但具体到实际项目中,不同的设计不同的情况不同的公司有不同的应对,大家在实际设计中都是如何处理这种情况的呢?欢迎留言讨论。如果文章中有任何错误,也请留言指出,大家一起学习进步~
-
电路
+关注
关注
172文章
5825浏览量
171724 -
时序
+关注
关注
5文章
384浏览量
37244
原文标题:时序约束实例分析——特殊的feedthrough path
文章出处:【微信号:ic_frontend,微信公众号:数字前端ic芯片设计】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论