A full adder is the single bit adder with a carry.
module full_adder (
input a,
input b,
input cin,
output sum,
output cout
);
assign sum = a ^ b ^ cin;
assign cout = (a & b) | (b & cin) | (a & cin);
endmodule
The best way is to not constrain an adder implementation by size. The best way is a parametrization.
module adder #(
parameter DATA_WIDTH = 8
) (
input [DATA_WIDTH-1:0] a,
input [DATA_WIDTH-1:0] b,
input cin,
output [DATA_WIDTH-1:0] sum,
output cout
);
genvar i;
wire [DATA_WIDTH:0] carries;
assign carries[0] = cin;
generate
for (i = 0; i < DATA_WIDTH; i = i + 1) begin : full_adder_instances
full_adder full_adder_inst(
.a(a[i]),
.b(b[i]),
.cin(carries[i]),
.sum(sum[i]),
.cout(carries[i+1])
);
end
endgenerate
assign cout = carries[DATA_WIDTH];
endmodule
or you could do this:
module adder #(
parameter DATA_WIDTH = 8
) (
input [DATA_WIDTH-1:0] a,
input [DATA_WIDTH-1:0] b,
input cin,
output [DATA_WIDTH-1:0] sum,
output cout
);
assign {cout, sum} = a + b + cin;
endmodule