fifo设计

http://www.cnblogs.com/qiweiwang/archive/2011/04/09/2010591.html

同步fifo---基于循环队列的方式

module fifo
#(
	parameter 	B=8,//存储数据宽度,一个数据有B位
					W=3//地址空间位数,可存储2^W个数据
)
(
	input clk,
	input rst_n,
	input rd,
	input wr,
	input [B-1:0]	w_data,
	output empty,
	output full,
	output reg [B-1:0] r_data
);

reg [B-1:0] array_reg[2**W-1:0];
reg [W-1:0] w_ptr_reg,w_ptr_next,w_ptr_succ;
reg [W-1:0] r_ptr_reg,r_ptr_next,r_ptr_succ;
reg full_reg,full_next,empty_reg,empty_next;
wire wr_en,rd_en;

assign wr_en =	wr & ~full_reg;
assign rd_en = rd & ~empty_reg;
assign full  = full_reg;
assign empty = empty_reg;

always @ (posedge clk)
begin
	if(wr_en)
		array_reg[w_ptr_reg] <= w_data;
	else if (rd_en)
		r_data <= array_reg[r_ptr_reg];
end

always @ (posedge clk ,negedge rst_n)
begin
	if(!rst_n)
		begin
			w_ptr_reg <= 1'b0;
			r_ptr_reg <= 1'b0;
			full_reg  <= 1'b0;
			empty_reg <= 1'b1;
		end
	else
		begin
			w_ptr_reg <= w_ptr_next;
			r_ptr_reg <= r_ptr_next;
			full_reg  <= full_next;
			empty_reg <= empty_next;
		end
end

always @ (*)
begin
	w_ptr_succ = w_ptr_reg + 1'b1;
	r_ptr_succ = r_ptr_reg + 1'b1;
	w_ptr_next = w_ptr_reg;
	r_ptr_next = r_ptr_reg;
	full_next  = full_reg;
	empty_next = empty_reg;
	case( {wr,rd} )
		2'b01:
			if(~empty_reg)
				begin
					r_ptr_next = r_ptr_succ;
					full_next  = 1'b0;
						if(r_ptr_succ==w_ptr_reg)
							empty_next = 1'b1;
				end
		2'b10:
			if(~full_reg)
				begin
					w_ptr_next = w_ptr_succ;
					empty_next = 1'b0;
						if(w_ptr_succ==r_ptr_reg)
							full_next = 1'b1;
				end
		2'b11:
			begin
				w_ptr_next = w_ptr_succ;
				r_ptr_next = r_ptr_succ;
			end
		default:;
	endcase
end

endmodule 

 

posted on 2011-09-09 16:24  齐威王  阅读(504)  评论(0编辑  收藏  举报

导航