0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

采用格雷码异步FIFO跟标准FIFO有什么区别

CHANBAEK 来源:硬件王国 作者:小山哥 2023-09-14 11:21 次阅读

导读:

异步FIFO包含"读"和"写“两个部分,写操作和读操作在不同的时钟域中执行,这意味着Write_Clk和Read_Clk的频率和相位可以完全独立。异步FIFO的原理很简单,写操作是在写使能有效时,写地址指针(Write_Pointer)逐渐递增,将数据写入存储器的相应位置。读操作是在读使能信号有效时,读地址指(Read_Pointer)逐渐递增,从存储器的相应位置读取数据。

但异步FIFO有一个难点就是—满和空的产生。写操作,我们得判断FIFO是不是满了,满了就不能继续往里面写,不然就会覆盖还没取走的数据。对于读操作,我们得判断FIFO是不是空了,空了就不能接着取,不然旧的数据会被取多次。

触发异步FIFO的满和空,是拿读和写的Pointer做比较得到的。问题在于:写操作下的Write_Pointer和读操作下的Read_Pointer属于两个不同的时钟域信号。两个不同的时钟域信号是不能直接做运算的,需要同步到同一个时钟域之后才行,因为有这个CDC同步器的开销,导致FIFO出现 真 满空和 假 满空。

接下来我们一起来看看标准异步FIFO的”真“满空和“假“满空如何产生,以及采用格雷码异步FIFO跟标准FIFO有什么区别。(这里所谓标准异步FIFO是指不使用特殊编码方式(如格雷码)的异步FIFO,即使用常规的二进制地址指针。)

标准异步FIFO

图片

标准异步FIFO结构如上图,假设FIFO的深度为8,addr(地址范围)为0 ~ 7。那么设计读写地址指针都是4bit,即w_ptr[3:0],r_ptr[3:0],其中最高bit是扩展位。ptr取值范围是0 ~15,要比FIFO地址(addr)多一倍。为什么这么设计呢?因为满和空本质上是读和写指向了FIFO的同一个存储单元,但是“空”是读指针追上了写指针,“满”是写指针超过了读指针整整一圈。其中最高位就是用来确定是 “谁追上了谁”

如果两个ptr低位全等,最高位不等,就是“满”;

如果两个Ptr低位全等,最高位相等,就是“空”。

如图所示,将w_ptr通过CDC同步之后,送到读时钟域,得到w_ptr_syn,然后再将它和r_ptr作比较,就可以得到“空”信号,代码如下:

assign empty = (w_ptr_syn[3:0]== r_ptr[3:0]);

同理,将r_ptr通过CDC同步之后,送到写时钟域,得到r_ptr_syn,然后将它和w_ptr作比较,就可以得到满信号,代码如下:

assign full = (w_ptr[3] != r_ptr_syn[3]) && (w_ptr[2:0] == r_ptr_syn[2:0]);

大家觉得上面的代码得到的满和空是“ 真”满空吗?

答案是否定的。因为CDC同步器本身也需要开销,一般简单的两级同步器需要目标时钟域两个时钟周期。当我们判断满信号的时候,我们是在 写时钟域 ,用w_ptr和同步过来的r_ptr_syn做比较。r_ptr_syn要比真正的r_ptr要滞后,导致判满的逻辑并不完全准确。当FIFO接近满的时候,full信号就会为1,从而阻止对FIFO继续写入(脑补:“满”意味着写比读块,写指针马上赶上读指针一圈,此刻还与滞后同步过来的读指针比较,是不是快满还没满时就满足full条件了?)。同理,当FIFO接近空,但是实际可能还没空的时候,empty信号就会为1。

这种假满空并不会导致FIFO的行为出错,只会导致FIFO的利用率并非百分百,相当于FIFO的深度少了那么一两层。

那么FIFO能得到真满空吗?

答案肯定是可以的。如果我们在写时钟域判断“空”信号,在读时钟域判断“满”信号呢?(在写时钟域,通过滞后的r_ptr_syn都得到了“空”信号,那说明实际的r_ptr必然真的赶上了w_ptr,此刻FIFO绝对空了。在读时钟域,通过滞后的w_ptr_syn都得到了“满”信号,那说明实际的w_ptr必然真的超过了r_ptr一圈,此刻FIFO绝对满了)。

assign empty_real = (w_ptr[3:0] == r_ptr_syn[3:0]);

assign full_real = (r_ptr[3] != w_ptr_syn[3]) && (r_ptr[2:0] == w_ptr_syn[2:0]);

这个“真”满空信号,用到的时候并不多。但是理解“真”满空和“假”满空,是理解异步FIFO的基础。

采用格雷码的异步FIFO

采用格雷码的异步FIFO判断“满”和“空”的原理没变,跟标准FIFO是一样的,即在写时钟域判断满条件,在读时钟域判断空条件:

如果两个ptr低位全等,最高位不等,就是“满”;

如果两个Ptr低位全等,最高位相等,就是“空”。

只不过,地址指针采用的是格雷码,如写地址指针:

assign nxt_wptr = (!full && wr_en) ? (wptr +1'b1):wptr;  

assign nxt_wptr_gray = (nxt_wptr >>1)^nxt_wptr;

判断空条件:则在读时钟域,读地址指针格雷码 与 两级同步过来后的写地址指针格雷码(nxt_wptr_gray)进行比较:

always@(posedge rclk or negedge rst_n)

begin

    if(!rst_n) begin

        wptr_sp1<=6'b0;

        wptr_sp2<=6'b0;

    end

    else begin

        wptr_sp1<=nxt_wptr_gray;

        wptr_sp2<=wptr_sp1;    

    end                        

end

assign empty=(rptr_gray==wptr_sp2);

同理,判断满条件:

assign full=(wptr_gray=={~rptr_sp2[3],rptr_sp2[2:0]});

理解到这儿,本质上两种FIFO似乎没什么区别,那为什么要用格雷码编码呢? 异步FIFO采用格雷码的主要原因是为了减少在异步时钟域中地址指针变化时可能出现的不稳定性,从而增强异步FIFO的可靠性和稳定性即使在亚稳态进行读写指针抽样也能进行正确的空满状态判断”。

下面两张图是采用格雷码的异步FIFO触发满和空条件的截图,从图示可看出,4根标红的格雷码地址指针 每一周期前后只有1位发生跳变,如wptr_gray:0010>0110>0111>0101>0100>1100>1101>1111>1110,这就是格雷码的特性,保证了相邻的两个值只有一个位元发生变化,因此在变化时不会出现多个位同时变化,减少了不稳定状态的可能性。

图片

满条件

图片

空条件

为什么2 进制指针做空满判断存在不稳定的可能呢?事实上 2 进制读指针在增减时,经常发生多位突变,比如 6 位地址 111111 会在下一时刻变成 000000 ,在实际电路中,这个变化过程要持续很长一段时间,会由 111111 经历 6 个状态转移到达 000000 。比如 111111-> 101111 -> 100111 ->100110 -> 100100 -> 000100-> 000000 。由于写时钟与读时钟不同步,异步的写时钟很可能会在状态不稳定的中间某个状态抽样,这样就会得到错误的读指针,进而做出错误的状态判断,导致系统异常。

当采用格雷码只有一个比特发生改变时,即使在中间状态抽样,其结果也不外乎两种:递增前原指针和递增后新指针。如果抽样到递增后的指针,预期结果跟设计一致。如果抽样到递增前的原指针,最坏的情况就是把“不满”判断成了“满”,但是这并不会对逻辑产生影响,只是带来了写操作的延迟。

总结(两种fifo的主要区别)

因此,标准范式的FIFO和采用格雷码的FIFO都存在一定的可能出现假满空。两者有一些区别,主要涉及到地址指针的表示和更新方式。以下是这两种FIFO的主要区别:

  1. 地址指针的表示:
    • 标准范式的FIFO:常常使用二进制表示的地址指针。这意味着每个存储单元都有一个唯一的二进制地址,用于指示数据在FIFO中的位置。
    • 采用格雷码的FIFO:地址指针通常使用格雷码来表示。格雷码是一种二进制码,相邻的两个值只有一个位元发生变化。使用格雷码可以减少地址指针在变化时的不稳定性,从而减少在时钟边沿时的不稳定状态。
  2. 地址指针的更新方式:
    • 标准范式的FIFO:地址指针在每个时钟周期朝一个方向递增或递减,用于确定要读取或写入的位置。在写入数据时,写指针增加;在读取数据时,读指针增加。
    • 采用格雷码的FIFO:格雷码地址指针的更新方式相对复杂一些。格雷码的特性使得在更新时只有一个位发生变化,这样可以减少指针变化的不稳定性。在读写操作时,格雷码地址指针的更新可能需要一些额外的逻辑。
  3. 时序稳定性:
    • 标准范式的FIFO:由于二进制地址指针的性质,通用FIFO在时序上需要额外的同步逻辑,以确保地址指针的稳定传递。这尤其在不同时钟域的情况下需要考虑。
    • 采用格雷码的FIFO:格雷码的特性减少了地址变化的不稳定性,因此在一些时序方面可能更容易处理。但格雷码的使用可能需要更多的逻辑来实现。

选择使用哪种FIFO设计取决于具体的应用需求和时序约束。格雷码的FIFO在一些特定情况下可能提供一些优势,但也需要权衡设计的复杂性。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • fifo
    +关注

    关注

    3

    文章

    387

    浏览量

    43505
  • 信号
    +关注

    关注

    11

    文章

    2774

    浏览量

    76556
  • 时钟域
    +关注

    关注

    0

    文章

    51

    浏览量

    9524
  • 异步FIFO
    +关注

    关注

    0

    文章

    20

    浏览量

    8348
收藏 人收藏

    评论

    相关推荐

    基于FPGA的异步FIFO的实现

    存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。 用途1: 异步FIFO读写
    的头像 发表于 06-21 11:15 6468次阅读
    基于FPGA的<b class='flag-5'>异步</b><b class='flag-5'>FIFO</b>的实现

    异步FIFO设计之

    相邻的只有1bit的差异,因此常常用于异步
    的头像 发表于 11-01 17:37 1335次阅读
    <b class='flag-5'>异步</b><b class='flag-5'>FIFO</b>设计之<b class='flag-5'>格</b><b class='flag-5'>雷</b><b class='flag-5'>码</b>

    详细讨论异步FIFO的具体实现???

    我在网上看到一篇利用来设计异步FIFO,但是看他们写的一些源码,小弟有些不是很理解,在设计时为什么会出现Waddr和wptr两个关于写
    发表于 05-19 11:04

    请问SPI使用FIFO和不使用什么区别?使用FIFO效率更高吗?

    本帖最后由 一只耳朵怪 于 2018-6-13 15:01 编辑 SPI使用FIFO和不使用什么区别,是不是使用FIFO效率更高
    发表于 06-13 11:12

    异步FIFO的VHDL设计

    给出了一个利用对地址编码的羿步FIFO 的实现方法,并给出了VHDL 程序,以解决异步读写时钟引起的问题。
    发表于 07-16 15:15 26次下载

    Camera Link接口的异步FIFO设计与实现

    介绍了异步FIFO在Camera Link接口中的应用,将Camera Link接口中的帧有效信号FVAL和行有效信号LVAL引入到异步FIFO的设计中。分析了FPGA中设计
    发表于 07-28 16:08 32次下载

    异步FIFO的设计分析及详细代码

    (每个数据的位宽) FIFO同步和异步两种,同步即读写时钟相同,异步即读写时钟不相同 同步FIFO用的少,可以作为数据缓存
    发表于 11-15 12:52 8543次阅读
    <b class='flag-5'>异步</b><b class='flag-5'>FIFO</b>的设计分析及详细代码

    利用VHDL语言和对地址进行编码的异步FIFO的设计

    FIFO (先进先出队列)是一种在电子系统得到广泛应用的器件,通常用于数据的缓存和用于容纳异步信号的频率或相位的差异。FIFO的实现通常是利用双口RAM和读写地址产生模块来实现的。FIFO
    的头像 发表于 08-02 08:10 2198次阅读
    利用VHDL语言和<b class='flag-5'>格</b><b class='flag-5'>雷</b><b class='flag-5'>码</b>对地址进行编码的<b class='flag-5'>异步</b><b class='flag-5'>FIFO</b>的设计

    异步FIFO的原因哪些

    异步FIFO通过比较读写地址进行满空判断,但是读写地址属于不同的时钟域,所以在比较之前需要先将读写地址进行同步处理,将写地址同步到读时钟域再和读地址比较进行FIFO空状态判断(同步后的写地址一定
    的头像 发表于 08-04 14:05 4392次阅读

    异步fifo详解

    异步fifo详解 一. 什么是异步FIFO FIFO即First in First out的英文简称,是一种先进先出的数据缓存器,与普通存储
    的头像 发表于 12-12 14:17 4066次阅读

    FIFO设计—异步FIFO

    异步FIFO主要由五部分组成:写控制端、读控制端、FIFO Memory和两个时钟同步端
    发表于 05-26 16:17 1509次阅读
    <b class='flag-5'>FIFO</b>设计—<b class='flag-5'>异步</b><b class='flag-5'>FIFO</b>

    异步FIFO-

    很多人在面试时被问到为什么异步FIFO中需要用到,可能大部分的答案是
    的头像 发表于 08-26 14:20 962次阅读
    <b class='flag-5'>异步</b><b class='flag-5'>FIFO</b>-<b class='flag-5'>格</b><b class='flag-5'>雷</b><b class='flag-5'>码</b>

    同步FIFO异步FIFO区别 同步FIFO异步FIFO各在什么情况下应用

    同步FIFO异步FIFO区别 同步FIFO异步FIFO
    的头像 发表于 10-18 15:23 1621次阅读

    关于另外一种设计异步FIFO的简介

    设计者为了提升FIFO的速度使用了将二进制计数器和计数器结合在一起的方法,从最开始用一组寄存器来进行
    的头像 发表于 10-20 10:50 434次阅读
    关于另外一种设计<b class='flag-5'>异步</b><b class='flag-5'>FIFO</b>的简介

    同步FIFO异步FIFO区别介绍

    1. FIFO简介 FIFO是一种先进先出数据缓存器,它与普通存储器的区别是没有外部读写地址线,使用起来非常简单,缺点是只能顺序读写,而不能随机读写。 2. 使用场景 数据缓冲:也就是数据写入过快
    的头像 发表于 06-04 14:27 1234次阅读
    同步<b class='flag-5'>FIFO</b>和<b class='flag-5'>异步</b><b class='flag-5'>FIFO</b><b class='flag-5'>区别</b>介绍