Synchronous FIFO Design in Verilog Using Extended Pointer Technique

An alternative approach to generating full and empty flags in a synchronous FIFO involves extending the read and write pointers by one bit. This method eliminates the need for a separate data counter, relying instead on the pointer arithmetic to determine the FIFO status.

When both the extended read and write pointers are iedntical—including the most significant bit (MSB) and all lower bits—the FIFO contains no data, and the empty flag is asserted. Converse, when the MSBs of the extended pointers differ but the remaining lower bits match, the write pointer has wrapped around exactly one more time than the read pointer. This condition indicates that the FIFO is completely filled, asserting the full flag.

RTL Implementation

module s_fifo #(
    parameter W = 8,
    parameter D = 16,
    parameter A = 4
)(
    input  wire             clk,
    input  wire             rst_n,
    input  wire             push_req,
    input  wire [W-1:0]     push_data,
    input  wire             pop_req,
    output reg  [W-1:0]     pop_data,
    output wire             is_full,
    output wire             is_empty
);

reg [A:0] wr_ptr_ext, rd_ptr_ext;
wire [A-1:0] wr_idx = wr_ptr_ext[A-1:0];
wire [A-1:0] rd_idx = rd_ptr_ext[A-1:0];

reg [W-1:0] buffer [D-1:0];

wire push_active = push_req & ~is_full;
wire pop_active  = pop_req  & ~is_empty;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        wr_ptr_ext <= 0;
    end else if (push_active) begin
        buffer[wr_idx] <= push_data;
        wr_ptr_ext <= wr_ptr_ext + 1'b1;
    end
end

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        rd_ptr_ext <= 0;
        pop_data   <= 0;
    end else if (pop_active) begin
        pop_data   <= buffer[rd_idx];
        rd_ptr_ext <= rd_ptr_ext + 1'b1;
    end
end

assign is_empty = (rd_ptr_ext == wr_ptr_ext);
assign is_full  = (wr_ptr_ext[A] != rd_ptr_ext[A]) & 
                  (wr_ptr_ext[A-1:0] == rd_ptr_ext[A-1:0]);

endmodule

Verification Testbench

`timescale 1ns/1ps

module s_fifo_validator;

parameter W = 8, D = 16, A = 4, T = 10;

reg              clk, rst_n, push_req, pop_req;
reg    [W-1:0]   push_data;
wire              is_full, is_empty;
wire    [W-1:0]   pop_data;

s_fifo u_fifo (
    .clk        (clk),
    .rst_n      (rst_n),
    .push_req   (push_req),
    .push_data  (push_data),
    .pop_req    (pop_req),
    .pop_data   (pop_data),
    .is_full    (is_full),
    .is_empty   (is_empty)
);

initial begin
    rst_n = 0; clk = 0;
    #5 rst_n = 1;
end

always #T clk = ~clk;

initial begin
    push_req = 0; pop_req = 0; push_data = 0;
    #20;
    
    // Fill the FIFO buffer
    push_req = 1;
    repeat(D) begin
        push_data = push_data + 1;
        #(2*T);
    end
    push_req = 0;
    #(2*T);
    
    // Drain the FIFO buffer
    pop_req = 1;
    repeat(D) begin
        #(2*T);
    end
    pop_req = 0;
    #(2*T);
    
    $finish;
end

endmodule

Tags: Verilog RTL Design Synchronous FIFO Digital Logic Hardware Verification

Posted on Mon, 27 Jul 2026 16:24:18 +0000 by nikhar021