verilog实现FIFO

一、计数器
代码

module sync_fifo_cnt #(
	parameter DEPTH = 8,
	parameter WIDTH = 8
)(
	input wire 				clk,
	input wire 				rst_n,
	
	input wire 				i_wen,
	input wire [WIDTH-1:0] 	i_wdata,
	
	input wire 				i_ren,
	output reg [WIDTH-1:0]	o_rdata,
	
	output 	wire			o_empty,
	output 	wire			o_full,
	output  reg [$clog2(DEPTH):0] cnt
);

reg [$clog2(DEPTH)-1:0] w_addr;
reg [$clog2(DEPTH)-1:0] r_addr;


reg [WIDTH-1:0] fifo_buffer[DEPTH-1:0]; //鐢ㄤ簩缁存暟缁勫疄鐜癛AM
//counter

//read
always @(posedge clk or negedge rst_n)
begin
	if(rst_n == 1'b0)
		begin
			r_addr <= 0;
		end
	else if(i_ren && !o_empty)
		  begin
			r_addr  <= r_addr+1'b1;
			o_rdata <= fifo_buffer[r_addr];
		  end
end
//write
always @(posedge clk or negedge rst_n)
begin
	if(rst_n == 1'b0)
		begin
			w_addr <= 0;
		end
	else if(i_wen && !o_full)
			begin
			w_addr <= w_addr + 1'b1;
			fifo_buffer[w_addr] <= i_wdata;
			end
end




always @(posedge clk or negedge rst_n)
begin
	if(rst_n == 1'b0)
		begin
			cnt <= 0;
		end
	else if(i_wen && i_ren)
		  begin
			cnt <= cnt;
		  end
	else if(i_wen && !(cnt == DEPTH))
		  begin
			cnt <= cnt + 1'b1;
		  end
	else if(i_ren && !(cnt == 0))
		  begin
			cnt <= cnt - 1'b1;
		  end
	
end



assign o_empty = (cnt == 0)?1'b1:1'b0;
assign o_full  = (cnt == DEPTH)?1'b1:1'b0;

endmodule

测试

`timescale 1ns/1ns	//时间单位/精度
 
//------------<模块及端口声明>----------------------------------------
module tb_sync_fifo_cnt();
 
parameter   WIDTH = 8  ;			//FIFO位宽
parameter   DEPTH = 8 ;			//FIFO深度
 
reg									clk		;
reg									rst_n	;
reg		[WIDTH-1:0]			data_in	;
reg									rd_en	;
reg									wr_en	;
						
wire	[WIDTH-1:0]			data_out;	
wire								empty	;	
wire								full	;
wire	[$clog2(DEPTH) : 0]	fifo_cnt;
 
 
//------------<例化被测试模块>----------------------------------------
sync_fifo_cnt
#(
	.WIDTH	(WIDTH),			//FIFO位宽
    .DEPTH	(DEPTH)			//FIFO深度
)
sync_fifo_cnt_inst(
	.clk		(clk		),
	.rst_n		(rst_n		),
	.i_wdata	(data_in	),
	.i_ren		(rd_en		),
	.i_wen		(wr_en		),
                 
	.o_rdata	(data_out	),	
	.o_empty		(empty		),	
	.o_full		(full		),
	.cnt	(fifo_cnt	)			
);



//------------<设置初始测试条件>----------------------------------------
initial begin
	clk = 1'b0;							//初始时钟为0
	rst_n <= 1'b0;						//初始复位
	data_in <= 'd0;		
	wr_en <= 1'b0;		
	rd_en <= 1'b0;
//重复8次写操作,让FIFO写满 	
	repeat(8) begin		
		@(negedge clk)begin		
			rst_n <= 1'b1;				
			wr_en <= 1'b1;		
			data_in <= $random;			//生成8位随机数
		end
	end
//重复8次读操作,让FIFO读空	
	repeat(8) begin
		@(negedge clk)begin		
			wr_en <= 1'b0;
			rd_en <= 1'd1;
		end
	end
//重复4次写操作,写入4个随机数据	
	repeat(4) begin
		@(negedge clk)begin		
			wr_en <= 1'b1;
			data_in <= $random;	//生成8位随机数
			rd_en <= 1'b0;
		end
	end
//持续同时对FIFO读写,写入数据为随机数据	
	forever begin
		@(negedge clk)begin		
			wr_en <= 1'b1;
			data_in <= $random;	//生成8位随机数
			rd_en <= 1'b1;
		end
	end
end
//------------<设置时钟>----------------------------------------------
always #10 clk = ~clk;			//系统时钟周期20ns
endmodule


posted @ 2025-02-20 19:51  心随鸥鹭齐舒羽  阅读(31)  评论(0)    收藏  举报