时钟域概念
在同步时序电路中,一个时钟通常驱动(Feed)许多同步单元(触发器,同步RAM块等)。由同一时钟驱动的一组同步单元被称为该时钟的时钟域(Clock Domain)。
跨时钟域概念
跨时钟域(Clock Domain Crossing,CDC)是指同步数字电路中的信号从一个时钟域跨越到另一个时钟域1。
亚稳态
对于边缘触发的触发器,触发器的建立时间(setup)和保持时间(hold)在时钟上升沿左右定义了一个时间窗口。如果输入数据在该窗口发生变化,那么就会产生时序违约。此时,触发器无法稳定在0或1状态,而是徘徊在一个中间电平状态(这个中间电平可能是正确值,也可能不是),得到的结果将是不可预知的。这种状态称为亚稳态(Metastability)。
单比特信号跨时钟域的同步处理方法
当在时钟域之间传递信号时,我们需要考虑一个重要的问题:是否要对从一个时钟域传输到另一个时钟域的信号的每一个值进行采样?
针对上述问题,当信号跨越时钟域边界时有两种可能的场景:
- 在跨时钟域时允许丢失部分采样值。
- 在跨时钟域时不允许丢失任何信号采样值。
对于第一种场景,有时对信号的每一个值进行采样是不必要的,但是被采样的值必须要保证精确度。标准异步 FIFO 设计中使用的一组格雷码计数器就是一个例子。在设计得当的异步 FIFO 模型中,同步格雷码计数器不需要捕获来自另一时钟域的每一个合法值,但采样值必须准确无误,以便识别何时出现了满和空的情况。
对于第二种场景,在允许对跨时钟域信号发生改变之前,必须被正确识别或识别并确认。
在这两种情况下,跨时钟域信号都需要被同步到其接受时钟域中。
双触发同步器
同步器是对异步信号进行采样,并输出与本地时钟或采样时钟同步转换的信号的设备。
如下图所示,数字电路设计中,最简单和普遍的是使用双触发同步器(Two flip-flop synchronizer),也就是所谓的“打两拍”。
值得注意的是,即使通过使用双触发同步器消除了亚稳态,也并不意味着第二级Flop所采到的值就是正确的,而只能保证其是稳定的。
当然,从理论上,由于第一阶段的信号在打一拍后还是有可能处于非稳定状态,从而导致级联的第二个寄存器输出还会表现为非稳定状态。
触发器进入亚稳态的时间可以用参数 MTBF2(mean time between failures)来描述, MTBF即触发器采样失败的时间间隔,其公式描述如下: $$ MTBF = \frac{e^{{t_R}/\tau}}{f_df_cT_0} $$ $t_R$ = 分辨时间(resolution time, the time after the clock edge that output data is needed)
$\tau, T_0$ = 触发器参数,由工艺决定
$f_d$ = 数据改变频率
$f_c$ = 采样时钟频率
从上述公式中我们可以看出,随着时钟频率的提高或者数据改变频率的提高,失败会发生的更频繁。
对于大多数同步应用,双触发同步器已经足够消除可能的亚稳态了。(存疑,该结论今天是否任然适用?)
在设计这种同步器时应当遵循以下原则:
- 级联的寄存器必须使用同一采样时钟。
- 发送端时钟域寄存器输出和接收端异步时钟域级联寄存器输入之间不能有任何其他组合逻辑(见下文[信号应在发送时钟域被同步](#信号应在 发送时钟域被同步))
- 同步器中级联的寄存器除了最后一个寄存器外的所有寄存器只能有一个扇出,即其只能驱动下一级寄存器的输入。
三级触发同步器
对于一些高速设计,使用两级触发器同步未必能满足要求,这时可以额外添加一级触发器来增加MTBF。
下图展示了一个三级触发同步器。
信号应在发送时钟域被同步
信号是否要在被传递至接受时钟域前将其登记在发送时钟域的寄存器中?答案是需要的。
下图展示了信号在A时钟域经过组合逻辑输出后未在寄存器中登记直接传递到B时钟域的场景。我们可以发现,这种做法增加了跨时钟域边界数据改变频率($f_d$),增加了跨时钟域边界信号边缘数量(信号有毛刺),使MTBF减小,增加了亚稳态的风险。
因此正确的做法是,在发送时钟域中,应将组合逻辑的输出打一拍登记在寄存器中。这样可以显著减小亚稳态的风险。
同步快信号到慢时钟域
如果快的时钟域的频率是慢时钟域的1.5倍(或更高),将慢时钟域的控制信号同步到快时钟域一般不会有问题,因为快时钟域的信号会对慢时钟域的CDC信号进行一次或多次采样。与将快信号采样到慢时钟域相比,将慢信号采样到快时钟域会造成较少的潜在问题,因此设计人员可以利用这一事实,使用简单的双触发器同步器在时钟域之间传递单个CDC信号。
如果信号在跨越两个时钟域边界时不允许丢失任何数值,那么同步技术或信号的宽度就显得非常重要。由于发送时钟域的时钟频率比接受时钟域的时钟频率高,信号在发送时钟域被采样前可能会出现数值的两次或多次变化,因此跨时钟域信号就有可能在跨时钟域边界之前经历两次或多次发送时钟域的上升沿。若被采样信号保持时间过短,则慢时钟域可能会漏采,一般要求被采样信号保持1.5或1.25个慢时钟域周期(保持慢时钟域的三个时钟变化沿)
如果丢失信号采样值对于设计来说是不被允许的,那么通常有两种方法可以解决这个问题:
- 一个是开环(open-loop)解决方案,确保信号在无须确认的情况下可以被采集。
- 另一种是闭环(close-loop)解决方案,即在跨时钟域边界时,信号需要接收端的反馈确认。
可能出现的问题
首先看一个比较极端的例子。在本例中,发送时钟域的频率大于接受时钟域,而跨时钟域信号的宽度正好等于发送时钟域的一个时钟周期。当该跨时钟域信号传递到慢时钟域时,被慢时钟采样后,该信号可能为低,也可能为高。也就是说,该信号在跨时钟边界时会丢失值。
然后看一个不太极端的例子。在本例中,发送时钟域的频率大于接受时钟域,而跨时钟域信号的宽度稍微大于接受时钟域(慢时钟域)的一个时钟周期。在大部分情况下,该信号能被慢时钟采样并传递。但在实际情况中,可能出现信号脉冲改变发生在离接收时钟域同步器的两个时钟上升沿太近,在这种情况下,第一个时钟沿处建立时间无法满足,第二个时钟沿处保持时间无法满足,从而无法得到预期的信号脉冲。
开环解决方案
开环解决方案采取上文介绍的同步器来采样跨时钟域信号,但是前提是需要先将目标信号展宽到至少超过接收时钟域的时钟周期。上文提到,最佳的脉冲宽度至少是接收时钟域时钟周期的1.5倍,这样跨时钟域信号将会被接收时钟域至少稳定地采样一次。
开环解决方案多用于相关时钟频率固定且时钟信号能被正确分析。
优点:无须接收时钟域的握手信号,最快地将信号传递通过跨时钟域边界。
缺点:容易让其他设计者误认为当前解决方案为通用跨时钟域边界方案,或者当设计要求发生改变时,设计者容易忘记重新分析之前的开环解决方案。
闭环解决方案
闭环解决方案是在发送时钟域将控制信号当成使能信号传递,并将其同步到接收时钟域,然后接收时钟域收到使能控制信号之后,将同步的控制信号反馈到发送时钟域,发送时钟域通过另一个同步器接收此反馈回来的控制信号,并以它作为信号正确接收的握手信号。
优点:可以非常安全地确认第一个使能控制信号已经被接收时钟域正确识别和采样。
缺点:存在相当大的延时,因为信号违背接收时钟域接收之前是不能被释放的,也即在正确接收之前目标信号不能改变数值,也就无法传递下一个数值。