利用SRAM设计一个FIFO.docx

上传人:b****4 文档编号:4021309 上传时间:2023-05-06 格式:DOCX 页数:14 大小:34.54KB
下载 相关 举报
利用SRAM设计一个FIFO.docx_第1页
第1页 / 共14页
利用SRAM设计一个FIFO.docx_第2页
第2页 / 共14页
利用SRAM设计一个FIFO.docx_第3页
第3页 / 共14页
利用SRAM设计一个FIFO.docx_第4页
第4页 / 共14页
利用SRAM设计一个FIFO.docx_第5页
第5页 / 共14页
利用SRAM设计一个FIFO.docx_第6页
第6页 / 共14页
利用SRAM设计一个FIFO.docx_第7页
第7页 / 共14页
利用SRAM设计一个FIFO.docx_第8页
第8页 / 共14页
利用SRAM设计一个FIFO.docx_第9页
第9页 / 共14页
利用SRAM设计一个FIFO.docx_第10页
第10页 / 共14页
利用SRAM设计一个FIFO.docx_第11页
第11页 / 共14页
利用SRAM设计一个FIFO.docx_第12页
第12页 / 共14页
利用SRAM设计一个FIFO.docx_第13页
第13页 / 共14页
利用SRAM设计一个FIFO.docx_第14页
第14页 / 共14页
亲,该文档总共14页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

利用SRAM设计一个FIFO.docx

《利用SRAM设计一个FIFO.docx》由会员分享,可在线阅读,更多相关《利用SRAM设计一个FIFO.docx(14页珍藏版)》请在冰点文库上搜索。

利用SRAM设计一个FIFO.docx

利用SRAM设计一个FIFO

292

练习十二利用SRAM设计一个FIFO 

在本练习中,要求同学利用练习十一中提供的SRAM模型,设计SRAM读写控制逻辑,使SRAM的行为对用户表现为一个FIFO(先进先出存储器。

 

1设计要求:

 

本练习要求同学设计的FIFO为同步FIFO,即对FIFO的读/写使用同一个时钟。

该FIFO应当提供用户读使能(fiford和写使能(fifowr输入控制信号,并输出指示FIFO状态的非空(nempty和非满(nfull信号,FIFO的输入、输出数据使用各自的数据总线:

in_data和

2FIFO接口的设计思路

FIFO的数据读写操作与SRAM的数据读写操作基本上相同,只是FIFO没有地址。

所以用SRAM实现FIFO的关键点是如何产生正确的SRAM地址。

我们可以借用软件中的方法,将FIFO抽象为环形数组,并用两个指针:

读指针(fifo_rp和写指针(fifo_wp控制对该环形数组的读写。

其中,读指针fifo_rp指向下一次读操作所要读取的单元,并且每完成一次读操作,fifo_rp加一;写指针fifo_wp则指向下一次写操作时存放数据的单元,并且每完成一次写操作,fifo_wp加一。

由fifo_rp和fifo_wp的定义易知,当FIFO被读空或写满后,fifo_rp和fifo_wp将指向同一单元,但在读空和写满之前FIFO的状态是不同的,所以如果能区分这两种状态,再通过比较fifo_rp和fifo_wp就可以得到nempty和nfull信号了。

下图为FIFO工作状态的示意。

N

单元内有数据单元内无数据

一般情况

再写即满

再读即空

在得到nfull和nempty信号后,就需要考虑如何应用这两个信号来控制对FIFO的读写,使得FIFO在被写满后不能再写入,从而防止覆盖原有数据,并且在被读空后也不能再进行读操作,防止读取无效数据。

此外,在进SRAM读写操作时,应该注意建立地址、数据和控制信号的先后顺序。

一般情况下,希望对SRAM读写的波形时序如下图所示:

RD

即写SRAM时,先建立地址和数据,然后置写使能信号WR有效,在WR保持有效一定时间后,先复位WR,然后释放地址和数据总线。

而读取SRAM时,则先建立地址,然后置读使能RD有效,在RD维持有效一定时间后,复位RD,同时读取数据总线上的值,然后再释放地址总线。

在进行FIFO操作时,用户一般希望除了没有地址外,其它三个信号的时序关系能保持不变。

请同学们在设计FIFO控制信号与SRAM控制信号间逻辑关系时注意这一点。

3FIFO接口的测试

在完成一个设计后,需要进行测试以确认设计的正确性和完整性。

而要进行测试,就需要编写测试激励和结果检查程序,即测试平台(testbench。

在某些情况下,如果设计的接口能够预先确定,测试平台的编写也可以在设计完成之前就进行,这样做的好处是在设计测试平台的同时也在更进一步深入了解设计要求,有助于理清设计思路,及时发现设计方案的错误。

编写测试激励时,除了注意对实际可能存在的各种情况的覆盖外,还要有意针对非正常情况下的操作进行测试。

在本练习中,就应当进行在FIFO读空后继续读取、FIFO写满后继续写入、FIFO复位后马上读取等操作的测试。

测试激励中通常会有一些复杂操作需要反复进行,如本练习中对FIFO的读写操作。

这时可以将这些复杂操作纳入到几个task中,即减小了激励编写的工作量,也使得程序的可读性更好。

下面的测试程序给同学们做为参考,希望同学们能先用这段程序测试所设计的FIFO接口,然后编写自己更全面的测试程序。

`defineFIFO_SIZE8

`include“sram.v”//有的仿真工具不需要加这句,只要sram.v模块编译过就可以了`timescale1ns/1ns

modulet;

reg[7:

0]in_data;//FIFO数据总线

regfiford,fifowr;//FIFO控制信号

wire[7:

0]out_data;

293

wirenfull,nempty;//FIFO状态信号

regclk,rst;

wire[7:

0]sram_data;//SRAM数据总线

wire[10:

0]address;//SRAM的地址总线

wirerd,wr;//SRAM读写控制信号

reg[7:

0]data_buf[`FIFO_SIZE:

0];//数据缓存,用于结果检查

integerindex;//用于读写data_buf的指针

//系统时钟

initialclk=0;

always#25clk=~clk;

//测试激励序列

initial

begin

fiford=1;

fifowr=1;

rst=1;

#40rst=0;

#42rst=1;

if(nempty$display($time,"Error:

FIFObeempty,nemptyshouldbelow.\n";

//连续写FIFO

index=0;

repeat(`FIFO_SIZEbegin

data_buf[index]=$random;

write_fifo(data_buf[index];

index=index+1;

end

if(nfull$display($time,"Error:

FIFOfull,nfullshouldbelow.\n";

repeat(2write_fifo($random;

#200

//连续读FIFO

index=0;

read_fifo_compare(data_buf[index];

if(~nfull$display($time,"Error:

FIFOnotfull,nfullshouldbehigh.\n";

repeat(`FIFO_SIZE-1begin

294

index=index+1;

read_fifo_compare(data_buf[index];

end

if(nempty$display($time,"Error:

FIFObeempty,nemptyshouldbelow.\n";

repeat(2read_fifo_compare(8'bx;

reset_fifo;

//写后读FIFO

repeat(`FIFO_SIZE*2

begin

data_buf[0]=$random;

write_fifo(data_buf[0];

read_fifo_compare(data_buf[0];

end

//异常操作

reset_fifo;

read_fifo_compare(8'bx;

write_fifo(data_buf[0];

read_fifo_compare(data_buf[0];

$stop;

end

fifo_interfacefifo_interface(

.in_data(in_data,.out_data(out_data,

.fiford(fiford,.fifowr(fifowr,

.nfull(nfull,.nempty(nempty,

.address(address,.sram_data(sram_data,

.rd(rd,.wr(wr,

.clk(clk,.rst(rst

;

sramm1(.Address(address,

.Data(sram_data,

.SRG(rd,//SRAM读使能

.SRE(1'b0,//SRAM片选,低有效

.SRW(wr;//SRAM写使能

taskwrite_fifo;

input[7:

0]data;

295

begin

in_data=data;

#50fifowr=0;//往SRAM中写数

#200fifowr=1;

#50;

end

endtask

taskread_fifo_compare;

input[7:

0]data;

begin

#50fiford=0;//从SRAM中读数

#200fiford=1;

if(out_data!

=data

$display($time,"Error:

Dataretrieved(%hnotmatchtheonestored(%h.\n",out_data,data;

#50;

end

endtask

taskreset_fifo;

begin

#40rst=0;

#40rst=1;

end

endtask

endmodule

4FIFO接口的参考设计

FIFO接口的实现有多种方案,下面给出的参考设计只是其中一种。

希望同学们在完成自己的设计后,和参考设计做一下比较。

`defineSRAM_SIZE8//为减小对FIFO控制器的测试工作量,置SRAM空间为8Byte`timescale1ns/1ns

modulefifo_interface(

in_data,//对用户的输入数据总线

out_data,//对用户的输出数据总线,

fiford,//FIFO读控制信号,低电平有效

fifowr,//FIFO写控制信号,低电平有效

nfull,

296

nempty,

address,//到SRAM的地址总线

sram_data,//到SRAM的双向数据总线

rd,//SRAM读使能,低电平有效

wr,//SRAM写使能,低电平有效

clk,//系统时钟信号

rst;//全局复位信号,低电平有效

//来自用户的控制输入信号

inputfiford,fifowr,clk,rst;

//来自用户的数据信号

input[7:

0]in_data;

output[7:

0]out_data;

reg[7:

0]in_data_buf,//输入数据缓冲区

out_data_buf;//输出数据缓冲区

//输出到用户的状态指示信号

outputnfull,nempty;

regnfull,nempty;

//输出到SRAM的控制信号

outputrd,wr;

//到SRAM的双向数据总线

inout[7:

0]sram_data;

//输出到SRAM的地址总线

output[10:

0]address;

reg[10:

0]address;

//InternalRegister

reg[10:

0]fifo_wp,//FIFO写指针

fifo_rp;//FIFO读指针

reg[10:

0]fifo_wp_next,//fifo_wp的下一个值

fifo_rp_next;//fifo_rp的下一个值

regnear_full,near_empty;

297

reg[3:

0]state;//SRAM操作状态机寄存器

parameteridle='b0000,

read_ready='b0100,

read='b0101,

read_over='b0111,

write_ready='b1000,

write='b1001,

write_over='b1011;

//SRAM操作状态机

always@(posedgeclkornegedgerst

if(~rst

state<=idle;

else

case(state

idle:

//等待对FIFO的操作控制信号

if(fifowr==0&&nfull//用户发出写FIFO申请,且FIFO未满

state<=write_ready;

elseif(fiford==0&&nempty//用户发出读FIFO申请,且FIFO未空

state<=read_ready;

else//没用对FIFO操作的申请

state<=idle;

read_ready:

//建立SRAM操作所需地址和数据

state<=read;

read:

//等待用户结束当前读操作

if(fiford==1

state<=read_over;

else

state<=read;

read_over:

//继续给出SRAM地址以保证数据稳定state<=idle;

write_ready:

//建立SRAM操作所需地址和数据

state<=write;

write:

//等待用户结束当前写操作

if(fifowr==1

state<=write_over;

else

state<=write;

298

write_over:

//继续给出SRAM地址和写入数据以保证数据稳定

state<=idle;

default:

state<=idle;

endcase

//产生SRAM操作相关信号

assignrd=~state[2];//state为read_ready或read或read_over

assignwr=(state==write?

fifowr:

1'b1;

always@(posedgeclk

if(~fifowr

in_data_buf<=in_data;

assignsram_data=(state[3]?

//state为write_ready或write或write_over

in_data_buf:

8'hzz;

always@(stateorfifordorfifowrorfifo_wporfifo_rp

if(state[2]||~fiford

address=fifo_rp;

elseif(state[3]||~fifowr

address=fifo_wp;

else

address='bz;

//产生FIFO数据

assignout_data=(state[2]?

sram_data:

8'bz;

always@(posedgeclk

if(state==read

out_data_buf<=sram_data;

//计算FIFO读写指针

always@(posedgeclkornegedgerst

if(~rst

fifo_rp<=0;

elseif(state==read_over

fifo_rp<=fifo_rp_next;

always@(fifo_rp

299

if(fifo_rp==`SRAM_SIZE-1

fifo_rp_next=0;

else

fifo_rp_next=fifo_rp+1;

always@(posedgeclkornegedgerst

if(~rst

fifo_wp<=0;

elseif(state==write_over

fifo_wp<=fifo_wp_next;

always@(fifo_wp

if(fifo_wp==`SRAM_SIZE-1

fifo_wp_next=0;

else

fifo_wp_next=fifo_wp+1;

always@(posedgeclkornegedgerst

if(~rst

near_empty<=1'b0;

elseif(fifo_wp==fifo_rp_next

near_empty<=1'b1;

else

near_empty<=1'b0;

always@(posedgeclkornegedgerst

if(~rst

nempty<=1'b0;

elseif(near_empty&&state==read

nempty<=1'b0;

elseif(state==write

nempty<=1'b1;

always@(posedgeclkornegedgerst

if(~rst

near_full<=1'b0;

elseif(fifo_rp==fifo_wp_next

near_full<=1'b1;

else

near_full<=1'b0;

always@(posedgeclkornegedgerst

if(~rst

300

nfull<=1'b1;

elseif(near_full&&state==write

nfull<=1'b0;

elseif(state==read

nfull<=1'b1;

endmodule

301

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

当前位置:首页 > 自然科学 > 物理

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

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