一个异步FIFO的设计示例.docx

上传人:b****1 文档编号:14542629 上传时间:2023-06-24 格式:DOCX 页数:20 大小:57.24KB
下载 相关 举报
一个异步FIFO的设计示例.docx_第1页
第1页 / 共20页
一个异步FIFO的设计示例.docx_第2页
第2页 / 共20页
一个异步FIFO的设计示例.docx_第3页
第3页 / 共20页
一个异步FIFO的设计示例.docx_第4页
第4页 / 共20页
一个异步FIFO的设计示例.docx_第5页
第5页 / 共20页
一个异步FIFO的设计示例.docx_第6页
第6页 / 共20页
一个异步FIFO的设计示例.docx_第7页
第7页 / 共20页
一个异步FIFO的设计示例.docx_第8页
第8页 / 共20页
一个异步FIFO的设计示例.docx_第9页
第9页 / 共20页
一个异步FIFO的设计示例.docx_第10页
第10页 / 共20页
一个异步FIFO的设计示例.docx_第11页
第11页 / 共20页
一个异步FIFO的设计示例.docx_第12页
第12页 / 共20页
一个异步FIFO的设计示例.docx_第13页
第13页 / 共20页
一个异步FIFO的设计示例.docx_第14页
第14页 / 共20页
一个异步FIFO的设计示例.docx_第15页
第15页 / 共20页
一个异步FIFO的设计示例.docx_第16页
第16页 / 共20页
一个异步FIFO的设计示例.docx_第17页
第17页 / 共20页
一个异步FIFO的设计示例.docx_第18页
第18页 / 共20页
一个异步FIFO的设计示例.docx_第19页
第19页 / 共20页
一个异步FIFO的设计示例.docx_第20页
第20页 / 共20页
亲,该文档总共20页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

一个异步FIFO的设计示例.docx

《一个异步FIFO的设计示例.docx》由会员分享,可在线阅读,更多相关《一个异步FIFO的设计示例.docx(20页珍藏版)》请在冰点文库上搜索。

一个异步FIFO的设计示例.docx

一个异步FIFO的设计示例

一、异步FIFO技术规

1.总体描述

1.1.功能定义

异步FIFO(FirstInFirstOut)指的是在两个相互独立的时钟域下,数据从一个时钟域写入FIFO而另一个时钟域又从这个FIFO中将数据读出。

本设计用8*256的RAM实现异步FIFO。

具体功能:

1.写使能有效,且FIFO不为满时,在写时钟的上升沿向FIFO中写入数据。

2.读使能有效,且FIFO不为空时,在读时钟的上升沿从FIFO中读出数据。

3.当FIFO写满时产生满信号,当FIFO读空时产生空信号。

1.2.应用围

异步FIFO是用来作为缓冲的存储器,它能对数据进行快速、顺序的存储和发送,主要用来解决不同速率器件间的速率匹配问题。

2.引脚描述

图1

2.1.引脚功能描述

信号名

输入/输出

功能描述

r_clk

输入

读数据时钟信号

w_clk

输入

写数据时钟信号

data_in[7:

0]

输入

8位的输入数据

r_en

输入

读使能,高电平有效,在FIFO非空时,clk上升沿读入数据;

w_en

输入

写使能,高电平有效,在FIFO非满时,clk上升沿写入数据;

rst

输入

异步清零,低电平有效,低电平时读地址,写地址,计数器都清零。

empty

输出

空信号,高电平有效,当FIFO读空时其值为1

full

输出

满信号,高电平有效,当FIFO写满时其值为1

data_out[7:

0]

输出

8位的输出数据

2.2.引脚时序描述

当写满时full由低变高,当读空时empty由低变高。

只要不为满full就为低,不为空empty就为低。

3.顶层模块划分

图2

顶层模块说明:

1.ram_fifo:

存储器模块,用于存放及输出数据;

2.w_addr_reg:

保存访问RAM的写地址;

3.r_addr_reg:

保存访问RAM的读地址;

4.w_addr_adder:

计算RAM下一个写地址;

5.r_addr_adder:

计算RAM下一个读地址;

6.cmp:

将读地址和写地址进行比较产生空满标志。

设计思想说明:

FIFO满空的判定:

当读地址的值加1之后等于写地址的值时,表明FIFO写满,当写地址的值加一之后等于读地址的值时,表明FIFO读空。

在初始状态时FIFO的读地址在RAM的中间位置,写地址在RAM的开始位置,所以初始状态FIFO不满也不空。

空满信号的产生由组合电路产生。

4.功能模块描述

4.1.ram_fifo模块

ram_fifo:

RAM存储器。

用8*256双口RAM实现。

4.2.w_addr_reg模块

w_addr_reg模块:

写地址寄存器。

用来寄存写地址加法器输出的地址。

4.3.r_addr_reg模块

r_addr_reg模块:

读地址寄存器。

用来寄存读地址加法器输出的地址。

4.4.w_addr_adder模块

w_addr_adder模块:

写地址加法器。

把写地址寄存器的输出加一,即表示当前写地址的下一地址位。

当w_en为低时停止累加。

4.5.r_addr_adder模块

r_addr_adder模块:

读地址加法器。

把读地址寄存器的输出加一,即表示当前读地址的下一地址位。

当r_en为低时停止累加。

4.6.cmp模块

cmp模块:

读地址和写地址进行比较,产生满空标志。

二、异步FIFO总体设计方案

1.概述

异步FIFO有高速、可靠性好等特点。

由于异步FIFO在两个不同时钟系统之间能够快速而方便地传输实时数据,因此在网络接口、图像处理等方面,异步FIFO得到了广泛的应用。

异步FIFO指的是在两个相互独立的时钟域下,数据从一个时钟域写入FIFO而另一个时钟域又从这个FIFO中将数据读出。

异步FIFO通常被用来将数据从一个时钟域安全地传送到另外一时钟域。

2.功能模块设计

2.1.ram_fifo模块

2.1.1.ram_fifo模块描述

ram_fifo:

RAM存储器。

用8*256双口RAM实现。

2.1.2.管脚描述

信号名称

输入/输出

功能描述

w_clk

输入

PIN

写时钟信号

w_en

输入

PIN

写使能信号

w_addr[7:

0]

输入

w_addr_reg

写地址信号

r_clk

输入

PIN

读时钟信号

r_en

输入

PIN

读使能信号

r_addr[7:

0]

输入

w_addr_reg

读地址信号

data_in[7:

0]

输入

PIN

输入数据

data_out[7:

0]

输出

输出数据

表2

2.1.3.实现说明

应使用双口RAM,双地址输入,并且带有读写使能,异步的读写时钟。

RAM宽度为8bit,深度为256个存储单元。

2.2.w_addr_reg模块

2.2.1.w_addr_reg模块描述

w_addr_reg模块:

写地址寄存器。

用来寄存写地址加法器输出的地址。

2.2.2.管脚描述

信号名称

输入/输出

目标

功能描述

W_clk

输入

PIN

写时钟信号

Rst

输入

PIN

复位信号,低电平有效

W_addr_nt[7:

0]

输入

W_addr_addr

输入数据

W_addr[7:

0]

输出

RAM

W_addr

输出数据

表3

2.2.3.实现说明

在时钟的上升沿将8位的输入数据锁存输出。

2.3.r_addr_reg模块

2.3.1.r_addr_reg模块描述

r_addr_reg模块:

读地址寄存器。

用来寄存读地址加法器输出的地址。

2.3.2.管脚描述

信号名称

输入/输出

目标

功能描述

R_clk

输入

PIN

读时钟信号

Rst

输入

PIN

复位信号,低电平有效

R_addr_nt[7:

0]

输入

R_addr_adder

输入数据

R_addr[7:

0]

输出

RAM

R_addr

输出数据

表4

2.3.3.实现说明

在时钟的上升沿将8位的输入数据所存输出。

2.4.w_addr_adder模块

2.4.1.w_addr_adder模块描述

w_addr_adder模块:

写地址加法器。

把写地址寄存器的输出加一,即表示当前写地址的下一地址位。

当w_en为低时停止累加。

2.4.2.管脚描述

信号名称

输入/输出

目标

功能描述

w_en

输入

PIN

1-允许地址加1;

0-禁止地址加1;

w_addr[7:

0]

输入

W_addr_reg

输入数据

W_addr_nt[7:

0]

输出

W_addr_reg

加一后输出数据

表5

2.4.3.实现说明

以w_addr为输入,输出为w_addr+1。

2.5.r_addr_adder模块

2.5.1.r_addr_adder模块描述

r_addr_adder模块:

读地址加法器。

把读地址寄存器的输出加一,即表示当前读地址的下一地址位。

当r_en为低时停止累加。

2.5.2.管脚描述

信号名称

输入/输出

目标

功能描述

r_en

输入

PIN

1-允许地址加1;

0-禁止地址加1;

r_addr[7:

0]

输入

r_addr_reg

输入数据

r_addr_nt[7:

0]

输出

r_addr_reg

加一后输出数据

表6

2.5.3.实现说明

以r_addr为输入,输出为r_addr+1。

2.6.cmp模块

2.6.1.cmp模块描述

cmp模块:

读地址和写地址进行比较,产生满空标志。

2.6.2.管脚描述

信号名称

输入/输出

目标

功能描述

W_addr[7:

0]

输入

W_addr_reg

FIFO当前的写地址

R_addr[7:

0]

输入

R_addr_re

FIFO当前的读地址

empty

输出

PIN

0-FIFO未空

1-FIFO读空

full

输出

PIN

0-FIFO未满

1-FIFO写满

表7

2.6.3.实现说明

将w_addr加一与r_addr对比,相等则full为1否则为0;

将r_addr加一与w_addr对比,相等则empty为1否则为0;

三、异步FIFO验证方案

总体验证方案

1.1.测试FIFO在正常状态下,是否能写入和读出;full和empty的标志位均为0;

1.2.测试FIFO在写满时,full是否能变为高;当满时读出一个数,full能否由高变低。

1.3.测试FIFO在读空时,empty是否能变为高;当空时写入一个数,empty能否由高变低。

1.4.异步复位后,FIFO是否可以正常工作。

另外,在编写激励时,FIFO读空后,则将读使能禁止,FIFO写满后,则将写使能禁止,以保证读出和写入数据的正确性。

四、电路设计源代码及仿真激励

(1)异步FIFO源代码:

modulefifo(

data_in,

data_out,

r_en,

w_en,

r_clk,

w_clk,

full,

empty,

rst

);

input[7:

0]data_in;

inputr_en;

inputw_en;

inputr_clk;

inputw_clk;

inputrst;

output[7:

0]data_out;

outputempty;

outputfull;

wire[7:

0]w_addr;

wire[7:

0]r_addr;

wire[7:

0]w_addr_nt;

wire[7:

0]r_addr_nt;

ramu1(

.data_out(data_out),

.data_in(data_in),

.w_clk(w_clk),

.r_clk(r_clk),

.w_en(w_en),

.r_en(r_en),

.w_addr(w_addr),

.r_addr(r_addr)

);

w_addr_regu2(

.w_addr(w_addr),

.w_addr_nt(w_addr_nt),

.w_clk(w_clk),

.rst(rst)

);

r_addr_regu3(

.r_addr(r_addr),

.r_addr_nt(r_addr_nt),

.r_clk(r_clk),

.rst(rst)

);

w_addr_adderu4(

.w_en(w_en),

.w_addr(w_addr),

.w_addr_nt(w_addr_nt)

);

r_addr_adderu5(

.r_en(r_en),

.r_addr(r_addr),

.r_addr_nt(r_addr_nt)

);

cmpu6(

.w_addr(w_addr),

.r_addr(r_addr),

.full(full),

.empty(empty)

);

endmodule

moduleram(

data_out,

data_in,

w_clk,

r_clk,

w_en,

r_en,

w_addr,

r_addr

);

input[7:

0]data_in;

inputw_clk;

inputr_clk;

inputw_en;

inputr_en;

input[7:

0]w_addr;

input[7:

0]r_addr;

output[7:

0]data_out;

reg[7:

0]ram_f[255:

0];

reg[7:

0]data_out;

always(posedger_clk)

begin

if(!

r_en)

data_out<=8'hzz;

else

begin

data_out<=ram_f[r_addr];

end

end

always(posedgew_clk)

begin

if(!

r_en)

ram_f[w_addr]<=ram_f[w_addr];

else

begin

ram_f[w_addr]<=data_in;

end

end

endmodule

 

//w_addr_reg

modulew_addr_reg(

w_addr,

w_addr_nt,

w_clk,

rst

);

input[7:

0]w_addr_nt;

inputw_clk;

inputrst;

output[7:

0]w_addr;

reg[7:

0]w_addr;

 

always(posedgew_clkornegedgerst)

begin

if(!

rst)

w_addr<=8'h1f;

else

w_addr<=w_addr_nt;

end

endmodule

//r_addr_reg

moduler_addr_reg(

r_addr,

r_addr_nt,

r_clk,

rst

);

input[7:

0]r_addr_nt;

inputr_clk;

inputrst;

output[7:

0]r_addr;

reg[7:

0]r_addr;

always(posedger_clkornegedgerst)

begin

if(!

rst)

r_addr<=8'h00;

else

r_addr<=r_addr_nt;

end

endmodule

 

/////////////////////////////////////////////////////////////////////

//w_addr_adder

modulew_addr_adder(

w_en,

w_addr,

w_addr_nt

);

inputw_en;

input[7:

0]w_addr;

output[7:

0]w_addr_nt;

assignw_addr_nt=w_en?

(w_addr+8'h01):

w_addr;

endmodule

//r_addr_adder

moduler_addr_adder(

r_en,

r_addr,

r_addr_nt

);

inputr_en;

input[7:

0]r_addr;

output[7:

0]r_addr_nt;

assignr_addr_nt=r_en?

(r_addr+8'h01):

r_addr;

endmodule

//cmp

modulecmp(

w_addr,

r_addr,

empty,

full

);

input[7:

0]w_addr;

input[7:

0]r_addr;

outputempty;

outputfull;

assignempty=r_addr+1==w_addr;

assignfull=w_addr+1==r_addr;

endmodule

见fifo_tb.v

`timescale1ns/100ps

modulefifo_tb;

reg[7:

0]data_in;

regr_en;

regw_en;

regr_clk;

regw_clk;

regrst;

wire[7:

0]data_out;

wirefull;

wireempty;

reg[7:

0]count;

fifou(

.data_in(data_in),

.data_out(data_out),

.r_en(r_en),

.r_clk(r_clk),

.w_en(w_en),

.w_clk(w_clk),

.rst(rst),

.full(full),

.empty(empty)

);

 

initial

begin

r_clk=0;

w_clk=0;

end

always

begin

#100r_clk=!

r_clk;

end

always

begin

#2

if(empty)

r_en=0;

else

r_en=1;

if(full)

w_en=0;

else

w_en=1;

end

 

always

begin

 

#5if(count)

w_clk=!

w_clk;

else

w_clk=0;

end

initial

begin

r_en=1;

w_en=1;

rst=0;

#100

rst=1;

#100

count=8'hff;

repeat(255)

begin

#10

data_in=count;

count=count-1;

end

#60000

//////////////////////////////

#100

r_en=1;

w_en=1;

count=8'h04;

repeat(4)

begin

#10

data_in=count;

count=count-1;

end

#10000

//////////////////////////////////

rst=0;

#1000

rst=1;

r_en=1;

w_en=1;

#10

count=8'hff;

repeat(300)

begin

#10

data_in=count;

count=count-1;

end

count=8'h00;

#60000

$stop;

end

 

Endmodule

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

当前位置:首页 > 工程科技 > 能源化工

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

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