A.
LOGICAL OPERATIONS
I. AND gate
An AND gate is a digital logic gate that performs a logical AND operation. It takes two
binary input signals (A and B) and produces a single binary output based on the following
truth table:
TABLE 1. AND GATE TRUTH TABLE
                        A     B           Y(OUTPUT)
                        0     0           0
                        0     1           0
                        1     0           0
                        1     1           1
The AND gate expression is given by-
                Y=A&B                                                         (1)
Where ‘&’ is used for AND operation.
SOURCE CODE:
module AND(
input [3:0]a,
input [3:0]b,
output [3:0] y);
assign y = a & b;
endmodule
SCHEMATIC:
                                       Fig 1. AND gate
II.     OR gate
An OR gate is a digital logic gate that performs a logical OR operation. It takes two binary
input signals (A and B) and produces a single binary output based on the truth table:
TABLE 2. OR GATE TRUTH TABLE
                    A          B             Y(OUTPUT)
                    0          0             0
                    0          1             1
                    1          0             1
                    1          1             1
The OR gate expression is given by-
                Y=A|B                                                           (2)
Where ‘|’ is used for OR operation.
SOURCE CODE:
module OR(
input [3:0]a,
input [3:0]b,
output [3:0] y);
assign y = a | b;
endmodule
SCHEMATIC:
                                       Fig 2. OR gate
III.   NOT gate
A NOT gate, also known as an inverter, is a digital logic gate that performs a logical NOT
operation. Unlike other gates that have multiple inputs, a NOT gate has only one input and
one output. The function of a NOT gate is to invert or complement the input signal.
TABLE 3. NOT GATE TRUTH TABLE
                   A          Y
                   0          1
                   1          0
The NOT gate expression is given by-
          Y= ~A                                                                  (3)
Where ‘~’ is used for NOT operation.
SOURCE CODE:
module NOT(
input [3:0]a,
output [3:0] y);
assign y = ~a;
endmodule
SCHEMATIC:
                                       Fig 3. NOT Gate
IV.    NAND gate
A NAND gate is a digital logic gate that performs the logical AND operation followed by the
logical NOT operation on its inputs. In simpler terms, it produces the opposite of the AND
gate output. A NAND gate has two or more inputs and one output.
TABLE 4. NAND GATE TRUTH TABLE
                       A     B           Y(OUTPUT)
                       0     0           1
                       0     1           1
                       1     0           1
                       1     1           0
The NAND gate expression is given by-
          Y= ~(A&B)                                                                   (4)
Where ‘~’ is used for NOT operation and ‘&’ is used for AND operation.
SOURCE CODE:
module NAND(
input [3:0]a,
input [3:0]b,
output [3:0] y);
assign y = ~(a & b);
endmodule
SCHEMATIC:
                                     Fig 4. NAND Gate
V.     NOR Gate
A NOR gate is a digital logic gate that performs the logical OR operation followed by the
logical NOT operation on its inputs. In simpler terms, it produces the opposite of the OR gate
output. A NOR gate has two or more inputs and one output.
TABLE 5. NOR GATE TRUTH TABLE
                       A         B       Y(OUTPUT)
                       0        0        1
                       0        1        0
                       1        0        0
                       1        1        0
The NOR gate expression is given by-
         Y= ~(A|B)                                                                   (5)
Where ‘~’ is used for NOT operation and ‘|’ is used for OR operation.
SOURCE CODE:
module NOR(
input [3:0]a,
input [3:0]b,
output [3:0] y);
assign y = ~(a |b);
endmodule
SCHEMATIC:
                                       Fig 5. NOR Gate
VI.    XOR Gate
An XOR gate (exclusive OR gate) is a digital logic gate that performs the logical exclusive
OR operation on its inputs. An XOR gate has two inputs and one output. The output of an
XOR gate is true (logic 1) if the number of true inputs is odd.
TABLE 6. XOR GATE TRUTH TABLE
                   A       B        Y(OUTPUT)
                   0       0        0
                   0      1        1
                   1      0        1
                   1      1        0
The XOR gate expression is given by-
        Y=A^B                                                                        (6)
Where ‘^’ is used for XOR operation.
SOURCE CODE:
module EXOR(
input [3:0]a,
input [3:0]b,
output [3:0] y);
assign y = (a ^ b);
endmodule
SCHEMATIC:
                                       Fig 6. XOR Gate
VII.   XNOR Gate
An XNOR gate (exclusive NOR gate) is a digital logic gate that performs the logical
exclusive NOR operation on its inputs. An XNOR gate is also known as an equivalence gate
because it produces a true output (logic 1) when the number of true inputs is even, making it
the logical complement of the XOR (exclusive OR) gate.
TABLE 7. XNOR GATE TRUTH TABLE
                       A        B       Y(OUTPUT)
                       0        0       1
                       0        1       0
                       1        0       0
                       1        1       1
The XNOR gate expression is given by-
     Y= ~(A^B)                                                                    (7)
Where ‘~’ is used for NOT operation and ‘^’ is used for XOR operation.
SOURCE CODE:
module XNOR(
input [3:0]a,
input [3:0]b,
output [3:0] y);
assign y = ~(a ^ b);
endmodule
SCHEMATIC:
                                     Fig 7. XNOR Gate
VIII. BUFFER Gate
A BUFFER gate, also referred to as a unity-gain buffer or simply a buffer, is a basic digital
logic gate with one input and one output. The purpose of a BUFFER gate is to pass its input
signal to the output without any change in logic level or voltage level.
TABLE 8. BUFFER GATE TRUTH TABLE
                        A            Y(OUTPUT)
                        0            0
                        1            1
The BUFFER gate expression is given by-
       Y=A                                                                              (8)
SOURCE CODE:
module GATES(
input [3:0]a,
output [3:0] y);
assign y = a;
endmodule
SCHEMATIC:
                                      Fig 8. BUFFER Gate
B. Shift Operators
The Shift operators are used to perform shifting operations. Shift operator provides the output
by shifting the operands either towards the left or right shift according to the number of bit
specified by the user. The left shift operation is performed by shifting the bits towards left
using the left shift operator ‘<<’. Similarly, the right shift operator ‘>>’ shifts the bits towards
right.
LEFT SHIFT:
SOURCE CODE:
module carry(
  input [3:0] A,
  input [3:0] B,     // 4-bit input A
  output [3:0] y);
assign y=A<<B;
endmodule
SCHEMATIC:
                                        Fig 9. Left Shift Operator
RIGHT SHIFT:
SOURCE CODE:
module carry(
  input [3:0] A,
  input [3:0] B,     // 4-bit input A
  output [3:0] y);
assign y=A>>B;
endmodule
SCHEMATIC:
                                        Fig 9. Right Shift Operator
C. ARITHETIC OPERATIONS
I. MANCHESTER CARRY CHAIN ADDER
The Manchester Carry Chain Adder is a type of adder circuit used in digital electronics and
arithmetic units for adding binary numbers. It's a carry-propagate adder that can efficiently
propagate carry bits across multiple stages of the adder, which makes it suitable for high-
speed arithmetic operations.
The sum and carry expressions are given by-
        Sum = A ^ B ^ Cin                                                         (9)
Where ‘^’ is used for XOR operation.
         Cout = (A&B)|(B & Cin)|(Cin & A)                                         (10)
Where A, B, Cin are the inputs, Sum and Cout are the outputs, ‘|’ used for OR operation and
‘&’ used for AND operation.
SOURCE CODE:
module ManchesterCarryChainAdder (
     input [3:0] A,              // 4-bit input A
     input [3:0] B,              // 4-bit input B
     output [3:0] Sum,           // 4-bit sum output
     output Cout                         // Carry out
);
wire [3:0] G;                    // Generate signals
wire [3:0] P;                    // Propagate signals
wire [3:0] C;                    // Carry signals
                                 // Generate and Propagate signals
assign G = A & B;
assign P = A ^ B;
assign C[0] = 0; // Initialize the first carry bit to 0
                                // Generate Carry Chain
genvar i;
generate
  for (i = 1; i < 4; i = i + 1) begin
      assign C[i] = G[i-1] | (P[i-1] & C[i-1]);
  end
endgenerate
                        // Sum Bits
assign Sum = A ^ B ^ C;
                        // Carry out
assign Cout = C[3];
endmodule
SCHEMATIC:
                               Fig 10. Manchester carry chain adder
II.     CARRY LOOK AHEAD SUBTRACTOR
A Carry Look-Ahead Subtractor (CLA Subtractor) is a digital circuit used to perform binary
subtraction. It's an advanced subtractor design that utilizes carry look-ahead logic to
accelerate the subtraction process by computing the borrow (carry-in) signals for each stage
of subtraction in parallel, rather than in a serial fashion as in a ripple-carry subtractor.
The difference and Borrow expressions are given by-
            Diff = A ^ B ^ Borrow in                                               (11)
Where ‘^’ is used for XOR operation.
        Borrow out = (~A) & (B ^ Borrow in) | (B & Borrow in)                     (12)
Where A, B, Borrow in are the inputs, Diff and Borrow out are the outputs, ‘~’ used for NOT
operation, ‘&’ used for AND operation and ‘|’ used for OR operation.
SOURCE CODE:
module carry(
     input [3:0] A,                // 4-bit input A
     input [3:0] B,                 // 4-bit input B
     output [3:0] Diff,            // 4-bit difference output
     output BorrowOut               // Borrow out
);
wire [3:0] G;                      // Generate signals
wire [3:0] P;                      // Propagate signals
wire [3:0] C;                      // Carry signals
                                   // Generate and Propagate signals
assign G = A & ~B;
assign P = A ^ B;
assign C[0] = A[0] & ~B[0]; // Initialize the first carry bit to G0
assign BorrowOut = C[3];          // Borrow out is the MSB carry bit
                               // Generate Carry Look-Ahead
generate
     genvar i;
     for (i = 1; i < 4; i = i + 1) begin
       assign C[i] = G[i-1] | (P[i-1] & C[i-1]);
     end
endgenerate
                           // Difference bits
assign Diff = A - B;
endmodule
SCHEMATIC:
                             Fig 11. Carry look Ahead Subtractor
III.   WALLAC TREE MULTIPLIER
A Wallace Tree Multiplier, also known as a Wallace Tree or Modified Booth Wallace Tree
Multiplier, is a hardware circuit used to perform fast binary multiplication of two binary
numbers. It's a type of multiplier architecture that leverages parallelism to speed up the
multiplication process, making it well-suited for high-performance computing systems and
digital signal processing applications.
The Boolean Expressions for multiplication is given by-
            Y= A*B                                                                 (13)
Where A, B are inputs, Y is the output and ‘*’ denotes multiplication operator.
SOURCE CODE:
module WallaceTreeMultiplier(
 input [3:0]A,
 input [3:0]B,
 output [7:0]prod
  );
 reg [3:0]PP1,PP2,PP3,PP4;
 wire HAC1,HAC2,HAC3,HAC4;
 wire HAS1,HAS2,HAS3,HAS4;
 wire FAC1,FAC2,FAC3,FAC4,FAC5,FAC6,FAC7,FAC8;
 wire FAS1,FAS2,FAS3,FAS4,FAS5,FAS6,FAS7,FAS8;
  always@(*) begin
   PP1={A[3]&&B[0],A[2]&&B[0],A[1]&&B[0],A[0]&&B[0]};
   PP2={A[3]&&B[1],A[2]&&B[1],A[1]&&B[1],A[0]&&B[1]};
   PP3={A[3]&&B[2],A[2]&&B[2],A[1]&&B[2],A[0]&&B[2]};
   PP4={A[3]&&B[3],A[2]&&B[3],A[1]&&B[3],A[0]&&B[3]};
  end
//stage 1
 HA h1 (PP1[2],PP2[1],HAS1,HAC1);
 FA f1 (PP1[3],PP2[2],PP3[1],FAS1,FAC1);
 FA f2 (PP2[3],PP3[2],PP4[1],FAS2,FAC2);
//stage 2
 HA h2 (FAS1,PP4[0],HAS2,HAC2);
 HA h3 (FAS2,FAC1,HAS3,HAC3);
 FA f3 (PP3[3],PP4[2],FAC2,FAS3,FAC3);
//stage 3
 HA h4 (PP1[1],PP2[0],HAS4,HAC4);
 FA f4 (HAS1,PP3[0],HAC4,FAS4,FAC4);
 FA f5 (HAS2,HAC1,FAC4,FAS5,FAC5);
 FA f6 (HAS3,HAC2,FAC5,FAS6,FAC6);
 FA f7 (FAS3,HAC3,FAC6,FAS7,FAC7);
 FA f8 (PP4[3],FAC3,FAC7,FAS8,FAC8);
 assign prod= {FAC8,FAS8,FAS7,FAS6,FAS5,FAS4,HAS4,PP1[0]};
endmodule
                            //HALF ADDER DECLARATION
module HA(A,B,sum,carry);
  input A,B;
  output sum,carry;
  assign sum= A^B;
  assign carry= A&&B;
endmodule
                            //FULL ADDER DECLARATION
module FA(A,B,Cin,sum, carry);
  input A,B,Cin;
  output sum,carry;
  assign sum= A^B^Cin;
  assign carry= (A&&B)||(Cin&&(A^B));
endmodule
SCHEMATIC:
                               Fig 12. Wallace tree multiplier
IV.    RESTORING DIVISION
Restoring division is a method of binary integer division used in digital computing and
microprocessor architectures. It's one of the classic techniques for performing division
operations on binary numbers. In restoring division, both the quotient and remainder are
computed as binary numbers.
SOURCE CODE:
module division(A,B,Q);
  input [3:0] A;
  input [3:0] B;
  output [3:0] Q;
                      //internal variables
  reg [3:0] Q = 0;
  reg [3:0] a1,b1;
  reg [3:0] p1;
  integer i;
  always@ (A or B)
  begin
                         //initialize the variables.
    a1 = A;
    b1 = B;
    p1= 0;
    for(i=0;i < 4;i=i+1)     begin //start the for loop
        p1 = {p1[4-2:0],a1[3]};
        a1[3:1] = a1[2:0];
        p1 = p1-b1;
        if(p1[3] == 1)    begin
          a1[0] = 0;
          p1 = p1 + b1; end
        else
          a1[0] = 1;
    end
    Q = a1;
  end
endmodule
SCHEMATIC:
                                     Fig 13. Restoring Division