异步fifo实现(无fifo IP核)

        前面分享了一篇基于ise的fifo实现,主要是调用了ip核,并且设置了一系列标志符号。这篇博文主要是通过调用一个双口的ram IP核,编写相对应的读和写控制模块来实现一个异步fifo。

逻辑框图如下图所示:

在读控制模块中,没有加入读使能,设置为给地址就出数据。

调用的ram核为宽度为8,深度为256,双口ram,截图如下:

ram的写使能为:

读空与写满信号的产生:

写满信号w_full: 当写地址比读地址快一圈时,此时写指针=读指针,w_full=1;

读空信号r_empty: 当复位时,读地址=写地址,r_empty=1;

                              当读地址追上写地址时,写地址=读地址,r_empty=1

可见,读空与写满均是两者相等,所以需要相应的方法来进行判别到底属于哪种情况。

举个例子:存储器深度为8,所以仅需要3位地址即可,当读地址r_addr=3'b100,写地址w_addr=3'b100时,不知道到底是写满还是读空,这就出现了混淆的现象。所以,可以在3位地址的基础上增加一位作为最高位,用最高位的符号来进行判别是读空还是写满:低位相等且最高位相等相当于读追上了写,为读空;低位相等而最高位不同相当于写满。即r_addr=4'b0100,w_addr=4'b0100时,读指针追上了写指针,读空;r_addr=4'b1100,w_addr=4'b0100,写指针领先于读指针一圈,写满。

判断代码如上图所示。

由于在异步FIFO设计中,读写时钟不同需要涉及到跨时钟域的问题,此时采用二进制来进行读写地址的比较是不合适的。比如二进制的7=0111,8=1000,在由7变化到8时,每一位都会发生跳变,这样的话在地址同步到另一个时钟域的时候很大概率会发生错误。

于是,可以用格雷码来解决这个问题:

格雷码编码的好处是相邻两个数只有1位不同,所以在转换时不会像上面那种情况发生大的跳变,这样就可以极大程度上减少跨时钟域产生的影响。格雷码产生方法:本二进制数右移一位异或本二进制数,即移位并异或。

举个例子:十进制数      8

                  二进制数      1000   

                  右移一位      0100

                  异或结果      1100

这样异或结果1100就为十进制数8的格雷码表示。

代码如下:

以上主要介绍了读空写满信号、二进制码、格雷码的产生。

跨时钟域产生格雷码读写地址模块框图:

下面是各个模块的产生:

写控制模块:

其中需要将读模块过来的读指针进行打两拍进行同步,尽可能减小亚稳态的影响。

读控制模块:

fifo memory模块:

仿真结果如下图:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值