module jelly_linear_interpolation_unit
        #(
            parameter   USER_WIDTH    = 1,
            parameter   RATE_WIDTH    = 4,
            parameter   COMPONENT_NUM = 3,
            parameter   DATA_WIDTH    = 8,
            parameter   DATA_SIGNED   = 1,
            parameter   COMPACT       = 0,
            parameter   BLENDING      = 0
        )
        (
            input   wire                                    reset,
            input   wire                                    clk,
            input   wire                                    cke,
            
            input   wire    [USER_WIDTH-1:0]                s_user,
            input   wire    [RATE_WIDTH-1:0]                s_rate,
            input   wire    [COMPONENT_NUM*DATA_WIDTH-1:0]  s_data0,
            input   wire    [COMPONENT_NUM*DATA_WIDTH-1:0]  s_data1,
            input   wire                                    s_valid,
            
            output  wire    [USER_WIDTH-1:0]                m_user,
            output  wire    [RATE_WIDTH-1:0]                m_rate,
            output  wire    [COMPONENT_NUM*DATA_WIDTH-1:0]  m_data0,
            output  wire    [COMPONENT_NUM*DATA_WIDTH-1:0]  m_data1,
            output  wire                                    m_valid
        );
    
    genvar      i;
    
    generate
    for ( i = 0; i < COMPONENT_NUM; i = i+1 ) begin : loop_data
        if ( DATA_SIGNED ) begin : blk_signed
            jelly_linear_interpolation_signed
                    #(
                        .DATA_WIDTH     (DATA_WIDTH),
                        .COMPACT        (COMPACT),
                        .BLENDING       (BLENDING)
                    )
                i_linear_interpolation_signed
                    (
                        .clk            (clk),
                        .cke            (cke),
                        
                        .s_sel          (s_rate[RATE_WIDTH-1]),
                        .s_data0        (s_data0[i*DATA_WIDTH +: DATA_WIDTH]),
                        .s_data1        (s_data1[i*DATA_WIDTH +: DATA_WIDTH]),
                        
                        .m_data0        (m_data0[i*DATA_WIDTH +: DATA_WIDTH]),
                        .m_data1        (m_data1[i*DATA_WIDTH +: DATA_WIDTH])
                    );
        end
        else begin  : blk_unsigned
            jelly_linear_interpolation_unsigned
                    #(
                        .DATA_WIDTH     (DATA_WIDTH),
                        .COMPACT        (COMPACT),
                        .BLENDING       (BLENDING)
                    )
                i_linear_interpolation_unsigned
                    (
                        .clk            (clk),
                        .cke            (cke),
                        
                        .s_sel          (s_rate[RATE_WIDTH-1]),
                        .s_data0        (s_data0[i*DATA_WIDTH +: DATA_WIDTH]),
                        .s_data1        (s_data1[i*DATA_WIDTH +: DATA_WIDTH]),
                        
                        .m_data0        (m_data0[i*DATA_WIDTH +: DATA_WIDTH]),
                        .m_data1        (m_data1[i*DATA_WIDTH +: DATA_WIDTH])
                    );
        end
    end
    endgenerate
    
    
    reg     [USER_WIDTH-1:0]    reg_user;
    reg     [RATE_WIDTH-1:0]    reg_rate;
    reg                         reg_valid;
    
    always @(posedge clk) begin
        if ( reset ) begin
            reg_user  <= {USER_WIDTH{1'bx}};
            reg_rate  <= {RATE_WIDTH{1'bx}};
            reg_valid <= 1'b0;
        end
        else if ( cke ) begin
            reg_user  <= s_user;
            reg_rate  <= (s_rate << 1) | s_rate[RATE_WIDTH-1];
            reg_valid <= s_valid;
        end
    end
    
    assign m_user  = reg_user;
    assign m_rate  = reg_rate;
    assign m_valid = reg_valid;
    
endmodule