`timescale 1ns / 1ps

module tb_comb_adder_18b;

  // Parameters
  localparam WIDTH = 18;
  localparam ADDER_IN_SIZE = WIDTH;
  localparam ADDER_OUT_SIZE = WIDTH + 4; // up to 16*18-bit addition → 22 bits

  // DUT inputs
  logic clk;
  logic reset;
  logic adder_start;
  logic [ADDER_IN_SIZE-1:0] op[0:15];

  // DUT output
  logic [ADDER_OUT_SIZE-1:0] result;

  // Instantiate DUT
  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)
  );

  // Clock generation
  initial clk = 0;
  always #5 clk = ~clk;

  // Test control
  logic [ADDER_OUT_SIZE-1:0] expected_sum;
  logic [ADDER_OUT_SIZE-1:0] captured_result;
  int i;

  initial begin
    $display("=== comb_adder_18b Testbench ===");

    // Initialize
    reset = 1;
    adder_start = 0;
    for (i = 0; i < 16; i++) op[i] = 0;
    #20;
    reset = 0;

    // Provide input data
    @(posedge clk);
    for (i = 0; i < 16; i++) begin
        
        op[i] = i * 2;  // simple pattern: 0, 2, 4, ..., 30
    end

    expected_sum = 0;
    for (i = 0; i < 16; i++)
      expected_sum += op[i];

    // Start adder
    @(posedge clk);
    adder_start = 1;
    @(posedge clk);
    adder_start = 0;

    // Wait for pipeline latency (~4 cycles here)
    repeat (3) @(posedge clk);

    captured_result = result;
    $display("Expected Sum: %0d (0x%h)", expected_sum, expected_sum);
    $display("Captured Sum: %0d (0x%h)", captured_result, captured_result);

    if (captured_result === expected_sum)
      $display("Test PASSED!");
    else
      $display("Test FAILED!");

    #10 $finish;
  end

endmodule
