module hamming_secded_decoder (
    input  wire        clk,
    input  wire        rst,
    input  wire        in_valid,
    input  wire [12:0] codeword_in,
    output reg         out_valid,
    output reg [7:0]   data_out,
    output reg         single_error_corrected,
    output reg         double_error_detected
);
    reg [3:0]  syndrome_value;
    reg        total_parity_odd;
    reg [12:0] corrected_word;
    reg [7:0]  decoded_data;
    reg        decoded_single;
    reg        decoded_double;

    function [3:0] calc_syndrome;
        input [12:0] cw;
        begin
            calc_syndrome[0] = cw[0] ^ cw[2] ^ cw[4] ^ cw[6] ^ cw[8] ^ cw[10];
            calc_syndrome[1] = cw[1] ^ cw[2] ^ cw[5] ^ cw[6] ^ cw[9] ^ cw[10];
            calc_syndrome[2] = cw[3] ^ cw[4] ^ cw[5] ^ cw[6] ^ cw[11];
            calc_syndrome[3] = cw[7] ^ cw[8] ^ cw[9] ^ cw[10] ^ cw[11];
        end
    endfunction

    function [7:0] extract_data;
        input [12:0] cw;
        begin
            extract_data = {cw[11], cw[10], cw[9], cw[8], cw[6], cw[5], cw[4], cw[2]};
        end
    endfunction

    always @(posedge clk) begin
        if (rst) begin
            out_valid <= 1'b0;
            data_out <= 8'h00;
            single_error_corrected <= 1'b0;
            double_error_detected <= 1'b0;
        end else begin
            if (in_valid) begin
                syndrome_value = calc_syndrome(codeword_in);
                total_parity_odd = ^codeword_in;
                corrected_word = codeword_in;
                decoded_single = 1'b0;
                decoded_double = 1'b0;

                if ((syndrome_value != 4'd0) && total_parity_odd) begin
                    corrected_word[syndrome_value - 4'd1] = ~corrected_word[syndrome_value - 4'd1];
                    decoded_single = 1'b1;
                end else if ((syndrome_value == 4'd0) && total_parity_odd) begin
                    decoded_single = 1'b1;
                end else if ((syndrome_value != 4'd0) && !total_parity_odd) begin
                    decoded_double = 1'b1;
                end

                decoded_data = extract_data(corrected_word);

                out_valid <= 1'b1;
                data_out <= decoded_data;
                single_error_corrected <= decoded_single;
                double_error_detected <= decoded_double;
            end else begin
                out_valid <= 1'b0;
                data_out <= 8'h00;
                single_error_corrected <= 1'b0;
                double_error_detected <= 1'b0;
            end
        end
    end
endmodule
