跨时钟域(CDC)设计方法之单bit信号篇(一)

2023-10-11 05:40

本文主要是介绍跨时钟域(CDC)设计方法之单bit信号篇(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

写在前面

        本博客所有CDC相关的内容:跨时钟域(CDC)设计汇总


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、其他

  • 以往我的文章我一般都是会贴出代码和仿真测试的。这次我就不贴了,因为我找到了一个不需要自己敲代码的方法。这个方法就下一篇文章再写吧!
  • 关于本文,您有什么想法均可在评论区留言!
  • 创作不易,如果本文对您有帮助,还请多多点赞、评论和收藏。您的支持是我更新的最大动力!

这篇关于跨时钟域(CDC)设计方法之单bit信号篇(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/185947

相关文章

Python中反转字符串的常见方法小结

《Python中反转字符串的常见方法小结》在Python中,字符串对象没有内置的反转方法,然而,在实际开发中,我们经常会遇到需要反转字符串的场景,比如处理回文字符串、文本加密等,因此,掌握如何在Pyt... 目录python中反转字符串的方法技术背景实现步骤1. 使用切片2. 使用 reversed() 函

Python中将嵌套列表扁平化的多种实现方法

《Python中将嵌套列表扁平化的多种实现方法》在Python编程中,我们常常会遇到需要将嵌套列表(即列表中包含列表)转换为一个一维的扁平列表的需求,本文将给大家介绍了多种实现这一目标的方法,需要的朋... 目录python中将嵌套列表扁平化的方法技术背景实现步骤1. 使用嵌套列表推导式2. 使用itert

Python使用pip工具实现包自动更新的多种方法

《Python使用pip工具实现包自动更新的多种方法》本文深入探讨了使用Python的pip工具实现包自动更新的各种方法和技术,我们将从基础概念开始,逐步介绍手动更新方法、自动化脚本编写、结合CI/C... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

在Linux中改变echo输出颜色的实现方法

《在Linux中改变echo输出颜色的实现方法》在Linux系统的命令行环境下,为了使输出信息更加清晰、突出,便于用户快速识别和区分不同类型的信息,常常需要改变echo命令的输出颜色,所以本文给大家介... 目python录在linux中改变echo输出颜色的方法技术背景实现步骤使用ANSI转义码使用tpu

Conda与Python venv虚拟环境的区别与使用方法详解

《Conda与Pythonvenv虚拟环境的区别与使用方法详解》随着Python社区的成长,虚拟环境的概念和技术也在不断发展,:本文主要介绍Conda与Pythonvenv虚拟环境的区别与使用... 目录前言一、Conda 与 python venv 的核心区别1. Conda 的特点2. Python v

Spring Boot中WebSocket常用使用方法详解

《SpringBoot中WebSocket常用使用方法详解》本文从WebSocket的基础概念出发,详细介绍了SpringBoot集成WebSocket的步骤,并重点讲解了常用的使用方法,包括简单消... 目录一、WebSocket基础概念1.1 什么是WebSocket1.2 WebSocket与HTTP

SQL Server配置管理器无法打开的四种解决方法

《SQLServer配置管理器无法打开的四种解决方法》本文总结了SQLServer配置管理器无法打开的四种解决方法,文中通过图文示例介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录方法一:桌面图标进入方法二:运行窗口进入检查版本号对照表php方法三:查找文件路径方法四:检查 S

MyBatis-Plus 中 nested() 与 and() 方法详解(最佳实践场景)

《MyBatis-Plus中nested()与and()方法详解(最佳实践场景)》在MyBatis-Plus的条件构造器中,nested()和and()都是用于构建复杂查询条件的关键方法,但... 目录MyBATis-Plus 中nested()与and()方法详解一、核心区别对比二、方法详解1.and()

golang中reflect包的常用方法

《golang中reflect包的常用方法》Go反射reflect包提供类型和值方法,用于获取类型信息、访问字段、调用方法等,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值... 目录reflect包方法总结类型 (Type) 方法值 (Value) 方法reflect包方法总结

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin