//=============================================================================
// File Name    : video_crop_filter.v
// Description  : Crops SLVS-EC sensor output to desired resolution (4K ref)
//                Removes OB lines (top) and blanking (bottom)
// Author       : India Solutions Team
//=============================================================================

module video_crop_filter #(
    // SLVS-EC parameters
    parameter g_LANE_WIDTH     = 8,       // Number of lanes
    parameter g_DATAWIDTH      = 8,       // Bits per pixel

    // Sensor input resolution
    parameter g_SENSOR_H_RES   = 8008,    // Sensor horizontal pixels
    parameter g_SENSOR_V_RES   = 2200,    // Sensor vertical lines

    // Desired output resolution (4K reference)
    parameter g_OUTPUT_H_RES   = 3840,    // Output horizontal (4K)
    parameter g_OUTPUT_V_RES   = 2160,    // Output vertical (4K)

    // Vertical crop offsets
    parameter g_V_SKIP_TOP     = 64       // OB lines to skip at top
)(
    input                                          clk_i,
    input                                          reset_n_i,

    // Input from SLVS_EC_RX (IMX_TOP)
    input                                          frame_valid_i,
    input                                          line_valid_i,
    input  [4*g_LANE_WIDTH*g_DATAWIDTH-1:0]        pixel_data_i,

    // Output to DDR_Write
    output                                         frame_valid_o,
    output reg                                     line_valid_o,
    output reg [4*g_LANE_WIDTH*g_DATAWIDTH-1:0]    pixel_data_o
);

//=============================================================================
// Local parameters
//=============================================================================
localparam V_VALID_START    = g_V_SKIP_TOP;
localparam V_VALID_END      = g_V_SKIP_TOP + g_OUTPUT_V_RES;
localparam PIXEL_BUS_WIDTH  = 4 * g_LANE_WIDTH * g_DATAWIDTH;

//=============================================================================
// Signal declarations
//=============================================================================
reg [12:0] line_count;
reg        line_valid_d;
reg        frame_valid_d;

wire       line_falling_edge;
wire       frame_rising_edge;
wire       v_in_valid_region;

//=============================================================================
// Edge detection
//=============================================================================
always @(posedge clk_i or negedge reset_n_i) begin
    if (!reset_n_i) begin
        line_valid_d  <= 1'b0;
        frame_valid_d <= 1'b0;
    end else begin
        line_valid_d  <= line_valid_i;
        frame_valid_d <= frame_valid_i;
    end
end

assign line_falling_edge = ~line_valid_i & line_valid_d;
assign frame_rising_edge = frame_valid_i & ~frame_valid_d;

//=============================================================================
// Line counter (vertical position)
//=============================================================================
always @(posedge clk_i or negedge reset_n_i) begin
    if (!reset_n_i) begin
        line_count <= 13'd0;
    end else if (frame_rising_edge) begin
        line_count <= 13'd0;
    end else if (line_falling_edge) begin
        line_count <= line_count + 1'b1;
    end
end

//=============================================================================
// Valid region detection
//=============================================================================
assign v_in_valid_region = (line_count >= V_VALID_START) &&
                           (line_count < V_VALID_END);

//=============================================================================
// Output assignments
//=============================================================================
assign frame_valid_o = frame_valid_i;

always @(posedge clk_i or negedge reset_n_i) begin
    if (!reset_n_i) begin
        line_valid_o  <= 1'b0;
        pixel_data_o  <= {PIXEL_BUS_WIDTH{1'b0}};
    end else begin
        line_valid_o  <= line_valid_i & v_in_valid_region;
        pixel_data_o  <= pixel_data_i;
    end
end

endmodule
