module altera_merlin_arb_adder
#(
    parameter WIDTH = 8
)
(
    input [WIDTH-1:0] a,
    input [WIDTH-1:0] b,

    output [WIDTH-1:0] sum
);

    wire [WIDTH:0] sum_lint;
    // ----------------------------------------------
    // Benchmarks indicate that for small widths, the full
    // adder has higher fmax because synthesis can merge
    // it with the mux, allowing partial decisions to be 
    // made early.
    //
    // The magic number is 4 requesters, which means an
    // 8 bit adder.
    // ----------------------------------------------
    genvar i;
    generate if (WIDTH <= 8) begin : full_adder

        wire cout[WIDTH-1:0];

        assign sum[0]  = (a[0] ^ b[0]);
        assign cout[0] = (a[0] & b[0]);

        for (i = 1; i < WIDTH; i = i+1) begin : arb

            assign sum[i] = (a[i] ^ b[i]) ^ cout[i-1];
            assign cout[i] = (a[i] & b[i]) | (cout[i-1] & (a[i] ^ b[i]));

        end

    end else begin : carry_chain

        assign sum_lint = a + b;
        assign sum = sum_lint[WIDTH-1:0];

    end
    endgenerate

endmodule