Full Adder Verilog

Full Adder



A. Behavioral

  • Truth Table
    • Using UDP
    • Using Operators
  • Data Flow
    • Using Assign

B. Structural

  1. Functional level
  2. 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
_____________________________________________________________________________
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

Popular posts from this blog

16-to-1 multiplexer (16X1 MUX) Verilog

8 bit Adder Verilog

Carry Lookahead 4-bit Adder Verilog