data/full_repos/permissive/463204869/units/async_fifo/source/rtl/verilog/async_fifo_rptr_empty_ctrl.v
data/verilator_xmls/04fbf18f-04f2-4f10-a7b7-39ea301483cf.xml
module async_fifo_rptr_empty_ctrl #(
    parameter ADDR_WIDTH          = 4,
    parameter ALMOST_EMPTY_BUFFER = 2
)(
    input  wire                 rclk_i,
    input  wire                 rresetn_i,
    input  wire                 rd_en_i,
    input  wire  [ADDR_WIDTH:0] rsync_wr_ptr_i,
    output wire                 ralmost_empty_o,
    output wire                 rempty_o,
    output reg   [ADDR_WIDTH:0] rd_ptr_o
);



    localparam ALMOST_EMPTY_THRESHOLD = ALMOST_EMPTY_BUFFER[ADDR_WIDTH:0] + {{(ADDR_WIDTH){1'b0}}, 1'b1};

    reg [ADDR_WIDTH:0] rd_ptr_bin;
    reg [ADDR_WIDTH:0] next_rd_ptr;
    reg [ADDR_WIDTH:0] next_rd_ptr_bin;
    reg [ADDR_WIDTH:0] rsync_wr_ptr_bin;

    wire do_read;
    wire [ADDR_WIDTH:0] wr_rd_diff = rsync_wr_ptr_bin - rd_ptr_bin;

    integer i;


    always @(posedge rclk_i or negedge rresetn_i) begin
        if (rresetn_i == 1'b0) begin
            rd_ptr_o <= 0;
        end else begin
            rd_ptr_o <= next_rd_ptr;
        end
    end


    assign do_read = rd_en_i & (~rempty_o);

    always @(rd_ptr_o or do_read or rsync_wr_ptr_i) begin

        for (i=0; i<=ADDR_WIDTH; i=i+1) begin
            rd_ptr_bin[i] = ^(rd_ptr_o>>i);
            rsync_wr_ptr_bin[i] = ^(rsync_wr_ptr_i>>i);
        end


        next_rd_ptr_bin = rd_ptr_bin + {{(ADDR_WIDTH){1'b0}}, do_read};


        next_rd_ptr = (next_rd_ptr_bin>>1) ^ next_rd_ptr_bin;
    end



    assign rempty_o = (rd_ptr_o == rsync_wr_ptr_i) ? 1'b1 : 1'b0;


    assign ralmost_empty_o = wr_rd_diff < ALMOST_EMPTY_THRESHOLD;

endmodule
module async_fifo_rptr_empty_ctrl #(
    parameter ADDR_WIDTH          = 4,
    parameter ALMOST_EMPTY_BUFFER = 2
)(
    input  wire                 rclk_i,
    input  wire                 rresetn_i,
    input  wire                 rd_en_i,
    input  wire  [ADDR_WIDTH:0] rsync_wr_ptr_i,
    output wire                 ralmost_empty_o,
    output wire                 rempty_o,
    output reg   [ADDR_WIDTH:0] rd_ptr_o
);




    localparam ALMOST_EMPTY_THRESHOLD = ALMOST_EMPTY_BUFFER[ADDR_WIDTH:0] + {{(ADDR_WIDTH){1'b0}}, 1'b1};

    reg [ADDR_WIDTH:0] rd_ptr_bin;
    reg [ADDR_WIDTH:0] next_rd_ptr;
    reg [ADDR_WIDTH:0] next_rd_ptr_bin;
    reg [ADDR_WIDTH:0] rsync_wr_ptr_bin;

    wire do_read;
    wire [ADDR_WIDTH:0] wr_rd_diff = rsync_wr_ptr_bin - rd_ptr_bin;

    integer i;


    always @(posedge rclk_i or negedge rresetn_i) begin
        if (rresetn_i == 1'b0) begin
            rd_ptr_o <= 0;
        end else begin
            rd_ptr_o <= next_rd_ptr;
        end
    end


    assign do_read = rd_en_i & (~rempty_o);

    always @(rd_ptr_o or do_read or rsync_wr_ptr_i) begin

        for (i=0; i<=ADDR_WIDTH; i=i+1) begin
            rd_ptr_bin[i] = ^(rd_ptr_o>>i);
            rsync_wr_ptr_bin[i] = ^(rsync_wr_ptr_i>>i);
        end


        next_rd_ptr_bin = rd_ptr_bin + {{(ADDR_WIDTH){1'b0}}, do_read};


        next_rd_ptr = (next_rd_ptr_bin>>1) ^ next_rd_ptr_bin;
    end



    assign rempty_o = (rd_ptr_o == rsync_wr_ptr_i) ? 1'b1 : 1'b0;


    assign ralmost_empty_o = wr_rd_diff < ALMOST_EMPTY_THRESHOLD;

endmodule