-2
\$\begingroup\$

enter image description here I'm new to Verilog programming. I'm trying to work up to a 64-bit CLA by building a 4-bit CLA, then an 8-bit (out of 2 instances of a 4-bit), then a 16-bit (out of 2 instances of the 8-bit one). I'll provide my code, then an explanation of the problem I'm having. Code:

// 4-BIT CLA CODE
module CLA4Bit(A, B, carryIn, carryOut, PG, GG, Sum);
    input[3:0] A, B;
    input carryIn;
    output carryOut;

    output PG;
    output GG;

    output[3:0] Sum;
    wire[3:0] G, P, C;

    assign G = A & B;
    assign P = A ^ B;
    assign Sum = P ^ C;

    assign C[0] = carryIn;
    assign C[1] = G[0] | (P[0] & C[0]);
    assign C[2] = G[1] | (P[1] & G[0]) | (P[1] & P[0] & C[0]);
    assign C[3] = G[2] | (P[2] & G[1]) | (P[2] & P[1] & G[0]) | (P[2] & P[1] & P[0] & C[0]);

    assign PG = P[3] & P[2] & P[1] & P[0];
    assign GG = G[3] | (P[3] & G[2]) | (P[3] & P[2] & G[1]) | (P[3] & P[2] & P[1] & G[0]);
endmodule

// 8-BIT CLA CODE
module CLA8Bit(A, B, carryIn, carryOut, Sum);
    input[7:0] A, B;        
    input carryIn;
    output carryOut;        
    output[7:0] Sum;

    // Block Propagate (BP) and Group Propagate (BG)
    // for each 4-bit CLA "Block"
    wire [1:0] BP, BG;

    // carryPipe that represents the carryIn for each
    // 4-bit CLA group. Calculated by the 2-block LCU
    wire [1:0] carryPipe;

    // Lookahead Carry Unit (LCU)
    LCU2Block LCU8Bit(carryIn, carryOut, BP, BG, carryPipe);

    // The two 4-bit CLA blocks that make up the 8-bit CLA

    CLA4Bit block1(A[3:0], B[3:0], carryIn, carryPipe[0], BP[0], BG[0], Sum[3:0]);
    CLA4Bit block2(A[7:4], B[7:4], carryPipe[0], carryPipe[1], BP[1], BG[1], Sum[7:4]);
endmodule

// 16-BIT CLA
module CLA16Bit_8Bit(A, B, carryIn, carryOut, Sum);
    input[15:0] A, B;
    input carryIn;
    output carryOut;
    output[15:0] Sum;

    // Block Propagate (BP) and Block Generate (BG)
    wire [1:0] BP16Bit, BG16Bit;

    // carryPipe that represents the carryIn for each
    // 8-bit CLA group; Calculated by the LCU
    wire [1:0] carryPipe;

    // Lookahead Carry Unit (LCU)
    LCU2Block LCU16Bit(carryIn, carryOut, BP16Bit, BG16Bit, carryPipe);

    // The 2 instances/"blocks" of 8-bit CLAs that 
    // make up the 16-bit CLA

    CLA8Bit block1(A[7:0], B[7:0], carryIn, carryPipe[0], Sum[7:0]);
    CLA8Bit block2(A[15:8], B[15:8], carryPipe[0], carryPipe[1], Sum[15:8]);
endmodule

// THIS IS THE LCU THAT CALCULATES THE CARRIES
module LCU2Block (carryIn, carryOut, BP, BG, carryPipe);

    input carryIn;
    output carryOut;

    // Block Propagate (BP) and Block Generate (BG)
    // represent the Group Propagate (PG) and Group
    // Generate (GG) of each "Block" of CLAs that are using
    // a particular LCU
    input[1:0] BP, BG;

    // carryPipe represents the carryIn for each 4-bit group of a 16-bit CLA,
    // and every 16-bit group of a 64-bit CLA.
    output[1:0] carryPipe;

    assign carryPipe[0] = BG[0] | (BP[0] & carryIn);
    assign carryPipe[1] = BG[1] | (BP[1] & carryPipe[0]);
endmodule

I wrote a simple testbench to test my code:

module CLA_TB(); 
    // Inputs
    reg[15:0] A;
    reg[15:0] B;
    reg carryIn;

    // Outputs
    wire carryOut;
    wire[15:0] Sum;

    CLA16Bit_8Bit CLA16Bit_8BitDUT(
    .A(A),
    .B(B),
    .carryIn(carryIn),
    .carryOut(carryOut),
    .Sum(Sum)
    );

    initial
        begin
        assign carryIn = 0;

        // Answer should be
        // Sum = b0000 0000 0000 0010 = h0002
        assign A = 16'b0000000000000001;
        assign B = 16'b0000000000000001;

        #20
        // Answer should be
        // Sum = b0000 0000 0100 1001 = h0049
        assign A = 16'b0000000000010010;
        assign B = 16'b0000000000110111;

        #20
        // Answer should be
        // Sum = 0000 1001 1110 1101 = h09ED
        assign A = 16'b0000011001011100;
        assign B = 16'b0000001110010001;

        #20
        // Answer should be
        // Sum = b0001 0101 1110 1110 = h15EE (with overflow carry!)
        assign A = 16'b1011011111010011;
        assign B = 16'b0101111000011011;

        #20
        $finish;
        end
endmodule

So the problem I'm having is that the 16-bit CLA correctly calculates all the 4-bit Sums properly EXCEPT for the second one from the left, which is seen as an X (please refer to picture).

I know that X's are displayed in Verilog when a wire has more than one driver (signal source), and I recently found out that it'll also display an X if a wire isn't given a value or if Z is used in an expression (however, I never used Z in any expression in my testbench).

I know that my carryOut is a "Z", but that wire is just a leftover from back when I was experimenting with different implementations of the CLAs - I shouldn't even have dragged that to the Wave graph for display. It is never used in the calculation of the carries (please refer to the CLA/LCU code).

I tested my 4-bit and 8-bit CLAs already; both work perfectly fine and add accurately despite the Z in the carryOut line, so I really don't think that's the problem.

I don't understand why this is happening. My only guess is that it has something to do with how the two LCUs (the one for the 8-bit CLA and the one for the 16-bit CLA) interact, maybe something's going wrong there?

I'm still trying to fix the problem, but I'm basically stumped so I decided to post here for help. Why is this happening? How can I fix it?

\$\endgroup\$
0
\$\begingroup\$

You never assigned to carryout in the first module. This means it's Z or X which will propagate.

It's always a good idea to check module inputs and outputs in your simulator to see where the X comes from.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.