`timescale 1ns/1ps

module RGB_to_RAM #(
    parameter COLOR_DEPTH = 8,
    parameter FIFO_SIZE = 128
) (
    input clk,
    input reset,

    // 数据输入
    output reg in_que,
    input in_en,
    input [3 * COLOR_DEPTH - 1:0] data_in,

    // 写入SRAM
    input write_que,
    output write_en,
    output [15:0] data_write
);
    // 状态机
    localparam READ_DATA = 0;
    localparam SEND_R = 1;
    localparam SEND_GB = 2;

    reg [2:0] state, nextState;
    reg [3 * COLOR_DEPTH - 1:0] data_cache;
    reg [15:0] fifo_data;
    wire fifo_full, fifo_empty;

    async_fifo #(
        .DSIZE(16),
        .ASIZE(FIFO_SIZE)
    ) fifo_image (
        .wclk(clk),
        .wrst_n(reset),
        .rclk(clk),
        .rrst_n(reset),

        .winc(in_en),
        .wdata(fifo_data),
        .wfull(fifo_full),
        /* verilator lint_off PINCONNECTEMPTY */
        .awfull(),

        .rinc(write_en),
        .rdata(data_write),
        .rempty(fifo_empty),
        /* verilator lint_off PINCONNECTEMPTY */
        .arempty()
    );
    
    // 当有数据请求且FIFO不为空时，输出数据
    assign write_en = (write_que && !fifo_empty) ? 1 : 0;

    always @(posedge clk or posedge reset) begin
        if (reset)
            state <= READ_DATA;
        else
            state <= nextState;
    end 

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            fifo_data <= 0;
            data_cache <= 0;
        end
        else begin
            case (state)
            // 读取数据
            READ_DATA: begin
                in_que <= 1;
                if (in_en) begin
                    data_cache <= data_in;
                    nextState <= SEND_R;
                end
            end

            SEND_R: begin
                in_que <= 0;
                fifo_data <= {8'b0, data_cache[3 * COLOR_DEPTH - 1:16]};
                nextState <= SEND_GB;
            end

            SEND_GB: begin
                fifo_data <= data_cache[15:0];
                nextState <= READ_DATA;
            end
            endcase
        end
    end
    
endmodule
