Full adder using two half adders

A full adder using two half adders is implemented here.

The equation for the sum and carry are:

Sum = A xor B xor Cin
Carry = (A xor B).Cin + A.B

fa

Code:


module full_adder(
input a,b,cin,
output sum, carry
);

wire temp_sum, temp_carry_1,temp_carry_2;
half_adder HA1(.a(a),.b(b),.sum(temp_sum),.carry(temp_carry_1));
half_adder HA2(.a(temp_sum),.b(cin),.sum(sum),.carry(temp_carry_2));
assign carry=temp_carry_1|temp_carry_2;


endmodule

module half_adder(
input a,b,
output reg sum,carry
);
always@(*)begin
{carry,sum} = a+b;
end
endmodule

Half adder (Using gates and behavioural code)

Let’s see how we can implement synchronous half adder using gates and also by using behavioural modelling.

Using Gates:


module half_adder_using_gates(
input clk,
input a,b,
output reg sum,carry
);


always@(posedge clk)begin
sum <= a^b;
carry <= a&b;
end


endmodule

Behavioural modelling:


module half_adder(
input clk,
input a,b,
output reg sum,carry
);


always@(posedge clk)begin
{carry,sum} = a+b;
end

endmodule

Sign magnitude adder

This can be used to add numbers in sign magnitude format.

module adder_sign_magnitude(a,b,sum);
parameter N=4;
input wire[N-1:0]a,b;
output reg[N:0]sum;

reg [N-2:0] mag_a, mag_b , max, min;
reg [N-1:0]mag_sum;
reg sign_a, sign_b, sign_sum;
always@(*)
begin
mag_a = a[N-2:0] ;
mag_b = b[N-2:0] ;
sign_a = a[N-1];
sign_b = b[N-1] ;
if (mag_a > mag_b)
begin
max = mag_a;
min = mag_b;
sign_sum = sign_a;
end
else
begin
max = mag_b;
min = mag_a;
sign_sum = sign_b;
end
// add/sub magnitude
if (sign_a==sign_b)
mag_sum = max + min;
else
mag_sum = max - min;
sum = {sign_sum, mag_sum};
end
endmodule

Carry Select Adder to add two 8-bit inputs

Carry select adders are one among the fastest adders used. Here is the code of a carry select adder.

module carry_select_adder(a,b,cin,sum);
input cin;
input [7:0]a,b;//8-bit inputs
output [8:0]sum; // = 9-bit output
wire [7:0]sum_temp;//temp reg to store 8-bit sum
wire cout;//MSB of 9-bit sum or carry out
wire cy_0,cy_1,cy_add1,cy_add2,cy_add3;
wire [3:0] sum_0,sum_1,a_1,b_1,a_2,b_2,sum_low,sum_high;
assign cy_0=1'b0;
assign cy_1=1'b1;
assign a_1={a[3],a[2],a[1],a[0]};//lower bits of input a
assign b_1={b[3],b[2],b[1],b[0]};//lower bits of input b
assign a_2={a[7],a[6],a[5],a[4]};//higher bits of input a
assign b_2={b[7],b[6],b[5],b[4]};//higher bits of input b


adder_4_bit ADD1(a_1,b_1,cin,sum_low,cy_add1);//lower k/2 bit adder
adder_4_bit ADD2(a_2,b_2,cy_0,sum_0,cy_add2);//upper k/2 bit adder with cin=0
adder_4_bit ADD3(a_2,b_2,cy_1,sum_1,cy_add3);//upper k/2 bit adder with cin=1
mux_2_to_1 MUX(sum_0,sum_1,cy_add1,sum_high);

assign sum_temp={sum_high,sum_low};
assign cout=cy_add1?cy_add3:cy_add2;
assign sum={cout,sum_temp};
endmodule

module adder_4_bit(a,b,cin,sum,cout);
input[3:0]a,b;
input cin;
output[3:0]sum;
output cout;
wire [2:0]cy;


full_adder FA1(a[0],b[0],cin,sum[0],cy[0]);
full_adder FA2(a[1],b[1],cy[0],sum[1],cy[1]);
full_adder FA3(a[2],b[2],cy[1],sum[2],cy[2]);
full_adder FA4(a[3],b[3],cy[2],sum[3],cout);

endmodule


module full_adder(a,b,cin,sum,cout);
input a,b,cin;
output sum,cout;
assign {cout,sum}=a+b+cin;
endmodule


module mux_2_to_1(i0,i1,s,out);
input[3:0]i0,i1;
input s;
output[3:0]out;
assign out=s?i1:i0;
endmodule

4-bit Ripple Carry Adder

module ripple_carry_adder_4_bit(a,b,cin,sum,cout);
input[3:0]a,b;
input cin;
output[3:0]sum;
output cout;
wire [2:0]cy;
full_adder FA1(a[0],b[0],cin,sum[0],cy[0]);
full_adder FA2(a[1],b[1],cy[0],sum[1],cy[1]);
full_adder FA3(a[2],b[2],cy[1],sum[2],cy[2]);
full_adder FA4(a[3],b[3],cy[2],sum[3],cout);
endmodule

module full_adder(a,b,cin,sum,cout);
input a,b,cin;
output sum,cout;
assign {cout,sum}=a+b+cin;
endmodule