## Verilog Full Adder Example

We will continue to learn more examples with Combinational Circuit - this time a full adder. A combinational circuit is one in which the present output is a function of only the present inputs - there is no memory. This is different from the sequential circuits that we will learn later where the present output is a function of not only the present input but also of past inputs/outputs as well.

Table: A one bit comparator

 Carry in Input y Input x Carry out Output A 0 0 0 0 0 0 0 1 0 1 0 1 0 0 1 0 1 1 1 0 1 0 0 0 1 1 0 1 1 0 1 1 0 1 0 1 1 1 1 1

Let us look at the source code for the implemmentation of a full adder

 `/* Full Adder Module for bit Addition Written by referencedesigner.com */module fulladder( input x, input y, input cin,  output A, output cout ); assign {cout,A} = cin + y + x; endmodule  `

The important statement to note is the assignment statement

assign {cout,A} = cin + y + x;

An left side of the assignemnt statement can contain a concatenation of scalar or vector. In this way it is possible in this case to assign the result of the adder to two bit vector. Notice how the vector array is formed using the curly bracket {cout,A}. The rightmost part of the vector {cout,A} , which is A in this case forms the LSB.

We will now add a test bench to confirm that the result is as expected. So here goes the test bench.
 `/* Full Adder Module for bit Addition Written by referencedesigner.com */`timescale 1ns / 100ps  module fulladdertb;  reg input1;reg input2;reg carryin; wire out;wire carryout;  fulladder uut (.x(input1),.y(input2),.cin(carryin),.A(out),.cout(carryout)); initialbegininput1 =0;input2 =0;carryin =0;#20; input1 =1;#20; input2 =1;#20; input1 =0;#20; carryin =1;#20; input2=0;#20; input1=1; #20; input2=1;#40;end  initialbegin\$monitor("time = %2d, CIN =%1b, IN1=%1b, IN2=%1b, COUT=%1b, OUT=%1b", \$time,carryin,input2, input1,carryout,out);end endmodule`

As usual we will compile the program with following commands
```
```
C:\vvp output
```
```
```
```
time =  0, CIN =0, IN1=0, IN2=0, COUT=0, OUT=0
time = 20, CIN =0, IN1=0, IN2=1, COUT=0, OUT=1
time = 40, CIN =0, IN1=1, IN2=1, COUT=1, OUT=0
time = 60, CIN =0, IN1=1, IN2=0, COUT=0, OUT=1
time = 80, CIN =1, IN1=1, IN2=0, COUT=1, OUT=0
time = 100, CIN =1, IN1=0, IN2=0, COUT=0, OUT=1
time = 120, CIN =1, IN1=0, IN2=1, COUT=1, OUT=0
tme = 140, CIN =1, IN1=1, IN2=1, COUT=1, OUT=1

```
```
Notice that we have introduced a system variable \$time as one of the parameters in the \$monitor statement. This comes handy when looking at the data ( if that is not in graph). The system variable \$time returns the current simulation time as a 64-bit integer.

Looking back at the code - the vector concatenation thing on the left hand side in the assignment statement
```
```
assign {cout,A} =  cin + y + x;
```
```

Could be replaced by two assignment statements ( looking at the table in the top of the page and writing sum of products.
```
```
assign A =  ((~cin) & x &(~y)) | ((~cin) &(~x)&y ) | (cin &(~x) &(~y)) | (cin & x & y)     ;
assign cout = ((~cin) & x &y) | ((cin) &(~x)&y ) | (cin &(x) &(~y)) | (cin & x & y)  ;
```
```
If you look more closely, the full adder circuit can be simplified quite a bit, but will require intelligent mix of Exclusive OR gates when writing term for sum.

This will form the basis of one of the exercises below.
 Exercise

1. Redo the full adder with Gate Level modeling. Run the test bench to make sure that you get the correct result.

2. Draw a truth table for full adder and implement the full adder using UDP.

3. Use the waveform viewer so see the result graphically.

 Solution

Before looking at the solution, make sure you have given your efforts to solve it. Here are the solution codes.
 `/* Full Adder Module for bit Addition Written by referencedesigner.com */module fulladder( input x, input y, input cin,  output A, output cout ); wire p,r,s; xor (p,x,y); xor (A,p,cin);  and(r,p,cin); and(s,x,y); or(cout,r,s); endmodule `

 `/* Full Adder Module for bit Addition Written by referencedesigner.com */module fulladder( input x, input y, input cin,  output A, output cout ); addtable(A,cin,x,y); addcarry(cout,cin,x,y); endmodule  primitive addtable(out, cin, in1, in2); output out; input cin,in1,in2; table// cin in1 in2 : out 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;    endtableendprimitive   primitive addcarry(cout,cin, in1, in2); output cout; input cin,in1,in2; table// cin in1 in2 : cout 0 0 0 : 0 ; 0 0 1 : 0; 0 1 0 : 0; 0 1 1 : 1; 1 0 0 : 0 ; 1 0 1 : 1; 1 1 0 : 1; 1 1 1 : 1; endtableendprimitive `

Exercise

1. Extend the full bit adder so that it can add two 2 bit inputs in place of two 1 bit inputs. It will also have a carry in and a carry out.