A D flip-flop is a sequential logic circuit with a single data input, D, that copies D to its output, Q, only at the moment its clock signal transitions, typically on the rising edge, and holds that value steady until the next edge. That edge-only behavior, not just “storing a bit,” is what separates a flip-flop from a latch, and it is why the D flip-flop is the default memory element in modern FPGA and ASIC design.
D Flip-Flop truth table (positive edge-triggered):
| Clock Edge | D | Q (next) |
|---|---|---|
| Rising | 0 | 0 |
| Rising | 1 | 1 |
| Not rising | X | Q (previous, held) |
Characteristic equation: Q(next) = D
module d_flip_flop (
input wire clk,
input wire rst_n,
input wire d,
output reg q
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
q <= 1'b0;
else
q <= d;
end
endmodule
The D flip-flop does not exist in isolation. It is the answer to a problem the SR latch and the D latch could not solve, and it is the starting point for the T and JK flip-flops that follow it. Every digital circuit that needs to remember something, a counter, a register, the state of a traffic light controller, depends on one of these building blocks. Combinational logic (AND gates, OR gates, multiplexers) has no memory: feed it the same input twice and you get the same output twice, with no regard for what happened a moment ago. Sequential logic is different. It has state, and the flip-flop is what holds that state between clock edges.
This guide covers the four circuits every digital logic course puts in front of a beginner: the SR latch, the D flip-flop, the T flip-flop, and the JK flip-flop, why each one exists, and how to move from the Verilog above to a working circuit on real FPGA hardware rather than a simulator alone.
What Most Beginners Get Wrong
Most beginners memorize truth tables without understanding the failure mode each flip-flop was built to fix. That approach breaks down the moment an exam or a design problem asks you to convert one flip-flop type into another, because memorization gives you no principle to reason from. The fix is to learn these four circuits as a sequence of engineering decisions, not four unrelated facts, starting from the SR latch below.
The SR Latch: Where Memory Starts
The SR latch (Set-Reset latch) is the simplest memory element in digital logic. It is built from two cross-coupled NOR gates or two cross-coupled NAND gates, and it has two inputs: S (set) and R (reset).
SR Latch truth table (NOR-based, active-high):
| S | R | Q (next) | State |
|---|---|---|---|
| 0 | 0 | Q (previous) | Hold |
| 0 | 1 | 0 | Reset |
| 1 | 0 | 1 | Set |
| 1 | 1 | Invalid | Forbidden |
The problem is that last row. When both S and R are 1 at the same time, the outputs Q and Q’ both try to go to the same value, which breaks the fundamental rule that Q and Q’ must always be opposite. This is the SR latch’s forbidden state, and it is one reason engineers avoid raw SR latches. The deeper reason is structural: an SR latch is built from combinational gates wired back into their own inputs, an asynchronous feedback loop with no clock involved. FPGAs are synchronous devices built from look-up tables and D flip-flops, and if a design accidentally infers a feedback loop like this, synthesis tools will flag it and static timing analysis cannot resolve it, because there is no clock edge to measure the timing against. That is the real-world reason raw SR latches do not appear in FPGA or ASIC designs, not just the forbidden state itself.
The D Latch: One Step Toward a Flip-Flop
Before reaching a true D flip-flop, it helps to see the D latch, because the two are easy to confuse and the difference matters once you start writing Verilog. A D latch is built by tying the SR latch’s S input to D and its R input to the inverse of D. This does remove the forbidden state, since S and R can never both be 1. But it does not make the circuit edge-triggered. A D latch is level-sensitive and transparent: for as long as the enable or clock signal is high, the output follows the D input directly. Only when the enable goes low does the latch hold its last value.
D Latch behavior:
| Enable | D | Q (output) |
|---|---|---|
| High | 0 | 0 (follows D) |
| High | 1 | 1 (follows D) |
| Low | X | Q (previous, held) |
This transparency is exactly what makes a plain D latch unsuitable as the general-purpose memory element in a synchronous design: its output can change multiple times while the enable is high, which makes timing hard to reason about in a larger circuit.
The D Flip-Flop: Sampling on the Edge, Not the Level
A true D flip-flop fixes the D latch’s transparency problem. Internally, it is built from two D latches in series, a master and a slave, clocked on opposite phases (a master-slave configuration). While the clock is low, the master latch is transparent and samples D, but the slave latch is closed and holds its previous output. When the clock rises, the master closes (locking in whatever D was at that instant) and the slave opens, passing that locked-in value through to Q. The net effect is that Q only ever changes at the clock edge itself, never while the clock is level-high or level-low. That edge-only behavior is what “edge-triggered” means, and it is the property a D latch does not have.
The truth table and characteristic equation for this behavior are at the top of this guide. The difference that matters between a D latch and a D flip-flop is entirely in when Q changes: a latch moves it continuously while enabled, a flip-flop moves it once, at the edge. In practice you will rarely build the master-slave pair from individual gates. You will write a posedge-sensitive always block in Verilog and let synthesis infer the flip-flop, which is covered in the Verilog section below. Registers, counters, and pipeline stages in real FPGA and ASIC designs are built almost entirely from D flip-flops, because edge-triggered timing is predictable in a way level-sensitive timing is not.
Reading the timing diagram. A truth table shows what happens at one instant; a timing diagram shows it across time, which is how you will actually debug this on hardware. Picture three horizontal lines stacked vertically: CLK on top, D in the middle, Q on the bottom, all moving left to right. CLK ticks up and down in a steady square wave. D changes whenever it wants, at any point, with no regard for CLK. Q, though, only ever changes in the instant CLK ticks upward, and it copies whatever value D happened to hold at that exact moment, ignoring every change D makes in between edges. If D flips from 0 to 1 and back to 0 entirely between two rising edges, Q never sees it. That is the whole discipline of edge-triggered design in one picture: Q cares about D only at the edge, never in between.
The T Flip-Flop: Built for Counting
The T flip-flop (Toggle flip-flop) exists for one job: counting. Where the D flip-flop stores whatever value you feed it, the T flip-flop has a single input, T, that tells it whether to hold its current state or flip to the opposite one.
T Flip-Flop truth table:
| Clock Edge | T | Q (next) |
|---|---|---|
| Rising | 0 | Q (previous, hold) |
| Rising | 1 | Q' (previous, toggle) |
Characteristic equation: Q(next) = T XOR Q
When T is 0, the flip-flop holds. When T is 1, it flips on every clock edge, dividing the clock frequency by two at its output. Older textbooks teach counters by chaining T flip-flops so each stage’s output clocks the next stage, a ripple counter. That construction is worth knowing for the history and for exam questions, but do not build one on an FPGA. FPGA clock routing is a dedicated, low-skew network separate from ordinary data routing, and feeding a flip-flop’s output into another flip-flop’s clock input bypasses that network entirely. It produces glitches, hold-time violations, and a circuit that static timing analysis cannot verify. On an FPGA, every flip-flop shares the same global clock, and counting is done with synchronous logic instead: a bank of D flip-flops with a combinational adder feeding their D inputs, so every bit updates on the same clock edge. The T flip-flop’s real value here is conceptual. It is almost always built from a D flip-flop with the toggle logic implemented externally (Q XOR T fed back into D), which is exactly the synchronous approach an FPGA counter actually uses, just described in T-flip-flop terms.
The JK Flip-Flop: Every Case Covered
The JK flip-flop takes the SR latch’s two-input structure and closes the one gap that made SR unusable: what happens when both inputs are active. Where SR treats S=1, R=1 as forbidden, the JK flip-flop defines it as toggle.
JK Flip-Flop truth table:
| Clock Edge | J | K | Q (next) |
|---|---|---|---|
| Rising | 0 | 0 | Q (previous, hold) |
| Rising | 0 | 1 | 0 (reset) |
| Rising | 1 | 0 | 1 (set) |
| Rising | 1 | 1 | Q' (previous, toggle) |
Characteristic equation: Q(next) = JQ' + K'Q
The JK flip-flop is often called the universal flip-flop because every other type can be built from it. Tie J and K together and you get a T flip-flop. Tie K to the inverse of J and you get a D flip-flop. This versatility is why JK flip-flops were the standard choice in TTL logic families for decades, though in modern FPGA and ASIC design, the D flip-flop has become the default building block because synthesis tools and standard cell libraries are built around it.
How the Four Relate
| Flip-Flop | Inputs | Forbidden State | Primary Use |
|---|---|---|---|
| SR Latch | S, R | Yes (S=1, R=1) | Basic memory element, rarely used directly |
| D | D | No | Registers, pipelines, general storage |
| T | T | No | Counters, frequency division |
| JK | J, K | No (S=1,R=1 becomes toggle) | Universal, can emulate D or T |
Every conversion between these four follows from their characteristic equations. If you can write Q(next) = D or Q(next) = T XOR Q from memory, you can derive any of the standard conversions (D to T, JK to D, and so on) on paper without needing to look them up, which is exactly the kind of reasoning an exam or an interview is testing for.
Building and Simulating a D Flip-Flop in Verilog
The full D flip-flop module is at the top of this guide. The posedge clk or negedge rst_n sensitivity list is what makes it synthesizable to a real flip-flop rather than a latch, a detail that trips up most beginners writing their first sequential Verilog. Leave rst_n out of the sensitivity list, or write the reset logic with a plain if instead of inside the clocked always block, and most synthesis tools will either throw a warning or infer unintended latch behavior. Getting this line right the first time is the difference between code that works in simulation and code that also works on real silicon.
Before touching hardware, confirm the module behaves correctly in simulation with a testbench, a second piece of Verilog that generates a clock and feeds test values into the module under test:
module d_flip_flop_tb;
reg clk;
reg rst_n;
reg d;
wire q;
d_flip_flop uut (
.clk(clk),
.rst_n(rst_n),
.d(d),
.q(q)
);
// Generate a clock: toggle every 5 time units, 10-unit period
initial clk = 0;
always #5 clk = ~clk;
initial begin
rst_n = 0; d = 0;
#12 rst_n = 1;
#10 d = 1;
#10 d = 0;
#10 d = 1;
#20 $finish;
end
initial
$monitor("time=%0t clk=%b rst_n=%b d=%b q=%b", $time, clk, rst_n, d, q);
endmodule
Run this in any Verilog simulator and the $monitor output will show q changing only at the clock edges you set up in the timing diagram above, not the instant d changes. That confirmation, seeing the simulated waveform match the edge-triggered behavior on paper, is the checkpoint to clear before moving to real hardware.
A T flip-flop built from this same D flip-flop, using the toggle logic described above:
module t_flip_flop (
input wire clk,
input wire rst_n,
input wire t,
output reg q
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
q <= 1'b0;
else if (t)
q <= ~q;
end
endmodule
Notice this is not a separate primitive. It is a D flip-flop with the toggle condition (~q when t is high) written directly into the always block, exactly the relationship shown in the comparison table above.
From Simulation to Real Hardware
Simulating these modules in a waveform viewer confirms the logic is correct, but it does not confirm the design synthesizes cleanly or behaves correctly under real clock timing, propagation delay, and I/O constraints. That gap between “correct in simulation” and “correct on hardware” is where most beginners get stuck, because most tutorials stop at the simulator.
Running the D and T flip-flop modules above on an EIM STEPFPGA board closes that gap, with one caution worth building in from the start. A mechanical switch does not produce one clean transition when you flip it; it bounces, making and breaking contact several times over a few milliseconds before settling. Feed that directly into a flip-flop input and you get exactly the kind of unpredictable, hard-to-diagnose behavior this guide is trying to help you avoid: a single press registering as several rapid toggles. The fix is a debounce circuit between the switch and the flip-flop input, and a synchronizer (typically two flip-flops in series) if that input crosses into a different clock domain from the switch itself. The board’s browser-based development environment lets you assign clk to the onboard oscillator, a debounced d or t to a physical switch, and q to an LED, then watch the flip-flop hold and toggle state in real time as you flip the switch, with no separate toolchain install required. That immediate physical feedback, seeing an LED latch a value and hold it exactly until the next clock edge, does more to cement the concept than any truth table, and building the debounce circuit first is itself a real lesson in why synchronous design discipline exists.
The FPGA Learning Kit is built around exactly this kind of exercise: short, verifiable circuits you build once in theory and then confirm on real hardware, which is the fastest way to know the theory actually stuck.
Where D, T, and JK Flip-Flops Go Next
Once you are comfortable with these four circuits, the next natural step is combining them into something that does real work. A ring of T flip-flops becomes a counter. A bank of D flip-flops becomes a register. That is the subject of Verilog or VHDL: Which Language to Learn First, which picks up exactly where this article leaves off: once you know what a flip-flop does, which language should you use to describe more of them.
For a broader view of where flip-flops fit inside a complete beginner FPGA curriculum, from your first blinking LED to a working project, see FPGA Projects for Beginners.
Frequently Asked Questions
What is the difference between a latch and a flip-flop?
A latch is level-sensitive: its output follows the input for as long as the enable or clock signal is active. A flip-flop is edge-triggered: it only samples its input at the moment the clock transitions, typically on the rising edge, and holds that value until the next edge. This distinction is why flip-flops, not latches, are the standard building block in synchronous digital design.
Why is the JK flip-flop called the universal flip-flop?
Because every other common flip-flop type can be derived from it by tying its two inputs together in different configurations. J and K tied together produces a T flip-flop. K tied to the inverse of J produces a D flip-flop. No other flip-flop type can reproduce all the others through simple input tying, which is why the JK design was the standard choice in TTL logic for decades.
Can a D flip-flop be built from an SR latch?
Yes. Connect the D input directly to the S input and the inverse of D to the R input. Because S and R can never be equal under this arrangement, the SR latch’s forbidden state (S=1, R=1) becomes structurally impossible, which is exactly what makes the D flip-flop safe to use where a raw SR latch is not.
Is a D flip-flop positive or negative edge-triggered?
It depends on the specific part or design. Both positive edge-triggered (triggers on the 0-to-1 transition) and negative edge-triggered (triggers on the 1-to-0 transition) D flip-flops exist, and the Verilog example in this guide uses posedge clk, meaning it samples on the rising edge. The datasheet or module declaration always specifies which edge a given flip-flop uses.
What is the D flip-flop excitation table used for?
An excitation table shows what input value is required to move a flip-flop from a given current state to a desired next state, which is the reverse of a truth table. It is the tool used when designing a sequential circuit: you decide what state transitions you need, then use the excitation table to work out what input logic produces them.
Why is a D flip-flop called a delay flip-flop?
Because the output Q reproduces whatever value was on the D input one clock edge earlier, effectively delaying that value by one clock cycle before it appears at the output. The “D” is commonly read as either Data or Delay, and both readings describe the same behavior.
How do you convert a D flip-flop to a T flip-flop?
Feed the flip-flop’s own output back into its D input through an XOR gate with the T signal: D = T XOR Q. When T is 0, D equals Q, so the flip-flop holds its state on the next edge. When T is 1, D equals the inverse of Q, so it toggles. This is the same relationship shown in the Verilog T flip-flop module above, just described at the gate level instead of in code.
EIM TECHNOLOGY
Founder & Engineering Education Innovator
Daniel Cao is the Founder of EIM Technology and holds a Master of Applied Science in Engineering. With experience in engineering research, product development, PCB design, and technical education, he is the author of several books on electronics engineering. His work focuses on developing practical learning systems that integrate engineering hardware, lab instruments, curriculum, and project-based learning. Through EIM Technology, Daniel aims to make electronics and computer engineering more accessible and engaging, helping students build real experience in designing, measuring, testing, and troubleshooting electronic systems.


