Verilog code for asynchronous FIFO


Verilog code for asynchronous FIFO is given below. The module “a_fifo5” should be used for Modelsim (or any other HDL simulator) simulation. The module “fifo_top” is used to synthesize the design in Spartan 3 board. Before invoking this module in ISE you should add Digital Clock Manager (DCM) code to your project. This can be done using Xilinx ISE wizard.

//==================================================

//a_fifo5.v; verilog code for asynchronous FIFO

//This module describes FIFO

//===================================================

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

//=================================================


Related Articles

12 comments:

  1. Good stuff Murali!!
    I congratulate your efforts in writing the blog.I wish graduates will find this blog helpful for making their careers in this prospective and challenging field.

    In fact it is a good idea of sharing knowledge. Thank you:-)

    ReplyDelete
  2. thanks sharma....happy reading !

    ReplyDelete
  3. For a long time I am looking for Multi-Clock domain and CDC stuff.I haven't got an opportunity to work with these.Could ypu please provide some stuff on this. Theoritically to some extent I am clear but I want to see few examples also which I never find on Internet.

    ReplyDelete
  4. this is nice......
    but is there any verilog code for async fifo using SRAM(dual port SRAM). if not, will give me any idea about how to implement this?

    ReplyDelete
  5. Keep up the Good Job Murali...

    Regards,
    Sainath

    ReplyDelete
  6. good job dude...its rreally helpful......keep on addind such stuff..... :)

    ReplyDelete
  7. Hi,
    We are proud to inform you that we are one of the leading training centre for both VLSI and Embedded System Design at Chennai.

    Regards,
    siva
    vlsiva@yahoo.co.in
    9003241032

    ReplyDelete
  8. Hi Murali,
    I dont get this. In you implementation, How come you are not using synchronizers to in the to synchronize read and write pointers in the two clock domains?

    Please explain.

    Thanks
    Tariq

    ReplyDelete
  9. hi everyone
    can any one tell me please
    where is the code for DCM (digital clock manager)?

    ReplyDelete
  10. Really awesome blog

    Thank you soooooooooooooo much

    ReplyDelete
  11. This code looks completely wrong to me. You are randomly mixing signals from different clock domains with no synchronization. The full condition is wrong.

    ReplyDelete
  12. ptr_diff logic you missed it. it is no the complete code. please correct the code.

    ReplyDelete

Your Comments... (comments are moderated)