`include "lr_acc.svh"

module comb_adder_18b_wrapper (
    input  logic clk,
    input  logic reset,
    input  logic run,
    output logic valid_out,
    output logic [`ADDER_OUT_SIZE_18b-1:0] result_out
);

    // DUT interface
    logic adder_start;
    logic [`ADDER_IN_SIZE_18b-1:0] op[0:15];
    logic [`ADDER_OUT_SIZE_18b-1:0] result;

    // DUT instantiation
    comb_adder_18b dut (
        .clk(clk),
        .reset(reset),
        .adder_start(adder_start),
        .op0(op[0]),  .op1(op[1]),  .op2(op[2]),  .op3(op[3]),
        .op4(op[4]),  .op5(op[5]),  .op6(op[6]),  .op7(op[7]),
        .op8(op[8]),  .op9(op[9]),  .opA(op[10]), .opB(op[11]),
        .opC(op[12]), .opD(op[13]), .opE(op[14]), .opF(op[15]),
        .result(result)
    );

    // Pipeline control shift register (4-cycle latency)
    logic [3:0] valid_pipe;
    always_ff @(posedge clk or posedge reset) begin
        if (reset)
            valid_pipe <= 4'b0;
        else
            valid_pipe <= {valid_pipe[2:0], adder_start};
    end

    assign valid_out  = valid_pipe[3];
    assign result_out = result;

    // FSM states
    typedef enum logic [1:0] {
        IDLE,
        LOAD,
        WAIT_RESULT
    } state_t;

    state_t state;
    logic [31:0] expected_sum;

    always_ff @(posedge clk or posedge reset) begin
        if (reset) begin
            adder_start   <= 0;
            expected_sum  <= 0;
            state         <= IDLE;
            for (int i = 0; i < 16; i++) op[i] <= 0;
        end else begin
            case (state)
                IDLE: begin
                    adder_start <= 0;
                    if (run)
                        state <= LOAD;
                end

                LOAD: begin
                    // Hardcoded test pattern: op[i] = i * 3
                    expected_sum = 0;
                    for (int i = 0; i < 16; i++) begin
                        op[i] = i * 3;
                        expected_sum += i * 3;
                    end
                    adder_start <= 1;
                    state <= WAIT_RESULT;
                end

                WAIT_RESULT: begin
                    adder_start <= 0;
                    if (valid_out) begin
                        $display("=== comb_adder_18b Output ===");
                        $display("Expected Sum: %0d (0x%h)", expected_sum, expected_sum);
                        $display("Received Sum: %0d (0x%h)", result_out, result_out);
                        if (result_out === expected_sum)
                            $display("✅ PASS");
                        else
                            $display("❌ FAIL");
                        state <= IDLE;
                    end
                end
            endcase
        end
    end

endmodule
