module sort8_ranker (
    input wire clk,
    input wire rst,
    input wire in_valid,
    input wire [127:0] in_data,
    output wire out_valid,
    output wire [127:0] out_data,
    output wire [23:0] out_index
);
    reg signed [15:0] sort_val [0:7];
    reg [2:0] sort_idx [0:7];
    reg signed [15:0] tmp_val;
    reg [2:0] tmp_idx;
    reg [127:0] sort_data_comb;
    reg [23:0] sort_index_comb;

    reg pipe_valid [0:6];
    reg [127:0] pipe_data [0:6];
    reg [23:0] pipe_index [0:6];

    integer i;
    integer j;
    integer stage;

    always @* begin
        for (i = 0; i < 8; i = i + 1) begin
            sort_val[i] = in_data[(16 * i) +: 16];
            sort_idx[i] = i[2:0];
        end

        for (i = 0; i < 7; i = i + 1) begin
            for (j = 0; j < 7 - i; j = j + 1) begin
                if ((sort_val[j] > sort_val[j + 1]) ||
                    ((sort_val[j] == sort_val[j + 1]) && (sort_idx[j] > sort_idx[j + 1]))) begin
                    tmp_val = sort_val[j];
                    sort_val[j] = sort_val[j + 1];
                    sort_val[j + 1] = tmp_val;
                    tmp_idx = sort_idx[j];
                    sort_idx[j] = sort_idx[j + 1];
                    sort_idx[j + 1] = tmp_idx;
                end
            end
        end

        sort_data_comb = 128'b0;
        sort_index_comb = 24'b0;
        for (i = 0; i < 8; i = i + 1) begin
            sort_data_comb[(16 * i) +: 16] = sort_val[i];
            sort_index_comb[(3 * i) +: 3] = sort_idx[i];
        end
    end

    always @(posedge clk) begin
        if (rst) begin
            for (stage = 0; stage < 7; stage = stage + 1) begin
                pipe_valid[stage] <= 1'b0;
                pipe_data[stage] <= 128'b0;
                pipe_index[stage] <= 24'b0;
            end
        end else begin
            pipe_valid[0] <= in_valid;
            pipe_data[0] <= in_valid ? sort_data_comb : 128'b0;
            pipe_index[0] <= in_valid ? sort_index_comb : 24'b0;

            for (stage = 1; stage < 7; stage = stage + 1) begin
                pipe_valid[stage] <= pipe_valid[stage - 1];
                pipe_data[stage] <= pipe_valid[stage - 1] ? pipe_data[stage - 1] : 128'b0;
                pipe_index[stage] <= pipe_valid[stage - 1] ? pipe_index[stage - 1] : 24'b0;
            end
        end
    end

    assign out_valid = pipe_valid[6];
    assign out_data = pipe_valid[6] ? pipe_data[6] : 128'b0;
    assign out_index = pipe_valid[6] ? pipe_index[6] : 24'b0;
endmodule
