异步dcfifo的原理

Dcfifo即是Double clk fifo,意思是双时钟的fifo。或许你现在还不知道什么是fifo,那我就先从fifo(就是同步fifo,不过同步fifo在实际运用中比较少)开始说起吧!

scfifo的原理

一般的fifo是单时钟(读写同步),就是读写用同一个时钟信号,其框图如下:

端口说明如下:

官方的DCFIFO资料中有这样一个时序图,如下

    上图是写操作,下图是读操作,通过图可以看到读写的时钟频率是不一样,不过这一点没有关系,这里把读写的时钟假设为相同,就是同步fifo。

写操作中,wrreq信号为写申请信号,在写时钟的上升沿有效,将wrreq置高后就可以往fifo送数据,在写满fifo后并在时钟的上升沿,wrfull写满信号有效,表明fifo已经写满了,不能再往fifo内部写如数据,否则就会数据丢失,写了也是白费。如果要对fifo重新写入数据,这时可以通过fifo的异步清零aclr进行操作,aclr为高电平有效,能立刻将fifo内部的数据全部清零,这样就可以再往fifo写数据。

读操作中,rdreq信号为读申请信号,在读时钟的上升沿有效,将rdreq置高后就可以从fifo读数据,在读空fifo后并在时钟的上升沿,rdempty读空信号有效,表明fifo已经读空了,不能再从fifo内部读如数据。

当然,fifo中还有一些可以选择调用的信号,可以根据需要进行调用,这里就不作介绍了。

dcfifo的原理

端口说明如下:

    相信在了解了scfifo之后,已经知道fifo的原理了,dcfifo和scfifo的区别就在与读写时钟是否同步。

    

    上图的分析上面已经讲解过了,不同的是,在dcfifo中读写时钟是不一致的,这也是很关键的一点,也是dcfifo运用比较多的一点。

在FPGA设计中经常性地会强调"同步"的问题,假设在A模块中采用的时钟频率是100M,在B模块中采用的时钟频率是50M,如果A和B要进行数据交换,由于两者的时钟不一样,所以就存在一个同步性的问题,一保证两者数据交换不会出现错误。要解决这个问题,就是解决跨时域操作的问题,跨时域交换数据最常用的就是采用dcfifo做为中间桥梁。假设为A模块往B模块送数据,则A模块以100M的时钟作为dcfifo的wrclk,往fifo写数据,而B模块则以50M的时钟频率作为dcfifo的rdclk,从fifo读数据,这就解决了跨时域交换数据的问题,当然这里面还有一些细节问题,不过相信你已经知道dcfifo的最大用处了。

异步dcfifo的调用过程

点击tools,选择调用宏功能模块的菜单,弹出下面的菜单;

选择新建一个新的宏功能模块,点击next,弹出下面的菜单;

在memory complier中选择FIFO,然后设置输出文件的名称也是这个宏功能模块的名称,然后弹出FIFO的设置向导窗口;

设置fifo的位宽、深度、同步和异步的选择,这里选择如上图所示,选择后点击next;

读fifo的潜伏期设置,这里选择最低的潜伏期,点击next;

选择fifo的接口信号,这里选择写端口的usedw、异步清零信号aclr,点击next;

选择fifo的模式,这里选择正常模式,存储资源的类型选择M4K,点击next;

点击Finish,调用fifo完成,接下来就是设计模块,将这个dcfifo调用起来;

读写dcfifo的控制模块设计

模块框图

该设计主要分为4个模块和PLL倍頻模块(提供100M的工作时钟),其中,fifo_ctrl为控制模块,负责控制对dcfifo(asy_fifo)进行读写操作,与write_fifo和read_fifo采用反馈的方式进行控制,具体方法为先控制write_fifo对asy_fifo进行写操作,write_fifo写如完成后,向fifo_ctrl反馈一个写入完成信号,fifo_ctrl便关闭对fifo的写操作,向read_fifo发送读使能的信号,read_fifo便在控制信号的控制下对fifo进行读操作,将读出的数据显示在LED上,读完成后便发送读完成信号给fifo_ctrl,fifo_ctrl在判断读操作完成后便重新对fifo进行写操作,以此循环。

其中,对asy_fifo的写时钟为100M(由PLL提供),读asy_fifo的时钟为50M(由外部晶振提供)。

各模块设计原理

这里采用至上而下的方法对整个工程进行设计:

顶层模块

顶层设计如下

fifo控制模块

fifo的控制模块根据读写的反馈信号,进行控制状态的跳转,同时输出控制信号。

上电后,控制状态为空闲态,接着转入到写状态,同时将现态的信号作为控制信号输出到write_fifo和read_fifo,在输出写控制信号后便对从write_fifo反馈的写入数量的信号进行判断,当写入了256个数据之后,便转到读状态,同时将读控制信号发送到read_fifo模块,read_fifo模块接收到读信号之后便进行读操作,读完成后便反馈读完成信号read_over,当read_over有效后,控制模块的控制状态便转到空闲态,以此循环。

fifo写模块

fifo写模块负责对fifo进行写操作,实际点就是发送写申请信号和发送数据,关键是什么时候进行写申请和什么时候发送什么数据,这就要听从fifo_ctrl的ctrl_signal信号,即是对ctrl_signal进行译码操作,配合着输出对fifo的写信号wrreq。

    

    将输入的100M的clk直接输入到fifo的读时钟,将wrusedw(fifo的当前存储数量)输出到wrdata_num反馈给fifo_ctrl。

当ctrl_signal为WRITE时,写申请信号wrreq_reg有效,同时用wrdata_cnt对写入的数据数进行计数,当wrdata_cnt等于255时,fifo_ctrl将控制信号转为读状态,这时ctrl_signal为READ,wrreq_reg被清零,写操作停止,进入读操作阶段。

fifo读模块

fifo读模块负责对fifo进行读操作,实际点就是发送读申请信号和读取数据,关键是什么时候进行读申请和什么时候接收什么数据,这就要听从fifo_ctrl的ctrl_signal信号,即是对ctrl_signal进行译码操作,配合着输出对fifo的读申请信号rdreq。

读申请信号产生模块,这个模块根据ctrl_signal信号对fifo进行读申请,在READ状态时读申请信号rdreq_reg有效,其他状态无效。

读完成信号产生模块,在ctrl_signal为READ时开始计数,判断读取的次数是否达到256次,当达到256次时read_over输出高电平,同时read_over反馈到fifo_ctrl模块,这是current_state跳转到IDLE状态,然后进行新一轮的写读操作。

实验效果

实验的工程文件为"asy_fifo",其源代码文件如下:

为了验证实验结果,实验中调用signaltap将从fifo中读取的数据调出来进行观察,

结果如下:

每日推送不同科技解读,原创深耕解读当下科技,敬请关注微信公众号“科乎”。

异步dcfifo的读写的更多相关文章

  1. 异步fifo的读写

    这里不讨论异步fifo是如何实现的,而是在实现fifo的前提下,对fifo的读写. 现在遇到的问题是:总线的数据不能写入fifo中,但是地址能加一. 代码如下: if( !fifo_tx_full & ...

  2. boost asio异步读写网络聊天程序client 实例具体解释

    boost官方文档中聊天程序实例解说 数据包格式chat_message.hpp <pre name="code" class="cpp">< ...

  3. boost asio异步读写网络聊天程序客户端 实例详解

    boost官方文档中聊天程序实例讲解 数据包格式chat_message.hpp <pre name="code" class="cpp">< ...

  4. SDRAM和dcfifo的联合

    SDRAM和dcfifo的联合 设计原理 在"SDRAM突发读写页"实验中,留下了一个问题,就是从SDRAM读取数据的速度要与SDRAM的驱动时钟同步,这就造成了读出的数据的速率过 ...

  5. 异步fifo的设计

    本文首先对异步 FIFO 设计的重点难点进行分析 最后给出详细代码 一.FIFO简单讲解 FIFO的本质是RAM, 先进先出 重要参数:fifo深度(简单来说就是需要存多少个数据)           ...

  6. Verilog设计异步FIFO

    转自http://ninghechuan.com 异步FIFO有两个异步时钟,一个端口写入数据,一个端口读出数据.通常被用于数据的跨时钟域的传输. 同步FIFO的设计.一个时钟控制一个计数器,计数器增 ...

  7. 异步fifo的Verilog实现

     一.分析 由于是异步FIFO的设计,读写时钟不一样,在产生读空信号和写满信号时,会涉及到跨时钟域的问题,如何解决? 跨时钟域的问题:由于读指针是属于读时钟域的,写指针是属于写时钟域的,而异步FIFO ...

  8. C#并行编程(5):需要知道的异步

    异步与并行的联系 大家知道"并行"是利用CPU的多个核心或者多个CPU同时执行不同的任务,我们不关心这些任务之间的依赖关系. 但是在我们实际的业务中,很多任务之间是相互影响的,比如 ...

  9. 异步FIFO跨时钟域亚稳态如何解决?

    跨时钟域的问题:前一篇已经提到要通过比较读写指针来判断产生读空和写满信号,但是读指针是属于读时钟域的,写指针是属于写时钟域的,而异步FIFO的读写时钟域不同,是异步的,要是将读时钟域的读指针与写时钟域 ...

随机推荐

  1. MySQL [Warning]: IP address 'xxxx' could not be resolved: Name or service not known

    MySQL的error log 出现大量的 DNS反解析错误. DNS解析是指,将 域名解析成ip地址: DNS反解析是指,将IP地址反解析成域名: Version: MySQL Community ...

  2. EF Power Tools的Reverse Engineer Code First逆向生成Model时处理计算字段

    VS2013上使用EF Power Tools的Reverse Engineer Code First逆向生成Model时,没有处理计算字段.在保存实体时会出现错误. 可以通过修改Mapping.tt ...

  3. IIS7配置PHP图解(转)

    IIS7+PHP_5.2.17 于之前安装IIS的时候已经选上了isapi扩展和isapi筛选,这里就不用另外再添加角色服务了,直接开始 先修改php.ini文件.. 把c:\php下的php.ini ...

  4. asp.net服务器控件onclick带参数

    服务器控件处理参数随笔 正确: <asp:CheckBox ID="cbComplareProduct" runat="server" Text=&quo ...

  5. C++杂谈(二)初识vector容器与迭代器

    教科书中失踪的vector 很奇怪的一件事情,在当时学习C++的时候,老师并没有讲授容器的内容,当时参考的谭浩强老师的红皮C++也没有这个内容,不知为何.后来再学C++,发现容器是一个很重要的概念,在 ...

  6. Android adb push 和 pull操作

    由于安卓真机本地调试时,每次启动并生成apk然后安装到设备比较费时,而很多情况是仅仅修改了hot 脚本文件(cocos2dx + lua). 所以,使用热更机制把修改后的lua文件push到热更目录( ...

  7. hdu-5127------hdu5137

    hdu-5127 思路: 本来正解好像是动态凸包,暴力10000+ms可以搞过去; hdu-5128 思路: 枚举两个长方形的对角线,然后判断是否不相交,更新答案就好; hdu-5130 思路: 将题 ...

  8. 【转】最长回文子串的O(n)的Manacher算法

    Manacher算法 首先:大家都知道什么叫回文串吧,这个算法要解决的就是一个字符串中最长的回文子串有多长.这个算法可以在O(n)的时间复杂度内既线性时间复杂度的情况下,求出以每个字符为中心的最长回文 ...

  9. oracle:sql函数

    Oracle将函数大致分为单行函数,聚合函数和分析函数. 单行函数分为字符函数,日期函数,转换函数,数字函数,通用函数,decode函数 一.字符函数 1)大小写控制函数 01.Lower() 全部小 ...

  10. 微软云Azure Website 远程调试

    微软云Azure Website 远程调试 是可以的 但是只有48小时,要在后台开启,所以还是很麻烦的啊! 但是安全性提高了,不得不承认哦