module crop #(
    parameter OFFSET_X = 8,
    parameter OFFSET_Y = 4,
    parameter OUT_WIDTH = 640,
    parameter OUT_HEIGHT = 480,
    parameter COLOR_DEPTH = 8
) (
    input clk,
    input reset,

    input in_en,
    output reg in_que,
    input [3 * COLOR_DEPTH - 1:0] data_in,

    output reg out_en,
    output reg [3 * COLOR_DEPTH - 1:0] data_out
);
    localparam READ_DATA = 0;
    localparam HANDLE_DATA = 1;
    localparam SEND_DATA = 2;

    reg [1:0] state, nextState;
    reg [11:0] cnt_x, cnt_y;
    reg [3 * COLOR_DEPTH - 1:0] data;

    // 状态切换
    always @(posedge clk or posedge reset) begin
        if (reset)
            state <= READ_DATA;
        else
            state <= nextState;
    end 

    // 下一状态更新
    always @(*) begin
        case (state)
            READ_DATA:      nextState = (in_que && in_en) ? HANDLE_DATA : READ_DATA; 
            HANDLE_DATA:    nextState = SEND_DATA;
            SEND_DATA:      nextState = READ_DATA;
        endcase
    end

    always @(posedge clk or posedge reset) begin
        if (reset) begin
            cnt_x <= 0;
            cnt_y <= 0;
            data <= 0;
        end
        else begin
            case (state)
                READ_DATA: begin
                    in_que <= 1;
                    
                    if (in_en) begin
                        data <= data_in;
                        in_que <= 0;
                    end
                end

                HANDLE_DATA: begin
                    if (OFFSET_Y <= cnt_y && cnt_y < (OFFSET_Y + OUT_HEIGHT)) begin
                        if (OFFSET_X <= cnt_x && cnt_x < (OFFSET_X + OUT_WIDTH)) begin
                            out_en <= 1;
                        end
                    end

                    if (cnt_x >= (OFFSET_X + OUT_WIDTH)) begin
                        cnt_x <= 0;
                        if (cnt_y >= (OFFSET_Y + OUT_HEIGHT)) begin
                            cnt_y <= 0;
                        end
                        else begin
                            cnt_y <= cnt_y + 1;
                        end
                    end
                    else begin
                        cnt_x <= cnt_x + 1;
                    end
                end

                SEND_DATA: begin
                    data_out <= data;
                    out_en <= 0;
                end
                
            endcase
        end
    end
    
endmodule
