首页 > 编程知识 正文

异步跨时钟域,异步fifo跨时钟处理

时间:2023-05-03 17:07:15 阅读:190006 作者:3331

1竞争冒险

在存在竞争的组合电路中,以下图为例,相对于图a的“与”门,初始时刻a为高电平,b为低电平,输出y为低电平。 如果在某个时刻b先开始跳跃,且达到了与门的vil[max],则在该时刻b被认为是高电平,a也在某个时刻[比b稍晚]开始跳跃。 此时还没有达到vil[max],因此仍然被视为高电平。 此时,y输出为高电平,因此会产生尖峰。 这个尖峰脉冲是系统内部的噪声。

将这样的两个逻辑信号向同一个方向迁移到相反的逻辑电平的现象称为竞争。 (竞争一定在同一扇门的输入处有两个信号,这两个信号会向相反的方向跳跃。)

但是,两个信号的竞争现象并不一定会产生尖峰。 因此,竞争风险现象可以解释为由于竞争而有可能在电路输出端产生尖峰的现象。

检查竞争冒险的常用方法:

逻辑表达式化简法

在输出端门电路的两个输入信号a和a通过两个不同的传输路径输入变量a的情况下,当输入变量改变时,可能在输出端产生尖峰。

因此,能够相对于输出侧逻辑函数在一定的条件下进行简化:

y=aa’,有“0”型的竞争;

y=aa’,有“1”型竞争;

的情况下,我判断一定会有竞争的冒险。

卡洛图法

也就是说,如果逻辑函数公式的卡洛图中画的圆不重叠且相切,就会被判断为有竞争的危险。 (本质上利用的是上面的方法,是直观形象的判断)

在以下卡洛图中,左图有竞争冒险,右图没有竞争冒险。

示例:对于逻辑函数y=ABA’c

当B=C=1时,y=aa’,因此函数有竞争风险。

我们发现,绘制该逻辑函数的卡洛图与上左图相似,因此存在竞争和冒险

消除冒险竞争

加入滤波电容器,消除毛刺的影响

在输出端连接小滤波电容,将尖峰脉冲的振幅减弱到门电路的阈值以下。

虽然很简单,但是输出电压波形的上升时间和下降时间会变长,波形会变差。

输入通信号码避免毛刺

导入选通信号p后,p的高电平会在电路达到稳定状态后出现,因此上图G0-G3的各栅极不会出现尖峰脉冲。

注意: G0-G3的信号也应为脉冲信号,宽度与脉冲相同。 例如,在AB=11的情况下,Y3并不是马上变成1,而是需要在p脉冲出现后发出正脉冲。

增加冗馀度,消除逻辑冒险。 (卡洛() ) ) )。

1 )有冲突时,增加冗馀项,实现输出去毛刺。

例如:逻辑公式如下。 y=a’bcab

在B=C=1的情况下,电路中存在“0”型的竞争。 附加项目:冗馀项目BC

变更后: y=a’BCA BBC (利用消除冗馀项公式) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )

2 )也有在两个相接的圆之间,在相接的地方增加一个相接的圆的方法。

对于以上的卡洛图,由于在相接的位置追加冗长项b’c,所以函数式y=a’b’ACB’c

2亚稳态

要理解亚稳态,首先需要知道几个概念:

1、同步逻辑、异步逻辑。

2、两个词的创立时间(Setup )和保持时间(Hold )。 其实时序分析的精髓在于分析每个触发器能否满足创立时间和保持时间的要求。

首先,同步逻辑、异步逻辑:

简单理解:一个模块中使用的时钟与时钟之间有一定的相位关系,或者时钟特征是可预测的,这被称为同步逻辑; 一个模块中使用的时钟彼此没有固定的相位关系。 也就是说,时钟的特征是不可预测的,被称为异步逻辑。

在一个时钟字段(src_data_out )中信号发生变化,在另一个时钟字段(dest_data_in )中采样时,输出将进入准稳态。 这就是所谓的同步失败,请参阅下图触发器的稳态。 这意味着它违反了保留时间的建立。

如何处理亚稳态

降低系统时钟

使用反应更快的FF

引入同步机制,防止亚稳态传播

改善时钟质量,使用边沿变化快的时钟信号

3跨时钟域

在时钟域之间传输信号的主要问题是亚稳态。 对于apb、ahb、iic等不同的时钟,处理时钟域之间的数据有单位和多位,但双拍打方式在处理单位数据的时钟域之间的问题中很常见。 2拍打的本质是定义2阶段寄存器,延迟拍摄数据。

不同时钟域之间的信息交换需要时钟同步,需要异步FIFO。

4同步FIFO

在谈论异步fifo之前,先了解同步fifo

5异步fifo

异步fifo常见问题,异步fifo介绍

异步fifo的结构如下。

如上图所示的同步模块synchronize to write clk,其作用是把读时钟域的读指针rd_ptr采集到写时钟(wr_clk)域,然后和写指针wr_ptr进行比较从而产生或撤消写满标志位wr_full同样,同步模块synchronize to read clk的作用是把写时钟域

的写指针wr_ptr采集到读时钟域,然后和读指针rd_ptr进行比较从而产生或撤消读空标志位rd_empty。另外还有写指针wr_ptr和写满标志位wr_full产生模块,读指针rd_ptr和读空标志位rd_empty产生模块,以及双端口存储RAM模块

可以通过比较读写指针来判断产生读空和写满信号,但是读指针是属于读时钟域的,写指针是属于写时钟域的,而异步FIFO的读写时钟域不同,是异步的,要是将读时钟域的读指针与写时钟域的写指针不做任何处理直接比较肯定是错误的,因此我们需要进行同步处理以后进行比较。

同步的过程有两个:

(1)将写时钟域的写指针同步到读时钟域,将同步后的写指针与读时钟域的读指针进行比较产生读空信号;

(2)将读时钟域的读指针同步到写时钟域,将同步后的读指针与写时钟域的写指针进行比较产生写满信号;

异步FIFO的写指针和读指针分属不同时钟域,这样指针在进行同步过程中很容易出错,比如写指针在从0111到1000跳变时4位同时改变,这样读时钟在进行写指针同步后得到的写指针可能是0000-1111的某个值,一共有2^4个可能的情况,而这些都是不可控制的,你并不能确定会出现哪个值,那出错的概率非常大,怎么办呢?到了格雷码发挥作用的时候了,而格雷码的编码特点是相邻位每次只有 1 位发生变化, 这样在进行指针同步的时候,只有两种可能出现的情况:

指针同步正确,正是我们所要的;

指针同步出错,举例假设格雷码写指针从000->001,将写指针同步到读时钟域同步出错,出错的结果只可能是000->000,因为相邻位的格雷码每次只有一位变化,这个出错结果实际上也就是写指针没有跳变保持不变,我们所关心的就是这个错误会不会导致读空判断出错?答案是不会,最多是让空标志在FIFO不是真正空的时候产生,而不会出现空读的情形。所以gray码保证的是同步后的读写指针即使在出错的情形下依然能够保证FIFO功能的正确性。在同步过程中的亚稳态不可能消除,但是我们只要保证它不会影响我们的正常工作即可。

问题1:读写时钟域之间如何同步的
通过格雷码转换,加拍两拍,减少亚稳态危害。
但是为什么要用格雷码进行同步传输?
我觉得使用格雷码的优势体现在读写时钟差异不是特别大的时候,不能一个是1000M一个是10M那谁也救不了了,无限加长FIFO深度吧。那么我们假定读写时钟频率差异没有过大,例如一个133M一个100M这样的。我们要知道这个异步时钟采样,再不经过特殊处理的情况下采错了是在所难免的。单个信号可能采错或者没采到,那多个信号的读写指针就更加有可能出问题了。我们来看下如果此时的指针是1011(二进制=2),那么在向1100(2)跳变时候,由于信号走的距离不一样啦触发事件或者逻辑门延时不同啦等等原因,在另外一段时钟域就可能采出多种情况例如1011(2)、1110(2)、1101(2)等,总之每个信号都可能是正确值或者未跳变时候的值。那么在得到“空”“满”逻辑时候很大可能概率会出错,这个我们不能忍。过程如下图所示。所以说我们就要选择格雷码了,来看下格雷码发生了什么事。1011(2)=1110(g),1100(2)=1010(g),因此格雷码跳变为1110(g)->1010(g)。同样考虑采样出问题了,由于我们提前说好了读写时钟频率差距不是太大,因此采样可能得到两种情况:1110(g)和1010(g),到另外的时钟域后会转换为二进制的1011(2)和1100(2)。看到这里是不是想到了什么!你看如果得到的是1100那没问题呀,这就是真是的值。如果是得到1011呢?我实际跑到了1100你采到了1011是不是类似于上一个问题的“指针实际已经跑到了9而你只采到了7,会不会出问题”,答案是不会呀!原因就在于我们进行对比时时钟域的选择已经解决了这个问题。因此可知使用格雷码即时出现了采样错误的情况,也不会时“空满”判定出现问题。

问题2:为什么把读指针同步到写时钟域和写指针判断写满wfull标志位,把写指针同步到读时钟域和读指针判断读孔rempth信号。
同步rd_cntr至clk_write时钟域,再与wr_cntr进行对比来决定FIFO是否满;(判断满是wr_cntr - rd_cntr)
同步wr_cntr至clk_read时钟域,再与rd_cntr进行对比来决定FIFO是否空;(判断空是rd_cntr == wr_cntr)
这是结论,那现在我们必须要仔细的思考这句话为什么是这么做的。
首先画个示意图。

那现在我们来设想各种情况下会发生什么,在此我们暂时不考虑亚稳态的事情,认为信号通过同步模块都被采到了但是会有信号丢失。

第一种情况我们假定写时钟特别快,读时钟都采不齐写指针。

那么此时空逻辑会不会出错呢?假设写指针已经跑了1 2 3 4 5 6 7 8 9,而读时钟采到了1 2 6 8;那么如果此时读指针就在8,两边一对比发现一样(当然了这只是假设的一种情况)则会报“空”!那么实际空没空呢,没有因为我写到9了写进去了一个数,不过没关系之后必然会采到9(或者采到10一类的),状态会很快恢复正常,或者说没有空而报了空我们还可以接受,因为这样对于一个将要空的FIFO会停止读数旋即恢复正常,不会使其数据发生紊乱。那会不会有空了而报不空使得读出数据出现问题的情况呢?不会的,你想想看写指针跑的比你采样的快,是趋向与“不空”(越写数据越多嘛)的,因此不会出现这样的错误。
读指针被同步到写时钟域本身不会出现漏采的情况,因此“满”逻辑的判断不会出现问题。

第二种情况我们假定读时钟域特别快,写时钟都采不齐读指针。

此时的满逻辑会出错么?我们来看下。我们同样假设读指针从1跑到了9,而只被采样到了7。如果此时写指针也写到了7,那么二者一比较发现写“满”了,实际呢没有满,不过此时也会停止外部写入(传出了满的信号),这是不会对FIFO中的数据产生影响的,并且很快会恢复到“不满”。如果此时写指针到了5,那么二者对比会得出“不满”的逻辑传出,真实情况呢同样是不满,因为读到7就已经不满了真实情况读到了9自然更加“不满”。这样就解释清楚了。
写指针被同步到读时钟域本身不会出现漏采的情况,因此“空”逻辑的判断不会出现问题。

我们可以选择一种记法:

“满”逻辑是要给谁的——给写信号告诉他你别写了——那么写指针能多跑出去么?跑多了不就把数据覆盖了!——所以必须在写时钟域进行对比;
“空”逻辑是要给谁的——给读信号告诉他你别读了——那么读指针能多跑出去么?跑多了不就读出来错误的数了!——所以在读时钟域进行对比;

异步FIFO的虚空虚满。
以满标志的产生为例,读地址通过同步器同步到写时钟域,在这会产生两个或三个周期的延迟,因此满标志的产生是通过比较现在的写地址和两三个周期以前的读地址产生的。所以这里显示的满并不是真的满,但是这不影响FIFO正常功能。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。