跨时钟域处理
转载:http://www.cnblogs.com/IClearner/p/6485389.html ;
最近我整理了一下跨时钟域设计的一些知识,一方面这与亚稳态有关系,承接前面讲到的内容,一方面当做复习吧。主要内容主要是是围绕跨时钟域展开的,主要内容概览:
·跨时钟域与亚稳态
·跨同步时钟的控制信号传输
·时钟同源,周期之间非整数倍的跨时钟域
·跨异步时钟域的控制信号传输
1、跨时钟域与亚稳态
跨时钟域通俗地讲,就是模块之间有数据交互,但是模块用的不是同一个时钟进行驱动,如下图所示:
左边的模块1由clk1驱动,属于clk1的时钟域;右边的模块2由clk2驱动,属于clk2的时钟域。当clk1比clk2的频率高时,则称模块1(相对于模块2)为快时钟域,而模块2位为慢时钟域。根据clk1和clk2是不是同步时钟,可以将上面的跨时钟域分为跨同步时钟域(clk1与clk2是同步时钟)和跨异步时钟域(clk1和clk2不是同步时钟)。根据信号是控制信号还是数据信号可以分为跨时钟域的控制信号传输和数据信号的传输。
在跨时钟域的信号传输过程中,可能出现亚稳态的情况,这个时候,需要同步器进行同步,减小亚稳态传播下去的概率;注意这里的同步器只能减少亚稳态往下传播的概率,如果产生亚稳态,亚稳态恢复稳定后的电平不一定是正确的电平,如果稳定后的电平是错误的,那么就很有可能引起后面的逻辑的错误,这是需要强调的;当然,一般情况下(我这里是说一般情况)很少发生亚稳态,不然后面的逻辑岂不是要挂?
根据上面的内容可知,跨时钟域可能需要同步器来抑制亚稳态的往下传播的概率,根据情况的不同需要不同的同步器,大致情况如下所示:
跨同步时钟域 |
快时钟域到慢时钟域 |
控制信号传输 |
跨异步时钟域 |
慢时钟域到快时钟域 |
数据信号传输 |
·跨同步时钟域下,快时钟域到慢时钟域 的控制信号传输;
·跨同步时钟域下,慢时钟域到块时钟域 的控制信号传输;
·跨同步时钟域下,快时钟域到慢时钟域 的数据信号传输;
·跨同步时钟域下,慢时钟域到块时钟域 的数据信号传输;
·跨异步时钟域下,快时钟域到慢时钟域 的控制信号传输;
·跨异步时钟域下,慢时钟域到块时钟域 的控制信号传输;
·跨异步时钟域下,快时钟域到慢时钟域 的数据信号传输;
·跨异步时钟域下,慢时钟域到块时钟域 的数据信号传输;
看着这八大类型,心里就虚,但是这里先剧透一下,在数据的传输(主要是多位数据的传输)里面,无论是跨同步还是跨异步,主要(注意是主要)都是使用比较大的同步隔离器,进行隔离缓冲数据,比如FIFO、RAM;因此一般就会分为控制信号(一般是1位信号)和数据这两种情况设计同步器。跨时钟域的数据传输我们放在最后讲。今天主要整理跨时钟域的控制信号传输。
我在前面的一篇博客中说到了同步电路与异步电路的区分:http://www.cnblogs.com/IClearner/p/6440488.html 。这里我们要随机应变,在这里更新一下传统同步时钟的概念:系统中的多个时钟,如果他们的边沿相对的时间差固定(或者说相位固定),那么就属于同步时钟。它们可以是不同时钟源产生的,但是通过锁相环把它们之间的相位进行固定,因此是同步时钟。它们可能是同一时钟源产生的,但是经过分频之后,它们之间的相位随着初始相位和时间变化,这类时钟可以叫他同步时钟,但是从这个传统的概念出发,这就是异步时钟(这个与我上面的那篇博客不一样,要注意),在处理上当做异步时钟进行处理。好了,说了这么多,接下来我们就根据时钟的分类来进行说说吧。
2、跨同步时钟的控制信号传输
(1)同频同相位的两个同步时钟:
波形如下所示:
这两个时钟可以看做是同一个时钟,也就是单时钟设计,允许有1个时钟的周期进行传输数据,因此只要满足普通的同步电路设计要求(满足建立时间和保持时间,控制信号的传输延时要在一定范围内)就可以了,不会出现亚稳态,也不会出现数据丢失的情况,一般不需要同步器。
(2)同频不同相位的两个同步时钟
波形如下所示:
这个固定的相位可以看成是时钟的偏移,允许的传输时间小于一个时钟周期,但是只要满足控制信号的输出是在clk1的控制下进行翻转的,因此只要满足同步设计的一般要求(满足建立时间和保持时间,控制信号的传输延时要在一定范围内),就可以满足时序,不会出生亚稳态,也不会出现数据丢失的情况,因此一般不需要同步器。
(3)不同频,但是存在整数倍的关系
假设没有初始相位差(或者即使有初始相位差固定,也可以通过后期修复),clk1的时钟频率是clk2的3倍。
·当从快时钟域跨到慢时钟域时(也就是控制信号从clk1的模块传输到clk2的模块),波形如下所示:
如果是clk1在第2个上升沿进行发送信号,只要控制信号在3个clk1的周期内到达,就不会出现亚稳态;...如果clk1在第4个上升沿进行发送信号,就需要控制信号在1个clk1的周期内到达,就不会出现亚稳态。因此只要控制信号从发送时钟域出发到达目的时钟域的时间小于clk1的时钟周期,就不需要同步器;一般情况下,控制信号是触发器触发,触发器捕获,一般满足这个关系,如下所示:
然而需要注意的,这个是从快传到慢,慢时钟域可能会采样不到控制信号从而丢失控制信号,也就是说,我控制信号在从clk1跑到clk2,并且保持一个时钟(clk1)周期,但是你clk2的时钟沿还没有来,等到clk2的上升沿来了,我这个控制信号就已经更新(或者失效)了,上面恰好在时钟clk2上升沿的前一个时钟周期clk1发出信号才采到,如果不是那个时候发送,就会丢失控制信号,如下所示:
在第2个时钟沿发送信号的时候,只持续了一个时钟周期,因此clk2捕捉不到(这样就是功能性错误了,不单单是时序上的亚稳态而已了);只有在第4个时钟沿的时候发送控制信号,clk2才捕捉得到。因此我们就需要把这个控制信号的周期延迟到clk1周期的3倍,这个可以通过计数器或者状态机进行实现,延长后的波形如下所示:
可见,这时候不论在上面时候进行发送数据,clk2都能捕捉得到。
因此一般情况下不需要同步器,但是需要把快时钟域的控制信号根据进行延长合适的时间(根据时钟之间的倍数关系进行确定,控制信号的长度要≥捕获时钟的周期,一般取1.5倍,上图只是1倍),避免慢时钟域丢失信号。
·当慢时钟到快时钟域时(也就是控制信号从clk2的模块传输到clk1的模块),波形如下所示:
很显然,快时钟能够采样得到慢时钟的控制信号,而且采样了三次,输出为:
Clock2的控制信号就达到了clk2周期的3倍,如果只需要1个clk周期的控制信号,可以通过上升沿检测电路实现,其输出波形如下所示:
3、时钟同源,周期之间非整数倍的跨时钟域
当两个时钟都来源于同一个时钟,经过PLL分频之后,产生两个时钟时钟,一个时钟是另外一个时钟的非整数倍,相位是随时间变化的。在这种情况下,我们可以把这两个时钟当做同步时钟,也可以当做异步时钟;在传统的设计中,这样的时钟会当做异步时钟进行处理。下面我们就来看看这样的时钟处理要不要加同步器吧。
假如时钟源的时钟频率为clk,经过PLL后,产生一个时钟clk1和一个时钟clk2:
假设clk1是快时钟,clk2是慢时钟。由于控制信号仅仅在两个时钟域的触发器之间传输,触发器之间不存在任何逻辑,因此控制信号从发送触发器到捕获触发器的时间很小,假设为t ps,当发送沿与捕获沿之间的间距大于tps,就不会产生亚稳态(理论情况,不考虑时钟偏移、翻转等因素)。当clk1的频率不是clk2的整数倍的时候,他们的相位是随着时间的改变而改变的,在知道了clk1和clk2的频率后,就可以知道理论下clk1和clk2的相位关系,那么就会有下面的情况:
(其实也就分为要不要加同步器的的情况)
(1)(跨时钟域无论是快到慢还是慢到快)两个时钟存在最小相位差,且最小相位差大于t。如下所示:
这里的这种情况下,时钟最小最小的相位差T>t,也就是说,控制信号不会违反捕获寄存器的建立时间和时间。需要注意的是,这是快时钟到慢时钟域的控制信号传输,要防止信号丢失的情况,也就是需要将控制信号延长到一定的长度。
从慢时钟到时钟的波形就不画了, 但是主要符合两个时钟(无论是快到慢还是慢到快)存在最小相位差,且最小相位差大于t,就不会违反建立时间和保持时间,基本不会产生亚稳态。因此在这种情况下,是不需要同步器的。
(2)(跨时钟域无论是快到慢还是慢到快)两个时钟中,发送沿到接收沿的相位很窄,小于t,也就是违反捕获寄存器的建立时间和保持时间,但是下一次的发送沿到接收沿的相位很大(不违反捕获寄存器的建立时间和保持时间)的情况,如下所示:
在相位小的地方,建立时间不足,引起了亚稳态,这时候就要上我们的同步器了,这里隆重推出我们的同步器——双D触发器,其电路图如下所示:
要注意,其中间不能有任何组合逻辑,电路图与对于的时序关系如下所示(代码就不写了,电路简单):
再次强调,双D触发器(触发器链)只能抑制亚稳态往下传输(或者减小其往下传输的概率),并不一定能够同步正确的控制信号的值,这与亚稳态稳定后的值有关,上图中一级触发器的亚稳态稳定后的值恰好是高电平,因此二级触发器采样后的输出值为高电平。如果上图中一级触发器的亚稳态稳定后的值是低电平,那么二级触发器采样后的输出值将为低电平,也就是输出了错误的控制信号。
这里再啰嗦一下,在这种情况下(也就是有亚稳态的情况下),从慢到快,只有亚稳态的问题;而从快传输到慢,不仅有要抑制亚稳态往下传播的问题,还有控制信号丢失的问题,这里就需要延长控制信号的长度或者采取其他措施(后面会讲)。
(3)两个时钟相邻的几次发送沿和接收沿的相位差都很小的情况,如下图所:
这种情况可以说就基本是异步时钟域之间的控制信号传输了,在这种情况下,必定要加触发器链同步器,抑制亚稳态往下传播。跟前面的情况一样,从慢到快,只有亚稳态的问题;而从快传输到慢,不仅有要抑制亚稳态往下传播的问题,还有控制信号丢失的问题,这里就需要延长控制信号的长度或者采取其他措施(后面会讲)。
4、跨异步时钟域的控制信号传输
其实跨异步时钟域的波形跟前面的3.(3)类似,只不过两个时钟域的时钟是完全没有关系的时钟而已。在这样的情况下,我们可以采取跟前面类似的方法:首先触发器链抑制亚稳态的传输一定是要的,然后是快时钟到慢时钟的问题,也就是采样短脉冲的控制信号问题,除了对控制信号进行延长之外,我们还可以其他的方法,下面就来整理整理吧:
(1)握手/反馈机制
采用握手反馈机制,即可以抑制亚稳态的传输,又可以正确地传输控制信号。这种握手/反馈机制对所有的跨异步时钟的控制信号都有用,不过主要用在快到慢时钟、易产生亚稳态的情况。说了那么多,都没有实在的,下面就来看点实在的吧——握手/反馈机制电路图:
波形如下所示(手绘....):
其实原理很简单,当控制信号变高时(adat与adat1),慢时钟域的触发器链(bdat1和bdat2)进行采样,采样得到的高电平(bdat2)后,也就是确认采样得到控制信号后,再通过触发器链反馈给快时钟域(abdat1和abdat2),让快时钟域把控制信号拉低(拉低的或者处理时长在后面有电路),就完成控制信号的正确跨时钟传输。本来不想写代码了的,毕竟有电路了,但是想想还是贴一下代码吧,毕竟最近整理过程中都没有写代码了,感觉有点生疏了,代码如下(如果有错请指出):
当然,在慢时钟域阶段,我们也可以添加边沿检测(上升沿)电路,一方面让输出只有一个脉冲的控制信号,另一方面准确地进行控制,以防止亚稳态的干扰。
在上面的握手方案中,我们通过反馈信号进行控制信号的延时来让慢时钟域充分采样得到控制信号,本质上是也是对控制信号的延时。这个延时的具体实现,需要对控制信号的产生逻辑进行处理,来满足延时的要求,如下所示:
除了上面对控制信号处理之外,我们还可以对快时钟域的时钟动点手脚,具体电路如下所示:
这里通过让快时钟域触发器(特指rd_en触发器)的时钟停止工作的方式,让控制信号保持一定的时间。时钟停止之后,rd_en触发器的输出就会保持不变,等到反馈信号回来,告知慢时钟域采样得到高电平后,再恢复快时钟域的时钟,波形如下所示:
时钟停止的逻辑电路(类门控电路)的代码如下所示(代码如果有错,欢迎指出):
当然,这是一个组合电路。这样子会令后面的输出电路产生毛刺,类似于门控时钟那样,于是乎我们就可以使用门控时钟那样的技巧,防止输出产生毛刺。这里就不详细说明了。
(2)窄脉冲捕捉电路
前面的控制信号,它都需要反馈信号来把有效拉为无效,可以说这个控制信号是不“自由”的。有时候,我们需要捕捉异步短脉冲控制信号,这个控制信号完全由前面的逻辑电路生成,与我后面的电路信号无关,也就是说没有反馈信号,你也需要采样到这个短脉冲控制信号。下面的窄脉冲捕捉电路可以捕捉到快时钟域产生的异步窄脉冲控制信号,电路如下所示:
波形图如下所示:
从波形图中可以知道,这是利用了脉冲信号的上升沿进行输出脉冲信号,然后通过后面反馈回来的信号进行清零,从而为下一次脉冲控制信号做好准备。需要注意的是,窄脉冲控制信号的产生频率不能太快,也就是需要等到清零信号无效(三个触发器的延时)后才能发出下一个脉冲控制信号,不然后面的慢时钟域采样电路无法识别两次控制信号,而只当成一次控制信号处理。代码根据电路图写就好了=.=。
==========================================分割线=====================================================
控制信号的跨时钟域传输到这里就讲完了,下面进行总结一下:
·在跨时钟域的时候,不一定需要跨时钟域电路(同步器或者握手信号),接近异步时钟或者就是异步时钟的时候跨时钟域就得加上了。
·在慢到快的时钟域中,加上触发器链基本上就可以了,主要是抑制亚稳态的传播。
·但是在快到慢的时钟域中,不仅需要触发器链进行抑制亚稳态的传播,还要防止慢时钟域采不到快时钟域的数据,因此就添加反馈/握手电路(这个反馈信号是指跨时钟域的反馈信号)。
·在最后,介绍了窄脉冲控制信号捕捉电路,这个电路不需要添加反馈信号,也就是说只要控制信号的频率不是快,只要有窄脉冲(不是毛刺),就可以捕捉得到,而不需要反馈信号控制脉冲宽度(这个反馈信号是指跨时钟域的反馈信号,其实还是需要反馈清0的)。