View Course Path

Verilog code for D flip-flop – All modeling styles

Updated for 2025:

In this article, we will explore the design and implementation of the D flip-flop using Verilog through three key abstraction levels: Gate-Level, Dataflow, and Behavioral modeling. We will also focus on using the latest tools and techniques to simulate, test, and optimize the design of flip-flops for modern digital systems. As digital designs have evolved, new trends such as hardware description languages (HDLs) integration with FPGA and ASIC development have become increasingly significant, especially in fields like IoT, AI, and high-speed computing. We’ll also walk through the RTL schematic generation for a D flip-flop and guide you through writing testbenches in Verilog using cutting-edge simulation tools for accurate and efficient verification.

By the end of this tutorial, you will have hands-on experience in modeling a D flip-flop using Verilog’s highest abstraction levels and a solid understanding of how to simulate and deploy the design on modern hardware platforms.

What is D flip flop?

A D flip-flop (also known as data flip-flop) is a type of sequential digital circuit used in electronics and digital systems for storing a single bit of data. It is one of the most basic building blocks in memory systems, shift registers, and counters. D flip-flops are fundamental in many applications such as register files, timing circuit, and finite state machines (FSMs).

A D flip-flop stands for data flip-flop. But sometimes it can also be interpreted as delay flip-flop. The reasoning behind this interpretation comes from the fact that the D flip-flop delays the input data until the next clock edge, storing the value until it is transferred to the output.

 

Symbol for D flip flop
D flip flop Symbol

Inputs:

  • D input: The data or value that will be stored in the flip-flop.
  • CLK input: A signal that triggers the storage of the data. The flip-flop captures the value of the D input on the rising or falling edge of the clock signal (depending on the design).

Outputs:

  • Q: This is the output that reflects the value of the D input after the clock edge.
  • Not-Q (Q’): This is the complimentary output, always the opposite of Q.

As we proceed, we will see how we can design a D flip flop using different levels of abstraction

Gate level modeling

Gate level modeling uses primitive gates available in Verilog to build circuits. Hence, we need to know the logic diagram of the circuit we want to design.

 

Logic circuit of D Flip Flop
The logic circuit of D Flip Flop

From the above circuit, we can see that we need four NAND gates and one NOT gate to construct a D-flip flop in gate-level modeling.

Gate level Modeling of D flip flop

As always, the module is declared listing the terminal ports in the logic circuit.

module d_ff_gate(q,qbar,d,clk);

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.

input d,clk;
output q, qbar;
Next, we have to declare intermediate signals. These are signals that aren’t terminal ports—for example, the signals outgoing from the not1, nand 1, nand2, etc.
wire dbar;       //output of not1
wire nand1_out;  // output of nand1
wire nand2_out;  // output of nand2

Time for us to write logic gates. We use the gate (<outputs>,<inputs>) format to use the in-built gates in Verilog. Using the appropriate instance name makes identifying code errors easier.

not ( dbar,d);
nand (nand1_out,clk,d);
nand (nand2_out,clk,dbar);
nand (q,qbar,nand2_out);
nand (qbar,q,nand1_out);

and thus the final code will be:

module d_ff_gate(q,qbar,d,clk);
input d,clk;
output q, qbar;
wire dbar; //output of not1
wire nand1_out; // output of nand1
wire nand2_out; // output of nand2
not ( dbar,d); 
nand (nand1_out,clk,d);
nand (nand2_out,clk,dbar);
nand (q,qbar,nand2_out);
nand (qbar,q,nand1_out);
endmodule

Dataflow Modeling

When the number of gates increases, the complexity of the circuit also increases. It is difficult to describe such complex circuits in terms of logic gates. That is when dataflow modeling comes handy.

Dataflow modeling is a higher level of abstraction compared to the gate-level. Instead of instantiating gates, we use the logic expression explaining how the data flows from input to output. Hence, it is much easier to construct complex circuits using this level of abstraction since there is no need to know the actual physical layout.

In dataflow modeling, we use the keyword assign to describe a design. Let’s see how it works.

Wait!

Before moving on, we need to know the logic equation. Right?

The characteristic equation of a D flip flop is

Q = D and Q’ = D’

Data Flow Modeling of D flip flop

As usual, we start with declaring the module and the terminal ports:

module dff_dataflow(d,clk,q,qbar);
input d,clk;
output q, qbar;

Now, we have to describe the flow of data to the outputs using assign.

assign q = clk?d:q;
assign qbar = clk?!d:qbar;

Hence, the final code will be:

module dff_dataflow(d,clk,q,qbar); 
input d,clk; 
output q, qbar;

assign q = clk?d:q;
assign qbar = clk?!d:qbar;

endmodule

Did you try to simulate this code?

Does something fishy?

Yes!

This code works more like a latch than a Flip flop. There is no provision in dataflow modeling to detect clock events like edge trigger. 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.

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 D Q Q’
No clock 0 Qn-1 Q’n-1
Positive /Negative edge 0 0 1
No clock 1 Qn-1 Q’n-1
Positive/Negative  edge 1 1 0

We can summarize the behavior of D-flip flop as follows:

  • When a triggering clock edge is detected, Q = D.
  • During the rest of the clock cycle, Q holds the previous value.

Behavioral Modeling of D flip flop

Again, starting with the module and the port declarations:

module dff_behave(d, clk, q, qbar);
input d,clk;
output reg q, qbar;

Did you notice we have mentioned output datatype as reg ? It stands for a register that will retain its value till the next value is given to it. We define output as  reg because we use procedural assignments. It holds a value from one procedural assignment statement to the next, which means it holds its value over simulation data cycles.

Then we write:

always@(posedge clk)
begin
.....
end

What you see in the bracket is the sensitivity list. Here the positive edge of the clock provided will control the statements in between begin and end. The always keyword will make sure that the statements get executed every time the sensitivity list is triggered.

In between begin and end, we write the procedure for how the system works:

always@(posedge clk)
begin
q <= d;
qbar <= !d;
end

Hence, our final code be:

module dff_behavioral(d,clk,q,qbar);
input d, clk;
output reg q, qbar;

always@(posedge clk)
begin
q <= d;
qbar = !d;
end
endmodule

Clear Input in Flip flop

All hardware systems should have a pin to clear everything and have a fresh start. It applies to flip flops too. Hence, we will include a clear pin that forces the flip flop to a state where Q = 0 and Q’ = 1 despite whatever input we provide at the D input. This clear input becomes handy when we tie up multiple flip flops to build counters, shift registers, etc.

Behavioral Modeling of D flip flop with Synchronous Clear

For synchronous clear, the output will reset at the triggered edge(positive edge in this case) of the clock after the clear input is activated.

Here’s the code:

module dff_behavioral(d,clk,clear,q,qbar); 
input d, clk, clear; 
output reg q, qbar; 
always@(posedge clk) 
begin
if(clear== 1)
q <= 0;
qbar <= 1;
else 
q <= d; 
qbar = !d; 
end 
endmodule

Behavioral Modeling of D flip flop with Asynchronous Clear

For asynchronous clear, the clear signal is independent of the clock. Here, as soon as clear input is activated, the output reset.

This can be achieved by adding a clear signal to the sensitivity list. Hence we write our code as:

module dff_behavioral(d,clk,clear,q,qbar); 
input d, clk, clear; 
output reg q, qbar; 
always@(posedge clk or posedge clear) 
begin
if(clear== 1)
q <= 0;
qbar <= 1;
else 
q <= d; 
qbar = !d; 
end 
endmodule

Structural Modeling

Like in Gate level modeling, we analyze the logic design for structural modeling. We will consider the gates required to build the design. But, instead of using in-built gates, we take each gate and create separate modules that will be integrated to form the whole circuitry.

In the case of D-flip flop, we have a NOT and four NAND gates that build the circuit.

Hence, we have to structurize each gate with their respective module.

Structural Modeling of D flip flop 

To start with code, we will first structurize the NAND gate.

We declare the module as nand_gate. The input and output ports are then declared.

module nand_gate(c,a,b);
input a,b;
output c;

Then, we use assign statement to write the logical expression for NAND.

assign c= ~(a & b);

The endmodule keyword is used for representing the end of the module.

Similarly, we do for NOT gate

module not_gate(f,e);
input e;
output f;

assign f = ~e;
endmodule

Note: We keep variables for assigning inputs and outputs in one module different from others. This ensures mixing up of signals does not happen during a simulation.

Now, we have to integrate these lower modules to form our D-flip flop. In order to do that, we use module instantiation. First, start with the name of the lower hierarchy module (defined and declared above) and write the name of the instance of your choice. The port-list will contain the output signals, followed by the input ones.

For example,

nand_gate nand1(x,clk,d);

Here,

  1. module-name :- nand_gate
  2. instance name:- nand1
  3. output port:- x(intermediate signal)
  4. input ports:- d and clk

Do the same for the rest of the instances

 
not_gate not1(dbar,d); 
nand_gate nand1(x,clk,d); 
nand_gate nand2(y,clk,dbar); 
nand_gate nand3(q,qbar,y); 
nand_gate nand4(qbar,q,x); 
endmodule

Hence, the final structure code will be:

module nand_gate(c,a,b); 
input a,b; 
output c; 
assign c = ~(a&b); 
endmodule

module not_gate(f,e); 
input e; 
output f; 
assign f= ~e; 
endmodule

module d_ff_struct(q,qbar,d,clk);
input d,clk; 
output q, qbar; 
not_gate not1(dbar,d); 
nand_gate nand1(x,clk,d); 
nand_gate nand2(y,clk,dbar); 
nand_gate nand3(q,qbar,y); 
nand_gate nand4(qbar,q,x); 
endmodule

Testbench

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.

Let’s see how we can write a test bench for D-flip flop by following step by step instruction

//test bench for d flip flop
//1. Declare module and ports

module dff_test;
reg D, CLK,reset;
wire Q, QBAR;

//2. Instantiate the module we want to test. We have instantiated the dff_behavior

dff_behavior dut(.q(Q), .qbar(QBAR), .clear(reset), .d(D), .clk(CLK)); // instantiation by port name.

//3. Monitor TB ports
$monitor("simtime = %g, CLK = %b, D = %b,reset = %b, Q = %b, QBAR = %b", $time, CLK, D, reset, Q, QBAR);

//4. apply test vectors
initial begin
  clk=0;
     forever #10 clk = ~clk;  
end 
initial begin 
 reset=1; D <= 0;
 #100; reset=0; D <= 1;
 #100; D <= 0;
 #100; D <= 1;
end 
endmodule

RTL Schematic

Here’s how the RTL Schematic will look if we peek into the elaborate design of the behavioral model of the D-flip flop without clear input.

RTL schematic of D flip flop
RTL schematic of D flip flop

With synchronous clear input,

RTL Schematic of D flip flop with Synchronous clear
RTL Schematic of D flip flop with Synchronous clear

And with asynchronous clear input,

RTL Schematic of D flip flop with Asynchronous Clear
RTL Schematic of D flip flop with Asynchronous Clear

Simulated Waveforms

D flip flop Without Reset

Simulated waveform of D flip flop without clear
Simulated waveform of D flip flop without clear
Simulated waveform of D flip flop with synchronous clear
Simulated waveform of D flip flop with synchronous clear

In this waveform, we can see that the Q and Q’ will be reset state at the positive cycle after clear is activated

Simulated waveform of D flip flop with asynchronous clear
Simulated waveform of D flip flop with asynchronous clear

In this waveform, we can see that the Q and Q’ will be in the reset state as soon as clear is activated.

Conclusion

In this article, we’ve explored the design and implementation of a D flip-flop using multiple modeling styles in Verilog, including Gate-level, Dataflow, and Behavioral modeling. Each approach offers unique benefits, from the simplicity and directness of gate-level modeling to the higher-level abstraction and ease of use in behavioral modeling. We also examined how to incorporate features like synchronous and asynchronous clear inputs, which are essential for resetting the flip-flop’s state in various applications.

D flip-flops are fundamental building blocks in digital design, playing a crucial role in memory storage and synchronization within sequential circuits. Understanding how to implement and test these flip-flops effectively across different modeling styles equips designers with the tools needed to create more complex systems such as registers, counters, and shift registers.

By grasping these core concepts, you will be better prepared to design and simulate robust digital systems that meet modern requirements, especially in areas like high-speed computing, signal processing, and embedded systems. Whether you’re a beginner or looking to refine your Verilog skills, mastering the D flip-flop’s design and testing techniques is a significant step forward in your digital design journey.

Frequently Asked Questions about D flip-flop

What is the difference between a D flip-flop and a D latch?

A D flip-flop and a D latch both store a single bit of data, but the key difference lies in the clocking mechanism. A D latch is level-sensitive, meaning it updates its output whenever the clock signal is high. In contrast, a D flip-flop is edge-triggered, meaning it only updates the output on the rising or falling edge of the clock signal.

What is the purpose of Q’ (Q bar) in a D flip-flop?

The Q’ (Q bar) output is the complement or inverse of the Q output. If Q is 1, Q’ will be 0, and vice versa. This dual output allows for applications where both the normal and inverted states of the flip-flop are needed in digital circuits.

What is the difference between synchronous and asynchronous clear in a D flip-flop?

In a synchronous clear, the flip-flop’s output is reset when the clear signal is activated during the clock edge. The reset operation is synchronized with the clock. In an asynchronous clear, the reset occurs immediately when the clear signal is triggered, independent of the clock signal.

Why is the reg data type used in behavioral modeling of D flip-flops?

The reg data type in Verilog is used in behavioral modeling because it allows the flip-flop to retain its value until a new assignment is made. It is required when writing sequential logic (such as in flip-flops) because reg can hold its value between clock cycles, unlike other data types that are used for combinational logic.

Can the D flip-flop be used for memory storage in larger digital systems?

Yes, D flip-flops are often used as memory elements in larger digital systems like registers, shift registers, and memory arrays. Multiple D flip-flops can be combined to store multi-bit data, and their predictable behavior makes them ideal for applications in data storage and synchronization.

What are the advantages of using Verilog for designing flip-flops?

Verilog is a hardware description language (HDL) that allows for efficient simulation, synthesis, and testing of digital systems. It is widely used because it supports multiple levels of abstraction (gate, dataflow, and behavioral modeling), making it suitable for a range of designs, from simple to complex. Additionally, Verilog’s modular nature helps in reusability and scalability of digital designs.

How do I simulate a D flip-flop in Verilog?

To simulate a D flip-flop in Verilog, you must write a testbench that applies various input patterns to the flip-flop and monitors the output. The testbench will apply clock pulses, set/reset signals, and the data input while observing how the Q and Q’ outputs behave in response to these inputs.

What are some common applications of D flip-flops in digital circuits?

D flip-flops are commonly used in applications such as:

  • Registers: To store multi-bit data in processors.
  • Counters: To count events or clock cycles in sequential circuits.
  • Shift Registers: For shifting data in communication systems or memory devices.
  • Timing and synchronization: To synchronize signals in systems with multiple clock domains.

2 thoughts on “Verilog code for D flip-flop – All modeling styles

  1. I cannot create a proper testbench for structural flip-flop, because my q and q_bar never takes some value. How can we make a testbench for structural verilog?

  2. Hi, Good Work. Small note:
    The D-FF which you have referred may be wrong.
    Here the CLK signal which is generated from TB/feeded to design will be pulses, not edge spikes.
    So In this case, the model will be sensitive when CLK is at High level which makes it a latch. (Design will be transparent when CLK is at Level 1)

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.