The D flip-flop is the single most important storage element in modern digital design. Nearly every register, pipeline stage, and state register in a synchronous chip is built from edge-triggered D flip-flops. Yet students frequently confuse the D flip-flop with its close relative, the D latch. Both store one bit and both have a single data input named D, but they sample that input in fundamentally different ways. One is level-sensitive (transparent), the other is edge-triggered. Understanding this distinction is the gateway to understanding clocking, timing, and the entire RTL design methodology. This article builds up both circuits from first principles, gives the exact truth tables and characteristic equations, shows how to construct a D latch from a 2:1 multiplexer and a D flip-flop from NAND gates, introduces setup and hold time, and ends with clean, synthesizable Verilog.
Why the D Element Exists: Taming the SR Latch
The most primitive memory cell is the SR (Set-Reset) latch, usually drawn as a pair of cross-coupled NOR or NAND gates. It has a serious flaw: when both inputs are asserted simultaneously it enters a forbidden or indeterminate state, and the output after that condition cannot be reliably predicted. The D element solves this by collapsing the two control inputs into one. Instead of asking “set or reset?”, we simply say “store this value D”. Internally the single D is routed so that the set and reset inputs can never both be active at the same time, which eliminates the forbidden state entirely. This is why D stands for data (sometimes called a delay element), and it is the reason the D family dominates practical design over the JK flip-flop and the SR latch for ordinary storage.
The D Latch: A Transparent, Level-Sensitive Cell
A D latch has two inputs: the data input D and an enable input (often labelled EN, E, G, or sometimes called the clock or gate). Its behaviour is level-sensitive, meaning its response depends on the level of the enable signal, not on a transition.
- When EN = 1 the latch is transparent: the output Q simply follows D. Whatever D does, Q copies it after a small propagation delay.
- When EN = 0 the latch is opaque (holding): Q freezes and retains the last value it had when EN went low, ignoring any further changes on D.
D Latch Truth Table
Here Q denotes the current stored output and Q(next) the output after the input is applied. “x” means don’t-care.
| EN | D | Q(next) | Mode |
|---|---|---|---|
| 0 | x | Q (no change) | Hold / opaque |
| 1 | 0 | 0 | Transparent |
| 1 | 1 | 1 | Transparent |
When the latch is enabled, Q(next) = D. When disabled, Q(next) = Q. These two cases combine into a single compact expression.
Characteristic Equation of the D Latch
Treating EN as the select between “hold” and “load”, the characteristic equation is:
Q(next) = EN · D + EN’ · Q
This equation reads directly as a 2:1 multiplexer, which is exactly how an elegant D latch is built.
Building a D Latch Using a 2:1 MUX
The characteristic equation above is the defining equation of a 2:1 multiplexer with a feedback loop. Map the terms as follows:
- The MUX select line is EN.
- Input I0 (selected when EN = 0) is the fed-back output Q, giving the hold behaviour.
- Input I1 (selected when EN = 1) is the external data D, giving the transparent behaviour.
- The MUX output is Q, which is wired back to I0 to close the storage loop.
So the construction is: take a single 2:1 MUX, feed D into the “1” input, feed the MUX’s own output back into the “0” input, and drive the select with EN. When EN = 1 the output tracks D; when EN = 0 the output holds itself through the feedback path. This mux-based latch is the standard way the cell is drawn in textbooks and is also close to how it is laid out in CMOS standard-cell libraries (using transmission gates rather than a gate-level MUX, but with identical logic). It makes the hold-versus-load intent completely explicit.
The D Flip-Flop: Edge-Triggered Storage
A D flip-flop (DFF) also has a D input and a clock input, but it is edge-triggered. It samples D only at the instant the clock makes a transition, typically the rising edge (0 to 1) for a positive-edge-triggered flip-flop. At every other time, including the entire high level and the entire low level of the clock, the flip-flop ignores D completely and holds its value. This is the crucial difference from the latch, which is transparent for a whole half-cycle.
D Flip-Flop Truth Table
The up-arrow symbol represents a rising clock edge.
| CLK | D | Q(next) | Mode |
|---|---|---|---|
| ↑ (rising edge) | 0 | 0 | Capture D |
| ↑ (rising edge) | 1 | 1 | Capture D |
| 0 (steady low) | x | Q (no change) | Hold |
| 1 (steady high) | x | Q (no change) | Hold |
Characteristic Equation of the D Flip-Flop
Because the flip-flop captures D at the active edge and holds otherwise, its characteristic equation is wonderfully simple:
Q(next) = D
This equation is understood to apply at the active clock edge. That is the whole point of the D flip-flop: the next state equals the data input, sampled once per clock. This clean “next state equals input” relationship is what makes the D flip-flop so convenient for describing sequential circuits and state machines in RTL.
Latch vs Flip-Flop: Side by Side
| Property | D Latch | D Flip-Flop |
|---|---|---|
| Triggering | Level-sensitive (on enable level) | Edge-sensitive (on clock edge) |
| Transparency | Transparent while EN = 1 | Never transparent; samples only at the edge |
| Output updates | Throughout the active level | Once per clock edge |
| Characteristic equation | Q(next) = EN·D + EN’·Q | Q(next) = D (at the edge) |
| Typical build | One 2:1 MUX with feedback | Two latches in master-slave, opposite enables |
| RTL usage | Usually unintended / avoided | The default storage element |
Master-Slave: How an Edge-Triggered DFF Is Made From Latches
An edge-triggered D flip-flop is most commonly implemented as two D latches in series, called the master and the slave, driven by opposite clock phases. When the clock is low, the master latch is transparent and tracks D while the slave holds. When the clock rises, the master becomes opaque (freezing the value that D had just before the edge) and the slave becomes transparent, passing that captured value to the output. Because only one latch is ever transparent at a time, data can never race straight through from input to output within a single clock level. The net effect is sampling on the edge: Q(next) = D at the rising edge. This is a neat illustration that a flip-flop is not more mysterious than a latch; it is simply two latches cooperating.
Building a D Flip-Flop From NAND Gates
Because the NAND gate is a universal gate, any flip-flop can be constructed entirely from NAND gates. The classic positive-edge-triggered D flip-flop using NAND gates uses six 2-input NAND gates arranged as three cross-coupled pairs:
- Output latch (gates 1 and 2): a cross-coupled NAND SR latch that produces Q and Q’. This is the final storage element.
- Steering / control latches (gates 3, 4, 5, 6): two more cross-coupled NAND pairs that sit between the D input, the clock, and the output latch. They form the edge-detection network.
The operation works like this. While the clock is low, the two control latches hold a configuration that keeps both inputs of the output SR latch inactive, so Q holds its value and any change on D is merely “pre-loaded” into the control stage. At the moment the clock rises, the control latches resolve according to the value D had just before the edge and briefly drive exactly one input of the output latch, either setting it (if D = 1) or resetting it (if D = 0), but never both. Crucially, after that instant the feedback within the control latches locks out any further influence from D until the next clock edge. That lockout is what makes the circuit edge-triggered rather than level-sensitive: changing D while the clock stays high has no effect. This six-NAND structure is a standard textbook result and a common lab and interview exercise, and it demonstrates why NAND gates are called universal. For a refresher on reducing such Boolean control logic, see our guide to the Karnaugh map.
Setup Time and Hold Time: Why Timing Matters
Because a flip-flop samples D at a precise instant, the data must be stable in a small window around the clock edge for the capture to be reliable. Two parameters define this window:
- Setup time (tsu): the minimum time before the active clock edge during which D must be held stable.
- Hold time (th): the minimum time after the active clock edge during which D must remain stable.
If D changes inside this forbidden window, the flip-flop may fail to resolve cleanly and can enter a metastable state, where the output hovers between 0 and 1 for an unpredictable time before settling. Setup violations are typically fixed by slowing the clock (lengthening the period) or shortening the combinational path feeding D; hold violations are more insidious because they do not depend on clock frequency and are usually fixed by adding delay to the data path. Together, setup and hold analysis form the backbone of static timing analysis (STA) in real chip design. The D latch has analogous constraints relative to the enable’s falling edge, but because it is transparent for a whole level it is far harder to time-close in a synchronous system, which is one more reason flip-flops are preferred.
Why the Edge-Triggered D Flip-Flop Is the Workhorse of RTL
In register-transfer level (RTL) design, the entire circuit is modelled as combinational logic clouds separated by registers, and those registers are built from edge-triggered D flip-flops. Several properties make the DFF the natural choice:
- A single, predictable sampling point. Because every flip-flop updates on the same clock edge, the whole design advances in lockstep. Timing analysis only needs to check the path between two edges, which is tractable.
- No transparency hazards. A latch that is transparent for half the clock can allow data to ripple through several stages in one cycle, making timing analysis and verification painful. Flip-flops close this door.
- Clean mapping from HDL. The characteristic equation Q(next) = D maps directly onto the non-blocking assignment inside a clocked
alwaysblock, so RTL reads almost like a specification. - Tool support. Synthesis tools, place-and-route, and STA are all optimized around edge-triggered flip-flops. In fact, an unintended latch inferred from an incompletely specified combinational block is a classic RTL bug that tools warn about.
This is why when designers build counters, shift registers, pipelines, and the state register of a finite state machine, the underlying element is almost always the positive-edge-triggered D flip-flop.
D Flip-Flop Verilog Code
A synchronous positive-edge-triggered D flip-flop is described with a clocked always block and a non-blocking assignment. Because the characteristic equation is simply Q(next) = D, the body is a single line:
module d_ff (
input wire clk, // clock
input wire d, // data input
output reg q // stored output
);
always @(posedge clk) begin
q <= d; // capture D on the rising edge
end
endmoduleTo add an active-low asynchronous reset, which is standard practice for initializing registers to a known state, extend the sensitivity list:
module d_ff_rst (
input wire clk,
input wire rst_n, // active-low async reset
input wire d,
output reg q
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
q <= 1'b0; // reset to 0
else
q <= d; // normal capture
end
endmoduleFor contrast, a D latch is written with a level-sensitive always block (sensitive to the enable level and data, not an edge), which is exactly the kind of code that infers a latch:
module d_latch (
input wire en,
input wire d,
output reg q
);
always @(*) begin
if (en)
q = d; // transparent; q holds otherwise
end
endmoduleNotice the DFF uses posedge clk and non-blocking <=, while the latch uses a level-sensitive combinational block and blocking =. These coding conventions are a core part of writing correct, synthesizable RTL. For a deeper look at the language choices involved, see our comparison of Verilog vs SystemVerilog.
Learn RTL Design the Right Way
Mastering flip-flops, latches, timing, and clean synthesizable coding is the foundation of a VLSI career. If you want structured, hands-on training that takes you from these fundamentals all the way to building real digital blocks, explore the ChipXpert Advanced RTL Design course (online and offline), where you will practice writing, simulating, and debugging register-based designs on real tools.
Frequently Asked Questions
What is the difference between a D latch and a D flip-flop?
A D latch is level-sensitive: while its enable is high it is transparent and the output follows D continuously. A D flip-flop is edge-triggered: it samples D only at the clock edge (usually the rising edge) and holds at all other times. In short, the latch reacts to a level for a whole half-cycle, while the flip-flop reacts only to a transition.
What is the characteristic equation of a D flip-flop?
The characteristic equation of a D flip-flop is Q(next) = D, understood to apply at the active clock edge. For a D latch it is Q(next) = EN·D + EN’·Q, which reduces to Q(next) = D only while the enable is active and to Q(next) = Q (hold) when the enable is low.
How do you build a D flip-flop using NAND gates?
A positive-edge-triggered D flip-flop is built from six 2-input NAND gates: one cross-coupled NAND pair forms the output SR latch, and two more cross-coupled NAND pairs form the edge-detecting control network between D, the clock, and that output latch. The control latches lock out further changes on D after the clock edge, which is what gives the circuit its edge-triggered behaviour. NAND gates suffice because NAND is a universal gate.
How do you make a D latch using a MUX?
A D latch is a single 2:1 multiplexer with feedback. The enable drives the select line; the data input D goes to the input selected when enable is 1; and the MUX output is fed back to the input selected when enable is 0. This directly realizes the characteristic equation Q(next) = EN·D + EN’·Q, giving transparent behaviour when enabled and hold behaviour when disabled.
Why are D flip-flops preferred over latches in RTL design?
Edge-triggered D flip-flops give every register in the design a single, predictable sampling instant, which makes static timing analysis tractable and prevents data from rippling through multiple stages in one clock level. Synthesis, place-and-route, and timing tools are all optimized around them, and the equation Q(next) = D maps cleanly onto a clocked always block. Unintended latches, by contrast, are a common RTL bug that tools flag as warnings.
What are setup time and hold time?
Setup time is the minimum interval before the clock edge during which the data input must be stable, and hold time is the minimum interval after the edge during which it must remain stable. If data changes inside this window the flip-flop can become metastable and produce an unpredictable output. Setup violations are usually fixed by slowing the clock or shortening the logic path, while hold violations are fixed by adding delay to the data path.
💻 Want the code? See the Verilog implementation with a verified testbench: D Flip Flop Verilog code →
Related digital electronics topics
- JK Flip-Flop: Truth Table & Working
- T Flip-Flop: Truth Table & Circuit
- SR Latch (NAND & NOR)
- Karnaugh Map (K-Map)
- Full Adder & Half Adder
- Universal Gates: NAND & NOR
- Finite State Machines (FSM)
- Sequential Circuits
- Shift Registers (SISO/SIPO/PISO/PIPO)
- 4:1 Multiplexer
- Encoders & Decoders
- Binary to Gray Code Conversion
- One's & Two's Complement
- Counters in Digital Electronics
- Demultiplexer (DEMUX)
Share your question in comments or talk to our mentor team for batch guidance.
Ask the Admin Team
Drop your basic question in comments: eligibility, prerequisites, tools, fee range, and placement support.
Our team reviews and responds regularly.
