同步FIFO代码与测试


FIFO即Firdst In First Out,是一种先进先出数据存储、缓冲器,我们知道一般的存储器是用外部的读写地址来进行读写,而 FIFO这种存储器结构并不需要外部的读写地址而是通过自动地加一操作来控制读写,这也就决定了FIFO只能顺序的读写数据
同步FIFO,读和写应用在同一个时钟。它的作用一般是做交互数据的一个缓存,也就是说它的主要作用就是一个buffer。

1.FIFO的主要参数

参数符号含义
宽度FIFO_data_sizeFIFO存储的数据宽度
深度FIFO_addr_size地址的大小,也就是能存多少个数据
满标志full当FIFO中的数据满了以后将不能进行数据的写入
空标志empty当FIFO为空的时候将不能进行数据的读出
写地址w_addr由自动加一生成,将数据写入该地址
读地址r_addr由自动加一生成,将该地址上的数据读出

同步fifo判断空满标志
时钟 ,clk, rst, 读写应用同一个时钟
计数器 , count , 用计数器来进行空满标志的判断

2.同步FIFO的设计

FIFO主要的设计难点在于如何产生空满标志,在同步FIFO中,我们定义一个计数器,当计数器的值为0时,产生空标志,当计数器的值为FIFO的深度时,产生满标志。基于以上的思想,可以将同步FIFO划分以下几个模块:write、read、count、RAM。

2.1模块划分

同步FIFO主要划分为四个模块,RAM模块是用来读取和写入数据;write模块是用来产生写地址;read模块是用来产生读地址;count模块是用来产生空满标志符,每写入一位数,count加一,每读出一位数,count减一。
在这里插入图片描述

2.2同步FIFO代码

w_en为1并且fifo不满时,写入数据,w_addr加1
r_en为1并且fifo不空时,读出数据,r_addr加1
计数器,为写时,count++,为读时,count --;

module FIFO_sync(
				clk,
				rst,
				w_en,
				r_en,
				data_in,
				data_out,
				count,
				full,
				empty);
	parameter FIFO_data_size=3,
			  FIFO_addr_size=2;
	input clk,rst;
    input w_en,r_en;
    input[FIFO_data_size-1:0] data_in;
    output[FIFO_data_size-1:0] data_out;
    output full,empty;
    output[FIFO_addr_size:0]count;
	
	reg [FIFO_data_size-1:0] data_out;
    reg [FIFO_addr_size:0]count;
    reg [FIFO_addr_size-1:0]w_addr,r_addr;
    reg [FIFO_data_size-1:0]mem[{FIFO_addr_size{1'b1}}:0];
	integer i;
	
	//memory的初始化以及写操作
	always@(posedge clk or negedge rst) begin
		if(!rst) begin
			w_addr <= 0;
			for(i=0;i<={FIFO_addr_size{1'b1}};i=i+1)
				mem[i] <= {FIFO_data_size{1'b0}};
		end
		else if (w_en & (~full)) begin
			mem[w_addr] <= data_in;
			w_addr <= w_addr+1;
		end		
	end
	
	//读操作
	always@(posedge clk or negedge rst) begin
		if (!rst)begin
			data_out <= {(FIFO_data_size-1){1'b0}};
			r_addr <= 0;
		end		
		else if (r_en&(~empty)) begin
			data_out <= mem[r_addr];
			r_addr <= r_addr+1;
		end
	end
	
	//count产生空满标志符
	always@(posedge clk or negedge rst) begin
		if(!rst) begin
			count <= 0;
		end
		else if (((w_en)&(~full)) & (~((r_en)&(~empty)))) begin
			count <= count+1;
		end
		else if (((r_en)&(~empty))&(~((w_en)&(~full)))) begin
			count <= count-1;
		end		
	end
	
	assign empty = (count==0)? 1:0;
	assign full= (count=={FIFO_addr_size{1'b1}}+1)? 1:0;
	
endmodule

测试代码

`timescale 1ns/1ns
module FIFO_sync_top;
	reg clk,rst,w_en,r_en;
	reg[2:0] data_in;
	
	wire[2:0] count;
	wire[2:0] data_out;
	
	reg[2:0] i;
	
	initial begin
	  clk=0;
      rst=1;
      data_in=3'b000;
      w_en=0;
      r_en=0;
      #25
      rst=0;
      #50
      rst=1;
      #25
      w_en=1;
      #100
      r_en=1;
      #100
      w_en=0;
      r_en=0;
      #100
      w_en=1;
      #400
      r_en=1;
	end
	
	initial begin
		for(i=0;i<=50; i=i+1)
			#100 data_in = i;
	end
	
	always
		#50 clk = ~clk;
	//参数化传递,宽度为3,深度为2
	FIFO_sync  #(.FIFO_data_size(3),.FIFO_addr_size(2)) ut(
.clk(clk),
.rst(rst),
.data_in(data_in),
.data_out(data_out),
.w_en(w_en),
.r_en(r_en),
.count(count),
.full(full),
.empty(empty));
endmodule

在这里插入图片描述

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值