Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Are these three Carry Look Ahead Circuits Equivalent?

Status
Not open for further replies.

kvn0smnsn

Junior Member level 2
Junior Member level 2
Joined
Nov 20, 2022
Messages
22
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
165
I've been reading up on carry look ahead adders, and from the diagram on "https://en.wikipedia.org/wiki/Carry.../File:Four_bit_adder_with_carry_lookahead.svg" I've built the following file:
Code:
module ClaFour( cOut, sum, aOp, bOp, cIn);
  output        cOut;
  output [ 3:0] sum;
  input  [ 3:0] aOp;
  input  [ 3:0] bOp;
  input         cIn;
  wire   [ 3:0] pro;
  wire   [ 3:0] gen;
  wire   [ 3:0] car;

  assign car[ 0] = cIn;

  genvar bt;
  generate
    for (bt = 0; bt < 4; bt = bt + 1)
    begin
      assign pro[ bt] = aOp[ bt] ^ bOp[ bt];
      assign gen[ bt] = aOp[ bt] & bOp[ bt];
      assign sum[ bt] = pro[ bt] ^ car[ bt];
    end
  endgenerate

  assign car[ 1] = gen[ 0] | cIn & pro[ 0];
  assign car[ 2] = gen[ 1] | pro[ 1] & gen[ 0] | pro[ 1] & pro[ 0] & cIn;
  assign car[ 3]
       = gen[ 2] | pro[ 2] & gen[ 1] | pro[ 2] & pro[ 1] & gen[ 0]
                 | pro[ 2] & pro[ 1] & pro[ 0] & cIn;
  assign cOut
       = gen[ 3] | pro[ 3] & gen[ 2] | pro[ 3] & pro[ 2] & gen[ 1]
                 | pro[ 3] & pro[ 2] & pro[ 1] & gen[ 0]
                 | pro[ 3] & pro[ 2] & pro[ 1] & pro[ 0] & cIn;

endmodule
But then I realized that this is really equivalent to this file:
Code:
module ClaFour_Eqv( cOut, sum, aOp, bOp, cIn);
  output        cOut;
  output [ 3:0] sum;
  input  [ 3:0] aOp;
  input  [ 3:0] bOp;
  input         cIn;
  wire   [ 3:0] pro;
  wire   [ 3:0] gen;
  wire   [ 3:0] car;

  assign car[ 0] = cIn;

  genvar bt;
  generate
    for (bt = 0; bt < 4; bt = bt + 1)
    begin
      assign pro[ bt] = aOp[ bt] ^ bOp[ bt];
      assign gen[ bt] = aOp[ bt] & bOp[ bt];
      assign sum[ bt] = pro[ bt] ^ car[ bt];
    end
  endgenerate

  assign car[ 1] = gen[ 0] | cIn & pro[ 0];
  assign car[ 2] = gen[ 1] | pro[ 1] & (gen[ 0] | pro[ 0] & cIn);
  assign car[ 3]
       = gen[ 2] | pro[ 2] & (gen[ 1] | pro[ 1] & (gen[ 0] | pro[ 0] & cIn));
  assign cOut
       =   gen[ 3]
         |   pro[ 3]
           & ( gen[ 2]
             | pro[ 2] & (gen[ 1] | pro[ 1] & (gen[ 0] | pro[ 0] & cIn)));

endmodule
Isn't it? And then I got to thinking, isn't that equivalent to the following
file with (nmBits) set to 4?
Code:
module ClaAdd #( nmBits = 4)
              ( cOut, sum, aOp, bOp, cIn);
  output               cOut;
  output [ nmBits-1:0] sum;
  input  [ nmBits-1:0] aOp;
  input  [ nmBits-1:0] bOp;
  input                cIn;
  wire   [ nmBits-1:0] pro;
  wire   [ nmBits-1:0] gen;
  wire   [ nmBits  :0] car;

  assign car[ 0] = cIn;
  assign cOut    = car[ nmBits];

  genvar bt;
  generate
    for (bt = 0; bt < nmBits; bt = bt + 1)
    begin
      assign pro[ bt    ] = aOp[ bt] ^ bOp[ bt];
      assign gen[ bt    ] = aOp[ bt] & bOp[ bt];
      assign sum[ bt    ] = pro[ bt] ^ car[ bt];
      assign car[ bt + 1] = gen[ bt] | pro[ bt] & car[ bt];
    end
  endgenerate

endmodule
So here are three files, that I think do the same thing. Am I wrong? Are any of these slower than the others, and if so, why?
 

At least the third design is no CLA because carry is generated recursively.
Code:
assign car[ bt + 1] = gen[ bt] | pro[ bt] & car[ bt];

To compare speed, you'll determine the longest combinational path in each design.
 

    kvn0smnsn

    Points: 2
    Helpful Answer Positive Rating
An additional comment. Presumed the three designs are logically equivalent, you should be aware that the synthesis tool may implement the gate level logic differently depending on timing and possible structure constraints. Respectively a CLA might be translated to non-CLA due to relaxed timing constraints or vise-versa non-CLA to CLA enforced by restrictive timing.
--- Updated ---

If the the question refers to FPGA implementation, the answer is partly different. FPGA logic elements have dedicated carry chains that are faster than other logic in- and outputs. Unfortunately, a gate level description as in the example isn't necessarily recognized as adder and doesn't take advantage of the fast carry chain. Adder inference depends on arithmetic operators in HDL code.
 
Last edited:

    kvn0smnsn

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top