Logo
All chapters
Volume II: Digital Logic  ›  Register Transfer Level Design

Latch-Free Design (Why Waste Silicon?)

How incomplete combinational HDL accidentally creates latches — and how to avoid it.

PrevRace-Free Design
NextSystemVerilog Introduction

Description

An unintended latch appears when a combinational block fails to assign an output on every path, forcing the tool to 'remember' the old value. Latch-free design assigns every output on every branch — via default assignments, complete if/else, or full case — so only intended flip-flops exist.

  • A combinational block leaves an output unassigned on some path.
  • The tool keeps the previous value → infers a latch.
  • Common cause: if without else, or case without default.
  • Latches are level-sensitive and timing-hazard-prone.
  • They are almost never intended in synchronous design.
  • Give every output a default at the top of the block.
  • Make every if have an else (or rely on the default).
  • Add a default to every case.
  • Use always @(*) / always_comb (tools warn on latches).
  • Assign all outputs on all paths — no exceptions.

At a glance

What

Avoiding inferred latches from incompletely specified combinational logic.

Why

Stray latches cause timing problems, hazards, and wasted area.

How

Assign every output on every path: defaults, else, default case, full case.

Where

All combinational always blocks.

When

Whenever writing combinational HDL.

Think of it like…

It's like a form with blank fields kept from last time: leave a box empty and the system 'remembers' the old answer (a latch) instead of recomputing.

How a latch sneaks in

  • A combinational block leaves an output unassigned on some path.
  • The tool keeps the previous value → infers a latch.
  • Common cause: if without else, or case without default.
  • Latches are level-sensitive and timing-hazard-prone.
  • They are almost never intended in synchronous design.

Avoiding latches

  • Give every output a default at the top of the block.
  • Make every if have an else (or rely on the default).
  • Add a default to every case.
  • Use always @(*) / always_comb (tools warn on latches).
  • Assign all outputs on all paths — no exceptions.

Latch causes & fixes

CauseFix
if without elseadd else / default
case without defaultadd default
unassigned outputdefault assignment

HDL — Verilog · VHDL · SystemVerilog

always @(*) begin
  y = 1'b0;            // default — no latch
  case (sel)
    2'b00: y = a;
    2'b01: y = b;
    default: y = 1'b0; // full case
  endcase
end

Default assignment prevents an inferred latch.

Real-world applications

All combinational RTLDecoders, muxes, ALUs

The 5 Whys

  1. 1

    Why latches appear? Unassigned outputs keep old values.

  2. 2

    Why bad? Level-sensitive, hazard-prone, wasteful.

  3. 3

    Why defaults fix it? Every path now assigns.

  4. 4

    Why always_comb? Tool flags accidental latches.

  5. 5

    Root cause: complete assignment guarantees pure combinational logic.

Cheat sheet

Working principle

  • Assign every output on every path: defaults, else, default case, full case.
  • Avoiding inferred latches from incompletely specified combinational logic.

Formulas & Boolean expressions

  • if without else = add else / default
  • case without default = add default
  • unassigned output = default assignment

Key facts

  • A combinational block leaves an output unassigned on some path.
  • Give every output a default at the top of the block.

Why it exists

  • Root cause: complete assignment guarantees pure combinational logic.
PrevRace-Free Design
NextSystemVerilog Introduction