Electrical – Testing JK Flipflop using system verilog

system-verilogverilog

I have a testbench written for a JK flip flop. Below I have the correct circuit that passes the testbench and another circuit which passes the testbench as well. Is there something wrong with my testbench.

a) Correct JK flip flop

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

b) Wrong JK flip flop but passes all test cases in the testbench

module jk_ff (input j, input k, input clk, output logic q);
 always @(posedge clk)
 case ({j,k})
 2'b10 : q <= ~ q ;
 2'b01 : q <= 0 ;
 2'b11 : q <= 0 ;

 endcase
 endmodule

c) Testbench

include "jk.sv"

module tb_jk();

    // open fitness file
    int passedFile;

   reg j;
   reg k;
   reg clk;
   wire q;

   always #5 clk = ~clk;

   jk_ff    jk0 ( .j(j),
                  .k(k),
                  .clk(clk),
                  .q(q));

   initial begin
    // open file
    passedFile = $fopen("passed.txt", "w");

      clk = 0;
      j = 0;
      k = 1;

      #10 if(clk == 1 && j == 0 && k == 1 && q == 0) $fdisplay(passedFile, "%d", 1);
         else $fdisplay(passedFile, "%d", 0);
      #10 j = 0; k = 0;

      #10 if(clk == 1 && j == 0 && k == 0 && q == 0) $fdisplay(passedFile, "%d", 1);
            else $fdisplay(passedFile, "%d", 0);
      #10 j = 1; k = 0;

       #10 if(clk == 1 && j == 1 && k == 0 && q == 1) $fdisplay(passedFile, "%d", 1);
             else $fdisplay(passedFile, "%d", 0);
      #10 j = 1; k = 1;

      #10 if(clk == 1 && j == 1 && k == 1 && q == 0) $fdisplay(passedFile, "%d", 1);
            else $fdisplay(passedFile, "%d", 0);


      #10 $finish;


      // close file
      $fclose(passedFile);
   end
endmodule
```

Best Answer

Yes, there is something wrong with your testbench. You are currently checking the output (q) every other clock cycle, but you should check it every clock cycle.

One way to check on every clock cycle (at the negedge as in your checker) is to add this code to the bottom of your testbench:

logic q2;
always @(posedge clk) begin : good
    case ({j,k})
        2'b00 :  q2 <= q2;
        2'b01 :  q2 <= 0;
        2'b10 :  q2 <= 1;
        2'b11 :  q2 <= ~q2;
    endcase
end

always @(negedge clk) begin
    if (q === q2) begin
        $display($time, " pass q=%b", q);
    end else begin
        $display($time, " fail q=%b q2=%b", q, q2);
    end
end

You should see a fail at time 60.

q2 is a model of your known-good jk_ff.

Related Topic