Hardware Engineering · Digital Logic
Latches, Flip-Flops, and What Edge Sensitivity Actually Means
How a cross-coupled pair stores a bit, why a master-slave arrangement turns level sensitivity into edge triggering, and what transparency costs downstream.
Combinational logic computes; it does not remember. Any circuit with state needs an element whose output depends on its past, and the smallest such element is a pair of inverting gates wired so that each drives the other. Everything from a single register bit to a memory array to a processor’s architectural state reduces to that loop plus a way to break it.
Storage from a feedback loop
Two inverters connected output to input cannot settle at a level that is neither 0 nor 1 — but they can settle at either rail, and which one they settle at depends on the history of the loop. That bistability is storage. The loop has two stable equilibria and one unstable equilibrium in between, and it holds whichever stable state it was last pushed into.
Two cross-coupled NOR gates make the arrangement controllable. The output of the first gate feeds the second, and vice versa, so the pair stores one bit. Asserting the set input forces the output high and, through the loop, keeps it high after the input is released. Asserting reset does the mirror. Asserting both — which the NOR form interprets as a simultaneous request to set and clear — drives both outputs low. That is not one of the two stored states, and it violates the invariant that the outputs are complements. When both inputs are then released simultaneously, which state the loop settles into depends on the relative strength of the two gates and on whatever noise is present at that instant. It is indeterminate in the design sense: the circuit has an outcome for any given fabrication and temperature, but the design does not specify it.
The cross-coupled inverter loop is also the storage element inside a six-transistor static RAM cell, where the two access transistors gate the loop onto the bit lines. The mechanism is the same; the difference is that the cell is optimized for density and read stability rather than for a clean single-ended interface.
A third possibility is dynamic storage: a capacitance holding a charge. It needs no feedback, is smaller, and leaks. A dynamic latch’s minimum clock rate is not zero, because the held value decays if the clock stops long enough. This is the reason that a circuit with a minimum-frequency requirement exists at all, and it is a real constraint in designs that gate their clock for power.
Level sensitivity and the transparent window
Wrap the loop with an enable and the result is a gated latch: while the enable is high the latch is transparent and the output follows the input, and while the enable is low the loop is closed and the value is held.
Transparency is a stronger statement than it appears. While transparent, the latch is not storage at all; it is a wire with delay. A circuit whose combinational paths pass through transparent latches has a path from input to output whose delay depends on the clock phase. Worse, if a path leaves a latch and returns to the same latch while it is transparent, the loop is a combinational cycle, and combinational cycles have no well-defined settling time.
The compensating advantage is that a latch’s sampling instant is the closing edge of the enable, and that instant can be tuned by the clock phase. A pipeline built from latches can borrow time: if one stage’s logic finishes late, it can use part of the next stage’s window as long as the following stage’s logic finishes early enough to compensate. Time borrowing is not available with edge-triggered elements, whose sampling instant is fixed.
How a latch pair becomes an edge-triggered flip-flop
An edge-triggered flip-flop is not a circuit that detects an edge. It is two latches in series controlled by opposite clock phases. In the common master-slave arrangement, the master latch is transparent while the clock is low and the slave is transparent while the clock is high. When the clock rises, the master closes and holds whatever value the input had just before the edge, while the slave opens and passes that value to the output. When the clock falls, the slave closes and holds the output while the master opens to accept the next value.
The externally visible behaviour is that the output changes only near the clock edges, and that the value captured is the input value at the instant of the rising edge. That behaviour is what “edge triggered” means: it describes the input-output relation, not the internal mechanism. Because the master is opaque during the high phase and the slave is opaque during the low phase, the two latches are never transparent simultaneously, and there is no window in which a change at the input can propagate straight to the output.
The distinction between the two devices is visible in a hardware description.
// Level-sensitive latch: while en is high, q follows d; when en falls, q holds.
module d_latch (input en, input d, output reg q);
always @(*) begin
if (en) q = d; // blocking assignment: transparency is intentional
end
endmodule
// Edge-triggered flip-flop: q takes the value of d on the rising edge only.
module d_flip_flop (input clk, input d, output reg q);
always @(posedge clk) begin
q <= d; // non-blocking: all flops in a design update together
end
endmodule
The two are one line apart in source and fundamentally different in behaviour. A synthesis tool infers a latch from an incomplete conditional in a combinational block, which is a common and usually unintended outcome; the latch is the correct inference for the first module and a defect for the second, and the difference is entirely in the sensitivity list and the assignment form.
The sampling contract
An edge-triggered element is characterized by the window around the clock edge during which the data input must not change. The setup time is the interval before the edge; the hold time is the interval after. Their sum is the aperture, and it is a property of the cell, not of the clock.
The aperture exists because the master latch needs a finite time to resolve the input and close. If the input transitions inside the window, some internal node is left between the rails, and the loop must amplify that residue to a full logic level. With enough time it always does; the question is how much time, which is probabilistic. That resolution behaviour, and the failure rate that follows from it, is treated in setup and hold timing.
Hold time is sometimes specified as a negative number, which is not a defect. A negative hold time means the internal delay from the clock input to the closing of the master latch exceeds the delay from the data input to the same internal point, so data arriving slightly after the edge is still captured correctly. The sign of the hold time is a comparison of two internal delays, and it varies by cell and by process corner.
The clock-to-output delay of a flip-flop is not small. It includes the clock buffer, the master latch’s closing, the slave latch’s propagation, and the output driver, which puts it in the same order of magnitude as a few levels of combinational logic in the same process. This is why deep pipelines gain less than a naive arithmetic estimate suggests: each boundary costs a fixed overhead, and beyond a certain depth the overhead dominates the logic being divided.
Why synchronous design prefers edge-triggered elements
The dominance of the flip-flop in synthesis flows follows from a property of timing analysis.
With edge-triggered registers, every path in the design starts at a register and ends at a register, and the entire path must complete within one clock period. The requirement is a single inequality per path, and the tool can enumerate paths and check them. With latches, the requirement depends on clock phases and on which latches are transparent when, so a path may legitimately take more than one cycle or less than one cycle, and the analysis becomes a search over phase relationships. That is tractable — latch-based design with time borrowing is used deliberately in high-performance processors — but it is far more work for both the tool and the designer.
The other reason is verification. A design built entirely from edge-triggered registers has a well-defined notion of “the value at the end of cycle N”, and a simulation or a formal proof can be written against cycle boundaries. A latch-based design has no such notion everywhere, and every property must be phrased in terms of time rather than cycles.
Latches retain a place for area and power: a transparent latch uses fewer transistors than an edge-triggered pair, and designs that need a clock enable can use a latch as the enable element instead of adding a multiplexer in front of a flip-flop. The trade is a slower, more complicated analysis in exchange for less area on a path where the phase relationship is under the designer’s control. The classic hazard of a gated clock — a combinational enable that glitches on an edge — is the same problem in a different guise described in combinational hazards, which is why clock gating is implemented with a dedicated latch-backed cell rather than with a plain AND gate.
Register files and arrays
A single-bit storage element scales badly. A register file with 32 entries of 64 bits needs 2,048 storage cells plus decoding for reads and writes, and the cost of routing a clock to every cell is comparable to the cost of the cells.
Arrays solve this with a different structure: a multi-ported cell or a single-ported cell with replication, bit lines shared across the array, and word lines driven by a decoder. Writes are edge-controlled by the word line and read is a combinational evaluation of the bit line, so the element is neither a clean latch nor a clean flip-flop. What the array preserves is the contract: every read after a completed write returns the written value, and the timing of that guarantee is specified as a setup and hold window at the array boundary rather than at the cell.
That contract is the interface that everything above the storage layer depends on, and its terms are the setup and hold window examined in setup and hold timing at the level of a single element.
References
- Digital Integrated Circuits: A Design Perspective — Rabaey, Chandrakasan, and Nikolic, Pearson
- Contemporary Logic Design — Katz and Borriello, Pearson
- IEEE Standard for Verilog Hardware Description Language (IEEE 1364-2005) — IEEE