module elastic_buffer #(
  parameter WIDTH = 32,
  parameter SIZE = 256
) (
  input clk,
  input reset,

  input [WIDTH-1:0] wr_data,

  output reg [WIDTH-1:0] rd_data,

  input ready_n,
  input do_release_n
);

localparam ADDR_WIDTH = SIZE > 128 ? 7 :
  SIZE > 64 ? 6 :
  SIZE > 32 ? 5 :
  SIZE > 16 ? 4 :
  SIZE > 8 ? 3 :
  SIZE > 4 ? 2 :
  SIZE > 2 ? 1 : 0;

reg [ADDR_WIDTH:0] wr_addr = 'h00;
reg [ADDR_WIDTH:0] rd_addr = 'h00;
reg [WIDTH-1:0] mem[0:SIZE - 1];

always @(posedge clk) begin
  if (ready_n == 1'b1) begin
    wr_addr <= 'h00;
  end else begin
    mem[wr_addr] <= wr_data;
    wr_addr <= wr_addr + 1'b1;
  end
end

always @(posedge clk) begin
  if (do_release_n == 1'b1) begin
    rd_addr <= 'h00;
  end else begin
    rd_addr <= rd_addr + 1'b1;
    rd_data <= mem[rd_addr];
  end
end

endmodule