verilogfpgashift-register

Why does Verilog output show x and z instead of zero and 1?


I am modelling a shift register consisting of three D flip flops. There are three inputs (clk, reset, shiftIn) and one output (shiftOut). The reset is synchronous active high and resets all the flip flops.

Design


    module shiftReg(shiftIn,clk,reset,shiftOut);
    input shiftIn, clk, reset;
    output shiftOut;
    reg Q1,Q2,shiftOut;
    always @(posedge clk or posedge reset) 
    begin
        if(reset == 1'b1) begin
            Q1 <= 1'b0;
            Q2 <= 1'b0;
            shiftOut <= 1'b0;
        end
        else begin
            Q1 <= shiftIn;
            Q2 <= Q1;
            shiftOut <= Q2;
        end
    end
    endmodule

testbench


    module tb_shiftReg();
    reg shiftin;
    reg clk;
    reg reset;
    wire shiftOut;
    shiftReg SR(shiftIn,clk,reset,shiftOut);
    initial begin
        clk=0;
        forever #10 clk = ~clk; 
    end
    initial begin
        $monitor("time=",$time, "shiftin=%b  reset =%d shiftout =%b",shiftIn,reset,shiftOut);
        $dumpfile("test.vcd");
        $dumpvars;           
        reset=0;
        shiftin <= 0;
        #100;
        reset=0;
        shiftin <= 1;
        #100;
        reset =1;
        shiftin <= 0;
        #100;
        reset =1;
        shiftin <= 0;
        #100 $finish;
    end
    endmodule

I am getting the following as output when I simulate it using iverilog:


    vu2swz@PPDP01:~$ iverilog Shiftregister.v 
    vu2swz@PPDP01:~$ ./a.out 
    VCD info: dumpfile test.vcd opened for output.
    time=                   0shiftin=z  reset =0 shiftout =x
    time=                  50shiftin=z  reset =0 shiftout =z
    time=                 200shiftin=z  reset =1 shiftout =0

Why am I getting z and x instead of 1 and zero?


Solution

  • Verilog is case-sensitive. shiftin is a different signal from shiftIn (capital "I"). In the testbench you declared shiftin, but you did not declare shiftIn. By default Verilog considers undeclared signals as type wire, and the default value of a wire is z. This means that the input to your design module is undriven. The simulator I used gave me a warning message about this. You can also try your code on different simulators on edaplayground to get more helpful messages.

    Change all shiftIn to shiftin in your testbench module, and that clears up most of your z and x:

    time=                   0shiftin=0  reset =0 shiftout =x
    time=                  50shiftin=0  reset =0 shiftout =0
    time=                 100shiftin=1  reset =0 shiftout =0
    time=                 150shiftin=1  reset =0 shiftout =1
    time=                 200shiftin=0  reset =1 shiftout =0
    

    You still get x at time 0 because reset is not asserted at time 0; reset is asserted at time 200. Typically, you would assert reset at time 0 (reset=1;), then deassert it (reset=0;) after a few clock cycles, say at time 100.

    module tb_shiftReg();
        reg shiftin;
        reg clk;
        reg reset;
        wire shiftOut;
        shiftReg SR(shiftin,clk,reset,shiftOut);
        initial begin
            clk=0;
            forever #10 clk = ~clk; 
        end
        initial begin
            $monitor("time=",$time, "shiftin=%b  reset =%d shiftout =%b",shiftin,reset,shiftOut);
            $dumpfile("test.vcd");
            $dumpvars;           
            reset=1;
            shiftin <= 0;
            #100;
            reset=0;
            shiftin <= 1;
            #100;
            shiftin <= 0;
            #100;
            shiftin <= 0;
            #100 $finish;
        end
    endmodule
    

    With the above changes, all signals show 0/1:

    time=                   0shiftin=0  reset =1 shiftout =0
    time=                 100shiftin=1  reset =0 shiftout =0
    time=                 150shiftin=1  reset =0 shiftout =1
    time=                 200shiftin=0  reset =0 shiftout =1
    time=                 250shiftin=0  reset =0 shiftout =0
    

    Note: Your reset signal is asynchronous, not synchronous, because you included reset in the sensitivity list:

    always @(posedge clk or posedge reset)