Search code examples
verilogflip-flop

Wrong output while modelling JK FF: output is x


I am modelling a JK FLIP Flop using Verilog. I am getting the output q as x in all the cases. I used case statement for various jk combinations. I hardly found any issue with the code.

Design


    module jk_ff ( input j, input k, input clk, output q);
    
           reg q;
    
           always @ (posedge clk)
    
                   case ({j,k})
                 2'b00 :  q <= q;
                 2'b01 :  q <= 1'b0;
                 2'b10 :  q <= 1'b1;
                 2'b11 :  q <= ~q;
              endcase
    endmodule

test bench


    module tb_jk;  
           reg j;  
           reg k;  
           reg clk;  
          
           always #5 clk = ~clk;  
          
           jk_ff    jk0 ( .j(j),  
                          .k(k),  
                          .clk(clk),  
                          .q(q));  
          
           initial begin  
               $dumpfile("test.vcd");
            $dumpvars;
              j <= 0;  
              k <= 0;  
          
              #5 j <= 0;  
                 k <= 1;  
              #20 j <= 1;  
                  k <= 0;  
              #20 j <= 1;  
                  k <= 1;  
              #20 $finish;  
           end  
          
           initial  
              $monitor ("j=%0d k=%0d q=%0d", j, k, q);  
        endmodule

logs


    vu2swz@PPDP01:~$ iverilog jk_ff.v 
    vu2swz@PPDP01:~$ ./a.out 
    VCD info: dumpfile test.vcd opened for output.
    j=0 k=0 q=x
    j=0 k=1 q=x
    j=1 k=0 q=x
    j=1 k=1 q=x

The output is showing only x instead of 0 1 and Q.


Solution

  • When I ran your simulation and looked at waveforms, I saw that clk was always unknown (x). You declared clk as reg, which means that it defaults to x. Your assignment (clk = ~clk) does not change the value of clk because ~clk evaluates to ~x, which is still x.

    You need to initialize clk to a known value in your testbench. For example, change:

           reg clk;
    

    to:

           reg clk = 0;
    

    This shows:

    j=0 k=0 q=x
    j=0 k=1 q=x
    j=0 k=1 q=0
    j=1 k=0 q=0
    j=1 k=0 q=1
    j=1 k=1 q=1
    j=1 k=1 q=0
    

    There are 2 ways to debug this problem. As I mentioned, one way is to look at waveforms; you already create the VCD file. This is the most efficient way. The iverilog site says GTKWave "is the preferred waveform viewer for Icarus Verilog".

    Another way is to add the clk signal to your $monitor statement:

              $monitor ("j=%0d k=%0d q=%0d clk=%b", j, k, q, clk);  
    

    Then you would have seen:

    j=0 k=0 q=x clk=x
    j=0 k=1 q=x clk=x
    j=1 k=0 q=x clk=x
    j=1 k=1 q=x clk=x