Problema con 8-bit Carry Lookahead Adder en Verilog

-2

SoynuevoenlaprogramacióndeVerilog.EstoytratandodetrabajarconunCLAde64bitsmediantelacreacióndeunCLAde4bits,luegode8bits(de2instanciasde4bits),luegode16bits(de2instanciasdeUnode8bits).Proporcionarémicódigo,luegounaexplicacióndelproblemaqueestoyteniendo.Código:

//4-BITCLACODEmoduleCLA4Bit(A,B,carryIn,carryOut,PG,GG,Sum);input[3:0]A,B;inputcarryIn;outputcarryOut;outputPG;outputGG;output[3:0]Sum;wire[3:0]G,P,C;assignG=A&B;assignP=A^B;assignSum=P^C;assignC[0]=carryIn;assignC[1]=G[0]|(P[0]&C[0]);assignC[2]=G[1]|(P[1]&G[0])|(P[1]&P[0]&C[0]);assignC[3]=G[2]|(P[2]&G[1])|(P[2]&P[1]&G[0])|(P[2]&P[1]&P[0]&C[0]);assignPG=P[3]&P[2]&P[1]&P[0];assignGG=G[3]|(P[3]&G[2])|(P[3]&P[2]&G[1])|(P[3]&P[2]&P[1]&G[0]);endmodule//8-BITCLACODEmoduleCLA8Bit(A,B,carryIn,carryOut,Sum);input[7:0]A,B;inputcarryIn;outputcarryOut;output[7:0]Sum;//BlockPropagate(BP)andGroupPropagate(BG)//foreach4-bitCLA"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

Escribí un banco de pruebas simple para probar mi código:

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

Entonces, el problema que tengo es que el CLA de 16 bits calcula correctamente todas las sumas de 4 bits EXCEPTO para el segundo desde la izquierda, que se ve como una X (consulte la imagen).

Sé que las X se muestran en Verilog cuando un cable tiene más de un controlador (fuente de señal), y recientemente descubrí que también mostrará una X si no se le asigna un valor a un cable o si Z es utilizado en una expresión (sin embargo, nunca usé Z en ninguna expresión en mi banco de pruebas).

Sé que mi carryOut es una "Z", pero ese cable es solo un remanente de atrás cuando estaba experimentando con diferentes implementaciones de los CLA; ni siquiera debería haber arrastrado eso al gráfico Wave para mostrarlo. Nunca se utiliza en el cálculo de los acarreos (consulte el código CLA / LCU).

Ya probé mis CLA de 4 bits y 8 bits; ambos funcionan perfectamente bien y agregan con precisión a pesar de la Z en la línea carryOut, así que realmente no creo que ese sea el problema.

No entiendo por qué sucede esto. Mi única suposición es que tiene algo que ver con la forma en que interactúan las dos LCU (la del CLA de 8 bits y la del CLA de 16 bits), ¿tal vez algo vaya mal?

Todavía estoy tratando de solucionar el problema, pero básicamente estoy perplejo, así que decidí publicar aquí en busca de ayuda. ¿Por qué está pasando esto? ¿Cómo puedo solucionarlo?

    
pregunta enharmonics

1 respuesta

0

Nunca asignó llevar a cabo en el primer módulo. Esto significa que es Z o X la que se propagará.

Siempre es una buena idea verificar las entradas y salidas del módulo en su simulador para ver de dónde proviene la X.

    
respondido por el Matt

Lea otras preguntas en las etiquetas