异步FIFO设计(易懂+verilog代码).pdf

上传人:b****3 文档编号:3219361 上传时间:2022-11-20 格式:PDF 页数:15 大小:765.54KB
下载 相关 举报
异步FIFO设计(易懂+verilog代码).pdf_第1页
第1页 / 共15页
异步FIFO设计(易懂+verilog代码).pdf_第2页
第2页 / 共15页
异步FIFO设计(易懂+verilog代码).pdf_第3页
第3页 / 共15页
异步FIFO设计(易懂+verilog代码).pdf_第4页
第4页 / 共15页
异步FIFO设计(易懂+verilog代码).pdf_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

异步FIFO设计(易懂+verilog代码).pdf

《异步FIFO设计(易懂+verilog代码).pdf》由会员分享,可在线阅读,更多相关《异步FIFO设计(易懂+verilog代码).pdf(15页珍藏版)》请在冰豆网上搜索。

异步FIFO设计(易懂+verilog代码).pdf

1异步异步FIFO设计设计2011.6.22摘要本文采用格雷码设计了一个异步FIFO,经过DC综合的结果如下:

时钟频率:

1.1GHz面积:

10744.447um2功耗:

7.791mw目录1.异步FIFO的设计.21.1异步FIFO简介.21.2FIFO的参数.21.3FIFO的设计原理.21.4FIFO的设计模块.61.5用modelsim仿真FIFO.111.6用DC对FIFO进行综合.132.参考文献.1521.异步异步FIFO的设计的设计1.1异步异步FIFO简介简介FIFO是英文FirstInFirstOut的缩写,是一种先进先出的数据缓存器,它与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。

根均FIFO工作的时钟域,可以将FIFO分为同步FIFO和异步FIFO。

同步FIFO是指读时钟和写时钟为同一个时钟。

在时钟沿来临时同时发生读写操作。

异步FIFO是指读写时钟不一致,读写时钟是互相独立的。

异步FIFO(AsynchronousFIFO),一般用于不同时钟域之间的数据传输,比如FIFO的一端连接频率较低的AD数据采样信号,另一端与计算机的频率较高的PCI总线相连。

另外,对于不同宽度的数据接口也可以用AFIFO,例如单片机为8位数据输出,而DSP可能是16位数据输入,在单片机与DSP连接时就可以使用AFIFO来达到数据匹配的目的。

由于实际中,异步FIFO比较常见。

为了便于描述,在后面的章节中将异步FIFO简称为FIFO.1.2FIFO的参数的参数FIFO的宽度:

进行一次读写操作的数据的位宽。

FIFO的深度:

双口存储器中能容纳的数据的总数。

满标志:

FIFO已满或将要满时由FIFO的状态电路送出的一个信号,以阻止FIFO的写操作继续向FIFO中写数据而造成溢出。

空标志:

FIFO已空或将要空时由FIFO的状态电路送出的一个信号,以阻止FIFO的读操作继续从FIFO中读出数据而造成无效数据的读出。

读时钟:

读操作所遵循的时钟,在每个时钟沿来临时读数据。

写时钟:

写操作所遵循的时钟,在每个时钟沿来临时写数据。

读指针:

指向下一个读出地址。

读完后自动加1。

写指针:

指向下一个要写入的地址的,写完自动加1。

读写指针其实就是读写memory的地址,只不过这个地址不能任意选择,而是连续的。

1.3FIFO的设计原理的设计原理整体的框图如下:

3图1.1FIFO的整体电路图1.3.1FIFO的读写指针的读写指针FIFO可以看成是先进新出的缓冲区,它不像普通的存储器那样,有专门的地址信号。

它只能根据地址,顺序地读写缓冲区。

所以需要有两个读写指针。

这里定义如下:

wptr:

写数据的指针rptr:

读数据的指针每读/写完一个数据,读/写指针就会加1,指向下一个待读/写的位置。

1.3.2同步器的设计同步器的设计为了产生空/满标志,需要对2个读/写指针进行比较。

由于FIFO的读/写时钟信号,来自2个不同的时钟域,所以先要将这2个指针同步到一个时钟域。

这里采用两级D触发器级联来构成同步器。

1.3.3格雷码计数器格雷码计数器采用二进制码对地址指针进行计数时,从一个计数值变到下一个计数值时,可能有多位发生跳变,如从78变化时,低位由01111000,这样同步器在采样数据时,可能会发生错误。

由于采用格雷码计数时,每次只有1位发生跳变,这样使亚稳态发生错误的可能性大大减小了。

41.3.4空标志的产生空标志的产生由于读/写指针,总是指向FIFO的memory中下一个要读/写的位置。

只有在读/写复位的时候,读/写指针才回到0位置。

复位后,随着数据的读出/写入,读/写指针指向的地址逐渐增加。

如果读的速度比较快,当读指针赶上写指针,即读指针与写指针指向同一个位置时,输出的空标志有效。

如下图所示:

图1.2FIFO的空/满标志1.3.5满标志的产生满标志的产生满标志的产生,基于这样的原理:

即“写指针比空指针多绕了一圈”后,又指向了空指针所指向的位置。

由上可知,空标志的产生,也是由于读/写指针指向了同一位置。

那怎么来区分,当读/写指针指向同一位置时,FIFO是满,还是空呢?

这里,采用增加一位地址位的方法,来区分满标志和空标志。

假设FIFO的深度为16,那么采用5位的读/写地址指针。

地址的低4位,用来对寻址memory,读/写指针的最高位用来判断FIFO为空还是为满。

当读/写指针的低4位相同时,如果最高位也相同,那么空标志有效,否则满标志有效。

由于格雷码具有一个特性:

关于中间的计数值对称。

如果从格雷码的中间划开,把它分成2段。

分别从上往下看,会发现在对应的位置,只有最高的2位是完全相反,而其余的低位部分则是相同的。

因此,当读/写指针的最高2位完全相反,而其余的低位完全相同时,满标志有效(“读指针比写指针多绕了一圈”)。

具体如下图所示:

5图1.3格雷码的对称特性1.3.6格雷码计数器格雷码计数器如果读/写数据的使能信号(rinc/winc)有效,在下一个读/写时钟的上升沿到来时,会从(对)memory读出/写入一个数据,并且相应的读/写指针会加1。

由于习惯上用二进制码来寻址memory,而且用二进制码能很方便地进行累积操作,所以这里以二进制码为主,并将二进制码转换为格雷码,以比较读/写指针来产生空/满标志位。

二进制码可以通过以下方式转换成格雷码:

gray=(bin1)bin其中,gray表示格雷码,bin表示二进制码。

如,设一个5位的二进制码为B4:

0,它对应的格雷码为G4:

0,则G4=B4G3=B3B3G2=B2B2G1=B1B1G0=B0B0具体如下图所示:

6图1.4比较指针和寻址指针的产生电路1.4FIFO的设计模块的设计模块整个FIFO包括1个顶层模块和5个子模块。

1.4.1子模块子模块fifomem这个子模块,主要实现对FIFO的memory进行操作。

如果写使能信号(winc)有效,且FIFO满标志(wfull)无效,则在下一个写时钟(wclk)的上升沿到来时,将数据(wdata)写入到memory中写地址(waddr)指针所指向的位置。

同时,只要给出读地址(raddr),就可以从memory中读出数据(rdata),与读时钟(rclk)无关。

相应的代码如下所示:

modulefifomem#(parameterDATASIZE=8,/MemorydatawordwidthparameterADDRSIZE=4)/Numberofmemaddressbits(outputDATASIZE1:

0rdata,inputDATASIZE1:

0wdata,inputADDRSIZE1:

0waddr,raddr,inputwclken,wfull,wclk);/RTLVerilogmemorymodellocalparamDEPTH=1ADDRSIZE;regDATASIZE1:

0mem0:

DEPTH1;assignrdata=memraddr;always(posedgewclk)7if(wclken&!

wfull)memwaddr=wdata;endmodule1.4.2子模块子模块sync_r2w这个子模块,通过2个D触发器的级联,将格雷码表示的读指针,同步到写时钟域中。

相应的代码如下:

modulesync_r2w#(parameterADDRSIZE=4)(outputregADDRSIZE:

0wq2_rptr,inputADDRSIZE:

0rptr,inputwclk,wrst_n);regADDRSIZE:

0wq1_rptr;always(posedgewclkornegedgewrst_n)if(!

wrst_n)wq2_rptr,wq1_rptr=0;elsewq2_rptr,wq1_rptr=wq1_rptr,rptr;endmodule1.4.3子模块子模块sync_w2r这个子模块,也采用2个D触发器的级联,将格雷码表示的读指针,同步到写时钟域中。

相应的代码如下:

modulesync_w2r#(parameterADDRSIZE=4)(outputregADDRSIZE:

0rq2_wptr,inputADDRSIZE:

0wptr,inputrclk,rrst_n);regADDRSIZE:

0rq1_wptr;always(posedgerclkornegedgerrst_n)if(!

rrst_n)rq2_wptr,rq1_wptr=0;elserq2_wptr,rq1_wptr=rq1_wptr,wptr;Endmodule81.4.4子模块子模块rptr_empty这个子模块的输入包括:

读使能信号(rinc)、读时钟(rclk)、读复位信号(rrst_n,低电平有效)。

输出包括:

读寻址指针(raddr)、读比较指针(rptr)。

其中读寻址指针为二进制码,读比较指针为格雷码,且读寻址指针比读比较指针少一位。

可以参照图1.4,相关的代码如下:

modulerptr_empty#(parameterADDRSIZE=4)(outputregrempty,outputADDRSIZE1:

0raddr,outputregADDRSIZE:

0rptr,inputADDRSIZE:

0rq2_wptr,inputrinc,rclk,rrst_n);regADDRSIZE:

0rbin;wireADDRSIZE:

0rgraynext,rbinnext;always(posedgerclkornegedgerrst_n)if(!

rrst_n)rbin,rptr=0;elserbin,rptr1)rbinnext;/FIFOemptywhenthenextrptr=synchronizedwptroronreset/assignrempty_val=(rgraynext=rq2_wptr);always(posedgerclkornegedgerrst_n)if(!

rrst_n)rempty=1b1;elserempty=rempty_val;endmodule91.4.5子模块子模块rptr_empty这个子模块的输入包括:

写使能信号(winc)、写时钟(wclk)、写复位信号(wrst_n,低电平有效)。

输出包括:

写寻址指针(waddr)、写比较指针(wptr)。

其中读寻址指针为二进制码,读比较指针为格雷码,且读寻址指针比读比较指针少一位。

可以参照图1.4,相关的代码如下:

modulewptr_full#(parameterADDRSIZE=4)(outputregwfull,outputADDRSIZE1:

0waddr,outputregADDRSIZE:

0wptr,inputADDRSIZE:

0wq2_rptr,inputwinc,wclk,wrst_n);regADDRSIZE:

0wbin;wireADDRSIZE:

0wgraynext,wbinnext;/GRAYSTYLE2pointeralways(posedgewclkornegedgewrst_n)if(!

wrst_n)wbin,wptr=0;elsewbin,wptr1)wbinnext;/Simplifiedversionofthethreenecessaryfulltests:

/assignwfull_val=(wgnextADDRSIZE!

=wq2_rptrADDRSIZE)&/(wgnextADDRSIZE1!

=wq2_

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 其它

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1