RV College of Engineering, Bengaluru-560059
(Autonomous Institution affiliated to VTU, Belgaum)
                     5TH SEMESTER
        EXPERENTIAL LEARNING
              REPORT
         SUBJECT: VLSI Fundamentals
                      Submitted By:
               NAME:ARYAN
             USN:1RV22EE008
                      Submitted To:
                       Dr. Ajay KM
     (Department of Electrical and Electronics
                       Engineering)
                                 i
      Cadence
Exp 1: Inverter Design
          ii
Exp 2:CMOS INVERTER CHARACTERISTCS
               iii
iv
8-bit Counter
      v
XOR gate
   vi
OR gate
  vii
AND gate
   viii
NOR gate
   ix
XNOR gate
    x
NAND gate
    xi
xii
                        Verilog
1. AND gate
module AND_Gate(
   input A,
   input B,
   output Y
);
   assign Y = A & B;
endmodule
testbench:
module AND_Gate_tb;
   reg A, B;
   wire Y;
  AND_Gate uut (
     .A(A),
     .B(B),
     .Y(Y)
  );
  initial begin
     $monitor("A = %b, B = %b, Y = %b", A, B, Y);
     A = 0; B = 0; #10;
     A = 0; B = 1; #10;
     A = 1; B = 0; #10;
     A = 1; B = 1; #10;
     $stop;
  end
endmodule
                           xiii
xiv
   2. OR gate
      Module or_gate(input a,b; output y;);
      Assign y=a|b;
      endmodule
testbench:
module tb_or_gate;
   reg A, B;
   wire Y;
  or_gate uut (
     .A(A),
     .B(B),
     .Y(Y)
  );
  initial begin
     A = 0; B = 0;
     #10;
     A = 0; B = 1;
     #10;
     A = 1; B = 0;
     #10;
     A = 1; B = 1;
     #10;
     $finish;
  end
  initial begin
     $monitor("A = %b, B = %b, Y = %b", A, B, Y);
  end
endmodule
                                 xv
xvi
3. NAND gate
   module nand_gate(
      input a,
      input b,
      output y
   );
      assign Y = ~(A & B);
   endmodule
  testbench:
  module tb_nand_gate;
     reg A, B;
     wire Y;
    nand_gate uut (
       .A(A),
       .B(B),
       .Y(Y)
    );
    initial begin
       A = 0; B = 0;
       #10;
       A = 0; B = 1;
       #10;
       A = 1; B = 0;
       #10;
       A = 1; B = 1;
       #10;
       $finish;
    end
    initial begin
       $monitor("A = %b, B = %b, Y = %b", A, B, Y);
    end
                             xvii
endmodule
            xviii
4. NOR gate
  Code:
  module myAND(
    input a,b,
    output c
    );
    assign c = ~(a|b);
  endmodule
  Testbench:
  module or_tb();
  reg a;
  reg b;
  wire c;
  myAND module_u_test(a,b,c);
  initial begin
  #100;
  a=1;b=0;#100;
  a=1;b=1;#100;
  a=0;b=0;#100;
  a=0;b=1;#100;
  end
  endmodule
                                xix
   5. XOR gate
Code:
module myAND(
  input a,b,
  output c
  );
  assign c = a^b;
endmodule
Testbench:
module or_tb();
reg a;
reg b;
wire c;
myAND module_u_test(a,b,c);
initial begin
#100;
a=1;b=0;#100;
a=1;b=1;#100;
a=0;b=0;#100;
a=0;b=1;#100;
end
endmodule
                              xx
Adders:
 1. Carry Lookahead adder:
 Code:
 module carry_lookahead(
   input [3:0]A,B,
   input Cin,
   output [3:0]Sum,
   output Cout
   );
   wire [3:0]G,P;
   wire [3:0]C;
   assign G=A&B;
   assign P=A^B;
   assign C[0]=Cin;
   assign C[1]=(G[0]|P[0]&C[0]);
   assign C[2]=(G[1]|P[1]&C[1]);
   assign C[3]=(G[2]|P[2]&C[2]);
   assign Cout=(G[3]|P[3]&C[3]);
   assign Sum=P^C;
 endmodule
 Testbench:
 module CLA_tb;
 reg [3:0]A,B;
 reg Cin;
 wire [3:0]Sum;
 wire Cout;
 carry_lookahead uut(
 .A(A),
 .B(B),
 .Cin(Cin),
 .Sum(Sum),
 .Cout(Cout)
 );
 initial begin
 A=4'b0011;B=4'b1010;Cin=1;#10;
 A=4'b1111;B=4'b1010;Cin=1;#10;
 A=4'b1001;B=4'b1011;Cin=1;#10;
 A=4'b1000;B=4'b1111;Cin=1;#10;
 A=4'b0011;B=4'b1000;Cin=1;#10;
 end
 endmodule
                                   xxi
xxii
   2. Carry skip adder
Code:
module CarrySelectAdder4Bit (
   input [3:0] A, B,
   input Cin,
   output [3:0] Sum,
   output Cout
);
  wire [3:0] Sum0, Sum1;
  wire [4:0] Carry0, Carry1;
  assign Carry0[0] = 0;
  assign Carry1[0] = 1;
  genvar i;
  generate
    for (i = 0; i < 4; i = i + 1) begin : bit_slice
      assign Sum0[i] = A[i] ^ B[i] ^ Carry0[i];
      assign Carry0[i+1] = (A[i] & B[i]) | (Carry0[i] & (A[i] ^ B[i]));
      assign Sum1[i] = A[i] ^ B[i] ^ Carry1[i];
      assign Carry1[i+1] = (A[i] & B[i]) | (Carry1[i] & (A[i] ^ B[i]));
    end
  endgenerate
  assign Sum = Cin ? Sum1 : Sum0;
  assign Cout = Cin ? Carry1[4] : Carry0[4];
endmodule
Testbench:
module CarrySelectAdder4Bit_tb;
 reg [3:0] A, B;
 reg Cin;
 wire [3:0] Sum;
 wire Cout;
  // Instantiate the CarrySelectAdder4Bit module
  CarrySelectAdder4Bit uut (
     .A(A),
     .B(B),
     .Cin(Cin),
     .Sum(Sum),
     .Cout(Cout)
  );
  initial begin
    // Monitor the values
    $monitor("Time=%0t A=%b B=%b Cin=%b | Sum=%b Cout=%b", $time, A, B, Cin, Sum,
Cout);
    // Apply test cases
    A = 4'b0000; B = 4'b0000; Cin = 0; #10;
    A = 4'b0001; B = 4'b0001; Cin = 0; #10;
    A = 4'b0010; B = 4'b0011; Cin = 1; #10;
    A = 4'b0110; B = 4'b0101; Cin = 0; #10;
                                                  xxiii
    A = 4'b1111; B = 4'b1111; Cin = 1; #10;
    // End simulation
    $finish;
  end
endmodule
                                              xxiv
   3. Carry save adder
Code:
module CarrySaveAdder4Bit (
   input [3:0] A, B, C,
   output [3:0] Sum,
   output [3:0] Carry
);
 assign Sum = A ^ B ^ C; // Sum without carry propagation
 assign Carry = (A & B) | (B & C) | (C & A); // Carry bits
endmodule
Testbench:
module CarrySaveAdder4Bit_tb;
 reg [3:0] A, B, C;
 wire [3:0] Sum, Carry;
 // Instantiate the CarrySaveAdder4Bit module
 CarrySaveAdder4Bit uut (
    .A(A),
    .B(B),
    .C(C),
    .Sum(Sum),
    .Carry(Carry)
 );
 initial begin
   // Monitor the values
   $monitor("Time=%0t A=%b B=%b C=%b | Sum=%b Carry=%b", $time, A, B, C, Sum, Carry);
   // Apply test cases
   A = 4'b0000; B = 4'b0000; C = 4'b0000; #10;
   A = 4'b0001; B = 4'b0001; C = 4'b0001; #10;
   A = 4'b0010; B = 4'b0011; C = 4'b0001; #10;
   A = 4'b0110; B = 4'b0101; C = 4'b0011; #10;
   A = 4'b1111; B = 4'b1111; C = 4'b1111; #10;
   // End simulation
   $finish;
 end
                                            xxv
endmodule
            xxvi
   4. Carry skip adders
Code:
module carry_skip_adder(
   input [3:0] A, B,
   input Cin,
   output [3:0] Sum,
   output Cout
);
 wire [4:0] carry;
 wire [3:0] P;
 assign carry[0] = Cin;
 genvar i;
 generate
   for (i = 0; i < 4; i = i + 1) begin : bit_slice
     assign P[i] = A[i] ^ B[i];
     assign Sum[i] = P[i] ^ carry[i];
     assign carry[i+1] = (P[i] & carry[i]) | (A[i] & B[i]);
   end
 endgenerate
 assign Cout = carry[4];
endmodule
Testbench:
module carry_skip_tb;
  reg [3:0] A, B;
  reg Cin;
  wire [3:0] Sum;
  wire Cout;
 // Instantiate the CarrySkipAdder4Bit module
 carry_skip_adder uut (
    .A(A),
    .B(B),
    .Cin(Cin),
    .Sum(Sum),
    .Cout(Cout)
 );
  initial begin
    // Monitor the values
    $monitor("Time=%0t A=%b B=%b Cin=%b | Sum=%b Cout=%b", $time, A, B, Cin, Sum,
Cout);
   // Apply test cases
   A = 4'b0000; B = 4'b0000; Cin = 0; #10;
   A = 4'b0001; B = 4'b0001; Cin = 0; #10;
   A = 4'b0010; B = 4'b0011; Cin = 1; #10;
   A = 4'b0110; B = 4'b0101; Cin = 0; #10;
   A = 4'b1111; B = 4'b1111; Cin = 1; #10;
   // End simulation
 end
                                                 xxvii
endmodule
            xxviii
   5. Inverter
Code:
module PMOS(
  input wire A,
  output wire Y
  );
  assign Y=~A;
endmodule
module NMOS(
  input wire A,
  output wire Y
  );
  assign Y=~A;
endmodule
module CMOS_INV(
  input wire in,
  output wire out
  );
  wire nmos_out,pmos_out;
  PMOS p1(.A(in),.Y(pmos_out));
  NMOS n1(.A(in),.Y(nmos_out));
  assign out=pmos_out|nmos_out;
endmodule
Testbench:
       module CMOS_TB;
       reg in;
       wire out;
       CMOS_INV uut(
       .in(in),
       .out(out)
       );
       initial begin
       in=0;
       #10;
       in=1;
       #10;
       in=0;
       #10;
       in=1;
       #10;
       in=0;
       #10;
       in=1;
       #10;
       in=0;
       #10;
       in=1;
       #10;
       in=0;
       #10;
       in=1;
       #10;
       in=0;
       #10;
       in=1;
       #10;
       $finish;
                                  xxix
end
endmodule
            xxx
6. Array Multiplier
Code:
module array_multiplier (
     input [7:0] A,
     input [7:0] B,
     output [15:0] product
);
     wire [7:0] partial [7:0];
     genvar i, j;
     generate
          for (i = 0; i < 8; i = i + 1) begin :
            for (j = 0; j < 8; j = j + 1) begin :
                assign partial[i][j] = A[i] & B[j];
            end
          end
     endgenerate
     assign product = (partial[0]) +
                   (partial[1] << 1) +
                   (partial[2] << 2) +
                   (partial[3] << 3) +
                   (partial[4] << 4) +
                   (partial[5] << 5) +
                   (partial[6] << 6) +
                   (partial[7] << 7);
endmodule
Testbench:
module tb_array_multiplier;
     reg [7:0] A, B;
     wire [15:0] product;
     array_multiplier uut (
          .A(A),
          .B(B),
          .product(product)
     );
                                                      xxxi
initial begin
  $display("A         B       | Product");
  $display("-----------------------------");
  A = 8'b00000001; B = 8'b00000001;
  #10; $display("%b %b | %b", A, B, product);
  A = 8'b00000011; B = 8'b00000010;
  #10; $display("%b %b | %b", A, B, product);
  A = 8'b00001111; B = 8'b00000101;
  #10; $display("%b %b | %b", A, B, product);
  A = 8'b11111111; B = 8'b11111111;
  #10; $display("%b %b | %b", A, B, product);
  A = 8'b01010101; B = 8'b10101010;
  #10; $display("%b %b | %b", A, B, product);
  A = 8'b11110000; B = 8'b00001111;
  #10; $display("%b %b | %b", A, B, product);
  $finish;
end
                                                xxxii
xxxiii
7. Barrel shifter
Code:
module BarrelShifter4Bit (
     input [3:0] A,
     input [1:0] Shift,
     input LeftRight,
     output [3:0] Out
);
     wire [3:0] stage1, stage2;
     assign stage1 = (LeftRight) ? {A[2:0], 1'b0} : {1'b0, A[3:1]};
     assign stage2 = (Shift[0]) ? stage1 : A;
     assign Out = (Shift[1]) ? ((LeftRight) ? {stage2[1:0], 2'b00} : {2'b00, stage2[3:2]}) : stage2;
endmodule
Testbench:
module BarrelShifter4Bit_tb;
     reg [3:0] A;
     reg [1:0] Shift;
     reg LeftRight;
     wire [3:0] Out;
     BarrelShifter4Bit uut (
          .A(A),
          .Shift(Shift),
          .LeftRight(LeftRight),
          .Out(Out)
     );
                                                xxxiv
  initial begin
    $monitor("Time=%0t A=%b Shift=%b LeftRight=%b | Out=%b", $time, A, Shift,
LeftRight, Out);
    // Apply test cases
    A = 4'b1010; Shift = 2'b00; LeftRight = 0; #10;
    A = 4'b1010; Shift = 2'b01; LeftRight = 0; #10;
    A = 4'b1010; Shift = 2'b10; LeftRight = 0; #10;
    A = 4'b1010; Shift = 2'b11; LeftRight = 0; #10;
    A = 4'b1010; Shift = 2'b00; LeftRight = 1; #10;
    A = 4'b1010; Shift = 2'b01; LeftRight = 1; #10;
    A = 4'b1010; Shift = 2'b10; LeftRight = 1; #10;
    A = 4'b1010; Shift = 2'b11; LeftRight = 1; #10;
    // End simulation
    $finish;
  end
endmodule
                                           xxxv
xxxvi
      8. FIFO AND LIFO
Code:
module lifo #(parameter WIDTH = 8, DEPTH = 8)(
     input clk,           // Clock signal
     input reset,         // Active-high reset
     input push,           // Push enable
     input pop,           // Pop enable
     input [WIDTH-1:0] data_in, // Data input
     output reg [WIDTH-1:0] data_out, // Data output
     output reg full,      // Stack full flag
     output reg empty         // Stack empty flag
);
     reg [WIDTH-1:0] stack [DEPTH-1:0]; // Stack memory
     reg [2:0] sp = 0;             // Stack pointer
     always @(posedge clk or posedge reset) begin
       if (reset) begin
          sp <= 0;
          full <= 0;
          empty <= 1;
       end else begin
          // Push Operation
          if (push && !full) begin
             stack[sp] <= data_in;
             sp <= sp + 1;
          end
          // Pop Operation
          if (pop && !empty) begin
             sp <= sp - 1;
             data_out <= stack[sp - 1];
          end
                                                      xxxvii
           // Update full and empty flags
           full <= (sp == DEPTH);
           empty <= (sp == 0);
       end
     end
endmodule
module fifo #(parameter WIDTH = 8, DEPTH = 8)(
     input clk,           // Clock signal
     input reset,         // Active-high reset
     input wr_en,           // Write enable
     input rd_en,           // Read enable
     input [WIDTH-1:0] data_in, // Data input
     output reg [WIDTH-1:0] data_out, // Data output
     output reg full,       // FIFO full flag
     output reg empty         // FIFO empty flag
);
     reg [WIDTH-1:0] memory [DEPTH-1:0]; // FIFO memory storage
     reg [2:0] wr_ptr = 0, rd_ptr = 0; // Write and Read pointers
     reg [3:0] count = 0;             // Number of elements in FIFO
     always @(posedge clk or posedge reset) begin
       if (reset) begin
           wr_ptr <= 0;
           rd_ptr <= 0;
           count <= 0;
           full <= 0;
           empty <= 1;
       end else begin
           // Write Operation
           if (wr_en && !full) begin
             memory[wr_ptr] <= data_in;
             wr_ptr <= (wr_ptr + 1) % DEPTH;
                                                    xxxviii
          count <= count + 1;
        end
        // Read Operation
        if (rd_en && !empty) begin
          data_out <= memory[rd_ptr];
          rd_ptr <= (rd_ptr + 1) % DEPTH;
          count <= count - 1;
        end
        // Update full and empty flags
        full <= (count == DEPTH);
        empty <= (count == 0);
    end
  end
endmodule
Testbench:
module tb_lifo;
  reg clk, reset, push, pop;
  reg [7:0] data_in;
  wire [7:0] data_out;
  wire full, empty;
  // Instantiate LIFO
  lifo uut (
    .clk(clk),
    .reset(reset),
    .push(push),
    .pop(pop),
    .data_in(data_in),
    .data_out(data_out),
    .full(full),
    .empty(empty)
                                            xxxix
  );
  // Clock Generation
  always #5 clk = ~clk;
  initial begin
       clk = 0;
       reset = 1;
       #10 reset = 0;
       // Push data into LIFO
       push = 1; pop = 0; data_in = 8'hA1; #10;
       data_in = 8'hB2; #10;
       data_in = 8'hC3; #10;
       push = 0; #10; // Stop pushing
       // Pop data from LIFO
       pop = 1; #30;
       pop = 0; #10; // Stop popping
       $finish;
  end
  initial begin
       $monitor("Time: %0t | Data In: %h | Data Out: %h | Full: %b | Empty: %b",
             $time, data_in, data_out, full, empty);
  end
endmodule
module tb_fifo;
  reg clk, reset, wr_en, rd_en;
  reg [7:0] data_in;
  wire [7:0] data_out;
                                                       xl
wire full, empty;
// Instantiate FIFO
fifo uut (
     .clk(clk),
     .reset(reset),
     .wr_en(wr_en),
     .rd_en(rd_en),
     .data_in(data_in),
     .data_out(data_out),
     .full(full),
     .empty(empty)
);
// Clock Generation
always #5 clk = ~clk;
initial begin
     clk = 0;
     reset = 1;
     #10 reset = 0;
     // Write data into FIFO
     wr_en = 1; rd_en = 0; data_in = 8'hA1; #10;
     data_in = 8'hB2; #10;
     data_in = 8'hC3; #10;
     wr_en = 0; #10; // Stop writing
     // Read data from FIFO
     rd_en = 1; #30;
     rd_en = 0; #10; // Stop reading
     $finish;
end
                                                   xli
  initial begin
    $monitor("Time: %0t | Data In: %h | Data Out: %h | Full: %b | Empty: %b",
          $time, data_in, data_out, full, empty);
  end
endmodule
                                                    xlii
xliii
9. D-flip flop
Code:
module d_flip_flop (
     input D,
     input clk,
     input reset,
     output reg Q
);
     always @(posedge clk or posedge reset) begin
           if (reset) begin
              Q <= 0;
           end else begin
              Q <= D;
           end
     end
endmodule
Testbench:
module tb_d_flip_flop;
     reg D;
     reg clk;
     reg reset;
     wire Q;
     d_flip_flop uut (
          .D(D),
          .clk(clk),
          .reset(reset),
          .Q(Q)
     );
     // Generate clock signal
     always begin
                                             xliv
    #5 clk = ~clk;
  end
  initial begin
    clk = 0;
    reset = 0;
    D = 0;
    reset = 1;
    #10;
    reset = 0;
    D = 1;
    #10;
    D = 0;
    #10;
    D = 1; /
    #10;
    D = 0;
    #10;
  end
  initial begin
    $monitor("At time %t, D = %b, Q = %b", $time, D, Q);
  end
endmodule
                                                  xlv
xlvi
    10. T-Flip Flop
    Code:
    module t_flip_flop (
         input T,
         input clk,
         input reset,
         output reg Q
    );
         always @(posedge clk or posedge reset) begin
           if (reset) begin
               Q <= 0;
           end else if (T) begin
               Q <= ~Q; 1
           end
         end
    endmodule
    Testbench:
module tb_t_flip_flop;
  reg T;
  reg clk;
  reg reset;
  wire Q;
  t_flip_flop uut (
     .T(T),
     .clk(clk),
     .reset(reset),
     .Q(Q)
  );
  always begin
    #5 clk = ~clk;
  end
  initial begin
     // Initialize inputs
     clk = 0;
     reset = 0;
     T = 0;
    reset = 1;
    #10;
    reset = 0;
                                                        xlvii
    T = 1;
    #10;
    T = 0;
    #10;
    T = 1;
    #10;
    T = 0;
    #10;
    $finish;
  end
  // Monitor the values of Q
  initial begin
     $monitor("At time %t, T = %b, Q = %b", $time, T, Q);
  end
endmodule
                                                      xlviii
    11. JK-Flip flop
Code:
module jk_flip_flop (
   input J,
   input K,
   input clk,
   input reset,
   output reg Q,
   output reg Qn
);
  always @(posedge clk or posedge reset) begin
    if (reset) begin
       Q <= 0;
       Qn <= 1;
    end else begin
       case ({J, K})
          2'b00: begin
             Q <= Q;
             Qn <= Qn;
          end
          2'b01: begin
             Q <= 0;
             Qn <= 1;
          end
          2'b10: begin
             Q <= 1;
             Qn <= 0;
          end
          2'b11: begin
             Q <= ~Q;
             Qn <= ~Qn;
          end
       endcase
    end
  end
endmodule
Testbench:
module tb_jk_flip_flop;
  reg J;
  reg K;
  reg clk;
  reg reset;
  wire Q;
  wire Qn;
  jk_flip_flop uut (
     .J(J),
     .K(K),
     .clk(clk),
     .reset(reset),
     .Q(Q),
     .Qn(Qn)
  );
  always begin
    #5 clk = ~clk;
  end
  initial begin
                                                 xlix
      clk = 0;
      reset = 0;
      J = 0;
      K = 0;
      reset = 1;
      #10;
      reset = 0;
      #10;
      J = 0; K = 0;
      #10;
      J = 0; K = 1;
      #10;
      J = 1; K = 0;
      #10;
      J = 1; K = 1;
      #10;
      $finish;
    end
    initial begin
       $monitor("At time %t, J = %b, K = %b, Q = %b, Qn = %b", $time, J, K, Q, Qn);
    end
                                                           l
li
12. SR Flip Flop
Code:
module srflipflop (
   input S,
   input R,
   input clk,
   input reset,
   output reg Q,
   output reg Qn
);
  always @(posedge clk or posedge reset) begin
    if (reset) begin
       Q <= 0;
       Qn <= 1;
    end else begin
       case ({S, R})
          2'b00: begin
             Q <= Q;
             Qn <= Qn;
          end
          2'b01: begin
             Q <= 0;
             Qn <= 1;
          end
          2'b10: begin
             Q <= 1;
             Qn <= 0;
          end
          2'b11: begin
             Q <= 1'bx;
             Qn <= 1'bx;
          end
       endcase
    end
  end
endmodule
Testbench:
module srfliptb;
  reg S;
  reg R;
  reg clk;
  reg reset;
  wire Q;
  wire Qn;
  srflipflop uut (
     .S(S),
     .R(R),
     .clk(clk),
     .reset(reset),
     .Q(Q),
     .Qn(Qn)
  );
  always begin
    #5 clk = ~clk;
  end
  initial begin
                                                 lii
    clk = 0;
    reset = 0;
    S = 0;
    R = 0;
    reset = 1;
    #10;
    reset = 0;
    #10;
    S = 0; R = 0;
    #10;
    S = 0; R = 1;
    #10;
    S = 1; R = 0;
    #10;
    S = 1; R = 1;
    #10;
    $finish;
  end
  initial begin
     $monitor("At time %t, S = %b, R = %b, Q = %b, Qn = %b", $time, S, R, Q, Qn);
  end
endmodule
                                                   liii
liv
13.Divider
Code:
module divider_4bit (
   input [3:0] dividend,
   input [3:0] divisor,
   output reg [3:0] quotient,
   output reg [3:0] remainder
);
  always @ (dividend or divisor) begin
    if (divisor != 0) begin
       quotient = dividend / divisor;
       remainder = dividend % divisor;
    end else begin
       quotient = 4'b0000;
       remainder = 4'b0000;
    end
  end
endmodule
Testbench:
module tb_divider_4bit;
  reg [3:0] dividend, divisor;
  wire [3:0] quotient, remainder;
  divider_4bit uut (
     .dividend(dividend),
     .divisor(divisor),
     .quotient(quotient),
     .remainder(remainder)
  );
  initial begin
     $display("Dividend Divisor | Quotient Remainder");
     $display("------------------------------------------");
     dividend = 4'b0010; divisor = 4'b0001;
     #10; $display("%b       %b       | %b     %b", dividend, divisor, quotient, remainder);
     dividend = 4'b0100; divisor = 4'b0010;
     #10; $display("%b       %b       | %b     %b", dividend, divisor, quotient, remainder);
     dividend = 4'b1001; divisor = 4'b0011;
     #10; $display("%b       %b       | %b     %b", dividend, divisor, quotient, remainder);
     dividend = 4'b1010; divisor = 4'b0101;
     #10; $display("%b       %b       | %b     %b", dividend, divisor, quotient, remainder);
     dividend = 4'b1111; divisor = 4'b0010;
     #10; $display("%b       %b       | %b     %b", dividend, divisor, quotient, remainder);
     dividend = 4'b1111; divisor = 4'b1111;
     #10; $display("%b       %b       | %b     %b", dividend, divisor, quotient, remainder);
     dividend = 4'b1000; divisor = 4'b0000;
     #10; $display("%b       %b       | %b     %b", dividend, divisor, quotient, remainder);
    $finish;
  end
endmodule
                                                           lv
lvi
14. Parallel Adder
    Code:
    module carry_lookahead(
     input [3:0]A,B,
     input Cin,
     output [3:0]Sum,
     output Cout
     );
     wire [3:0]G,P;
     wire [3:0]C;
     assign G=A&B;
     assign P=A^B;
     assign C[0]=Cin;
     assign C[1]=(G[0]|P[0]&C[0]);
     assign C[2]=(G[1]|P[1]&C[1]);
     assign C[3]=(G[2]|P[2]&C[2]);
     assign Cout=(G[3]|P[3]&C[3]);
     assign Sum=P^C;
    endmodule
    Testbench:
    module CLA_tb;
    reg [3:0]A,B;
    reg Cin;
    wire [3:0]Sum;
    wire Cout;
    carry_lookahead uut(
    .A(A),
    .B(B),
    .Cin(Cin),
    .Sum(Sum),
    .Cout(Cout)
    );
    initial begin
    A=4'b0011;B=4'b1010;Cin=1;#10;
    A=4'b1111;B=4'b1010;Cin=1;#10;
    A=4'b1001;B=4'b1011;Cin=1;#10;
    A=4'b1000;B=4'b1111;Cin=1;#10;
    A=4'b0011;B=4'b1000;Cin=1;#10;
    end
    endmodule
                                     lvii
lviii
15. Serial Adder
Code:
module serial_adder_4bit (
input clk,
input reset,
input start,
input A_in,
input B_in,
output reg sum,
output reg carry_out,
output reg done
);
reg [1:0] bit_count;
reg [4:0] A_reg, B_reg;
reg [1:0] state, next_state;
parameter IDLE = 2'b00, ADD = 2'b01, DONE = 2'b10;
always @(posedge clk or posedge reset) begin
if (reset) begin
state <= IDLE;
bit_count <= 0;
A_reg <= 0;
B_reg <= 0;
sum <= 0;
carry_out <= 0;
done <= 0;
end else begin
state <= next_state;
                                               lix
end
end
always @(*) begin
case (state)
IDLE: next_state = start ? ADD : IDLE;
ADD: next_state = (bit_count == 4) ? DONE : ADD;
DONE: next_state = IDLE;
default: next_state = IDLE;
endcase
end
always @(posedge clk) begin
if (state == ADD) begin
A_reg <= {A_in, A_reg[4:1]};
B_reg <= {B_in, B_reg[4:1]};
sum <= A_reg[0] ^ B_reg[0] ^ carry_out;
carry_out <= (A_reg[0] & B_reg[0]) | (carry_out & (A_reg[0] ^ B_reg[0]));
bit_count <= bit_count + 1;
end else if (state == DONE) begin
done <= 1;
end else begin
done <= 0;
end
end
                                               lx
Testbench:
module tb_serial_adder_4bit;
  reg clk;
  reg reset;
  reg start;
  reg A_in, B_in;
  wire sum;
  wire carry_out;
  wire done;
  serial_adder_4bit uut (
     .clk(clk),
     .reset(reset),
     .start(start),
     .A_in(A_in),
     .B_in(B_in),
     .sum(sum),
     .carry_out(carry_out),
     .done(done)
  );
  always begin
    #5 clk = ~clk;
  end
  initial begin
     clk = 0;
     reset = 0;
     start = 0;
     A_in = 0;
     B_in = 0;
    reset = 1;
    #10;
    reset = 0;
    start = 1;
    #10;
    start = 0;
    A_in = 1; B_in = 1; #10;
    A_in = 0; B_in = 0; #10;
    A_in = 1; B_in = 1; #10;
    A_in = 1; B_in = 1; #10;
    #20;
    if (done) $display("Addition is done. Sum: %b, Carry Out: %b", sum, carry_out);
  end
  initial begin
     $monitor("At time %t, A_in = %b, B_in = %b, Sum = %b, Carry Out = %b, Done = %b", $time, A_in, B_in, sum,
carry_out, done);
  end
endmodule
                                                        lxi
lxii