module gfx_fifo #(parameter WIDTH=0, DEPTH=0) ( input logic clk, rst_n, input logic[WIDTH - 1:0] in, input logic in_valid, output logic in_ready, input logic out_ready, output logic out_valid, output logic[WIDTH - 1:0] out ); logic do_read, do_write, full_if_eq, in_stall, out_stall, may_read, may_write, read, read_ok, write; logic[WIDTH - 1:0] fifo[DEPTH], read_data, write_data; logic[$clog2(DEPTH) - 1:0] read_ptr, write_ptr; assign do_read = read && may_read; assign do_write = write && may_write; always_comb begin may_read = full_if_eq; may_write = !full_if_eq; if (read) may_write = 1; if (read_ptr != write_ptr) begin may_read = 1; may_write = 1; end end gfx_skid_flow in_flow ( .stall(in_stall), .out_ready(may_write), .out_valid(write), .* ); gfx_skid_flow out_flow ( .stall(out_stall), .in_ready(read), .in_valid(read_ok), .* ); gfx_skid_buf #(.WIDTH(WIDTH)) in_skid ( .out(write_data), .stall(in_stall), .* ); gfx_skid_buf #(.WIDTH(WIDTH)) out_skid ( .in(read_data), .stall(out_stall), .* ); always_ff @(posedge clk or negedge rst_n) if (!rst_n) begin read_ok <= 0; read_ptr <= 0; write_ptr <= 0; full_if_eq <= 0; end else begin if (!out_stall) read_ok <= read && may_read; if (do_read) read_ptr <= read_ptr + 1; if (do_write) write_ptr <= write_ptr + 1; if (do_read && !do_write) full_if_eq <= 0; else if (!do_read && do_write) full_if_eq <= 1; end always_ff @(posedge clk) begin if (!out_stall) read_data <= fifo[read_ptr]; if (may_write) fifo[write_ptr] <= write_data; end endmodule