这一期老李来聊聊一个在后端设计中比较常用的技术Lockup Latch。
在说Lockup Latch是什么之前,我们先来看看要解决的问题是什么。当我们把RTL综合成netlist之后,很重要的一步就是要close setup/hold timing。我们不仅要给功能路径(functional path)要close timing,还要给scan path来close timing。库里面的scan flip flop的示意图如下
图1,scan flip flop
其中SI是scan In输入,SE是scan enable,在function mode下,flop会存储D的值,在scan mode下,flop会存储SI的值。在scan shift mode下,在一条chain上的scan flops是通过前一个flop的Q连到下一个flop的SI形成一个长长的scan chain,本质上就是一串shift register。如下图所示
图2,scan chain示意图
可以看出,scan mode下和functional mode不同,scan chain两个flop之间就是直接连接的,而不像functional path中间存在combo logic,再加上scan clock的频率一般也比functional clock的频率要低,所以通常来说setup time是很容易满足的,但是hold time可能会出问题,特别是当两个flop的clock tree没有做balance的时候,两个flop的clock skew可能会很大,相应的hold time violation也会很大。
这里你可能会问下面几个问题:
第一,两个相邻的flop怎么clock tree会没有做balance?注意我们这里说的是scan shift mode,通常情况下我们在做clock tree balance的时候是在functional mode下来做的,很可能在functional mode下,这两个flop压根属于不同的clock domain,所以他们之间就不会做balance,但是在scan mode下,本来分属于不同的clock domain的两个flop被穿在了一条scan chain下,共用同一个scan clock,这个时候他们之间的clock skew就可能很大了。
第二,你可能会说,只有hold violation,没有setup violation,那修timing不是很简单吗,插buffer增加delay就可以了啊。不错,插buffer来修hold的确是常用的办法,但是这种做法通常是针对不是很大的violation,比如几个或者几十个ps。但是如果是好几百ps甚至好几个ns的violation,如果还选择插buffer,那么就需要插很多很大的buffer,另外由于PVT的变化,插入的buffer的delay在不同的corner下都会变化,所以你就得插足够多的buffer来cover最坏的情况,甚至有可能你插入的buffer会影响到functional path。这样做会增加很多无意义的功耗和面积, 这个时候就是我们今天的主题-- lockup latch派上用场的时候了。lockup latch的主要作用,就是来解决scan shift mode下存在比较大的hold time violation的问题。
下面是两个clock skew比较大的flop的timing示意图
图3,hold violation示意
可以看出,当clk2相比clk1有正skew的时候,setup是被放松了,有更长的时间满足setup time,但是hold就变差了。(当然如果clk2相比clk1是负的skew,那么setup time变差了,但是hold更容易满足。而因为前面说过,setup本身是比较好满足的,所以这种情况下负skew是有助于close hold timing)那么我们的做法是给Q1和SI2之间插入一个latch,这个latch是低电平使能的latch,即当clock 为0的时候latch导通,clock为1的时候latch锁住。这样timing就变成了下面所示
图4,negative level lockup latch
注意,lockup latch的clock和flop1的clock是balance的,可以认为他们之间的沿基本是对齐的。我们先来看从Q1到Lockup latch的时序。当clock1的上升沿到来,Q1发生变化,这个时候Lock up latch从导通状态变成锁定状态,latch锁定的值应该是上一个CLK1上升沿所产生的Q1,而不能让当前的这个Q1破坏掉锁定的值,所以这就是hold1所表示的hold check,可以看出,由于flop1存在clock-to-q delay再加上wire delay,而且它们的时钟沿对齐,所以hold1比较容易满足。再看setup time,当CLK Latch为高的时候,latch处在锁定状态,并不会接入Q1的值,而只有当CLK latch的下降沿到来的时候,latch开始导通,这个时候需要Q1的值被latch住,也就是下降沿之前latch的输入要保持稳定,这就是setup1表示的setup check(其实这里有点小问题,我们后面讨论)。
再来看从lockup latch到Q2的时序。在CLK Latch为高这段时间,latch的输出其实依然保持稳定在上一个周期的Q1,直到CLK Latch的下降沿到来之后才会更新成当前cycle的Q1,对于Flop2来说,这个Q1应该是下一个时钟沿到来的时候才会被flop2给采到。这就是上面表示的setup2,相应的,hold2就表示这个Q1不能影响上一个CLK2上升沿的采样。
我们可以看出,在两个flop之间插入了一个lockup latch,可以将setup timing path和hold timing path分成了两段。其中setup time总和并没有变化,两段都比较容易满足,但是hold有了极大改善,特别是hold2,相当于利用latch把Q1的值延后了半个周期,假设scan clock的周期是50MHz,那么相当于一下子把hold check往后延了10ns,这比插buffer要带来的delay大得多。这是latch起到time borrow的一个典型应用。
这里关于插入lockup latch之后的setup time时序老李要多说两句。严格意义上来说,如果只是针对一个D-latch,它的setup time 和hold time其实都是对于从导通到关断那个时钟沿来说的,对于这一点还不熟悉的小伙伴建议去复习一下latch的timing。那么其实对于上面的电路,对于lockup latch本身来说,它的setup/hold其实应该是下面图5所示的这样
图5,latch timing
即只要Q1在红虚线所示的上升沿之前满足setup time,Q1就可以被latch锁住,那么相应的,对于从latch到SI2的setup time就要做调整,要保证在CLK2的上升沿之前latch的值要稳定。总体的效果依然和前面一样,即要满足CLK1第一个上升沿引起的Q1变化要满足CLK2的第二个上升沿的setup time。但是实际应用中,我们并不会按照图5的时序关系去close timing,而是按照图4的时序关系。原因在于,setup1无论是按照图4中的下降沿还是图5中的上升沿,都是比较好满足的,因为latch和flop1有同一个balance的clock, 它们之间又会比较近,中间还没有任何combo逻辑。但是对于图5中的setup2来说,当lockup latch和flop2距离有点远,或者skew不那么大的时候,想要close setup2就麻烦一些。那既然这样,我们就何苦去费劲close 图5中的setup2,还不如利用setup1 close比较容易,来分给setup2半个周期?所以说,在实际工程中大家有时也不能拘泥于教科书,要实际问题区别对待。
下面你可能会问,这里我们图4插入的lockup latch是和flop1距离近,能不能把lockup latch放在距离flop2那边呢?如图6所示
图6,lockup latch和flop2靠近
老李看过很多网上讲解lockup latch的文章,都告诉大家不可以,原因是时序会变成上面图6所示,那么hold1其实面临的问题和图3是一样的,由于postiive skew导致hold1很难close,所以那些文章就告诉你说lockup latch不能插在capture flop这边,而只能插在launch flop这边。这些文章其实只说对了一半:对于低电平使能的lockup latch,只能插在launch flop这边,不能插在capture flop这边。但是,如果我们把lockup latch换成高电平使能,是可以插在capture flop这边的。如图7所示
图7,高电平使能lockup latch
这个时候注意hold1变成了CLK1的上升沿到CLK Latch的前一个下降沿之间的check,也就是latch在关闭之前不能破坏之前稳定的值,同样的,利用latch我们可以利用半个周期的时间来去抵消skew带来的问题。而hold2变成了balance的clock之间的check,close起来要容易许多。setup1这个时候就变成了严格按照latch 的setup time要求来,在latch的下降沿之前满足setup time,这样刚好半周期,给setup2也有足够的时间。
总结一下,lockup latch的作用主要是用来帮助修复scan chain上存在较大skew导致两个flop之间有很大hold violation的问题。利用latch的锁存delay特性,将hold time check推后半个周期,从而使得hold check容易满足。
对于positive edge trigger的flop,如果要靠近在launch flop这边,要插入低电平使能的lockup latch,而如果要靠近在capture flop这边,要插入高电平使能的lockup latch。
对于negative edge trigger的flop,则刚好反过来。
当然lockup latch插入之后也会带来一些问题,比如说插入之后的scan chain就没法再reorder了,因为一reorder可能skew关系又变了,所以说目前lockup latch的插入都是physical aware的,这样可以尽量避免chain无法reorder从而导致的congestion issue。
作者:硅谷老李
来源:https://mp.weixin.qq.com/s/gk8o_GoOcH2oT-eEYRZWVg作者微信公众号
相关文章推荐
更多IC设计技术干货请关注IC设计技术专栏。