异步dcfifo的读写
异步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的读写的更多相关文章
- 异步fifo的读写
这里不讨论异步fifo是如何实现的,而是在实现fifo的前提下,对fifo的读写. 现在遇到的问题是:总线的数据不能写入fifo中,但是地址能加一. 代码如下: if( !fifo_tx_full & ...
- boost asio异步读写网络聊天程序client 实例具体解释
boost官方文档中聊天程序实例解说 数据包格式chat_message.hpp <pre name="code" class="cpp">< ...
- boost asio异步读写网络聊天程序客户端 实例详解
boost官方文档中聊天程序实例讲解 数据包格式chat_message.hpp <pre name="code" class="cpp">< ...
- SDRAM和dcfifo的联合
SDRAM和dcfifo的联合 设计原理 在"SDRAM突发读写页"实验中,留下了一个问题,就是从SDRAM读取数据的速度要与SDRAM的驱动时钟同步,这就造成了读出的数据的速率过 ...
- 异步fifo的设计
本文首先对异步 FIFO 设计的重点难点进行分析 最后给出详细代码 一.FIFO简单讲解 FIFO的本质是RAM, 先进先出 重要参数:fifo深度(简单来说就是需要存多少个数据) ...
- Verilog设计异步FIFO
转自http://ninghechuan.com 异步FIFO有两个异步时钟,一个端口写入数据,一个端口读出数据.通常被用于数据的跨时钟域的传输. 同步FIFO的设计.一个时钟控制一个计数器,计数器增 ...
- 异步fifo的Verilog实现
一.分析 由于是异步FIFO的设计,读写时钟不一样,在产生读空信号和写满信号时,会涉及到跨时钟域的问题,如何解决? 跨时钟域的问题:由于读指针是属于读时钟域的,写指针是属于写时钟域的,而异步FIFO ...
- C#并行编程(5):需要知道的异步
异步与并行的联系 大家知道"并行"是利用CPU的多个核心或者多个CPU同时执行不同的任务,我们不关心这些任务之间的依赖关系. 但是在我们实际的业务中,很多任务之间是相互影响的,比如 ...
- 异步FIFO跨时钟域亚稳态如何解决?
跨时钟域的问题:前一篇已经提到要通过比较读写指针来判断产生读空和写满信号,但是读指针是属于读时钟域的,写指针是属于写时钟域的,而异步FIFO的读写时钟域不同,是异步的,要是将读时钟域的读指针与写时钟域 ...
随机推荐
- 大数据挖掘: FPGrowth初识--进行商品关联规则挖掘
@(hadoop)[Spark, MLlib, 数据挖掘, 关联规则, 算法] [TOC] 〇.简介 经典的关联规则挖掘算法包括Apriori算法和FP-growth算法.Apriori算法多次扫描交 ...
- 省级联动(使用ajax实现)
在博客园学习了很多实用的东西,现在该慢慢开始自己写写博客文章, 由于本人水平有限,刚走出校园的小菜鸟,另外,文章在表述和代码方面如有不妥之处,欢迎批评指正.留下你 的脚印,欢迎评论! 有什么问题,可以 ...
- 深入理解linux系统的目录结构(总结的非常详细)
对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能,对于我们用好linux系统只管重要,下面 ...
- Elasticsearch 安装中文分词
github地址:https://github.com/medcl/elasticsearch-analysis-ik 注意版本要对应,否则编译完成后elasticsearch不能正常启动 下载文件, ...
- VC++ Debug编译方式
字节填充 VC++在Debug编译方式下,new的内存用0xcd(助记词为Cleared Data)填充,防止未初始化: delete后,内存用0xdd(Dead Data)填充,防止再次被使用. 这 ...
- Python 变量类型
Python 变量类型 变量存储在内存中的值.这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同的数据 ...
- 深入理解TCP(一)
TCP是面向连接的传输层层协议,可以为应用层提供可靠的数据传输服务.所谓的面向连接并不是真正意思上的连接,只不过是在发送数据之前,首先得相互握手,也就是说接收方知道你要发数据给它了.而UDP是面向无连 ...
- 嵌入式Linux驱动开发日记
嵌入式Linux驱动开发日记 主机硬件环境 开发机:虚拟机Ubuntu12.04 内存: 1G 硬盘:80GB 目标板硬件环境 CPU: SP5V210 (开发板:QT210) SDRAM: 512M ...
- CoCreateInstance调用COM接口伪流程
在编写组件程序时,经常会使用CoCreateInstance直接取COM组件的接口,非常方便,那CoCreateInstance到底干了些什么事呢?1.CoCreateInstance取COM组件的接 ...
- luogu2038[NOIP2014 T4]无线网络发射器选址
题目描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129 条东西向街道和129 条南北向街道所形成的网格状,并且相邻 ...