基于Verilog利用SRAM设计一个FIFO

更新时间:2023-10-08 08:17:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

基于Verilog利用SRAM设计一个FIFO

专 业:班 级:学 号:姓 名:

电子信息工程 电子092

2012年 11 月23 日

1

一、设计要求:

本练习要求同学设计的FIFO为同步FIFO,即对FIFO的读/写使用同一个时钟。该FIFO 应当提供用户读使能(fiford)和写使能(fifowr)输入控制信号,并输出指示FIFO状态的

非空(nempty)和非满(nfull)信号,FIFO的输入、输出数据使用各自的数据总线:in_data 和out_data。下图为FIFO接口示意图。

二、FIFO接口的设计思路

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工作状态的示意。

在得到nfull和nempty信号后,就需要考虑如何应用这两个信号来控制对FIFO的读

写,使得FIFO在被写满后不能再写入,从而防止覆盖原有数据,并且在被读空后也不能再 进行读操作,防止读取无效数据。

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

2

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

即写SRAM时,先建立地址和数据,然后置写使能信号WR有效,在WR保持有效一定时 间后,先复位WR,然后释放地址和数据总线。而读取SRAM时,则先建立地址,然后置 读使能RD有效,在RD维持有效一定时间后,复位RD,同时读取数据总线上的值,然后 再释放地址总线。在进行FIFO操作时,用户一般希望除了没有地址外,其它三个信号的时 序关系能保持不变。请同学们在设计FIFO控制信号与SRAM控制信号间逻辑关系时注意这 一点。

三、FIFO接口的测试

在完成一个设计后,需要进行测试以确认设计的正确性和完整性。而要进行测试,就需 要编写测试激励和结果检查程序,即测试平台(testbench)。在某些情况下,如果设计的接 口能够预先确定,测试平台的编写也可以在设计完成之前就进行,这样做的好处是在设计测 试平台的同时也在更进一步深入了解设计要求,有助于理清设计思路,及时发现设计方案的 错误。

编写测试激励时,除了注意对实际可能存在的各种情况的覆盖外,还要有意针对非正常 情况下的操作进行测试。在本练习中,就应当进行在FIFO读空后继续读取、FIFO写满后 继续写入、FIFO复位后马上读取等操作的测试。

测试激励中通常会有一些复杂操作需要反复进行,如本练习中对FIFO的读写操作。这 时可以将这些复杂操作纳入到几个task 中,即减小了激励编写的工作量,也使得程序的可 读性更好。

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

`define FIFO_SIZE 8

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

module t;

reg [7:0] in_data; //FIFO数据总线 reg fiford,fifowr; //FIFO控制信号 wire[7:0] out_data;

wire nfull, nempty; //FIFO状态信号 reg clk,rst;

wire[7:0] sram_data; //SRAM数据总线 wire[10:0] address; //SRAM的地址总线 wire rd,wr; //SRAM读写控制信号 reg [7:0] data_buf[`FIFO_SIZE:0]; //数据缓存,用于结果检查

3

integer index; //用于读写data_buf的指针

//系统时钟

initial clk=0;

always #25 clk=~clk; //测试激励序列 initial begin fiford=1; fifowr=1; rst=1; #40 rst=0;

#42 rst=1;

if (nempty) $display($time,\, nempty should be low.\\n\ index = 0;

repeat(`FIFO_SIZE) begin data_buf[index]=$random; write_fifo(data_buf[index]); index = index + 1; end

if (nfull) $display($time,\ repeat(2) write_fifo($random);

#200 //连续读FIFO

index=0;

read_fifo_compare(data_buf[index]);

if (~nfull) $display($time,\ repeat(`FIFO_SIZE-1) begin index = index + 1;

read_fifo_compare(data_buf[index]); end

if (nempty) $display($time,\, nempty should be low.\\n\ repeat(2) read_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_interface fifo_interface(

.in_data(in_data),.out_data(out_data),

//连续写FIFO 4

.fiford(fiford),.fifowr(fifowr), .nfull(nfull),.nempty(nempty),

.address(address),.sram_data(sram_data), .rd(rd),.wr(wr), .clk(clk),.rst(rst) );

sram m1( .Address(address),

.Data(sram_data),

.SRG(rd), //SRAM 读使能 .SRE(1'b0), //SRAM 片选,低有效 .SRW(wr)); //SRAM写使能 task write_fifo; input [7:0] data; begin

in_data=data;

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

endtask

task read_fifo_compare; input [7:0] data;

begin

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

if (out_data != data)

$display($time,\ out_data, data); #50; end

endtask

task reset_fifo; begin

#40 rst=0; #40 rst=1; end endtask endmodule

4) FIFO接口的参考设计

FIFO接口的实现有多种方案,下面给出的参考设计只是其中一种。希望同学们在完成自己的设计后,和参考设计做一下比较。

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

module fifo_interface(

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

5

本文来源:https://www.bwwdw.com/article/i6ud.html

Top