CODE:
module a_fifo5(d_out,f_full_flag,f_half_full_flag,f_empty_flag,
f_almost_full_flag,f_almost_empty_flag,d_in,r_en,w_en,r_clk,w_clk,reset);
parameter f_width=8; //FIFO width
parameter f_depth=16; //FIFO depth
parameter f_ptr_width=4; //because depth =16;
parameter f_half_full_value=8;
parameter f_almost_full_value=14;
parameter f_almost_empty_value=2;
output [f_width-1:0] d_out; reg [f_width-1:0] d_out; //outputs
output f_full_flag,f_half_full_flag,f_almost_full_flag,f_empty_flag,f_almost_empty_flag;
input [f_width-1:0] d_in;
input r_en,w_en,r_clk,w_clk;
input reset;
//internal registers,wires
wire [f_ptr_width-1:0] r_ptr,w_ptr;
reg r_next_en,w_next_en;
reg [f_ptr_width-1:0] ptr_diff;
reg [f_width-1:0] f_memory[f_depth-1:0];
assign f_full_flag=(ptr_diff==(f_depth-1)); //assign FIFO status
assign f_empty_flag=(ptr_diff==0);
assign f_half_full_flag=(ptr_diff==f_half_full_value);
assign f_almost_full_flag=(ptr_diff==f_almost_full_value);
assign f_almost_empty_flag=(ptr_diff==f_almost_empty_value);
//---------------------------------------------------------
always @(posedge w_clk) //write to memory
begin
if(w_en) begin
if(!f_full_flag)
f_memory[w_ptr]<=d_in; end
end
//---------------------------------------------------------
always @(posedge r_clk) //read from memory
begin
if(reset)
d_out<=0; //f_memory[r_ptr];
else if(r_en) begin
if(!f_empty_flag)
d_out<=f_memory[r_ptr]; end
else d_out<=0;
end
//---------------------------------------------------------
always @(*) //ptr_diff changes as read or write clock change
begin
if(w_ptr>r_ptr)
ptr_diff<=w_ptr-r_ptr;
else if(w_ptr
begin
ptr_diff<=((f_depth-r_ptr)+w_ptr);
end
else ptr_diff<=0;
end
//---------------------------------------------------------
always @(*) //after empty flag activated fifo read counter should not increment;
begin if(r_en && (!f_empty_flag))
r_next_en=1;
else r_next_en=0;
end
//--------------------------------------------------------
always @(*) //after full flag activated fifo write counter should not increment;
begin if(w_en && (!f_full_flag))
w_next_en=1;
else w_next_en=0;
end
//---------------------------------------------------------
b_counter //instantiate address counters r_b_counter(.c_out(r_ptr),.c_reset(reset),.c_clk(r_clk),.en(r_next_en));
b_counter w_b_counter(.c_out(w_ptr),.c_reset(reset),.c_clk(w_clk),.en(w_next_en));
endmodule
//==============================================================
//b_counter.v; 4 bit asynchronous binary up counter
//==============================================================
module b_counter(c_out,c_reset,c_clk,en);
parameter c_width=4; //counter width
output [c_width-1:0] c_out; reg [c_width-1:0] c_out;
input c_reset,c_clk,en;
always @(posedge c_clk or posedge c_reset)
if (c_reset)
c_out <= 0;
else if(en)
c_out <= c_out + 1;
endmodule
//===========================================================
//===========================================================
//fifo_top.v; top level verilog code of FIFO
//To be used with Xilinx ISE-simulation and synthesis
//For functional simulation this module is not necessary
//============================================================
module fifo_top(x,y,z,d_out,f_full_flag,f_half_full_flag,f_empty_flag,
f_almost_full_flag,f_almost_empty_flag,d_in,r_en,w_en,CLKIN_IN,RST_IN,reset);
parameter f_width=8;
parameter f_depth=16;
parameter f_ptr_width=4;
parameter f_half_full_value=8;
parameter f_almost_full_value=14;
parameter f_almost_empty_value=2;
output [f_width-1:0] d_out; //reg [f_width-1:0] d_out; //outputs
output f_full_flag,f_half_full_flag,f_almost_full_flag,f_empty_flag,f_almost_empty_flag;
output x,y,z;
input [f_width-1:0] d_in;
input r_en,w_en,CLKIN_IN,RST_IN;
input reset;
a_fifo5 a_fifo55(d_out,f_full_flag,f_half_full_flag,f_empty_flag,
f_almost_full_flag,f_almost_empty_flag,d_in,r_en,w_en,CLK0_OUT,CLKDV_OUT,reset); //instantiate fifo
dcm_fifo dcm_fifo1(CLKIN_IN,RST_IN,CLKDV_OUT,CLKFX_OUT,CLKIN_IBUFG_OUT,CLK0_OUT, LOCKED_OUT); //instantiate DCM
assign x=CLKIN_IBUFG_OUT; //simply to avoid error
assign y=LOCKED_OUT;
assign z=CLKFX_OUT;
endmodule