No, latches are not bad in themselves. A latch is a perfectly valid storage element, and many high-performance and low-power designs use them deliberately for time borrowing and clock gating. What is bad is a latch nobody intended, or a latch whose enable is glitchy or poorly timed. Used on purpose, with a clean enable and proper timing constraints, a latch is a sound engineering choice.
It is not completely correct to say that we have to avoid latches in our designs. In one of our projects we spent a good deal of time debating only the disadvantages of latches, and in the end we removed all of them because many on the team were not convinced. There are cases where you can safely use latches; you just have to be careful, and the designer needs to be really sure of the intended functionality. In this post let us look at the cases where latches are preferred and where they are not. If you think any of the statements are wrong, let us have a healthy debate.
Key takeaways
- A latch is level-sensitive: it is transparent while its enable is active and holds its value while the enable is inactive. A flip-flop samples only on a clock edge.
- The biggest real-world problem is the unintended latch, inferred by synthesis from incomplete combinational code.
- Intentional latches save area and power, allow time borrowing between pipeline stages, and are the standard way to build a glitch-free clock gate.
- Latches make static timing analysis, DFT and CDC review harder, so every intentional latch should be documented, constrained and reviewed.
- If the design is not power or timing critical, flip-flops are the simpler and safer default.
Latch versus flip-flop: how they differ
A D latch passes its input to its output whenever the enable (often a clock phase) is active. When the enable goes inactive the latch closes and holds the last value. A D flip-flop is usually built as two latches in series, a master and a slave, enabled on opposite clock phases, so the output changes only at the clock edge.
The latch has a disadvantage of being transparent until the enable closes it: any change on the input, including a glitch, propagates straight through while it is open. The flip-flop samples the input only on the rising or falling edge of the clock, which makes its behaviour much easier to reason about and to time.
| Property | Latch | Flip-flop |
|---|---|---|
| Sensitivity | Level (enable high or low) | Edge (rising or falling) |
| Typical size | Smaller, roughly one stage of a master-slave flop | Larger, two latch stages plus clocking |
| Clock load and power | Lower | Higher |
| Timing | Can borrow time from the next stage | Hard boundary at each edge |
| Glitch tolerance on data | Glitches pass while transparent | Only the value at the edge matters |
| STA, DFT and CDC tools | Supported, but need more care | Default assumption of every flow |
The bad guys
- Combinational loops and oscillation. One of the main reasons latches are avoided is combinational feedback. A latch, or a loop of logic that behaves like one, can oscillate when its enable is open and its output feeds back to its input. This creates serious problems in simulation and can also cause simulation versus synthesis mismatches.
- Controllability for STA and DFT. Latches are harder to control and observe than flip-flops. They complicate static timing analysis, because paths flow through transparent latches across clock phases, and they can reduce test coverage if scan cannot control them.
- Glitches on the enable. A major cause of trouble is a glitch on the latch enable. A short pulse on the enable opens the latch and captures whatever is on D at that moment, which can cause an unrecoverable functional failure.
- Inferred latches from bad coding style. Last but not least, the biggest culprit of all: latches inferred by synthesis because a combinational block does not assign an output on every path.
How an unintended latch is inferred
In the code below, y is not assigned when sel is 2'b11. The language says y must keep its previous value in that case, and the only hardware that can do that is a storage element, so synthesis builds a latch enabled by the decode of sel. That enable is itself combinational and can glitch.
// Unintended latch: no assignment to y when sel is 2'b11
module mux_bad (input [1:0] sel, input a, b, c, output reg y);
always @(*) begin
if (sel == 2'b00) y = a;
else if (sel == 2'b01) y = b;
else if (sel == 2'b10) y = c;
end
endmodule
// Fixed: default assignment first, so every path assigns y
module mux_good (input [1:0] sel, input a, b, c, output reg y);
always @(*) begin
y = 1'b0;
case (sel)
2'b00: y = a;
2'b01: y = b;
2'b10: y = c;
default: y = 1'b0;
endcase
end
endmodule
The fix is simple: give every output a default value at the top of the block, and cover every branch. In SystemVerilog, write combinational logic in always_comb; most tools then warn or error when a latch would be inferred. Always read the synthesis log for latch inference messages and treat each one as a bug until proven otherwise.
Advantages of latches
- Area and power. Latches consume less power and area than flip-flops. A flip-flop is essentially two latches, so a latch-based register needs fewer transistors and puts less load on the clock tree, which is often the largest single consumer of dynamic power in a chip.
- When power does not matter, use flops. If the design is not power aware, flip-flops are preferred, and almost all latches could be replaced by flip-flops without affecting functionality.
- Early decode. The decode of a latched address can begin before the latch actually closes, because the new value is already visible at the output while the latch is transparent. This is the essence of time borrowing.
- Time borrowing. In a latch-based pipeline a slow stage can take extra time from the following stage, as long as the total fits. This lets designers balance uneven logic without adding pipeline stages.
- Glitch-free clock gating. The standard integrated clock gating cell is a latch followed by an AND gate. This is probably the most common intentional latch in modern SoCs.
Worked example: time borrowing (illustrative numbers)
Take a 100 MHz clock (10 ns period, 50% duty cycle) and a path split across two latch stages, one transparent in each half cycle, so each stage is nominally given 5 ns. Stage 1 needs 6 ns of logic and stage 2 needs 4 ns. Ignoring setup time, clock-to-output delay and skew for simplicity:
- With edge-triggered flops at each half-cycle boundary, stage 1 fails by 1 ns.
- With latches, stage 1 data reaches the second latch at 6 ns, 1 ns after that latch opened. Because the latch is transparent, the data passes straight through and stage 2 starts 1 ns late. Stage 2 then has 4 ns left in the cycle and needs exactly 4 ns, so the path meets timing.
The total of 10 ns fits in one cycle, and the latch absorbs the imbalance. In a real design the borrowed time is limited by the latch's own setup requirement before it closes, and STA tools report the amount borrowed on each latch so that the next stage is checked correctly.
Example: a latch-based clock gate
The latch is transparent while the clock is low, so the enable can settle during the low phase. While the clock is high the latch is closed, so any glitch on the enable cannot reach the gated clock. A plain AND gate without the latch would pass such glitches as clock pulses.
// Intentional transparent-high D latch
module d_latch (input en, input d, output reg q);
always @(*)
if (en) q = d;
endmodule
// Latch-based clock gate (ICG behaviour): enable is captured while clk is low
module icg (input clk, input en, input test_en, output gclk);
reg en_l;
always @(*)
if (!clk) en_l = en | test_en;
assign gclk = clk & en_l;
endmodule
In production, instantiate the library's clock gating cell rather than writing this in RTL, so that the latch and the AND gate are placed together and timed as one cell. The test_en input keeps the clock running during scan shift.
Corrective measures
- Use a glitch-free enable. If latches are unavoidable, drive the enable from a register or a clock phase, not from a deep combinational decode.
- Control the enable logic directly. If you are synthesising the code that generates the enable, consider instantiating the gates that drive the latch enable directly, so that synthesis cannot restructure them into something that glitches. Then you can be doubly sure.
- Respect hold time at the closing edge. The data must stay valid long enough after the latch closes. If your latch enable is derived from a clock, the latch enable will lag the clock, so the latch's D inputs must be held valid for some time after that clock edge.
- Constrain and review every intentional latch. Make sure STA sees the latch as a latch, checks time borrowing limits, and that DFT has a plan for it, for example making it transparent in test mode or replacing it with a scan flop.
- Lint for latches. Run lint and synthesis checks that flag every inferred latch, and keep a reviewed waiver list for the ones you meant.
When to use latches and when not to
| Situation | Recommendation |
|---|---|
| General control logic, FSMs, datapath registers | Flip-flops |
| Clock gating | Latch-based library ICG cell |
| High-frequency custom pipelines with uneven stages | Latches with two-phase clocking, if the team has the STA experience |
| Large low-power register files and some memories | Latch arrays can save significant area and power |
| FPGA designs | Avoid; FPGA timing tools and fabric are built around flip-flops |
| Any latch reported by synthesis that you did not write on purpose | Fix the RTL |
Common mistakes
- Missing
elsebranches orcasedefaults in combinational blocks. - Incomplete sensitivity lists in Verilog-1995 style code, which cause simulation to behave like a latch while synthesis builds combinational logic. Use
@(*)oralways_comb. - Driving a latch enable from a combinational decode of several signals that change at slightly different times.
- Gating a clock with a plain AND or OR gate instead of a latch-based gate.
- Forgetting to tell the DFT team about functional latches until scan insertion fails.
FAQ
Does synthesis ever add latches on its own?
Only when the RTL describes storage in a combinational block, typically through an incomplete assignment. Clean, fully assigned combinational code does not produce latches.
Can static timing analysis handle latches?
Yes. Mainstream STA tools model latch transparency and time borrowing. The analysis is more involved than for flip-flops, so the constraints and the reports need closer review.
Are latches a problem for scan test?
They can be. Scan flows are built around flip-flops, so functional latches are usually made transparent during test or handled with dedicated test logic. Latch-based scan styles such as LSSD do exist and were widely used in the past.
Should I use latches in an FPGA?
Generally no. FPGA fabrics and their timing tools are optimised for flip-flops, and latches built from look-up tables are prone to glitches and timing surprises.
Bottom line
If you are not careful when developing synchronous digital designs, latches can create asynchronous behaviour that becomes unstable. Used deliberately, with a clean enable, correct constraints and a DFT plan, they save area and power and give timing flexibility that flip-flops cannot. Avoid the accidental ones, and justify the intentional ones.

This a good information.and good point.let us think about the matter deeply
ReplyDeletecombinational loopback - how about showing a diagram explaining how it occurs in latches? that is of course, if you want your article to be THE point of reference for good v.s. bad about latches on the internet.
ReplyDelete