_TOP_MENU

Oct 17, 2021

Synchronous FIFO RTL code

During many interviews this question is common to ask to design a FIFO with input clock frequency and output clock frequency. 

Here is the design for synchronous FIFO.


Here is the source code of sync fifo.  

//// -------------------- start -----

module sync_fifo #(parameter DATA_WIDTH ,
                   parameter ADDR_WIDTH,
                   parameter RAM_DEPTH ) (
input clk,
input rst_n,

input  [DATA_WIDTH-1:0] wr_data,
output [DATA_WIDTH-1:0] rd_data,

input wr_en,
input rd_en,

output fifo_empty,
output reg fifo_full

);

reg [ADDR_WIDTH-1:0] wr_pointer;
reg [ADDR_WIDTH-1:0] rd_pointer;
reg [RAM_DEPTH:0] fifo_pointer;

// Read pointer 
always @ (posedge clk or negedge rst_n ) begin 
if ( !rst_n) 
  rd_pointer <= 'b0; 
else if (rd_en ) 
  rd_pointer <= rd_pointer + 1'b0; 
end 

// Write pointer 
always @ (posedge clk or negedge rst_n ) begin 
if ( !rst_n) 
  wr_pointer <= 'b0; 
else if (rd_en ) 
  wr_pointer <= wr_pointer + 1'b0; 
end 

// Fifo empty and Fifo Full signal logic 

always @(posedge clk or negedge rst_n) begin 
if (!rst_n)
 fifo_pointer <= 'b0;
else if (wr_en && !rd_en  && !fifo_full) 
 fifo_pointer <= fifo_pointer + 1'b1; 
else if (!wr_en && rd_en  && !fifo_empty) 
 fifo_pointer <= fifo_pointer - 1'b1 ; 
end 


always @(*) begin
if (fifo_pointer == RAM_DEPTH) 
  fifo_full = 1'b1;
else 
  fifo_full = 1'b0; 
end 
  
assign fifo_empty = (fifo_pointer == 'b0);

dual_port_RAM  #(.DATA_WIDTH(DATA_WIDTH) , 
                           .ADDR_WIDTH(ADDR_WIDTH) ,
                           .RAM_DEPTH (RAM_DEPTH))
                           memory_ins ( .clk          (clk) , 
                           .rstn         (rst_n),
                           .wr_address   (wr_pointer),
                           .rd_address   (rd_pointer),
                           .write_en     (wr_en),
                           .read_en      (rd_en),
                           .read_data    (rd_data),
                           .write_data   (wr_data) 
                         );

endmodule 


module dual_port_RAM # (parameter DATA_WIDTH ,
                        parameter ADDR_WIDTH ,
                        parameter RAM_DEPTH ) (
input clk,   
input rstn,
input [ADDR_WIDTH-1:0] wr_address ,
input [ADDR_WIDTH-1:0] rd_address ,
input write_en    ,
input read_en     ,
output reg [DATA_WIDTH-1:0] read_data  , 
input [DATA_WIDTH-1:0] write_data 
);

reg [DATA_WIDTH-1:0] mem [RAM_DEPTH-1:0];
always @(posedge clk ) begin 
if (write_en)
   mem[wr_address] <= write_data ;
end 

always @(posedge clk) begin 
if (read_en )
 read_data <= mem[rd_address];
end  

endmodule 

            
Below is the output after compiling , elaborating and simulating the source code of synchronous fifo.


 
If you want to download the code with testbench (basic testbench ) , click below link. 

RTL code - 

Testbench ->

tb.v


Related Topic: 

Synchronous FIFO Interview Question

Feedback/Comments are most welcome.

No comments:

Post a Comment