异步FIFO设计Word文件下载.docx

上传人:wj 文档编号:8430196 上传时间:2023-05-11 格式:DOCX 页数:15 大小:485.44KB
下载 相关 举报
异步FIFO设计Word文件下载.docx_第1页
第1页 / 共15页
异步FIFO设计Word文件下载.docx_第2页
第2页 / 共15页
异步FIFO设计Word文件下载.docx_第3页
第3页 / 共15页
异步FIFO设计Word文件下载.docx_第4页
第4页 / 共15页
异步FIFO设计Word文件下载.docx_第5页
第5页 / 共15页
异步FIFO设计Word文件下载.docx_第6页
第6页 / 共15页
异步FIFO设计Word文件下载.docx_第7页
第7页 / 共15页
异步FIFO设计Word文件下载.docx_第8页
第8页 / 共15页
异步FIFO设计Word文件下载.docx_第9页
第9页 / 共15页
异步FIFO设计Word文件下载.docx_第10页
第10页 / 共15页
异步FIFO设计Word文件下载.docx_第11页
第11页 / 共15页
异步FIFO设计Word文件下载.docx_第12页
第12页 / 共15页
异步FIFO设计Word文件下载.docx_第13页
第13页 / 共15页
异步FIFO设计Word文件下载.docx_第14页
第14页 / 共15页
异步FIFO设计Word文件下载.docx_第15页
第15页 / 共15页
亲,该文档总共15页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

异步FIFO设计Word文件下载.docx

《异步FIFO设计Word文件下载.docx》由会员分享,可在线阅读,更多相关《异步FIFO设计Word文件下载.docx(15页珍藏版)》请在冰点文库上搜索。

异步FIFO设计Word文件下载.docx

满标志:

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

空标志:

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

读时钟:

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

写时钟:

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

读指针:

指向下一个读出地址。

读完后自动加1。

写指针:

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

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

1.3FIFO的设计原理

整体的框图如下:

图1.1FIFO的整体电路图

1.3.1FIFO的读写指针

FIFO可以看成是先进新出的缓冲区,它不像普通的存储器那样,有专门的地址信号。

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

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

这里定义如下:

wptr:

写数据的指针

rptr:

读数据的指针

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

1.3.2同步器的设计

为了产生空/满标志,需要对2个读/写指针进行比较。

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

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

1.3.3格雷码计数器

采用二进制码对地址指针进行计数时,从一个计数值变到下一个计数值时,可能有多位发生跳变,如从7à

8变化时,低位由0111à

1000,这样同步器在采样数据时,可能会发生错误。

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

1.3.4空标志的产生

由于读/写指针,总是指向FIFO的memory中下一个要读/写的位置。

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

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

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

如下图所示:

图1.2FIFO的空/满标志

1.3.5满标志的产生

满标志的产生,基于这样的原理:

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

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

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

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

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

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

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

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

关于中间的计数值对称。

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

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

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

具体如下图所示:

图1.3格雷码的对称特性

1.3.6格雷码计数器

如果读/写数据的使能信号(rinc/winc)有效,在下一个读/写时钟的上升沿到来时,会从(对)memory读出/写入一个数据,并且相应的读/写指针会加1。

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

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

gray=(bin>

>

1)^bin

其中,gray表示格雷码,bin表示二进制码。

如,设一个5位的二进制码为B[4:

0],它对应的格雷码为G[4:

0],则

G[4]=B[4]

G[3]=B[3]^B[3]

G[2]=B[2]^B[2]

G[1]=B[1]^B[1]

G[0]=B[0]^B[0]

图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,//Memorydatawordwidth

parameterADDRSIZE=4)//Numberofmemaddressbits

(output[DATASIZE-1:

0]rdata,

input[DATASIZE-1:

0]wdata,

input[ADDRSIZE-1:

0]waddr,raddr,

inputwclken,wfull,wclk);

//RTLVerilogmemorymodel

localparamDEPTH=1<

<

ADDRSIZE;

reg[DATASIZE-1:

0]mem[0:

DEPTH-1];

assignrdata=mem[raddr];

always@(posedgewclk)

if(wclken&

&

!

wfull)mem[waddr]<

=wdata;

endmodule

1.4.2子模块sync_r2w

这个子模块,通过2个D触发器的级联,将格雷码表示的读指针,同步到写时钟域中。

相应的代码如下:

modulesync_r2w#(parameterADDRSIZE=4)

(outputreg[ADDRSIZE:

0]wq2_rptr,

input[ADDRSIZE:

0]rptr,

inputwclk,wrst_n);

reg[ADDRSIZE:

0]wq1_rptr;

always@(posedgewclkornegedgewrst_n)

if(!

wrst_n)

{wq2_rptr,wq1_rptr}<

=0;

else

={wq1_rptr,rptr};

1.4.3子模块sync_w2r

这个子模块,也采用2个D触发器的级联,将格雷码表示的读指针,同步到写时钟域中。

modulesync_w2r#(parameterADDRSIZE=4)

0]rq2_wptr,

0]wptr,

inputrclk,rrst_n);

0]rq1_wptr;

always@(posedgerclkornegedgerrst_n)

rrst_n)

{rq2_wptr,rq1_wptr}<

else

={rq1_wptr,wptr};

Endmodule

1.4.4子模块rptr_empty

这个子模块的输入包括:

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

输出包括:

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

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

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

modulerptr_empty#(parameterADDRSIZE=4)

(outputregrempty,

output[ADDRSIZE-1:

0]raddr,

outputreg[ADDRSIZE:

input[ADDRSIZE:

inputrinc,rclk,rrst_n);

0]rbin;

wire[ADDRSIZE:

0]rgraynext,rbinnext;

rrst_n)

{rbin,rptr}<

else

={rbinnext,rgraynext};

//Memoryread-addresspointer(okaytousebinarytoaddressmemory)

assignraddr=rbin[ADDRSIZE-1:

0];

assignrbinnext=rbin+(rinc&

~rempty);

assignrgraynext=(rbinnext>

1)^rbinnext;

//---------------------------------------------------------------------------------------

//FIFOemptywhenthenextrptr==synchronizedwptroronreset

assignrempty_val=(rgraynext==rq2_wptr);

rempty<

=1'

b1;

=rempty_val;

1.4.5子模块rptr_empty

这个子模块的输入包括:

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

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

modulewptr_full#(parameterADDRSIZE=4)

(outputregwfull,

0]waddr,

inputwinc,wclk,wrst_n);

0]wbin;

0]wgraynext,wbinnext;

//GRAYSTYLE2pointer

wrst_n)

{wbin,wptr}<

={wbinnext,wgraynext};

//Memorywrite-addresspointer(okaytousebinarytoaddressmemory)

assignwaddr=wbin[ADDRSIZE-1:

assignwbinnext=wbin+(winc&

~wfull);

assignwgraynext=(wbinnext>

1)^wbinnext;

//------------------------------------------------------------------

//Simplifiedversionofthethreenecessaryfull-tests:

//assignwfull_val=((wgnext[ADDRSIZE]!

=wq2_rptr[ADDRSIZE])&

//(wgnext[ADDRSIZE-1]!

=wq2_rptr[ADDRSIZE-1])&

//(wgnext[ADDRSIZE-2:

0]==wq2_rptr[ADDRSIZE-2:

0]));

assignwfull_val=(wgraynext=={~wq2_rptr[ADDRSIZE:

ADDRSIZE-1],

wq2_rptr[ADDRSIZE-2:

0]});

wfull<

b0;

=wfull_val;

1.4.6顶层模块afifo

这个顶层模块,主要完成5个子模块例化和互联。

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

moduleafifo#(parameterDSIZE=8,

parameterASIZE=4)

(output[DSIZE-1:

0]rdata,

outputwfull,

outputrempty,

input[DSIZE-1:

0]wdata,

inputwinc,wclk,wrst_n,

inputrinc,rclk,rrst_n);

wire[ASIZE-1:

0]waddr,raddr;

wire[ASIZE:

0]wptr,rptr,wq2_rptr,rq2_wptr;

sync_r2wsync_r2w

(.wq2_rptr(wq2_rptr),.rptr(rptr),

.wclk(wclk),.wrst_n(wrst_n));

sync_w2rsync_w2r

(.rq2_wptr(rq2_wptr),.wptr(wptr),

.rclk(rclk),.rrst_n(rrst_n));

fifomem#(DSIZE,ASIZE)fifomem

(.rdata(rdata),.wdata(wdata),

.waddr(waddr),.raddr(raddr),

.wclken(winc),.wfull(wfull),

.wclk(wclk));

rptr_empty#(ASIZE)rptr_empty

(.rempty(rempty),

.raddr(raddr),

.rptr(rptr),.rq2_wptr(rq2_wptr),

.rinc(rinc),.rclk(rclk),

.rrst_n(rrst_n));

wptr_full#(ASIZE)wptr_full

(.wfull(wfull),.waddr(waddr),

.wptr(wptr),.wq2_rptr(wq2_rptr),

.winc(winc),.wclk(wclk),

.wrst_n(wrst_n));

1.5用modelsim仿真FIFO

1.5.1编写测试代码

根据前面的顶层模块afifo,编写测试代码如下:

`timescale1ns/1ns

moduletest;

reg[7:

0]wdata;

regwinc;

regwclk;

regwrst_n;

regrinc;

regrclk;

regrrst_n;

wire[7:

0]rdata;

wirewfull;

wirerempty;

integeri;

always

begin

#50wclk=1;

#50wclk=0;

end

always

#100rclk=1;

#100rclk=0;

initial

wrst_n=0;

rrst_n=0;

rinc=0;

winc=0;

wclk=0;

rclk=0;

wdata=0;

i=0;

#400;

wrst_n=1;

rrst_n=1;

for(i=0;

i<

16;

i=i+1)

begin

repeat

(1)@(posedgewclk)

#20winc=1;

wdata=i;

end

repeat

(1)@(posedgewclk)

#20winc=0;

repeat

(1)@(posedgerclk)

#20rinc=1;

repeat

(1)@(posedgerclk)

#20rinc=0;

end

afifoafifo(.rdata(rdata),

.wdata(wdata),

.wclk(wclk),

.rclk(rclk),

.wrst_n(wrst_n),

.rrst_n(rrst_n),

.wfull(wfull),

.rempty(rempty),

.winc(winc),

.rinc(rinc)

);

1.5.2仿真波形

当写时钟(wclk)和读时钟(rclk)的周期相同,且都为50ns时,波形如下:

图1.5仿真波形--读写时钟的周期都为50ns

当写时钟(wclk)周期为100ns,读时钟(rclk)周期为50ns时,波形如下:

图1.6仿真波形--读/写时钟的周期都为50ns/100ns

当写时钟(wclk)周期为50ns,读时钟(rclk)周期为100ns时,波形如下:

图1.6仿真波形--读/写时钟的周期都为100ns/50ns

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

当前位置:首页 > 高等教育 > 军事

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2