FPGA异步时钟设计中的同步策略
1 引言
    基于FPGA的数字系统设计中大都推荐采用同步时序的设计,也就是单时钟系统。但是实际的工程中,纯粹单时钟系统设计的情况很少,特别是设计模块与外围芯片的通信中,跨时钟域的情况经常不可避免。如果对跨时钟域带来的亚稳态、采样丢失、潜在逻辑错误等等一系列问题处理不当,将导致系统无法运行。本文总结出了几种同步策略来解决跨时钟域问题。
2 异步设计中的亚稳态
    触发器是FPGA设计中最常用的基本器件。触发器工作过程中存在数据的建立(setup)和保持(hold)时间。对于使用上升沿触发的触发器来说,建立时间就是在时钟上升沿到来之前,触发器数据端数据保持稳定的最小时间。而保持时间是时钟上升沿到来之后,触发器数据端数据还应该继续保持稳定的最小时间。我们把这段时间成为setup-hold时间(如图1所示)。在这个时间参数内,输入信号在时钟的上升沿是不允许发生变化的。如果输入信号在这段时间内发生了变化,输出结果将是不可知的,即亚稳态 (Metastability)。 
    一个信号在过渡到另一个时钟域时,如果仅仅用一个触发器将其锁存,那么采样的结果将可能是亚稳态。这也就是信号在跨时钟域时应该注意的问题。如图2所示。 
    信号dat经过一个锁存器的输出数据为a_dat。用时钟b_clk进行采样的时候,如果a_dat正好在b_clk的setup-hold时间内发生变化,此时b_ dat就既不是逻辑"1",也不是逻辑"0",而是处于中间状态。经过一段时间之后,有可能回升到高电平,也有可能降低到低电平。输出信号处于中间状态到恢复为逻辑"1"或逻辑"0"的这段时间,我们称之为亚稳态时间。
     触发器进入亚稳态的时间可以用参数MTBF(Mean Time Between Failures)来描述,MTBF即触发器采样失败的时间间隔,表示为: 
其中fclock表示系统时钟频率,fdata代表异步输入信号的频率,tmet代表不会引起故障的最长亚稳态时间,C1和C2分别为与器件特性相关的常数。如果MTBF很大,就认为这个设计在实际工作中是能够正常运行的,不会因为亚稳态导致整个系统的失效。当触发器处于亚稳态,且处于亚稳态的时间超过了一个时钟周期,这种不确定的状态还会影响到下一级的触发器,最终导致连锁反应,从而使整个系统功能失常。
3 同步策略
    在异步设计中,完全避免亚稳态是不可能的。因此,设计的基本思路应该是:首先尽可能减少出现亚稳态的可能性,其次是尽可能减少出现亚稳态并给系统带来危害的可能性。以下是根据实际工作总结出来的几种同步策略。
3.1 双锁存器法
    为了避免进入亚稳态,应当使参数MTBF尽可能大。通常采用的方法是双锁存器法,即在一个信号进入另一个时钟域之前,将该信号用两个锁存器连续锁存两次(如图3所示)。理论研究表明这种设计可以将出现亚稳态的几率降低到一个很小的程度,但这种方法同时带来了对输入信号的一级延时,需要在设计时钟的时候加以注意。 
    对于上面的双锁存器法,如果a_clk的频率比b_clk的频率高,将可能出现因为dat变化太快,而使b_clk无法采样的问题。即在信号从快时钟域向慢时钟域过渡的时候,如果信号变化太快,慢时钟将可能无法对该信号进行正确的采样,所以在使用双锁存器法的时候,应该使原始信号保持足够长的时间,以便另一个时钟域的锁存器可以正确地对其进行采样。
3.2 结绳法
    由于双锁存器法在快时钟域向慢时钟域过渡中可能存在采样失效的问题,我们引入了一种安全的跨时钟域的方法:结绳法。结绳法适合任何时钟域的过渡(clk1,clk2的频率和相位关系可以任意选定),如图4所示。 
    图4中的_clk1表示该信号属于clk1时钟域,_clk2的信号表示该信号属于clk2时钟域。在两次src_req_clk1之间被src_vld_clk1结绳(Pluse2Toggle)。将src_vld—clk1用双锁存器同步以后,该信号转换为dst_req_clk2(Toggle2Pluse)。同理,用dst_vld_clk2将dat_req_clk2结绳,dst_vld_clk2表明在clk2时钟域中,src_dat_clk1已经可以进行正确的采样了。最后将dst_vld_clk2转换为dst_ack_clk1(Synchronizer and Toggle2Pluse)。dst_ack_clk表明src_dat_clk1已经被clk2正确采样了,此后clk1时钟域就可以安全地传输下一个数据了。可以看出,结绳法的关键是将信号结绳以后,使其保持足够长的时间,以便另一个时钟可以正确采样。图5描述了结绳法的具体实现,主要包括3个基本单元:Pluse2Toggle、Synchronizer和Toggle2Pluse。 
    Pluse2Toggle模块负责将两个脉冲信号结绳,即将单脉冲信号延长;Synchronizer模块用双锁存器法将得到的信号过渡到另一个时钟域;Toggle2Pluse模块与Pluse2Toggle功能相对,即将延长的脉冲信号还原为单脉冲,这里用到了异或门。整体的设计思想就是用Pluse2Toggle将信号延长,用Synchronizer过渡,再用Toggle2Pluse还原,以保证另一个时钟域可以正确采样,而接收方用相反的流程送回响应信号。
    结绳法可以解决快时钟域向慢时钟域过渡的问题,且适用的范围很广。但是结绳法实现较复杂,在设计要求较高的场合应该慎用。
4 结束语
    本文主要把FPGA异步时钟设计中产生的问题,原因以及解决问题所采用的同步策略做了详细的分析。其中双锁存器法比较适用于只有少数信号跨时钟域;结绳法比较适用快时钟域向慢时钟过渡的情况。所以,在实际的应用中,应根据自身设计的特点选择适当的同步策略。
FPGA异步时钟设计中的同步策略的更多相关文章
- FPGA异步时钟系统中信号处理之单比特信号
		有些东西当你习以为常而不去深思熟虑的时候,致命的错误就会因此埋下! FPGA开发中难免会遇到跨时钟域处理的问题,而对于单比特信号,我会不假思索的回答:打两拍不久解决了吗?但是事实时,这佯作的 ... 
- FPGA 异步时钟处理方
		1 假设FPGA设计,包括不同的频率的时钟,它会发出涉及异步时钟. 我们需要一些方法来使时钟同步,从而保证FPGA可靠性设计. 2 在建立和保持时间所构成的有效时间窗体内,数据输入到触发器进行转换. ... 
- 关于FPGA异步时钟采样--结绳法的点点滴滴
		一.典型方法 典型方法即双锁存器法,第一个锁存器可能出现亚稳态,但是第二个锁存器出现亚稳态的几率已经降到非常小,双锁存器虽然不能完全根除亚稳态的出现(事实上所有电路都无法根除,只能尽可能降低亚稳态的出 ... 
- verilogHDL设计中的同步时序逻辑
		引用自夏宇闻教授 1.同步时序逻辑: 是指表示状态的寄存器组的值只能在唯一确定的触发条件发生改变. 只能由时钟的正跳变沿或者负跳变沿触发的状态机就是一例,always@(posedge clk). 1 ... 
- Go语言 | 并发设计中的同步锁与waitgroup用法
		今天是golang专题的第16篇文章,我们一起来聊聊golang当中的并发相关的一些使用. 虽然关于goroutine以及channel我们都已经介绍完了,但是关于并发的机制仍然没有介绍结束.只有go ... 
- FPGA设计中的异步复位、同步释放思想
		1.一个简单的异步复位例子: module test( input clk, input rst_n, input data_in, output reg out ); always@(posedge ... 
- 7系列FPGA的时钟资源——UG472
		时钟架构总览 7系的FPGA使用了专用的全局(Global)和区域(Regional)IO和时钟资源来管理设计中各种的时钟需求.Clock Management Tiles(CMT)提供了时钟合成(C ... 
- 影响FPGA设计中时钟因素的探讨。。。转
		http://www.fpga.com.cn/advance/skill/speed.htm http://www.fpga.com.cn/advance/skill/design_skill3.ht ... 
- FPGA设计中的电源管理(转载)
		过去,FPGA设计者主要关心时序和面积使用率问题.但随着FPGA不断取代ASSP和ASIC器件,设计者们现正期望能够开发低功耗设计,在设计流程早期就能对功耗进行正确估算,以及管理和对与FPGA相关的各 ... 
随机推荐
- jquery ajax cache的问题
			function test() { $.ajax({ type:'GET', url:"tt. ... 
- 创建通用型framework
			http://years.im/Home/Article/detail/id/52.html http://www.cocoachina.com/industry/20131204/7468.html ... 
- [WebKit]浏览器的加载与页面性能优化
			非常棒.非常系统的一份资料,值得阅读! 原文来自百度泛用户体验. 作者:nwind 本文将探讨浏览器渲染的loading过程,主要有2个目的: 了解浏览器在loading过程中的实现细节,具体都做了什 ... 
- Ubuntu 安装Chrome步骤
			一.添加PPA 从Google Linux Repository(http://www.google.com/linuxrepositories/)下载安装Key,或把下面的代码复制进终端,回车,需要 ... 
- CONTAINING_RECORD 宏
			Windows中提供了一个宏 #define CONTAINING_RECORD (address, type, field ) ((type *)( \ (PCHAR)(address ) - \ ... 
- FZU 2225 小茗的魔法阵 扫描线+树状数组
			这个题和一个CF上的找"Z"的题差不多,都是扫描线+树状数组 从右上角的主对角线开始扫描,一直扫到左下角,每次更新,右延伸等于该扫描线的点,注意在其所在的树状数组更新就好了 时间复 ... 
- LittleTools之网格输出为模型
			我经常要在Unity中生成一些网格,但是这些网格需要交给美工修改,所以又要将网格输出为模型.于是就有了下面的代码: using UnityEngine; using UnityEditor; usin ... 
- [POJ1852]Ants
			Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 12431 Accepted: 5462 Description An a ... 
- Class.forName()数据库驱动
			在学习jdbc中,用到Class.forName(驱动);,当时学习的时候知道Class.forName就是加载一个类到虚拟机,在加载一个类的时候,这个类的信息会被放到一个方法区,一个CLass 在J ... 
- ArrayLLis 线程不安 实验
			这段代码演示了ArrayList的线程不安全,我让3个线程分别对list加入300个字符串,最后的arr的大小为800多,大家可以测试一下,我的一次是898,一次是897,同时还学了join的用法 i ... 
