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 

 

你可能感兴趣的:(设计)