Designing a D flip-flop
In entry 5 we looked at a single D flip-flop from a 74HC74 (the chip has 2). It has input pins "D" and "Clock" (as well as PR and CLR that we did not consider).
The D flip-flop: When the clock goes high (rising edge), the value of D is "latched" into the flip-flop. It has output pins Q (the latched valued), and the complement of Q. Here is the truth-table of a positive edge-triggered D flip-flop from 74HC74 (ignoring PR and CLR for now):
This is the symbol used (again, ignoring PR and CLR for now):
Let's try to build a D flip-flop ourselves. So I asked Grok: "How is a D flip-flop designed?"
Designing a D flip-flop involves creating a circuit that captures the value of the D (data) input at a specific clock edge (e.g., rising edge) and holds it at the output (Q) until the next edge. While you can buy D flip-flops as part of ICs (like the 74LS74), understanding how to build one from scratch reveals the magic of digital design. The most common approach is the master-slave configuration using two latches, often SR or JK latches, coordinated by a clock. Here’s how it’s done, step by step, focusing on a rising-edge-triggered D flip-flop using SR latches.
-tbc-
Grok mentioned SR latches, see entry 7, as well as "JK latches", which I do not know what they are.
-cont:
Concept
A D flip-flop needs to:
- Sample D only when the clock transitions (edge-triggered).
- Store that value and ignore D changes until the next clock edge.
- Avoid invalid states (unlike a raw SR latch).
The master-slave design splits this into two stages:
- Master latch: Captures D when the clock is low (or high, depending on design).
- Slave latch: Transfers the captured value to Q when the clock switches, locking it in.
Components
- 8 NAND gates (2 for master SR latch, 2 for slave SR latch, 4 for input/clock logic).
- 2 Inverters
- Inputs: D, CLK.
- Outputs: Q, Q̅.
Step-by-Step Construction..
I removed Groks explanation and replaced it with a picture:
Note that the Master Latch as well as the Slave Latch are SR latches of NAND type, where 1,1-input is "no change" (see entry 7).
Building a D flip-flop
Let's build this. I am not going to physically connect 8 NAND gates and two inverters, that sounds like too much tedious work (and I do not have that many NAND gates). Instead, I will design it using basic gates in ACEL. The result will be the same.
NAND latches are named Master and Slave, We need 4 NAND gates (named according to picture) and 2 inverters (named by its input pin):
- I have a button for "D", connected to Arduino pin 2.
- I have a button for "Clk", connected to Arduino pin 3.
- I have an LED (to display Q) connected to Arduino pin 4.
You can, of course, use real buttons, a real LED and the Arduino Mega. These are the connections we need:
All of this works exactly as the D flip-flop from the 74HC74:
You can play with this yourself on Wokwi. The name of the project is "D flip-flop".
Understanding the D flip-flop
One way to understand the D flip-flop is to play around with it, printing the state of all gates / latches. This is the basic analysis of the D flip-flop:
- When Clk = 0, NAND gates 3 and 4 outputs 1 (NAND gate outputs 0 only if both inputs are 1) and there can be no change in the Slave SR latch. The Slave latch is "frozen".
- Similarly, when Clk = 1, there can be no change in the Master SR latch and it is "frozen".
- When Clk = 0, the Master Q is equal to D. Confirm this by a print when Clk = 0, D = 0, and Clk = 0, D = 1.
- When Clk goes high, the Slave Q is equal to Master Q. Confirm this by a print.
All in all, the result is this:
Here is a more detailed explanation from Grok, which may be more useful:
How It Works (Rising-Edge Triggered)
- CLK = 0:
- NOT CLK = 1.
- Master S̅ = NAND(D, 1) = NOT D, R̅ = NAND(NOT D, 1) = D.
- Master is transparent: Q (master) follows D (if D = 1, Q = 1; if D = 0, Q = 0).
- Slave S̅ = NAND(Q (master), 0) = 1, R̅ = NAND(Q̅ (master), 0) = 1.
- Slave holds its previous state (no change).
- CLK rises to 1 (Rising Edge):
- NOT CLK = 0.
- Master S̅ = NAND(D, 0) = 1, R̅ = NAND(NOT D, 0) = 1.
- Master locks its state (holds the D value it had when CLK was 0).
- Slave S̅ = NAND(Q (master), 1) = NOT Q (master), R̅ = NAND(Q̅ (master), 1) = NOT Q̅ (master).
- Slave updates: Q (slave) takes the master’s Q (the D value from just before the edge).
- CLK = 1:
- Master stays locked (S̅ = 1, R̅ = 1).
- Slave stays stable (Q reflects the captured D).
- CLK falls to 0:
- Master becomes transparent again, tracking D.
- Slave holds its value (CLK = 0 forces S̅ = 1, R̅ = 1).
Key Result: Q updates only when CLK goes from 0 to 1, making it rising-edge-triggered.
Verification
- D = 1, CLK = 0: Master Q = 1, Slave Q holds old value.
- CLK → 1: Master locks Q = 1, Slave Q becomes 1.
- D changes to 0, CLK = 1: Master stays locked, Slave Q stays 1.
- CLK → 0: Master Q = 0, Slave Q still 1 (no change until next rising edge).
Preset and Clear
In addition to D, Clock, Q and Q-bar, the 74HC74 has two additional input pins Preset and Clear. Clear will set the Q value to 0 while Preset will set it to 1. Preset and Clear are both "active low" meaning that you need to make the Preset pin low / Clear pin low to set Q = 1 / Q = 0:
This is the symbol for D flip-flop from the 74HC74:
The "circles" in Preset and Clear indicate that they are active low. Adding Preset and Clear to the D flip flop we considered above is simple, no need to ask Grok. We replace the Slave section with the following:
Note that when the clock is low, the output of 3 and 4 is 1. If Clear is low and Preset high, then the Slave latch will reset and Q = 0. I did not build this, but you are welcome to do so.
ACEL D flip-flop
I built an ACEL component based on the schedules above called DFlipFlop. Since I am not a fan of "Active low", I designed DFlipFlop with Preset and Clear "Active high":
This is the symbol I will use for the ACEL D flip-flop:
PR and CLR are by default 0, so if they are not needed, then no connection is required. These are the names of the pins:
- Input pin: D
- Input pin: Clock
- Input pin: Clear
- Input pin: Preset
- Output pin: Q
- Output pin: Q_Bar