Full Adder Verilog
Full Adder
A. Behavioral
B. Structural
1. Using UDP
Design Code
___________________________________________________________________________
primitive FA_sum(sum, a, b, c);
input a, b, c;
output sum;
table
// a b c : Sum
0 0 0 : 0;
0 0 1 : 1;
0 1 0 : 1;
0 1 1 : 0;
1 0 0 : 1;
1 0 1 : 0;
1 1 0 : 0;
1 1 1 : 1;
endtable
endprimitive
primitive FA_carry(cout, a, b, cin);
input a, b, cin;
output cout;
table
// a b c : cout
1 1 ? : 1; // ? is Don't care
? 1 1 : 1; // we know that if any two inputs is high, cout is high
1 ? 1 : 1;
0 0 ? : 0; // we also know that if any two inputs is low, cout is low
? 0 0 : 0;
0 ? 0 : 0;
endtable
endprimitive
_________________________________________________________________________________
Test Bench
________________________________________________________________________________
module FA_test;
reg [2:0] x;
wire sum, cout;
FA_sum (sum, x[0], x[1], x[2]); //instant name is optional
FA_carry (cout, x[0], x[1], x[2]);
initial
begin
$display("\t\t Time \t a b Cin \t Sum, Cout");
$monitor($time,"\t %b %b %b \t %b %b", x[0],x[1],x[2],sum,cout);
x = 3'O0;
#5 x = 3'O1;
#5 x = 3'O2;
#5 x = 3'O3;
#5 x = 3'O4;
#5 x = 3'O5;
#5 x = 3'O6;
#5 x = 3'O7;
#5 $finish;
end
endmodule
Output
___________________________________________________
Time a b Cin Sum, Cout
0 0 0 0 0 0
5 1 0 0 1 0
10 0 1 0 1 0
15 1 1 0 0 1
20 0 0 1 1 0
25 1 0 1 0 1
30 0 1 1 0 1
35 1 1 1 1 1
____________________________________________________
2. Using Operators
Design Code
___________________________________________________________________________
module Full_adder(output sum, cout, input a, b, cin);
reg sum;
reg cout;
wire [2:0] all_input;
assign all_input = {a, b, cin};
always @(*)
begin
if(all_input == 3'o0)
begin
sum<=1'b0;
cout<=1'b0;
end
else if(all_input == 3'o1)
begin
sum<=1'b1;
cout<=1'b0;
end
else if(all_input == 3'o2)
begin
sum<=1'b1;
cout<=1'b0;
end
else if(all_input == 3'o3)
begin
sum<=1'b0;
cout<=1'b1;
end
else if(all_input == 3'o4)
begin
sum<=1'b1;
cout<=1'b0;
end
else if(all_input == 3'o5)
begin
sum<=1'b0;
cout<=1'b1;
end
else if(all_input == 3'o6)
begin
sum<=1'b0;
cout<=1'b1;
end
else if(all_input == 3'o7)
begin
sum<=1'b1;
cout<=1'b1;
end
end
endmodule
Same Test Bench Same Output
4. Structural Design (Suppose using two half adders and one OR gate)
Here Full Adder is defined in structural modelling while half adder is defined in behavioral modelling.
Design Code
____________________________________________________________________________
5. Structural Design version 2
Design Code
_________________________________________________________________________________
module Full_adder(output sum, cout, input a, b, cin);
wire w1, w2, w3;
Half_Adder HA1 (w1, w2, a, b); // w1 = a^b, w2 = a&b
Half_Adder HA2 (sum, w3, w1, cin); // sum = w1^cin = (a^b^cin), w3 = cin & (a^b)
or_function G1 (cout, w2, w3); // Cout = w2|w3 = (a&b)|(cin&(a^b)) = a.b + b.cin + cin.a
endmodule
module Half_Adder(output S1, CY, input a, b);
xor G1 (S1, a, b);
and G2 (CY, a, b);
endmodule
module or_function(output f, input a, b); // type of variable is declared inside module parameter lists
or G1 (f, a, b);
endmodule
_________________________________________________________________________________
Same test bench same output
Here all modules are in structural style.
A. Behavioral
- Truth Table
- Using UDP
- Using Operators
- Data Flow
- Using Assign
B. Structural
- Functional level
- Gate Level
1. Using UDP
Design Code
___________________________________________________________________________
primitive FA_sum(sum, a, b, c);
input a, b, c;
output sum;
table
// a b c : Sum
0 0 0 : 0;
0 0 1 : 1;
0 1 0 : 1;
0 1 1 : 0;
1 0 0 : 1;
1 0 1 : 0;
1 1 0 : 0;
1 1 1 : 1;
endtable
endprimitive
primitive FA_carry(cout, a, b, cin);
input a, b, cin;
output cout;
table
// a b c : cout
1 1 ? : 1; // ? is Don't care
? 1 1 : 1; // we know that if any two inputs is high, cout is high
1 ? 1 : 1;
0 0 ? : 0; // we also know that if any two inputs is low, cout is low
? 0 0 : 0;
0 ? 0 : 0;
endtable
endprimitive
Test Bench
________________________________________________________________________________
module FA_test;
reg [2:0] x;
wire sum, cout;
FA_sum (sum, x[0], x[1], x[2]); //instant name is optional
FA_carry (cout, x[0], x[1], x[2]);
initial
begin
$display("\t\t Time \t a b Cin \t Sum, Cout");
$monitor($time,"\t %b %b %b \t %b %b", x[0],x[1],x[2],sum,cout);
x = 3'O0;
#5 x = 3'O1;
#5 x = 3'O2;
#5 x = 3'O3;
#5 x = 3'O4;
#5 x = 3'O5;
#5 x = 3'O6;
#5 x = 3'O7;
#5 $finish;
end
endmodule
_________________________________________________________________________________
Output
___________________________________________________
Time a b Cin Sum, Cout
0 0 0 0 0 0
5 1 0 0 1 0
10 0 1 0 1 0
15 1 1 0 0 1
20 0 0 1 1 0
25 1 0 1 0 1
30 0 1 1 0 1
35 1 1 1 1 1
____________________________________________________
2. Using Operators
1. Using If & else If statement
Design Code
___________________________________________________________________________
module Full_adder(output sum, cout, input a, b, cin);
reg sum;
reg cout;
wire [2:0] all_input;
assign all_input = {a, b, cin};
always @(*)
begin
if(all_input == 3'o0)
begin
sum<=1'b0;
cout<=1'b0;
end
else if(all_input == 3'o1)
begin
sum<=1'b1;
cout<=1'b0;
end
else if(all_input == 3'o2)
begin
sum<=1'b1;
cout<=1'b0;
end
else if(all_input == 3'o3)
begin
sum<=1'b0;
cout<=1'b1;
end
else if(all_input == 3'o4)
begin
sum<=1'b1;
cout<=1'b0;
end
else if(all_input == 3'o5)
begin
sum<=1'b0;
cout<=1'b1;
end
else if(all_input == 3'o6)
begin
sum<=1'b0;
cout<=1'b1;
end
else if(all_input == 3'o7)
begin
sum<=1'b1;
cout<=1'b1;
end
end
endmodule
_______________________________________________________________________________
Test Bench
______________________________________________________________________________
module FA_test;
reg [2:0] x;
wire sum, cout;
Full_adder FA1 (sum, cout, x[0], x[1], x[2]);
initial
begin
$display("\t\t Time \t a b Cin \t Sum, Cout");
$monitor($time,"\t %b %b %b \t %b %b", x[0],x[1],x[2],sum,cout);
x = 3'O0;
#5 x = 3'O1;
#5 x = 3'O2;
#5 x = 3'O3;
#5 x = 3'O4;
#5 x = 3'O5;
#5 x = 3'O6;
#5 x = 3'O7;
#5 $finish;
end
endmodule
_______________________________________________________________________________
Output is same
______________________________________________________________________________
2. Using case statement
module Full_adder(output sum, cout, input a, b, cin);
reg sum; // As sum is used in LHS in always block, it is defined as reg
reg cout; // As cout is used in LHS in always block, it is defined as reg
wire [2:0] all_input;
assign all_input = {a, b, cin};
always @(*) // Always block (procedural)
begin
case(all_input)
3'o0:
begin
sum<=1'b0; // Non-blocking statement, sum is in LHS
cout<=1'b0; // this statement is executed concurrently with above statement
end
3'o1:
begin
sum<=1'b1;
cout<=1'b0;
end
3'o2:
begin
sum<=1'b1;
cout<=1'b0;
end
3'o3:
begin
sum<=1'b0;
cout<=1'b1;
end
3'o4:
begin
sum<=1'b1;
cout<=1'b0;
end
3'o5:
begin
sum<=1'b0;
cout<=1'b1;
end
3'o6:
begin
sum<=1'b0;
cout<=1'b1;
end
3'o7:
begin
sum<=1'b1;
cout<=1'b1;
end
endcase
end
endmodule
2. Using case statement
module Full_adder(output sum, cout, input a, b, cin);
reg sum; // As sum is used in LHS in always block, it is defined as reg
reg cout; // As cout is used in LHS in always block, it is defined as reg
wire [2:0] all_input;
assign all_input = {a, b, cin};
always @(*) // Always block (procedural)
begin
case(all_input)
3'o0:
begin
sum<=1'b0; // Non-blocking statement, sum is in LHS
cout<=1'b0; // this statement is executed concurrently with above statement
end
3'o1:
begin
sum<=1'b1;
cout<=1'b0;
end
3'o2:
begin
sum<=1'b1;
cout<=1'b0;
end
3'o3:
begin
sum<=1'b0;
cout<=1'b1;
end
3'o4:
begin
sum<=1'b1;
cout<=1'b0;
end
3'o5:
begin
sum<=1'b0;
cout<=1'b1;
end
3'o6:
begin
sum<=1'b0;
cout<=1'b1;
end
3'o7:
begin
sum<=1'b1;
cout<=1'b1;
end
endcase
end
endmodule
_____________________________________________________________________________
Same Test Bench Same Output
_____________________________________________________________________________
3. Using assign statement
Design Code
______________________________________________________________________________
module Full_adder(output sum, cout, input a, b, cin);
wire sum = a^b^cin;
wire cout = (a&b)|(b&cin)|(cin&a);
endmodule
______________________________________________________________________________Same Test Bench Same Output
4. Structural Design (Suppose using two half adders and one OR gate)
Here Full Adder is defined in structural modelling while half adder is defined in behavioral modelling.
Design Code
____________________________________________________________________________
module Full_adder(output sum, cout, input a, b, cin);
wire w1, w2, w3; // used for interconnection between Half adders and OR gate
Half_Adder HA1 (w1, w2, a, b); // w1 = a^b, w2 = a&b
Half_Adder HA2 (sum, w3, w1, cin); // sum = w1^cin = (a^b^cin), w3 = cin & (a^b)
or_function G1 (cout, w2, w3); // Cout = w2|w3 = (a&b)|(cin&(a^b)) = a.b + b.cin + cin.a
endmodule
module Half_Adder(output S1, CY, input a, b);
wire S1 = a^b; // behavioral modelling
wire CY = a&b; // behavioral modelling
endmodule
module or_function(output f, input a, b); // type of variable is declared inside module parameter lists
wire f;
assign f = a|b; // behavioral modelling
endmodule
______________________________________________________________________________
Same Test Bench Same Output
Here full adder (Full_adder) is defined in structural modelling, since it defines the interconnections between sub-systems (half adders and OR gate). However, both Half adder and OR gate are defined in behavior style since they just provide the input-output relationships not the internal architecture of the system.
5. Structural Design version 2
Design Code
_________________________________________________________________________________
module Full_adder(output sum, cout, input a, b, cin);
wire w1, w2, w3;
Half_Adder HA1 (w1, w2, a, b); // w1 = a^b, w2 = a&b
Half_Adder HA2 (sum, w3, w1, cin); // sum = w1^cin = (a^b^cin), w3 = cin & (a^b)
or_function G1 (cout, w2, w3); // Cout = w2|w3 = (a&b)|(cin&(a^b)) = a.b + b.cin + cin.a
endmodule
module Half_Adder(output S1, CY, input a, b);
xor G1 (S1, a, b);
and G2 (CY, a, b);
endmodule
module or_function(output f, input a, b); // type of variable is declared inside module parameter lists
or G1 (f, a, b);
endmodule
_________________________________________________________________________________
Same test bench same output
Here all modules are in structural style.
Comments
Post a Comment