Search code examples
verilogfpgavivado

Carry look ahead adder fails in generating proper sum and carry bits


Full adder module:

`timescale 1ns / 1ps

module FA(A,B,carry_in,sum,carry_out);
input A,B, carry_in;
output sum, carry_out;
assign sum = A ^ B ^ carry_in;
assign carry_out = (A^B) | ((carry_in) & ( A | B));
endmodule

Carry look ahead adder:

module CLAA
#(
parameter WIDTH = 4
) 
(
input  [WIDTH-1:0]         A,
input  [WIDTH-1:0]         B,
output [WIDTH:0]           sum
);
wire   [WIDTH:0]          t_carry;
wire   [WIDTH-1:0]        t_genr;
wire   [WIDTH-1:0]        t_prop;
wire   [WIDTH-1:0]        t_sum;

// create Full adders using genvar
genvar              i;
generate
for (i=0; i< WIDTH; i=i+1)
begin
FA FA_Instantiation
(
.A(A[i]),
.B(B[i]),
.carry_in(t_carry[i]),
.sum(t_sum[i]),
.carry_out()
);  
end
endgenerate

// creating generate and propagate terms
// Gi = Ai & Bi
// Pi = Ai | Bi

genvar j;
generate
for ( j=0; j< WIDTH; j=j+1)
begin
assign t_genr            = A[j] & B[j];
assign t_prop            = A[j] | B[j];
assign t_carry[j+1]      = t_genr[j] | ( t_prop[j] & t_carry[j]);
end
endgenerate

assign t_carry[0] = 1'b0;             
assign sum      = {t_carry[WIDTH],t_sum};
//$display("t_sum is %b",t_sum);
endmodule

Test Bench:

module carry_lookahead_adder_tb ();

parameter WIDTH = 4;

reg [WIDTH-1:0] A = 0;
reg [WIDTH-1:0] B = 0;
wire [WIDTH:0]  sum;

CLAA #(.WIDTH(WIDTH)) carry_lookahead_inst
(
.A(A),
.B(B),
.sum(sum)
 );
 
 initial begin
    $monitor (" A is %b, B is %b, sum is %b", A, B ,sum);
 end

 initial
 begin
  #10;
  A = 3'b000;
  B = 3'b001;
  #10;
  A = 3'b010;
  B = 3'b010;
  #10;
  A = 3'b101;
  B = 3'b110;
  #10;
  A = 3'b111;
  B = 3'b111;
  #10;
  end

  endmodule

Solution

  • You need to add the j index to your assign statements. Change:

    assign t_genr            = A[j] & B[j];
    assign t_prop            = A[j] | B[j];
    

    to:

    assign t_genr[j]         = A[j] & B[j];
    assign t_prop[j]         = A[j] | B[j];
    

    Output:

     A is 0000, B is 0000, sum is 00000
     A is 0000, B is 0001, sum is 00001
     A is 0010, B is 0010, sum is 00100
     A is 0101, B is 0110, sum is 01011
     A is 0111, B is 0111, sum is 01110
    

    If you are not already doing so, you should dump waveforms and look at internal signals. Debugging with $monitor alone is usually insufficient.