同步FIFO与异步FIFO的Verilog实现

上传人:cl****1 文档编号:431803862 上传时间:2023-09-26 格式:DOCX 页数:17 大小:170.98KB
返回 下载 相关 举报
同步FIFO与异步FIFO的Verilog实现_第1页
第1页 / 共17页
同步FIFO与异步FIFO的Verilog实现_第2页
第2页 / 共17页
同步FIFO与异步FIFO的Verilog实现_第3页
第3页 / 共17页
同步FIFO与异步FIFO的Verilog实现_第4页
第4页 / 共17页
同步FIFO与异步FIFO的Verilog实现_第5页
第5页 / 共17页
点击查看更多>>
资源描述

《同步FIFO与异步FIFO的Verilog实现》由会员分享,可在线阅读,更多相关《同步FIFO与异步FIFO的Verilog实现(17页珍藏版)》请在金锄头文库上搜索。

1、FIFOFIFO即First In First Out,是一种先进先出数据存储、缓冲器,我们知道一般的存储器是 用外部的读写地址来进行读写,而FIFO这种存储器的结构并不需要外部的读写地址而是通 过自动的加一操作来控制读写,这也就决定了 FIFO只能顺序的读写数据。下面我们就介绍 一下同步FIFO和异步FIFO。1、FIFO 分类同步FIFO,读和写应用同一个时钟。它的作用一般是做交互数据的一个缓冲,也就是 说它的主要作用就是一个buffer。异步FIFO,读写应用不同的时钟,它有两个主要的作用,一个是实现数据在不同时钟 域进行传递,另一个作用就是实现不同数据宽度的数据接口。2、FIFO 的主

2、要参数同步FIFO和异步FIFO略有不同,下面的参数适用于两者。宽度,用参数FIFO_data_size表示,也就是FIFO存储的数据宽度;深度,用参数 FIFO_addr_size 表示,也就是地址的大小,也就是说能存储多少个数据; 满标志,full,当FIFO中的数据满了以后将不再能进行数据的写入;空标志,empty,当FIFO为空的时候将不能进行数据的读出;写地址,w_addr,由自动加一生成,将数据写入该地址;读地址,r_addr,由自动加一生成,将该地址上的数据读出;同步FIFO和异步FIFO的最主要的不同就体现在空满标志产生的方式上,由此引出两者 一些不同的参数。同步FIFO时钟,

3、clk, rst,读写应用同一个时钟;计数器,count,用计数器来进行空满标志的判断;异步 FIFO时钟,clk_w, rst_w, clk_r, rst_r,读写应用不同的时钟;指针,w_pointer_gray, r_pointer_gray,用指针来判断空满标识;同步指针,w_pointer_gray_sync, r_pointer_gray_sync,指针的同步操作,用来做对比产 生空满标志符;3、同步 FIFOFIFO主要的设计难点在于如何产生空满标志,在同步FIFO中,我们定义一个计数器, 当计数器的值为0时,产生空标志,当计数器的值为FIFO的深度时,产生满标志。3.1同步FI

4、FO代码源文件module FIFO_sync(clk,rst,w_en,r_en,data_in,data_out,count,full,empty);parameter FIFO_data_size=3,FIFO_addr_size=2;input clk,rst;input w_en,r_en;inputFIFO_data_size-1:0 data_in; outputFIFO_data_size-1:0 data_out;output full,empty;outputFIFO_addr_size:0count;reg FIFO_data_size-1:0 data_out;reg

5、FIFO_addr_size:0count;reg FIFO_addr_size-1:0w_addr,r_addr;reg FIFO_data_size-1:0memFIFO_addr_size1b1:0;integer i;/memory 的初始化以及写操作always(posedge clk or negedge rst)beginif(!rst)beginw_addr=0;for(i=0;i=FIFO_addr_size1b1;i=i+1)memi=FIFO_data_size1b0;endelse if(w_en&(full)beginmemw_addr=data_in;w_addr=

6、w_addr+1;endend/读操作always(posedge clk or negedge rst)beginif(!rst)begindata_out=(FIFO_data_size-1)1b0;r_addr=0;endelse if(r_en&(empty)begindata_out=memr_addr;r_addr=r_addr+1;endend/count 产生空满标志符always(posedge clk or negedge rst)beginif(!rst)count=0;else if(w_en)&(full)&(r_en)&(empty)count=count+1;el

7、se if(r_en)&(empty)&(w_en)&(full)count=count-1;endassign empty=(count=0);assign full=(count=FIFO_addr_size1b1+1); endmodule测试代码timescale 1ns/1nsmodule FIFO_sync_top;reg clk,rst,w_en,r_en;reg2:0data_in;wire2:0count;wire2:0dtat_out;reg2:0i;initialbeginclk=0;rst=1;data_in=3b000;w_en=0;r_en=0;#25rst=0;#

8、50rst=1;#25w_en=1;#100r_en=1;#100w_en=0;r_en=0;w_en=1;r_en=1;endinitialbeginfor(i=0;ip/ut/w_addr & FO_syn_tfip/utii,daLa_in* iiFFO_Eync_txp/,utlir_en J /FlFCLsyncjDop/Lit/unrcty4 * FO_sym:_top/utift,_addrifl FO_Eync_tBpAjdata_ixjt 丄 jTFO_5ync_bop/iut1i,c0untHhm忆hm狂而坯I胆丘2匕扫;(z1w Y:由订2打3述D疗応 厅呵(2Tim f

9、Tj加 I hhs(2Tio 运KT;珀丄忖hs扫时【3h5【ska hli 丁讯hi円hz占1“ 0h弧h5 団繭迪冋31茁hd好1伽珂4、异步 FIFO异步FIFO的设计难点在于空满标志符的产生,由于异步FIFO的读写是用不同的时钟来控制的,所以不能采用计数器的方法来产生空满标志符,就好像同一个变量不能再两个always 块里赋值一样,所以我们必须寻求新的方法来产生空满标志符。4.1 空满标志我们知道FIFO的状态是满还是空,他们的相同的判断条件都是w_addr=r_addr,但到底 是空还是满我们还不能确定。在这里介绍一种方法来判断空满状态。我们设定一个指针 r_pointer_bin,

10、 w_pointer_bin,宽度为FIFO_addr_size:0,也就是说比传统的地址多一位, 我们就用这多出来的一位做空满判断。如果是满状态的话,也就是说w_pointer_bin比r_pointer_bin多走了一圈,反应在数值 上就是w_pointer_bin和r_pointer_bin的最高位不相同。如果是空状态的话,也就是说w_pointer_bin和r_pointer_bin的路径相同,反应在数值 上就是 w_pointer_bin 和 r_pointer_bin 的每一位相等。如下例子所示:将一个时钟域上的指针r_pointer_bin/w_pointer_bin同步到另一个

11、时钟域,如果数据用二进制的方式进行同步的话就会出现多位数据同时跳变的问题,比如3b011到3b100即3 到4跳变会引起多位数据的改变,这样会大大增加出错的概率。Gray码就很好的解决了上 述问题,gray码相邻数据只有一位跳变,这样就大大降低了数据出错的概率。下面以一个 例子介绍一下二进制码向格雷码的转化的算法。其他各位 Gj =耳=0, 1, 2,-2例:二进制数为10110格雷码为11101某二进制数为兔1儿砂禺算对应的格雷码为-QGG0其中:最高位保留异或运算: 相同为o相异为1在不同时钟域进行数据交换的时候我们一般采用格雷码的数据形式进行数据传递,这样 能很大程度上降低出错的概率。引

12、入格雷码同时也引入一个问题,就是数据空满标志的判断不再是二进制时候的判断标 准。如果是空状态的话,无可厚非,仍然是要满足r_pointer_gray和w_pointer_gray每一位 都相等。如果是满状态的话, 我们以二进制为例, 应该满足 r_pointer_bin=3b111, w_pointer_bin=3b011 , 相 对 应 的 格 雷 码 应 该 满 足 r_pointer_gray=3b100 , w_pointer_gray=3b010,通俗来讲,满状态要满足 r_pointer_gray 和 w_pointer_gray 的高位 和次高位相反,其余各位相等。同时由于格雷码

13、的引入,使得FIFO的深度只能是2的幕次方。4.3 数据同步我们知道满状态以后数据就不能进行写入,空状态以后数据就不能进行读出。由此,我 们在write模块进行满状态的判断,在read模块进行空状态的判断。在满状态的判断时,我们要用到r_pointer_gray,为了避免亚稳态,选择两级D触发器 相串联构成的同步模块来传送r_pointer_gray,最后用r_pointer_gray_sync和w_pointer_gray 相比较产生full信号。在空状态的判断时,同理我们要用 w_pointer_gray_sync 和 r_pointer_gray 相比较产生 empty 信号。两拍延时的数据同步对空满标志产生的影响由此信号r_pointer_gray经过两级D触发器,就会有两拍的延时形成r_pointer_gray_sync 信号,所以在进行比较的时候就不是实时的r_pointer_gray与w_pointer_gray进行比较,而 是两拍之前的r_pointer_gray即r_pointer_gray_sync与此刻的w_pointer_gray进行比较。那 么问题就来了这与我们的本意其实是不

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 建筑资料

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号