Search code examples
verilogsystem-verilog

Getting Z values when expecting a proper output


Below is my code. It was supposed to output the addition of B+C when 'Odds' is true, and the subtraction of B-C when 'Evens' is true and 'Odds' is false. And then 0 when neither are true. I am getting ZZZ for the output of my full adder below - although all of the logic should be correct. I have checked multiple times...If you can help identify why my code is working that would be greatly appreciated.

module ECE228_2(
    input [7:0] A,
    input [3:0] B,
    input [3:0] C,
    output [4:0] Out
    );
    
    wire Odds, XEvens, Evens;
    wire [3:0]Bit4AddOut, Bit4AddCarry, Bit4SubOut, Bit4SubCarry, NotC;
    wire [4:0]EvenMuxOut;
    
    //C inversion for 2's Complement Subtraction
    not xC0(NotC[0],C[0]);
    not xC1(NotC[1],C[1]);
    not xC2(NotC[2],C[2]);
    not xC3(NotC[3],C[3]);
    
    //Generate The Xor of the Odd Positions to check for odd # of 1's
    xor xo0(Odds,A[1],A[3],A[5],A[7]);
    
    //Generate the Xor of the Even Positions and reverse it to check for even # of 1's
    xor xo1(XEvens,A[0],A[2],A[4],A[6]);
    not evenflip(Evens,XEvens);
    
    //4 Bit Add of B and C in case it is desired output
    FullAdd FA0(B[0],C[0],1'b0,Bit4AddOut[0],Bit4AddCarry[0]);
    FullAdd FA1(B[1],C[1],Bit4AddCarry[0],Bit4AddOut[1],Bit4AddCarry[1]);
    FullAdd FA2(B[2],C[2],Bit4AddCarry[1],Bit4AddOut[2],Bit4AddCarry[2]);
    FullAdd FA3(B[3],C[3],Bit4AddCarry[2],Bit4AddOut[3],Bit4AddCarry[3]);
    
    //4 Bit Subtract of B and C in case it is desired output
    FullAdd FAS0(B[0],NotC[0],1'b1,Bit4SubOut[0],Bit4SubCarry[0]);
    FullAdd FAS1(B[1],NotC[1],Bit4SubCarry[0],Bit4SubOut[1],Bit4SubCarry[1]);
    FullAdd FAS2(B[2],NotC[2],Bit4SubCarry[1],Bit4SubOut[2],Bit4SubCarry[2]);
    FullAdd FAS3(B[3],NotC[3],Bit4SubCarry[2],Bit4SubOut[3],Bit4SubCarry[3]);
    
    //2:1 Mux with even positions check as sel and (A-B) as true cases and 00000 as false case (5 Bits)
    MUX2_1 EvenMux0(Bit4SubOut[0],1'b0,Evens,EvenMuxOut[0]);
    MUX2_1 EvenMux1(Bit4SubOut[1],1'b0,Evens,EvenMuxOut[1]);
    MUX2_1 EvenMux2(Bit4SubOut[2],1'b0,Evens,EvenMuxOut[2]);
    MUX2_1 EvenMux3(Bit4SubOut[3],1'b0,Evens,EvenMuxOut[3]);
    MUX2_1 EvenMux4(Bit4SubCarry[3],1'b0,Evens,EvenMuxOut[4]);
    
    //2:1 Mux with odd positions check as sel and (A+B) as true case and even check as false case
    MUX2_1 OddMux0(Bit4AddOut[0],EvenMuxOut[0],Odds,Out[0]);
    MUX2_1 OddMux1(Bit4AddOut[1],EvenMuxOut[1],Odds,Out[1]);
    MUX2_1 OddMux2(Bit4AddOut[2],EvenMuxOut[2],Odds,Out[2]);
    MUX2_1 OddMux3(Bit4AddOut[3],EvenMuxOut[3],Odds,Out[3]);
    MUX2_1 OddMux4(Bit4AddCarry[3],EvenMuxOut[4],Odds,Out[4]);
    

       
endmodule


//Need a 2:1 MUX Module
module MUX2_1(
    input MuxTrue,
    input MuxFalse, 
    input MuxSel,   
    output MuxOut
    );

    wire MuxA1, MuxA2, XMuxSel;
    
    //Selector Not
    not XSel(XMuxSel,MuxSel);
    
    //When Sel is 1
    and MATrue(MuxA1,MuxTrue,MuxSel);
    
    //When Sel is 0
    and MAFalse(MuxA2,MuxFalse,XMuxSel);
    
    //Or of the cases
    or MuxOr(MuxOut,MuxA1,MuxA2);

endmodule

//Need a Full Adder Module
module FullAdd(
    input FAin1,
    input FAin2,
    input FACin,
    output FAOut,
    output FACout
    );
    
    wire FAWHA1Out,FAWHA1Cout,FAWHA2Cout;
    
    //Both calls to Half Adder
    HalfAdd FA_HA1(FAin1,FAin2,FAWHA1Cout,FAWHA1Out);
    HalfAdd FA_HA2(FAWHA1Out,FACin,FAWHA2Cout,FAout);
    or FAOr(FACout,FAWHA1Cout,FAWHA2Cout);
    
endmodule    

//Need a Half Adder Module
module HalfAdd(
    input HAin1,
    input HAin2,
    output HACout,
    output HAOut
    );
    
    //Gate design of a half adder
    //Add but output 0 for carryover condition
    xor HAXOR(HAOut,HAin1,HAin2);
    //check for carryover condition
    and HAAND(HACout,HAin1,HAin2);
    
endmodule

Here is the test bench:

module ECE228_2_test;
    reg [7:0]A;
    reg [3:0]B;
    reg [3:0]C;
    wire [4:0]Out;
   
ECE228_2 uut (
    .A(A),
    .B(B),
    .C(C),
    .Out(Out)
);    
    
initial
    begin
        B = 4'b0111;  //B = 7
        C = 4'b0011;  //C = 3         
        //Start counting
        A = 8'b00000000;
   #10   A = 8'b00000001; 
   #10   A = 8'b00000010;  
   #10   A = 8'b00000011; 
   #10   A = 8'b00000100; 
   #10   A = 8'b00000101; 
   #10   A = 8'b00000111; 
   #10   A = 8'b00001000;
        //Too many to count - Lets do some random instead   
   #10   A = 8'b11011000;
   #10   A = 8'b00011110;
   #10   A = 8'b10100101;
   #10   A = 8'b00110101;
   #10   A = 8'b11001010;
   #10   A = 8'b11100001;
   #10   A = 8'b11111111;
   #10   A = 8'b01011010;
   #10   A = 8'b01110010;
    end    
endmodule

Here is the output of the objects:

enter image description here


Solution

  • Verilog is a case-sensitive language. This means that the signal named FAout is different from the one named FAOut.

    The FullAdd module output port, FAOut, is undriven, which means it will have the high-impedance value (z). You likely meant to connect the output of the FA_HA2 instance to the FAOut port instead of the signal named FAout.

    Here is the fixed version of the module:

    module FullAdd(
        input FAin1,
        input FAin2,
        input FACin,
        output FAOut,
        output FACout
        );
        
        wire FAWHA1Out,FAWHA1Cout,FAWHA2Cout;
        
        //Both calls to Half Adder
        HalfAdd FA_HA1(FAin1,FAin2,FAWHA1Cout,FAWHA1Out);
        HalfAdd FA_HA2(FAWHA1Out,FACin,FAWHA2Cout,FAOut);
        or FAOr(FACout,FAWHA1Cout,FAWHA2Cout);
        
    endmodule    
    

    The full adder no longer has z output.

    By default, Verilog does not require you to declare all signals. You could also change the default behavior and require explicitly declared signals using this compiler directive:

    `default_nettype none
    

    This helps you find common coding mistakes like this.

    Error-[IND] Identifier not declared
      Identifier 'FAout' has not been declared yet. If this error is not expected,
      please check if you have set `default_nettype to none.