这周老李继续给大家带来干货内容,是关于RDC (Reset Domain Crossing)的初步介绍。
在讲解RDC之前,如果你对CDC不够了解,大家可以先看一下老李之前关于CDC的文章(可以直接在公众号窗口点击下面的"CDC"菜单,就可以看到老李全部CDC系列的文章),再建议看一下介绍关于Reset同步的文章,复习一下Asynchronous Reset。Reset信号 如何同步?
很多人都听说过CDC,也对CDC都有了很不错的了解,但是对于RDC可能许多工业界的新人都没怎么接触过。老李也是工作两年之后才接触到这个领域的。这个领域其实在工业界也是最近十年多才被特别重视起来,而不像是CDC大家已经有了充足的经验了。
我们知道很多数字模块中都用到了Asynchronous Reset,那么用Asynchronous Reset有什么问题呢?别的缺点老李在Reset同步里面讲了,但是没有讲RDC的问题。下面我们先看下面一个例子
在上面这个图中,我们有2个reset,分别是reset1\_n和reset2\_n。其中flop F1是被reset1\_n给异步reset的。而F3是被reset2\_n给异步reset的。F2可能是被同步reset给复位,也可能没有reset。而这其中,F1是F2和F3的控制逻辑的fan-in,也就是说F1的变化会影响到F2和F3的值。
那么考虑这种情况,reset1\_n assert了,但是reset2\_n并没有assert,F3和F2依然工作在正常模式,并没有被复位,那么会发生什么情况呢?结果可能很糟糕,即F2和F3会产生metastability,导致芯片发生逻辑错误。你可能会说,老李不对啊,这里又没有跨时钟域,哪来的metastability? 注意看,因为reset1\_n对F1是异步reset,也就是说,当reset1\_n assert,F1立马会被reset,F1的Q立刻会发生变化。而我们说,asynchronous reset 的assertion是可以在任何时间的,不然就不叫asynchronous 了,它和时钟沿没有关系,甚至与有没有时钟都没有关系,换句话说,F1的Q变成reset值可以发生在任何时候!那么F2和F3的D输入经过那一堆组合逻辑,就可能在任何时候产生变化,如果这个变化恰好落在F2和F3的setup/hold window里,那不就导致了setup/hold time violation, 从而产生了亚稳态吗?
你可能还是有点将信将疑,难道F1的Q和F3的D,F1的Q和F2的Q之间不是有STA来做timing check的吗?在timing都满足的情况下怎么还会有setup/hold timing violation? 你没有说错,如果F1, F2, F3确实都处在同一个时钟域,STA的确会做register to register的timing closure,但是注意,STA能够做的,是分析从F1的Tclk2q 再加上Tcombo是不是满足register to register的setup/hold。STA 是无法做reset to q 再加上Tcombo的check的,还是那个原因,asynchronous reset的assertion是可以任何时间来的,所以没有办法做STA。(注意,reset de-assertion是和时钟沿对齐的,所以reset de-assertion是会做STA的)。也就是说,图上红色的timing path其实是unconstrained。
好,我们再来总结一下这个例子,这里我们至少有了两个reset domain,其中reset domain 1就是包含所有被reset1\_n所复位的flop,而reset domain2是包含被reset2\_n复位的flop。如果这两个reset domain的flop在functional mode的时候存在逻辑关系,而reset1\_n可以单独assert,那么就可能在reset domain2产生metasable。
注意,这里产生reset domain crossing issue的条件有
- 必须是asynchronous reset assertion。因为synchronous reset的话,无论assertion还是de-assertion其实都是被STA check的
- 存在不被这个asynchronous reset给控制的flop。如果你告诉我其实reset2\_n在reset1\_n assert的时候也assert了,那么其实也不会有问题。
这一类问题随着现在的SoC越来越复杂,集成度越来越高,IP reuse也越来越多而越发变得常见,并且变得越来越重要。你可能会问,什么情况下reset1\_n assert,但是reset2\_n不assert呢?举个例子,如果reset1\_n的部分要被power gating了, 或者被soft reset了, 而reset2\_n的domain依然工作,那么就会出现这种情况。产生RDC最根本的原因,其实是因为asynchronous reset assertion 的路径无法被STA给约束。
下面还有两个常见的例子。
在这个例子中,reset1\_n虽然经过了一个double flop的reset synchronizer,但是对于F1来说还是asynchronous reset,红色的path依然不会被STA给约束。
在这个例子中,F1没有asynchronous reset pin, 并不是被直接asynchronous reset,但是dst\_reset\_n 在assert的时候是作为D的逻辑,导致了F1本身可能就产生metastable,进而继续影响下游的F2和F3。 同样的,红线的path没有被STA给约束。
好,那么产生了RDC的问题,我们要怎么解决呢?
首先,最简单粗暴的思路就是,能不用asynchronous reset,就不用。
因为synchronous reset无论assertion还是de-assertion都会被STA给约束,所以你可以放心,不会产生setup/hold的问题。
但是你可能会说,没法不用asynchronous reset啊,比如说我想在没有时钟的时候reset电路,我非得用asynchronous reset不可,或者说你拿到的是一个别人或者买来的IP,IP本身就用asynchronous reset了,你也没法改啊。那怎么办呢?
首先,如果这个是你自己的设计,那你就得多加小心。
- 在同一个时钟域内,不要混用asynchronous reset和synchronous reset。
- 用asynchronous reset的时候,问自己一个问题:后级的logic 也会被这个asynchronous reset给reset吗?
如果确认RDC path不可避免,那么我们来看可以怎么来修复。
最常见的办法就是加clamp。看下面的例子
在F1的Q端加一个与门,被一个rst\_clamp给控制住。这个rst\_clamp信号必须要在reset1\_n assert之前先active,这样可以先一步将与门的输出控制在0 (你也可以clamp在1,取决于后面的要求),这样的好处就是,当F1被asynchronous reset的时候,F1的Q的变化时不会影响到F2和F3的。当然,rst\_clamp控制的与门是被STA给约束的,所以不会产生metastable。这是最常见的解决思路,难点就是要找出所有的F1,加上适当的clamp,而且还要设计恰当的rst\_clamp信号。而且要加的clamp cell可能很多,漏了一个可能都会有问题。当然现在已经有了RDC检查的EDA工具,如果你漏了应该能够帮你找出来。
另外一个思路不加clamp cell,而是在asynchronous reset assertion之前将F2和F3的clock给停住,这样既然F2和F3都没有clock,那自然不会有setup/hold的问题。当然,这种办法的缺点就是可能F2和F3的clock 不能停,还是要工作在function mode。如果有这样的要求的话就不能这样修复了。
还有一个思路,是借鉴CDC中的办法,即给F1的输出加synchronizer,如下图所示
这样F3和F2的输入也都不会产生setup/hold violation,但是这样做的缺点也很明显:第一,和clamp cell一样,要找到每一个crossing的flop,然后加synchronizer,面积消耗比一个与门要大得多。第二,加了synchronizer可能会破坏F1和F3,F1和F2之间本来的逻辑关系,因为synchronizer会导致F1的值会被延迟两拍之后才给F2和F3。这种修复办法只有在确保加入synchronizer不会使得逻辑关系错误的情况下才能使用。
好了,这就是RDC的一个初步介绍。更多更详细的介绍大家在工作中可以参考EDA工具的手册,并且在工作中的实际问题中学习,增加经验。
作者:硅谷老李
来源:https://mp.weixin.qq.com/s/s\_2mcIR75eidjXhUfaesvg
作者微信公众号
相关文章推荐
更多IC设计技术干货请关注IC设计技术专栏。