Updated for 2025: This article provides Verilog code for the JK Flip-Flop in all modeling styles (Behavioral, Dataflow, and Gate-Level). Since 2024, simulation and testing methods have improved, making testbenches an essential part of hardware design. We’ve added a detailed simulation waveform analysis and a testbench example to help you verify your JK Flip-Flop design efficiently.
In this article, we will learn to
- Describe the JK-flip flop using the three levels of abstraction – Gate level, Dataflow, and behavioral modeling.
- Generate the RTL schematic for the JK flip flop.
- Write the testbench.
- Generate simulated waveforms.
Contents
What is a JK flip flop?
Flip-flops are fundamental building blocks of sequential circuits. A flip flop can store one bit of data. Hence, it is known as a memory cell. Since they work on the application of a clock signal, they come under the category of synchronous circuits.
The J-K flip-flop is the most versatile of the basic flip flops. The JK flip flop is a gated SR flip-flop with the addition of a clock input circuitry that prevents the illegal or invalid output condition that can occur when both inputs S and R are equal to logic 1. Due to this additional clocked input, a JK flip-flop has four possible input combinations, “logic 1”, “logic 0”, “no change” and “toggle”.

As we proceed, we will see how to write Verilog code for SR Flip Flop using different levels of abstraction.
Gate-Level Modeling
With the help of a logic diagram, we will be able to know the essential logic gates needed to build a circuit. Verilog provides us with gate primitives, which help us create a circuit by connecting basic logic gates. Gate level modeling enables us to describe the circuit using these gate primitives.
Given below is the logic diagram of a JK flip flop.

From the above logic circuit, we can see that we need four NAND gates to construct a JK flip flop.
Gate Level Modeling of JK Flip Flop
As always, the module
declaration in Verilog is done by listing the terminal ports in the logic circuit.
module jkff_gate(q,qbar,clk,j,k);
Note that we declare outputs first followed by inputs since built-in gates also follow the same pattern.
Now, let’s declare the input and output ports using the syntax for IO port declaration.
input j,k,clk; output q,qbar;
wire nand1_out; // output from nand1 wire nand2_out; // output from nand2
Time for us to write logic gates. We use the gate (<outputs>,<inputs>) format to use the in-built gates in Verilog.
nand(nand1_out, j,clk,qbar); nand(nand2_out, k,clk,q); nand(q,qbar,nand1_out); nand(qbar,q,nand2_out);
and thus the final code will be:
module jkff_gate(q,qbar,clk,j,k); input j,k,clk; output q,qbar; wire nand1_out; // output from nand1 wire nand2_out; // output from nand2 nand(nand1_out, j,clk,qbar); nand(nand2_out, k,clk,q); nand(q,qbar,nand1_out); nand(qbar,q,nand2_out); endmodule
Dataflow Modeling
Describing a flip flop using dataflow modeling is not applicable. Flip flops are supposed to work on edge-triggered clocks. In dataflow modeling, it is not possible to construct an edge-triggered flip flop. It works more like a latch. Also, when modeling sequential circuits with dataflow, it can sometimes result in an unpredictable output during a simulation. Hence, we prefer the highest level of abstraction (behavioral modeling) to describe sequential circuits like flip flops.
However there is an alternative implementation using a latch: module jkff_dataflow(q, qbar, j, k, clk); input j, k, clk; output q, qbar; assign q = (j & clk) | (~k & q); assign qbar = ~q; endmodule
Behavioral Modeling
Behavioral modeling is the highest level of abstraction. Unlike gate and dataflow modeling, behavior modeling does not demand knowing logic circuits or logic equations. As a designer, we just need to know the algorithm (behavior) of how we want the system to work. This type of modeling is simple since it does not involve using complex circuitry. A simple truth table will help us describe the design.
CLOCK | J | K | Q | Q’ | State |
Positive edge | 0 | 0 | Q | Q’ | No change |
Positive edge | 0 | 1 | 0 | 1 | Reset |
Positive edge | 1 | 0 | 1 | 0 | Set |
Positive edge | 1 | 1 | (Qprev)’ | Qprev | Toggle |
Using the described behavior, we can start coding.
Behavioral Modeling of JK Flip Flop
As always, we start with the module
declaration and the port declarations
module jkff_behave(clk,j,knq,qbar); input clk,j,k; output reg q,qbar;
Wait! Did we mention output as reg? Yes, we did. Why? We define output using the reg
datatype because we use procedural assignments. Therefore, we have to make sure the outputs retain their value until the next value is given to them.
Then we write:
always@(posedge clk) begin ..... end
The always
keyword makes sure the statements between begin
and end
will be executed as soon as the sensitivity list is triggered. Here, we are designing a positive edge-triggered JK Flipflop. The posedge clk
in the sensitivity list will make sure the statements between begin
and end
will be executed as soon as the positive edge of the clock is detected.
Now, we describe how we want our flip flop to work. Depending on the values given to J and K, we assign our Q and Q’ output.
always@(posedge clk) begin if(k = 0) begin q <= 0; qbar <= 1; end else if(j = 1) begin q <= 0; qbar <= 0; end else if(j = 0 & k = 0) begin q <= q; qbar <= qbar; end else if(j = 1 & k = 1) begin q <= ~q; qbar <= ~qbar; end end
Depending on the conditions applied, the if-else
statements execute the statement. As per above code, depending on the J and K inputs, the statements for Q and Q’ output will be executed.
Hence, our final code be:
module jkff_behave(clk, j, k, q, qbar); input clk, j, k; output reg q, qbar; always @(posedge clk) begin if (j == 0 && k == 0) begin q <= q; // No change qbar <= qbar; end else if (j == 0 && k == 1) begin q <= 0; // Reset qbar <= 1; end else if (j == 1 && k == 0) begin q <= 1; // Set qbar <= 0; end else if (j == 1 && k == 1) begin q <= ~q; // Toggle qbar <= ~qbar; end end endmodule
Testbench for JK Flip-Flop
A testbench is an HDL module that is used to test another module, called the device under test (DUT). The test bench contains statements to apply inputs to the DUT and, ideally, to check that the correct outputs are produced. The input and desired output patterns are called test vectors.
Ler’s see how we can write the testbench for JK flip flop.
//test bench for JK flip flop //1. Declare module and ports module jkff_test; reg J, K, CLK; wire Q, QBAR; // Instantiate DUT (Device Under Test) jkff_behave dut (.clk(CLK), .j(J), .k(K), .q(Q), .qbar(QBAR)); // Generate Clock Signal initial begin CLK = 0; forever #10 CLK = ~CLK; end // Apply test vectors initial begin J = 1; K = 0; #100; J = 0; K = 1; #100; J = 0; K = 0; #100; J = 1; K = 1; #100; $stop; // Stop simulation end // Monitor outputs initial begin $monitor("Time = %0t | CLK = %b | J = %b | K = %b | Q = %b | QBAR = %b", $time, CLK, J, K, Q, QBAR); end endmodule
RTL Schematic for JK Flip-Flop
Here’s how the RTL Schematic will look if we peek into the elaborate design of the behavioral model of the JK-flip flop.

The RTL (Register Transfer Level) schematic provides a visual representation of how the JK flip-flop is implemented in hardware based on the Verilog code. It illustrates the internal logic structure, showing how different components such as logic gates and flip-flops are interconnected.
- The schematic will typically include NAND gates (if using gate-level modeling) or register elements (if using behavioral modeling) that define how the JK flip-flop processes input signals.
- The clock (CLK) signal is a key component, ensuring that changes occur synchronously at each positive edge.
- The inputs J and K determine whether the output Q remains the same, resets, sets, or toggles.
- The complementary output QBAR is always the inverse of Q.
Simulated Waveform for JK Flip-Flop
We can verify the functional correctness of described SR flip-flop by simulation. The simulated waveform of SR flip flop is given below:

The simulated waveform confirms the correct functionality of the JK flip-flop by showing how the output (Q, QBAR) changes with respect to the clock (CLK) and inputs (J, K). Initially, some signals may appear undefined (blue or red in Vivado) due to uninitialized values, but once the clock starts toggling, the flip-flop responds at the positive edge of the clock.
- When J = 0 and K = 0, Q retains its previous state, as expected.
- When J = 1 and K = 0, Q is set to 1.
- When J = 0 and K = 1, Q is reset to 0.
- When J = 1 and K = 1, Q toggles at each positive clock edge.
This waveform visualization helps verify the correctness of the Verilog implementation and ensures the flip-flop behaves as intended.