`timescale 1ns / 1ps
`include "meggitt_decoder_mld.v"

module meggitt_tb;
    reg clk;
    reg rst_n;
    reg start;
    reg [7:0] data_in;
    reg data_valid;
    wire done;
    wire [7:0] data_out;
    wire data_out_valid;
    wire [15:0] bit_counter;
    wire [7:0] error_count;

    // Instantiate specific module name based on file name
    // meggitt_decoder_mld -> instantiates meggitt_decoder_mld
    meggitt_decoder_mld uut (
        .clk(clk),
        .rst_n(rst_n),
        .start(start),
        .data_in(data_in),
        .data_valid(data_valid),
        .done(done),
        .data_out(data_out),
        .data_out_valid(data_out_valid),
        .bit_counter(bit_counter),
        .error_count(error_count)
    );

    // Clock generation
    initial begin
        clk = 0;
        forever #5 clk = ~clk; // 100MHz
    end

    integer mem_file, r, i;
    reg [7:0] byte_read;
    reg [7:0] expected_data [0:2303];

    initial begin
        $dumpfile("meggitt.vcd");
        $dumpvars(0, meggitt_tb);

        // Load expected data directly from original bin file
        mem_file = $fopen("codeword.bin", "rb");
        r = $fread(expected_data, mem_file);
        $fclose(mem_file);

        rst_n = 0;
        start = 0;
        data_in = 0;
        data_valid = 0;
        #20 rst_n = 1;

        // Start command
        #10 start = 1;
        #10 start = 0;

        // Feed codeword.mem byte by byte
        mem_file = $fopen("codeword.mem", "r");
        for (i = 0; i < 2304; i = i + 1) begin
            r = $fscanf(mem_file, "%b\n%b\n%b\n%b\n%b\n%b\n%b\n%b\n", 
                        data_in[7], data_in[6], data_in[5], data_in[4],
                        data_in[3], data_in[2], data_in[1], data_in[0]);
            data_valid = 1;
            #10;
        end
        data_valid = 0;
        $fclose(mem_file);

        $display("Decoding started...");
        wait(done);
        $display("Decoding finished. Found %3d errors.", error_count);

        $display("Verifying output data...");
        for (i = 0; i < 2304; i = i + 1) begin
            wait(data_out_valid);
            if (data_out !== expected_data[i]) begin
                $display("ERROR at byte %4d: Expected %02X, Got %02X", i, expected_data[i], data_out);
            end
            #10;
        end
        $display("Verification complete.");
        $finish;
    end
endmodule
