作者:孤独的单刀,文章来源:CSDN博客
1、什么是跨时钟域?
FPGA内容的设计大都是以同步电路为基础,而同步电路的触发则需要统一时钟。时钟信号彷佛是电路的“心跳”,统一给“被管理的”触发器提供血液,而在这个时钟信号下的信号就可以被称之为--属于该时钟域。随着芯片集成度的提高,以及日益严苛的设计要求,在嵌入式系统内部或与其他系统的数据交互中,难免会出现原本属于时钟域A的信号a,需要传入到另一时钟域B来对其进行操作,这一操作则称之为跨时钟域,对应Clock Domain Crossing,CDC。
由于双方时钟频率、相位等的差异,导致原本属于时钟域A下的同步信号a变成了一个时钟域B下的异步信号。我们知道,异步信号是有概率无法满足触发器的建立时间要求和保持时间要求。一旦出现建立时间和保持时间违例,则有可能会导致系统发生亚稳态。
时序电路的基础是触发器(FF、Flip-Flop),触发器正常工作需要满足建立时间和保持时间的时序要求。
建立时间(Tsu:set up time)
是指在触发器的时钟信号上升沿到来以前,数据稳定不变的时间,如果建立时间不够,数据将不能在这个时钟上升沿被稳定的打入触发器,Tsu就是指这个最小的稳定时间
保持时间(Th:hold time)
是指在触发器的时钟信号上升沿到来以后,数据稳定不变的时间,如果保持时间不够,数据同样不能被稳定的打入触发器,Th就是指这个最小的保持时间
2、什么是亚稳态?
亚稳态 (Metastability):如果数据传输中不满足触发器的建立时间要求和保持时间要求不满足,就可能产生亚稳态,此时触发器输出端Q在有效时钟沿之后比较长的一段时间处于不确定的状态,在这段时间里Q端在0和1之间处于振荡状态,而不是等于数据输入端D的值。这段时间称为决断时间Tmet(resolution time)。经过resolution time之后Q端将稳定到0或1上,但是稳定到0或者1,是随机的,与输入没有必然的关系。
只要系统中有异步元件,亚稳态就是无法避免的,亚稳态主要发生在异步信号检测、跨时钟域信号传输以及复位电路等常用设计中。由于产生亚稳态后,寄存器Q端输出在稳定下来之前可能是毛刺、振荡、固定的某一电压值。在信号传输中产生亚稳态就会导致与其相连其他数字部件将其作出不同的判断,有的判断到“1”有的判断到“0”,有的也进入了亚稳态,数字部件就会逻辑混乱。
更多关于建立时间、保持时间及亚稳态的参考: FPGA设计的“打拍(寄存)”和“亚稳态” 到底是什么?
3、跨时钟域处理方法的分类
既然信号的跨时钟域可能会引入亚稳态问题,那么就需要想办法对其进行处理,从而降低亚稳态发生的概率(即提高MTBF)。
跨时钟域处理方法可以分为两个大类:单Bit信号跨时钟域处理、多Bit信号跨时钟域处理。分类的原因是多bit信号的传递不光只有亚稳态这一个问题,还可能会因为多个信号之间由于工艺、PCB布局等因素导致的信号传输延时(skew)的存在,从而导致信号被漏采或者错采。
4、单bit信号进行跨时钟域处理的方法
信号从源时钟域跨到目的时钟域后,需要在目的时钟的“指挥”下进行操作,这一过程可视为用目的时钟对被处理后的信号进行“采集”,既然是采集,则必须满足奈奎斯特采样定理,也就是说目的时钟频率需要至少是源时钟频率的2倍。
在实际应用过程中,不光需要将慢时钟域信号跨到快时钟域,也需要将快时钟域信号跨到慢时钟域,而后者显然是无法满足采样定理的,所以需要进行一些特定处理。
4.1、电平信号
如果是电平信号进行CDC,不用考虑时钟快慢,直接用2级或其他级数的同步器就可以,因为总能被采样到。实际上可以将电平型号看做一个频率超级低的脉冲信号。
4.2、从慢时钟域到快时钟域的脉冲信号
首先需要约定的是,所谓快时钟频率应该至少是慢时钟频率的两倍。若无法满足,则可使用4.3方法进行处理。在这一前提条件下,是可以保证需要处理的信号能被目的时钟域正确采集到的。
2级同步器进行同步(DFF)是我们最常见的CDC处理方法。这一方法的本质是用触发器将被CDC信号同步到目的时钟域下,但是每一次的同步仍然可能出现亚稳态,随着同步级数的增加,亚稳态出现的概率也会减少。需要注意的是,这一过程并非线性的。实际上,3级同步器以上对亚稳态减小的作用就很小了。通常使用2级或者3级同步器即可将亚稳态发生的概率维持在一个非常小的值。
4.3、从快时钟域到慢时钟域的脉冲信号
下图中,adat是快时钟域a下的脉冲信号,bclk是目的时钟(慢时钟),很明显,信号adat被同步到目的时钟域后出现了漏采,这是因为adat的频率高于目的时钟。
既然脉冲信号频率高于目的时钟才导致的漏采,那么我将脉冲信号拓宽到一定的程度不就可以保证采集到了吗?这一方法的本质实质上是降频,也就是将问题转换为我们已经能解决的用较快的时钟来采集较慢的时钟。如下图:
将信号adat扩宽为3倍aclk后,脉冲信号成为了一个较慢的信号,而目的时钟成为了一个较快的时钟,这样我们就可以使用2级同步器的方法来对被CDC信号进行同步。
需要注意的是,这一方法具有一定的局限性:
1. 若需要同步的两个脉冲信号距离很近,则第一个脉冲信号的扩宽可能会覆盖第二个脉冲信号,从而导致第二个脉冲信号的漏采;
2. 脉冲信号的扩宽是以目的时钟为参考的,但是若不知道目的时钟的频率,则该方法可能失效,也就是说该方法不具备普遍性。
为了探寻一种具备普遍性的方法,我们可以使用握手法来进行CDC。握手法的本质是负反馈,通俗来讲,就是我先将被CDC信号展宽,展宽后将其同步到目的时钟域,在目的时钟域生成指示信号,该指示信号用来指示此时信号已经被目的时钟域接收,然后将指示信号反馈到源时钟域(反馈过程),源时钟域接收到这个反馈信号后将被CDC信号拉低,从而确定了展宽长度,也通过”发送--反馈--操作“这一握手过程完成了一次CDC传输。
上图是典型的握手过程来进行CDC:
1. 源时钟域aclk下的信号adt1信号是要进行CDC的信号;
2. adt1先是在源时钟域aclk下被展宽,然后通过两级同步器被同步到目的时钟域bclk下,分别为bq1_dat,bq2_dat;
3. bq2_dat作为指示信号(反馈信号,也可以通过bq1_dat和bq2_dat来生成新的指示信号)又被反馈到了目的时钟域aclk下,并进行同步,分别为aq1_dat,aq2_dat;
4. aq2_dat的拉高则说明反馈信号的同步完成,此时可以将adt1拉低(结束展宽过程);
5. adt1拉低(结束展宽过程)后表示一次CDC操作结束。
5、其他
以往我的文章我一般都是会贴出代码和仿真测试的。这次我就不贴了,因为我找到了一个不需要自己敲代码的方法。这个方法就下一篇文章再写吧!
关于本文,您有什么想法均可在评论区留言!
创作不易,如果本文对您有帮助,还请多多点赞、评论和收藏。您的支持是我更新的最大动力!