【异步FIFO的一些小事·1】空满判断与格雷码

简介: 【异步FIFO的一些小事·1】空满判断与格雷码

今天经过与HR的交谈意识到自己对于异步FIFO的理解还不深,因此回来之后又其结构进行了一些理解,于此分享。

异步FIFO的设计:http://blog.csdn.net/moon9999/article/details/77822606

疑问1:进行数据空满的对比时,读写时钟域都有读写指针,此时应该怎么对比?为什么?

另外一篇博客中有这样的话:

同步rd_cntr至clk_write时钟域,再与wr_cntr进行对比来决定FIFO是否满;(判断满是wr_cntr - rd_cntr)
同步wr_cntr至clk_read时钟域,再与rd_cntr进行对比来决定FIFO是否空;(判断空是rd_cntr == wr_cntr)

这是结论,那现在我们必须要仔细的思考这句话为什么是这么做的。

首先画个示意图。

0b783af7ada606dad4728406e5a72251_SouthEast.jpg

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

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

那么此时空逻辑会不会出错呢?假设写指针已经跑了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自然更加“不满”。这样就解释清楚了。

写指针被同步到读时钟域本身不会出现漏采的情况,因此“空”逻辑的判断不会出现问题。

受到HR的点播或许我们可以选择一种记法:

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

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

我现在先理解到这一步吧。

疑问2:为什么要用格雷码进行同步传输?

我觉得使用格雷码的优势体现在读写时钟差异不是特别大的时候,不能一个是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,会不会出问题”,答案是不会呀!原因就在于我们进行对比时时钟域的选择已经解决了这个问题。因此可知使用格雷码即时出现了采样错误的情况,也不会时“空满”判定出现问题。


相关文章
|
前端开发 芯片
【芯片前端】“异步FIFO全解析”的BUG——格雷码连续性
【芯片前端】“异步FIFO全解析”的BUG——格雷码连续性
162 1
|
26天前
|
Java 程序员
为什么循环调用wait()比if块更可靠?小米为你揭晓答案!
大家好,我是小米,29岁程序员。在一次社招面试中,我遇到了一个有趣的Java并发编程问题:“如何调用wait()方法?使用if块还是循环?”通过这次经历,我深入探讨了wait()方法的正确使用方式。使用if块存在隐患,可能会导致线程在唤醒后不检查条件变化,从而引发错误。相比之下,使用循环可以确保线程在唤醒后再次检查条件,避免虚假唤醒和条件变化未处理的问题。此外,我还分享了wait()方法的最佳实践,包括在同步块中调用、处理InterruptedException等。希望这篇文章能帮助大家更好地理解和使用wait()方法。欢迎关注我的微信公众号“软件求生”,获取更多技术干货!
21 3
|
存储 算法 调度
C语言模拟银行排队叫号(顺序队)
C语言模拟银行排队叫号(顺序队)
257 0
|
传感器
《逻辑与计算机设计基础(原书第5版)》——1.7 格雷码
本节书摘来自华章计算机《逻辑与计算机设计基础(原书第5版)》一书中的第1章,第1.7节,作者:(美)M.莫里斯·马诺(M. Morris Mano)著, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1790 0
|
消息中间件 编解码 算法
准循环 LDPC 码的多码长设计 | 带你读《5G-NR信道编码》之十
本节将为你介绍准循环 LDPC 码(QC-LDPC)的基本内容。
准循环 LDPC 码的多码长设计 | 带你读《5G-NR信道编码》之十
|
C语言
牛客网带你刷 · C语言 | 有序序列判断
问:输入一个整数序列,判断是否是有序序列,有序,指序列中的整数从小到大排序或者从大到小排序(相同元素也视为有序)
214 0
牛客网带你刷 · C语言 | 有序序列判断
【滴水逆向三期41作业】C语言提取文件PE头部信息
【滴水逆向三期41作业】C语言提取文件PE头部信息
【期末不挂科-单片机考前速过系列P6】(第六章:10题速过定时计数器的结构和工作方式例题)经典例题盘点(带图解析)
【期末不挂科-单片机考前速过系列P6】(第六章:10题速过定时计数器的结构和工作方式例题)经典例题盘点(带图解析)
【数字IC手撕代码】Verilog单bit跨时钟域快到慢,慢到快,(打两拍,边沿同步,脉冲同步)|题目|原理|设计|仿真
【数字IC手撕代码】Verilog单bit跨时钟域快到慢,慢到快,(打两拍,边沿同步,脉冲同步)|题目|原理|设计|仿真
【数字IC手撕代码】Verilog单bit跨时钟域快到慢,慢到快,(打两拍,边沿同步,脉冲同步)|题目|原理|设计|仿真

热门文章

最新文章