Saturday, July 9, 2022

Digital VLSI Design/RTL Design - Key Suggestions/Best Practices

                            

Key Suggestions/Best Practices for RTL Design


1) Always Partition Your Design into Small Blocks :

     - Partition the design into subsystems which is easy to design and test individual

     - Use Major/Minor FSMs whenever appropriate

2) Always Try to Use Same Edge Triggered Flip Flops:

     - If there are multiple clock domain , careful about passing the information from one clock domain to another clock domain

     - Proper clock domain crossing need to take place in order to corrupt any data passing between two clock domains

     - Beware of clock skew

3) Design Should be "Glitch" Free:

     - There is always glitch problem with combinations circuits

     - Never drive any critical asynchronous control signal ( Clock , Write Enable etc ) directly from the output of combinational logic

     - Whenever needed, always try to create glitch free signals by registering them

     - Always ensure a stable combinational logic output before it is sampled by clock

4) Synchronize all Asynchronous Signals:

    - Synchronize by using N-DFF ( Ex : 2-DFF Synchronizer)

5) Always Avoid Tri-State Bus Contention by Design

6) Use Asynchronous Memories Carefully:

    - Make sure write pulse is glitch free

    - Avoid any address change when Write Enable is True

    - Avoid any Z (High Impedance) address to SRAM when CE is asserted

7) During Block - to - Block Communication -

    - Might need to synchronize signals

    - Asynchronous Protocols can also be used



Thanks !


Friday, July 8, 2022

Digital Design of N - Bit Magnitude Comparator (Circuit + Verilog HDL Code)


N-Bit Magnitude Comparator:

- N bit magnitude comparators can be created by cascading 1 bit or 2 bit or 4 bit magnitide comparators

- In this blog we are going to develop N - Bit Magnitude Comparator using 1 - Bit Magnitude Comparators


Block Diagram of N Bit Magnitude Comparator:
    


Circuit Diagram of N Bit Magnitude Comparator:

     

Note:

- The AEQB_in of first comparator need to be tied to ONE inorder to perform comparision of first bit in the N bit number

- AGB_in and ALB_in of first comparator can be tied to ZERO


Verilog HDL Code:

---------------------------------------------------------------------------------------------------------------------------

// Code your design here

`include "magnitude_comparator_1_bit_type2.sv"

module magnitude_comparator_n_bit_type2#(parameter N = 4)(a_in, b_in, aeqb_o, agb_o, alb_o, aeqb_in, agb_in, alb_in);

  input [N-1 : 0] a_in;

  input [N-1 : 0] b_in;

  output aeqb_o;

  output agb_o;

  output alb_o;

  input aeqb_in;

  input agb_in;

  input alb_in;

  genvar gen;

  wire [N : 0] aeqb_w;

  wire [N : 0] agb_w;

  wire [N : 0] alb_w;

  assign aeqb_w[0] = aeqb_in;

  assign agb_w[0] = agb_in;

  assign alb_w[0] = alb_in;    

generate 

    for (gen = 0; gen < N; gen++)

      begin        

        magnitude_comparator_1_bit_type2 CMP(.a_in(a_in[gen]), .b_in(b_in[gen]), .aeqb_in(aeqb_w[gen]), .agb_in(agb_w[gen]), .alb_in(alb_w[gen]), .aeqb_o(aeqb_w[gen + 1]), .agb_o(agb_w[gen + 1]), .alb_o(alb_w[gen + 1]));

      end

endgenerate        

  assign aeqb_o = aeqb_w[N];

  assign  agb_o = agb_w[N];

  assign  alb_o = alb_w[N];

endmodule

module magnitude_comparator_1_bit_type2(a_in, b_in, aeqb_o, agb_o, alb_o, aeqb_in, agb_in, alb_in);

  input a_in;

  input b_in;

  output aeqb_o;

  output agb_o;

  output alb_o;

  input aeqb_in;

  input agb_in;

  input alb_in;

  

 /* a_in      b_in    aeqb     agb    alb

    0        0       1        0      0

    0        1       0        0      1

    1        0       0        1      0

    1        1       1        0      0        */  

  

 reg aeqb_w, agb_w, alb_w;

  always @(*)

    begin

      if(aeqb_in)

        begin

          aeqb_w = ((~a_in & ~b_in) | (a_in & b_in));

           agb_w = (a_in & ~b_in);

           alb_w = (~a_in & b_in);

        end

      else

        begin

          aeqb_w = aeqb_in;

           agb_w = agb_in;

           alb_w = alb_in;

        end

    end

 assign aeqb_o = aeqb_w;

 assign agb_o = agb_w;  

 assign alb_o = alb_w;

endmodule


Test Bench Code:

---------------------------------------------------------------------------------------------------------------------------

module magnitude_comparator_n_bit_type2_test;

  parameter N = 4;

  reg [N-1 : 0] a_in;

  reg [N-1 : 0] b_in;

  reg aeqb_in;

  reg agb_in;

  reg alb_in;

  wire aeqb_o;

  wire agb_o;

  wire alb_o;

  // Instantiate design under test

  magnitude_comparator_n_bit_type2 #(4) DUT(.a_in(a_in), .b_in(b_in), .aeqb_in(aeqb_in), .agb_in(agb_in), .alb_in(alb_in), .aeqb_o(aeqb_o), .agb_o(agb_o), .alb_o(alb_o));

  initial begin

    // Dump waves

    $dumpfile("dump.vcd");

    $dumpvars(1);

    a_in = 4'b0;

    b_in = 4'b0;

    aeqb_in = 1'b0;

    agb_in = 1'b0;

    alb_in = 1'b0;

    #10 a_in = 4'b0001; b_in = 4'b0000;

    #10 a_in = 4'b0100; b_in = 4'b1001;

    #10 a_in = 4'b1010; b_in = 4'b1000;

    #10 a_in = 4'b1110; b_in = 4'b0010; 

    #5 aeqb_in = 1'b1;

    #10 a_in = 4'b0001; b_in = 4'b0000;

    #10 a_in = 4'b0100; b_in = 4'b1001;

    #10 a_in = 4'b1010; b_in = 4'b1000;

    #10 a_in = 4'b1110; b_in = 4'b0010; 

  end   

endmodule


Thanks !




Digital Design of 1-Bit Magnitude Comparator Type#2 (Circuit + Verilog HDL Code)

Magnitude Comparator:

- A magnitude comparator is a combinational circuit which is used to compare two binary numbers in order to find out whether one number is equal or greater or less than the other number

Block Diagram of 1 Bit Magnitude Comparator:

   

Truth Table:
          

a_in

 

  b_in

 agb_in

  aeqb_in

 alb_in

   agb_o

   aeqb_o

 alb_o

     0

    0

                 X

      0

         X

agb_in

aeqb_in

alb_in

     0

    1

                 X

      0

         X

agb_in

aeqb_in

alb_in

     1

    0

     x

      0

         X

agb_in

aeqb_in

alb_in

     1

    1

                 X

      0

         X

agb_in

aeqb_in

alb_in

     0

    0

                 X

      1

         X

      0

      1

    0

     0

    1

                 X

      1

         X

      0

      0

    1

     1

    0

                 X

      1

         X

      1

      0

    0

     1

    1

     x

      1

         x

      0

      1

    0

 

Logic Expresison:

- From the truth table above we can see that when aeqb_in == 0, The outputs (aeqb_o, agb_o, alb_o) always gets the input values (aeqb_in, agb_in, alb_in)

- When the aeqb_in is 1, the output values are similar to one bit magnitude comparator.

- Putting in a logical expression format -

aeqb_o = (aeqb_in == 0) ? aeqb_in : (a_in' . b_in' + a_in . b_in);

agb_o = (aeqb_in == 0) ? agb_in : (a_in . b_in');

alb_o = (aeqb_in == 0) ? alb_in : (a_in' . b_in);



Circuit Diagram:

   



Verilog HDL Code:

-----------------------------------------------------------------------------------------------------------------------------

module magnitude_comparator_1_bit_type2(a_in, b_in, aeqb_o, agb_o, alb_o, aeqb_in, agb_in, alb_in);

  input a_in;

  input b_in;

  output aeqb_o;

  output agb_o;

  output alb_o;

  input aeqb_in;

  input agb_in;

  input alb_in;

  

 /* a_in      b_in    aeqb     agb    alb

    0        0       1        0      0

    0        1       0        0      1

    1        0       0        1      0

    1        1       1        0      0        */  

  

 reg aeqb_w, agb_w, alb_w;

  always @(*)

    begin

      if(aeqb_in)

        begin

          aeqb_w = ((~a_in & ~b_in) | (a_in & b_in));

           agb_w = (a_in & ~b_in);

           alb_w = (~a_in & b_in);

        end

      else

        begin

          aeqb_w = aeqb_in;

           agb_w = agb_in;

           alb_w = alb_in;

        end

    end

 assign aeqb_o = aeqb_w;

 assign agb_o = agb_w; 

 assign alb_o = alb_w; 

endmodule


Test Bench Code:

--------------------------------------------------------------------------------------------------------------------------

module magnitude_comparator_1_bit_type2_test;

  reg a_in;

  reg b_in;

  reg aeqb_in;

  reg agb_in;

  reg alb_in;

  wire aeqb_o;

  wire agb_o;

  wire alb_o;

  // Instantiate design under test

  magnitude_comparator_1_bit_type2 DUT(.a_in(a_in), .b_in(b_in), .aeqb_in(aeqb_in), .agb_in(agb_in), .alb_in(alb_in), .aeqb_o(aeqb_o), .agb_o(agb_o), .alb_o(alb_o));     

  initial begin

    // Dump waves

    $dumpfile("dump.vcd");

    $dumpvars(1); 

    a_in = 1'b0;

    b_in = 1'b0;

    aeqb_in = 1'b0;

    agb_in = 1'b0;

    alb_in = 1'b0;

    #10 a_in = 1'b1; b_in = 1'b0;

    #10 a_in = 1'b0; b_in = 1'b1;

    #10 a_in = 1'b1; b_in = 1'b1;

    #10 a_in = 1'b0; b_in = 1'b0; 

    #5 aeqb_in = 1'b1;

    #10 a_in = 1'b1; b_in = 1'b0;

    #10 a_in = 1'b0; b_in = 1'b1;

    #10 a_in = 1'b1; b_in = 1'b1; 

    #10 a_in = 1'b0; b_in = 1'b0; 

  end

endmodule

Simulation Waveform:

   



Thanks !


Wednesday, July 6, 2022

Digital Design of 1-Bit Magnitude Comparator Type#1 (Circuit + Verilog HDL Code)



Magnitude Comparator:

- A magnitude comparator is a combinational circuit which is used to compare two binary numbers in order to find out whether one number is equal or greater or less than the other number

Block Diagram of 1 Bit Magnitude Comparator:

  



Truth Table of 1 Bit Magnitude Comparator:      

         a_in

         b_in

       a_in > b_in

       a_in = b_in

    a_in < b_in

            0

            0

                 0

                 1

                0

            0

            1

                 0

                 0

                1

            1

            0

                 1

                 0

                0

            1

            1

                 0

                 1

                0

                        
                                Table 1 : 1 Bit Magnitude Comaparator Truth Table

Logic Expression ( From the Truth Table 1 Above):

Lets call a_in > b_in as agb, a_in = b_n as aeq, a_in < b_in as alb

From the truth table ,

agb = a_in . b_in';

aeqb = a_in' . b_in + a_in . b_in' ;

aeqb = a_in ^ b_in;

alb = a_in . b_in' ;

Circuit Diagram of 1 Bit Magnitude Caomapartor:

   


    

Verilog HDL Code:

------------------------------------------------------------------------------------------------------------------------

module magnitude_comparator_1_bit(a_in, b_in, aeqb_o, agb_o, alb_o);

  input a_in;

  input b_in;

  output aeqb_o;

  output agb_o;

  output alb_o;

  

 /* a_in      b_in    aeqb     agb    alb

    0        0       1        0      0

    0        1       0        0      1

    1        0       0        1      0

    1        1       1        0      0        */  

  

  assign aeqb_o = ((~a_in & ~b_in) | (a_in & b_in));

  assign agb_o = (a_in & ~b_in);

  assign alb_o = (~a_in & b_in);

endmodule


Test Bench Code:

-----------------------------------------------------------------------------------------------------------------------

module magnitude_comparator_1_bit_test;

  reg a_in;

  reg b_in;

  wire aeqb_o;

  wire agb_o;

  wire alb_o;

  // Instantiate design under test

  magnitude_comparator_1_bit DUT(.a_in(a_in), .b_in(b_in), .aeqb_o(aeqb_o), .agb_o(agb_o), .alb_o(alb_o));    

  initial begin

    // Dump waves

    $dumpfile("dump.vcd");

    $dumpvars(1);

    a_in = 1'b0;

    b_in = 1'b0;

    #10 a_in = 1'b1; b_in = 1'b0;

    #10 a_in = 1'b0; b_in = 1'b1;

    #10 a_in = 1'b1; b_in = 1'b1; 

    #10 a_in = 1'b0; b_in = 1'b0;  

  end     

endmodule


Simulation Waveform:





Thanks !

Digital Design of Parallel Adder/Subtractor (Circuit + HDL Code )



Parallel Adder/Subtractor Design:

- The parallel adder/subtractor circuit is capable to perform both addition and subtraction operations

- The control input of the parallel adder/subtractor circuit defines if it is going to perfom additon or subtraction operation

- If control signal is '0' , the circuit will perform addition operation else if control input is '1' , the circuit will perform subtraction operation

- The Ex-Or Gate will invert the second input (B) bits when control input is 1, hence performing 1's compliemnt of input B

- The control input will be added with 1's compleiemnt of B using full adder (FA0) which will result in 2's compliemnt of B

- Finally A + 2's Compliemnt value of B , will be added , which is nothing but 'A - B'

Block Diagram of Parallel Adder/Subtractor:

    


Verilog HDL Code:

----------------------------------------------------------------------------------------------------------------------------

// Code your design here

`include "full_adder.sv"

module parallel_adder_subtractor(a_in, b_in, control_in, sum_diff_o, carry_borrow_o);

  input [3:0] a_in;

  input [3:0] b_in;

  input control_in;

  output [3:0]sum_diff_o;

  output carry_borrow_o; 

  wire [3:0] b_in_q;

  wire carry_borrow_1, carry_borrow_2, carry_borrow_3; 

  assign b_in_q = b_in ^ ({4{control_in}});

  full_adder FA1(.a_in(a_in[0]), .b_in(b_in_q[0]), .carry_in(control_in), .sum_o(sum_diff_o[0]), .carry_o(carry_1));

  full_adder FA2(.a_in(a_in[1]), .b_in(b_in_q[1]), .carry_in(carry_1), .sum_o(sum_diff_o[1]), .carry_o(carry_2));  

  full_adder FA3(.a_in(a_in[2]), .b_in(b_in_q[2]), .carry_in(carry_2), .sum_o(sum_diff_o[2]), .carry_o(carry_3)); 

  full_adder FA4(.a_in(a_in[3]), .b_in(b_in_q[3]), .carry_in(carry_3), .sum_o(sum_diff_o[3]), .carry_o(carry_borrow_o));  

endmodule


module full_adder (a_in, b_in, carry_in, sum_o, carry_o);

  input a_in;

  input b_in;

  input carry_in;

  output sum_o;

  output carry_o;

  assign sum_o = (a_in ^ b_in ^ carry_in);

  assign carry_o = (((a_in ^ b_in)& carry_in) | (a_in & b_in));

  //assign carry_o = ((a_in & b_in) | (b_in & carry_in) | (a_in & carry_in));  

endmodule


Test Bench Code:

-------------------------------------------------------------------------------------------------------------------------

module parallel_adder_subtractor_test;

  reg [3:0]a_in;

  reg [3:0]b_in;

  reg control_in;

  wire [3:0]sum_diff_o;

  wire carry_borrow_o; 

  // Instantiate design under test

  parallel_adder_subtractor DUT(.a_in(a_in), .b_in(b_in), .control_in(control_in), .sum_diff_o(sum_diff_o), .carry_borrow_o(carry_borrow_o));      

  initial begin

    // Dump waves

    $dumpfile("dump.vcd");

    $dumpvars(1);

    a_in = 4'b0000;

    b_in = 4'b0000;

    control_in = 1'b0;   

    #10 a_in = 4'b0000; b_in = 4'b0001; control_in = 1'b1;

    #10 a_in = 4'b0001; b_in = 4'b0001; control_in = 1'b0;

    #10 a_in = 4'b0010; b_in = 4'b0011; control_in = 1'b1; 

    #10 a_in = 4'b1111; b_in = 4'b1010; control_in = 1'b0; 

    #10 a_in = 4'b1001; b_in = 1'b1000; control_in = 1'b1;

    #10 a_in = 4'b1101; b_in = 4'b1001; control_in = 1'b0 

    #10 a_in = 4'b0001; b_in = 4'b0011; control_in = 1'b1; 

    #10 a_in = 4'b0001; b_in = 4'b0000; control_in = 1'b0;   

  end     

endmodule

Simulation Waveform:

  




Thanks !

Tuesday, July 5, 2022

Digital Design of 16 - Bit Carry Look Ahead Adder ( Circuit + Verilog HDL)



16 Bit Carry Look-ahead Adder:

- In last blog we discussed about 4 bit carry look-ahead adder - 4 bit Carry Look-ahead Adder

- Connecting four instances of 4-bit carry look-ahead adder will result in a 16 Bit Carry Look-ahead Adder

Block Diagram of 16 Bit Carry Look-ahead Adder:

     


Verilog HDL Code:

-------------------------------------------------------------------------------------------------------------------------

`include "carry_look_ahead_adder_4_bit.sv"

module carry_look_ahead_adder_16_bit(a_in, b_in, carry_in, sum_o, carry_o);

  input [15:0] a_in;

  input [15:0] b_in;

  input carry_in;

  output [15:0] sum_o;

  output carry_o;

  wire c1, c2, c3, c4;

  carry_look_ahead_adder_4_bit   CLA1(.a_in(a_in[3:0]), .b_in(b_in[3:0]), .carry_in(carry_in), .sum_o(sum_o[3:0]), .carry_o(c1)); 

  carry_look_ahead_adder_4_bit   CLA2(.a_in(a_in[7:4]), .b_in(b_in[7:4]), .carry_in(c1), .sum_o(sum_o[7:4]), .carry_o(c2)); 

  carry_look_ahead_adder_4_bit   CLA3(.a_in(a_in[11:8]), .b_in(b_in[11:8]), .carry_in(c2), .sum_o(sum_o[11:8]), .carry_o(c3)); 

  carry_look_ahead_adder_4_bit   CLA4(.a_in(a_in[15:12]), .b_in(b_in[15:12]), .carry_in(c3), .sum_o(sum_o[15:12]), .carry_o(c4));  

  assign carry_o = c4;

endmodule


// Code your design here

`include "full_adder.sv"

module carry_look_ahead_adder_4_bit(a_in, b_in, carry_in, sum_o, carry_o);

  input [3:0]a_in;

  input [3:0]b_in;

  input carry_in;

  output [3:0]sum_o;

  output carry_o;

  wire g0, g1, g2, g3;  // Carry generate

  wire p0, p1, p2, p3;  // Carry Propogate 

  wire c0, c1, c2, c3, c4;      // Next step carry 

  wire c_1, c_2, c_3, c_4;

  assign g0 = a_in[0] & b_in[0];

  assign g1 = a_in[1] & b_in[1];

  assign g2 = a_in[2] & b_in[2];

  assign g3 = a_in[3] & b_in[3];

  assign p0 = a_in[0] ^ b_in[0]; 

  assign p1 = a_in[1] ^ b_in[1];

  assign p2 = a_in[2] ^ b_in[2]; 

  assign p3 = a_in[3] ^ b_in[3];

 // C1 = G0 + P0 · C0

 // C2 = G1 + P1 · C1 = G1 + P1 · G0 + P1 · P0 · C0

 // C3 = G2 + P2 · C2 = G2 + P2 · G1 + P2 · P1 · G0 + P2 · P1 · P0 · C0

 // C4 = G3 + P3 · C3 = G3 + P3 · G2 + P3 · P2 · G1 + P3 · P2 · P1 · G0 + P3 · P2 · P1 · P0 · C0

  assign c0 = carry_in;

  assign c1 = (g0 | (p0 & c0));

  assign c2 = (g1 | (p1 & g0) | (p1 & p0 & c0));

  assign c3 = (g2 | (p2 & g1) | (p2 & p1 & g0) | (p2 & p1 & p0 & c0));

  assign c4 = (g3 | (p3 & g2) | (p3 & p2 & g1) | (p3 & p2 & p1 & g0) | (p3 & p2 & p1 & p0 & c0));

  full_adder FA1(.a_in(a_in[0]), .b_in(b_in[0]), .carry_in(c0), .sum_o(sum_o[0]), .carry_o(c_1));

  full_adder FA2(.a_in(a_in[1]), .b_in(b_in[1]), .carry_in(c1), .sum_o(sum_o[1]), .carry_o(c_2));

  full_adder FA3(.a_in(a_in[2]), .b_in(b_in[2]), .carry_in(c2), .sum_o(sum_o[2]), .carry_o(c_3)); 

  full_adder FA4(.a_in(a_in[3]), .b_in(b_in[3]), .carry_in(c3), .sum_o(sum_o[3]), .carry_o(c_4)); 

  assign carry_o = c4;  

endmodule


module full_adder (a_in, b_in, carry_in, sum_o, carry_o);

  input a_in;

  input b_in;

  input carry_in;

  output sum_o;

  output carry_o;

  assign sum_o = (a_in ^ b_in ^ carry_in);

  assign carry_o = (((a_in ^ b_in)& carry_in) | (a_in & b_in));

  //assign carry_o = ((a_in & b_in) | (b_in & carry_in) | (a_in & carry_in));  

endmodule


Test Bench Code:

-----------------------------------------------------------------------------------------------------------------------

module carry_look_ahead_adder_16_bit_test

  reg [15:0]a_in;

  reg [15:0]b_in;

  reg carry_in;

  wire [15:0]sum_o;

  wire carry_o;

  // Instantiate design under test

  carry_look_ahead_adder_16_bit DUT(.a_in(a_in), .b_in(b_in), .carry_in(carry_in), .sum_o(sum_o), .carry_o(carry_o));   

  initial begin

    // Dump waves

    $dumpfile("dump.vcd");

    $dumpvars(1);

    a_in = 16'h0000;

    b_in = 16'h0000;

    carry_in = 1'b0; 

    #10 a_in = 16'h0000; b_in = 16'h0001; carry_in = 1'b1;

    #10 a_in = 16'h0001; b_in = 16'h0001; carry_in = 1'b0; 

    #10 a_in = 16'h0010; b_in = 16'h0011; carry_in = 1'b1;

    #10 a_in = 16'h1111; b_in = 16'h1010; carry_in = 1'b0;

    #10 a_in = 16'h9001; b_in = 16'h8000; carry_in = 1'b1;

    #10 a_in = 16'h1101; b_in = 16'h1001; carry_in = 1'b0;

    #10 a_in = 16'h0001; b_in = 16'h0011; carry_in = 1'b1  

    #10 a_in = 16'h0001; b_in = 16'h0000; carry_in = 1'b0  

  end    

endmodule


Simulation Waveform:

Thanks !

  

Monday, July 4, 2022

Digital Design of 4 - Bit Carry Look Ahead Adder ( Circuit + Verilog HDL)

 

Carry Look-ahead Adder:

- A carry look-ahead adder reduces the total propagation delay as compared to a ripple carry adder

- Propagation delay reduction comes at a cost of more complex hardware to be introduced in Carry Look-ahead Adder

- Trade-off between propagation delay and area between carry look-ahead adder and ripple carry adder

- If speed is the concern ( Need Faster ) - Go for carry look-ahead adder else if area is the concern (Need Less Area ) - Go for Ripple Carry Adder


Block Diagram of Carry Look-ahead Adder:

   



Full Adder Truth Table:

                   a_in

                   b_in

        carry_in

                 sum_o

             carry_o

                      0

                     0

               0

                     0

                    0

                      0

                     0

               1

                     1

                    0

                      0

                     1

               0

                     1

                    0

                      0

                     1

               1

                     0

                    1

                      1

                     0

               0

                     1

                    0

                      1

                     0

               1

                     0

                    1

                      1

                     1

               0

                     0

                    1

                      1

                     1

               1

                     1

                    1

                                              Table 1 : Full Adder Truth Table

             a_in

            b_in

       carry_in

  carry_out

Type of Carry

               0

               0

            0

            0

  None

               0

               0

            1

            0

  None

               0

               1

            0

            0

  None

               0

               1

            1

            1

 Carry Propagate

               1

               0

            0

            0

  None

               1

               0

            1

            1

  Propagate

               1

               1

            0

            1

  Carry Generate

               1

               1

            1

            1

Carry Generate/Propagate

                                             Table 2 : Carry Generate , Carry Propagate


Logic Expression for Carry Generate and Carry Propagate ( From Table 2)

Carry Genearte (cg) = a_in . b_in;

Carry Propagate (cp) = a_in' . b_in + a_in . b_in';

cp = a_in ^ b_in;

In General ,

cp[i] = a_in[i] ^ b_in[i];

cg[i] = a_in[i] . b_in[i];

For 4 bit Carry Look-ahead Adder -

cg[0] = a_in[0] & b_in[0];

cg[1] = a_in[1] & b_in[1];

cg[2] = a_in[2] & b_in[2];

cg[3] = a_in[3] & b_in[3];

cp[0] = a_in[0] ^ b_in[0];

cp[1] = a_in[1] ^ b_in[1];

cp[2] = a_in[2] ^ b_in[2];

cp[3] = a_in[3] ^ b_in[3];

Now, we know that carry expression for a full adder is -

carry_out= (a_in ^ b_in)carry_in + a_in . b_in;

In General,

carry[i + 1] = cp [i] . carry[i] + cg[i];

Input stage Carry = carry[0];

Output Carry from First Stage ,

carry[1] = cp[0] . carry[0] + cg[0];

carry[2] = cp[1] . carry[1] + cg[1];

Putting Value of carry[1] ,

carry[2] = cp[1] . (cp[0] . carry[0] + cg[0]) + cg[1];

carry[2] = (cg1 | (cp1 & cg0) | (cp1 & cp0 & carry0));

Similarly,

carry[3] = (cg[2] | (cp[2] & cg[1]) | (cp[2] & cp[1] & cg[0]) | (cp[2] & cp[1] & cp[0] & carry[0]));

carry[4] = (cg[3] | (cp[3] & cg[2]) | (cp[3] & cp[2] & cg[1]) | (cp[3] & cp[2] & cp[1] & cg[0]) | (cp[3] & cp[2] & cp[1] & cp[0] & carry[0]));

    

Verilog HDL Code:

--------------------------------------------------------------------------------------------------------------------------

// Code your design here

`include "full_adder.sv"

module carry_look_ahead_adder_4_bit(a_in, b_in, carry_in, sum_o, carry_o);

  input [3:0]a_in;

  input [3:0]b_in;

  input carry_in;

  output [3:0]sum_o;

  output carry_o;

  wire g0, g1, g2, g3;  // Carry generate

  wire p0, p1, p2, p3;  // Carry Propogate 

  wire c0, c1, c2, c3, c4;      // Next step carry 

  wire c_1, c_2, c_3, c_4;

  assign g0 = a_in[0] & b_in[0]; 

  assign g1 = a_in[1] & b_in[1];

  assign g2 = a_in[2] & b_in[2]; 

  assign g3 = a_in[3] & b_in[3];

  assign p0 = a_in[0] ^ b_in[0];

  assign p1 = a_in[1] ^ b_in[1];

  assign p2 = a_in[2] ^ b_in[2];

  assign p3 = a_in[3] ^ b_in[3];

 // C1 = G0 + P0 · C0

 // C2 = G1 + P1 · C1 = G1 + P1 · G0 + P1 · P0 · C0

 // C3 = G2 + P2 · C2 = G2 + P2 · G1 + P2 · P1 · G0 + P2 · P1 · P0 · C0

 // C4 = G3 + P3 · C3 = G3 + P3 · G2 + P3 · P2 · G1 + P3 · P2 · P1 · G0 + P3 · P2 · P1 · P0 · C0

  assign c0 = carry_in;

  assign c1 = (g0 | (p0 & c0));

  assign c2 = (g1 | (p1 & g0) | (p1 & p0 & c0));

  assign c3 = (g2 | (p2 & g1) | (p2 & p1 & g0) | (p2 & p1 & p0 & c0));

  assign c4 = (g3 | (p3 & g2) | (p3 & p2 & g1) | (p3 & p2 & p1 & g0) | (p3 & p2 & p1 & p0 & c0));


  full_adder FA1(.a_in(a_in[0]), .b_in(b_in[0]), .carry_in(c0), .sum_o(sum_o[0]), .carry_o(c_1)); 

  full_adder FA2(.a_in(a_in[1]), .b_in(b_in[1]), .carry_in(c1), .sum_o(sum_o[1]), .carry_o(c_2));

  full_adder FA3(.a_in(a_in[2]), .b_in(b_in[2]), .carry_in(c2), .sum_o(sum_o[2]), .carry_o(c_3));

  full_adder FA4(.a_in(a_in[3]), .b_in(b_in[3]), .carry_in(c3), .sum_o(sum_o[3]), .carry_o(c_4));

  assign carry_o = c4;  

endmodule


module full_adder (a_in, b_in, carry_in, sum_o, carry_o);

  input a_in;

  input b_in;

  input carry_in;

  output sum_o;

  output carry_o; 

  assign sum_o = (a_in ^ b_in ^ carry_in);

  assign carry_o = (((a_in ^ b_in)& carry_in) | (a_in & b_in));

  //assign carry_o = ((a_in & b_in) | (b_in & carry_in) | (a_in & carry_in));  

endmodule

  

Test Bench Code:

--------------------------------------------------------------------------------------------------------------------------

module carry_look_ahead_adder_4_bit_test;
  reg [3:0]a_in;
  reg [3:0]b_in;
  reg carry_in;
  wire [3:0]sum_o;
  wire carry_o;
   
  // Instantiate design under test
  carry_look_ahead_adder_4_bit DUT(.a_in(a_in), .b_in(b_in), .carry_in(carry_in), .sum_o(sum_o), .carry_o(carry_o));
       
  initial begin
    // Dump waves
    $dumpfile("dump.vcd");
    $dumpvars(1);
    
    a_in = 4'b0000;
    b_in = 4'b0000;
    carry_in = 1'b0;
    
    #10 a_in = 4'b0000; b_in = 4'b0001; carry_in = 1'b1;   
    
    #10 a_in = 4'b0001; b_in = 4'b0001; carry_in = 1'b0;
    
    #10 a_in = 4'b0010; b_in = 4'b0011; carry_in = 1'b1; 
    
    #10 a_in = 4'b1111; b_in = 4'b1010; carry_in = 1'b0;
    
    #10 a_in = 4'b1001; b_in = 1'b1000; carry_in = 1'b1;
    
    #10 a_in = 4'b1101; b_in = 4'b1001; carry_in = 1'b0; 
    
    #10 a_in = 4'b0001; b_in = 4'b0011; carry_in = 1'b1;
    
    #10 a_in = 4'b0001; b_in = 4'b0000; carry_in = 1'b0;
   
  end 
      
endmodule


Simulation Waveform:

   


Thanks !