最近写资料的空闲时间,想着看看clifford E. Cummings的经典论文,虽然年代较远,但是每一篇都值得好好研究。本系列不定期更新,计划看完以下论文。
本文英文链接http://www.deepchip.com/downloads/cliffsnug01.pdf
本文较长,分两次推送。
在一般情况下,单时钟的设计是很少的,主要还是多时钟设计。但是多时钟设计就会涉及到很多的问题,主要如下:
1.亚稳态
如上所示,当出现两个时钟模块时,则很容易使得数据不满足建立/保持时间,因此会出现亚稳态。
2.同步器
同步器是对异步信号进行采样,并且按照本时钟域的时钟输出的设备。
最基本的同步器是两个串联的触发器,又俗称为打两拍,均由目的时钟域提供时钟。这个电路称为两个触发器同步器。如果输入数据的变化非常接近接收时钟边沿(在建立/保持时间内),则同步器中的第一个触发器可能会变为亚稳态,但是在信号被采样之前,仍然有一个完整的时钟使信号变得稳定--第二级触发器。然后,目标时钟域的逻辑使用的是第二个触发器的输出。
两级触发器可防止亚稳态传播的原理:假设第一级触发器的输入不满足其建立/保持时间,它在第一个脉冲沿到来后输出的数据就为亚稳态,那么在下一个脉冲沿到来之前,其输出的亚稳态数据在一段恢复时间后必须稳定下来,而且稳定的数据必须满足第二级触发器的建立时间,如果都满足了,在下一个脉冲沿到来时,第二级触发器将不会出现亚稳态,因为其输入端的数据满足其建立保持时间。同步器有效的条件:第一级触发器进入亚稳态后的恢复时间 第二级触发器的建立时间 <= 时钟周期。如果不满足上述表达式,那么到第二个触发器开始,信号仍然可能是亚稳态的。在这种情况下,将发生同步错误,并且设计可能会发生故障,但是这种情况是很罕见的。对于大多数的同步应用,两级触发器已经足以消除所有可能的亚稳态。为了进一步提高MTBF,有时会使用具有更好的建立/保持时间特性的库单元(其具有低阈值电压)构建两个触发器同步器。
在跨时钟域(CDC)发送信号到同步器之前,通常先在源时钟域中使用寄存器保存信号。这也是为什么上图中介绍为什么在两个时域的触发器之间需要没有组合逻辑的原因,只有这样才可以首先消除了组合电路产生的毛刺。如下图所示:
因为在组合逻辑电路中常常因为各个输入信号的不一致性以及各路径延迟的不一样,可能导致输出结果存在毛刺。
而在跨时钟域时,又不确定目的时钟域时钟上升沿什么时候到来,因此目的时钟域时钟的采样就更加无法保证。因此必须保证两个时域的触发器之间没有组合逻辑。
- 慢时钟域到快时钟域
最简单的情况是将信号从慢速时钟域传递到快速时钟域。只要快时钟的频率大于慢时钟频率的1.5-2倍,通常就不会有问题。这保证了信号将被目标时钟的至少一个(但可能更多)时钟沿采样。快速目标时钟将简单地对慢速信号进行多次采样。在这些情况下,一个简单的两级串联触发器同步就足够了。
目的时钟域如果不采取任何操作,那么就会多次采样同一个值,这会导致一个问题--电路误以为这是多个操作。因此为了避免这种错误的发生,通常添加一些简单的逻辑使得同步后的采样值出现周期和原时钟域的一样。具体操作,在soc设计方法与实现书上有讲。
如果快时钟的频率小于慢时钟频率的1.5倍,也就是稍微快点,这个欢迎各位讨论,我觉得使用握手就行。
- 快时钟域到慢时钟域
困难的情况是将快速信号传递到慢速时钟域。明显的问题是,如果快速信号上的脉冲短于慢速时钟的周期,则该脉冲可能会在被慢速时钟采样之前消失。下面的波形显示了这种情况。
还有一个考虑较少的问题是,即使脉冲只是比慢时钟的周期稍宽,信号也会在目标触发器的建立/保持时间内(在慢时钟上)变化,这会违反时序并导致亚稳性。
在处理上述问题时,首先应该确认是否需要源信号中的每个值,如果可以不需要,那么采样在上文异步FIFO中设计的格雷码就可以异步FIFO设计。当然如果需要在目的域中使用每个值,那么就得想办法设计新方法。
另外方法是使用握手同步机制。在快时钟域中添加控制逻辑使得信号被保持知道被慢时钟域接收。因此,异步信号经过反馈逻辑之后,就可以按照快时钟同步慢时钟的控制方法同步此信号。需要注意的是,无论是从快时钟传递到慢时钟还是从慢时钟传递到快时钟,都需要同步器。因此最终具体实现如下所示:
上图中,源域通过两个触发器同步器将信号发送到目的时钟域,然后通过另一个两个触发器同步器将同步信号传递回源时钟域,作为反馈确认。通过反馈的方式很安全,但是从上图可以看出来延时是非常大的。下图显示了同步器的波形。
而且上述电路并不能解决信号在连续两个慢时钟上升沿之间发生多次信号翻转的问题,因此必须保证adat的两次有效信号之间有个最小值,不能小于整个反馈电路中的时间域异步时钟同步器中第一级触发器恢复到无效值的时间之和。
通过改进逻辑,如下所示可以不受上述限制。
当发现控制信号有效之后,由组合逻辑发出停止时钟。stallb 信号(低电平有效)拉平快速时钟的下一个时钟的上升沿。既然时钟都已经停掉了,由触发器输出的控制信号就不会再改变了,这样就可以保证慢速时钟能够采到有效的控制信号。在收到从目的时钟返回的反馈信号之后得知异步时钟已经采到了此控制信号,satllb 信号再会拉高从而恢复快速时钟。常用于低功耗设计。
3.静态时序分析
静态时序分析的目的是为了验证设计中的每个信号路径是否满足所需的时序目标,这应该对所有的信号路径都是满足的。静态定时分析不用于验证设计的功能是否满足,只用于验证设计是否满足时序目标。从理论上讲,时序验证可以通过布局布线后。使用SDF对实际延迟时间值进行反向注释的穷举门级模拟来完成。这通常被称为动态时序验证。
静态时序验证相对于动态时序验证来说,有三个主要优势:(1)静态时序分析工具验证任意两个相连元素之间的每条时序路径。(2)静态时序分析不需要任何测试向量的生成。(3)静态时序分析工具比动态时序验证快了好几个数量级。
对于同步电路,可以使用synopsys家的工具进行分析,例如DC中的DesignTime或者PT。
但是对于多个异步时钟的模块进行时序分析是很容易出错,也很困难还很耗时。由于信号与异步时钟之间的相位关系总是在变化,因此,与所述同步时钟同步的信号的时序信息是不准确的。因此,静态定时分析工具必须检查信号和异步时钟之间的无限个相位关系。
对于有两个或多个异步时钟作为输入的RTL模块,需要设计人员向静态定时分析工具指出应该忽略哪些信号路径。这是通过对从一个时钟域到另一个时钟域的信号“设置假路径”来实现的。主要遵循以下规则:1.时钟命名,用来约定和标识设计模块中每个信号的时钟源。这种做法可以帮助设计者识别设计中信号的时钟域,还可以在综合脚本中使用正则表达式中的通配符,较容易的进行时序分析。2.每个模块中只允许使用一个时钟。这是因为静态时序分析和综合脚本更容易在单个时钟模块/组中完成。从一个时钟域传递到另一个时钟域的每一组信号都要创建同步器模块。在同步器中, 都会存在从一个时钟域到另一个时钟域传输的建立时间/保持时间问题。同步器不需要在最坏的情况下满足情况,只需要在最好的情况下对第一级和第二级触发器进行时序分析以满足所有的保持时间都是满足的。此外,门级网表仿真更容易配置为为第一级触发器忽略建立时间保持时间违例的情况。
4.综合脚本与时序分析
按照上述方法执行后,用于解决多个时钟域问题的综合脚本命令现在变成了分组、设置虚假路径和执行最小最大时序分析的问题。
1.分组
把不是同步器的,在同一个时钟域中的所有模块分到同一个组中。换句话说,在一个设计中,同一时钟域的设计代码组成一个组。这些组都将进行时序验证,每个组之间就好像独立的,组内就是完全同步的设计。
2.识别虚假路径
一般来说,我们只在同步器的输入端口执行"setfalsepath"命令。因此如果我们使用了时钟命名的方法,则很容易使用通配符轻松识别所有的异步输入。例如,syncu2v模块的输入应该都以字母“u”开头。
setfalse_path -from { u* }
3.进行最大最小时序分析
每个时钟域的分组模块集现在是一个完全同步的子设计,可以使用诸如DesignTime或PrimeTime之类的工具来验证最坏的情况下的时序(包括建立时间检查)和最佳情况下的时序(包括保持时间检查)。同步块分别进行时序验证。最坏情况下不需要时序检查,因为这些模块只是由触发器组成,用来同步异步输入信号;因此,没有长路径延迟,输出被完全寄存。在所有异步输入上设置虚假路径之后,进行最佳情况(最低)时序验证,以确保在从第一阶段传递到第二阶段的同步触发器的所有信号上都满足保持时间要求。
End