Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • RTL Foundations36
  • Combinational Design25
    • Combinational Timing Overview
    • Muxes, Decoders and Encoders
    • Arithmetic Blocks
    • Comparators and Shifters
    • Tri-State and Shared Buses
    • Latch Inference
      • Why Accidental Latches Happen
      • The Complete-Assignment Pattern
      • Intentional Latches
    • Arithmetic Datapaths
  • Sequential Design27
  • FSM & Control27
  • Timing & Clocking39
  • Reset & CDC34
  • Memory & Buses57
  • Advanced RTL28
  • Senior & Interview76
  • Glossary and Notation
Loading lesson

‹Latch Inference
  1. Topics
  2. RTL Design
  3. Combinational Design
  4. Latch Inference
  5. The Complete-Assignment Pattern

Part 2 · Combinational · Intermediate

The Complete-Assignment Pattern

Default every output first, then override: the one habit that makes accidental latches impossible.

On this page

    Why this matters

    The most reliable cure for an accidental latch is to assign every output a default at the top of the block. The pattern costs one line and leaves the branches unchanged.

    After this lesson you can: apply the default-then-override pattern, choose a safe default, and avoid fixes that re-infer the latch.

    Default first, then override

    The most reliable fix is to assign every output before any conditional logic. Later statements only override the default for specific cases.

    No path can leave the output unassigned, because the default has already assigned it.

    fixed_if.sv
    1
    2
    3
    4
    5
    6
    7
    // yosys: ok
    module fixed_if (input logic en, a, output logic y);
      always_comb begin
        y = 1'b0;                 // default
        if (en) y = a;            // override
      end
    endmodule
    fixed_case.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // yosys: ok
    module fixed_case (input logic [1:0] sel, input logic a, b, c, output logic y);
      always_comb begin
        y = 1'b0;                 // default covers sel == 3 and anything unexpected
        case (sel)
          2'd0: y = a;
          2'd1: y = b;
          2'd2: y = c;
          default: ;
        endcase
      end
    endmodule
    fixed_partial.sv
    1
    2
    3
    4
    5
    6
    7
    8
    // yosys: ok
    module fixed_partial (input logic sel, a, b, output logic x, y);
      always_comb begin
        x = a;
        y = 1'b0;                 // every output has a default
        if (sel) y = b;
      end
    endmodule

    Yosys accepts all three without a latch; the broken versions in the previous lesson are rejected. That is the same check your synthesis tool performs on your design.

    Blocking for combinational logic, nonblocking for flip-flops

    Use blocking = in always_comb and reserve nonblocking <= for always_ff. Do not mix them.

    The defaults-then-override pattern needs order: each statement must read the values written above it. Blocking = gives that order, and mixing the two is how simulation and synthesis start to disagree.

    Check yourself In the defaults-then-override pattern, what breaks if the override uses <= instead of =?

    The default y = 0 is blocking, so it takes effect at once, but the override y <= a is scheduled for later. A read such as z = y; after the if in the same activation sees the default 0, not a, and y takes a only afterwards. That stale read is why always_comb uses = throughout and always_ff uses <=. An all-nonblocking block is a separate case, where every read of the block's own outputs is stale; see the scheduling lesson.

    Patterns, defaults and warnings

    Check yourself A block has 8 outputs and 5 if branches. What is the cheapest change that guarantees no latch?

    Assign all 8 outputs a default value at the very top of the always_comb, then let the branches override. You do not need to touch the branches at all.

    Check yourself A case lists every select value you planned for, but has no default. An unplanned input combination arrives. What happens?

    The unplanned value has no branch, so the output holds and a latch returns. A default assignment before the case would have covered it.

    The four reliable patterns

    Pattern

    Example

    Use when

    Defaults first

    y = 0; if (en) y = a;

    Always the safest choice

    Full if/else

    if (en) y = a; else y = 0;

    A single decision with two outcomes

    case with default

    default: y = 0;

    Multi-way selects

    Temporary variable

    Compute next once, then assign outputs from it

    Complex logic with many outputs

    Default value choices

    • Choose the default so it is a safe, benign value (0, an idle code, 'no request'), not x. In x defaults, simulation and silicon can disagree.

    • For next-state logic, next = state; is the natural default: stay where you are unless told otherwise.

    • A default: branch that is truly unreachable should still assign a safe value, and an assertion can prove it is never taken.

    Tip

    Let the tool help. Use always_comb, turn on lint (verilator -Wall reports latches with the LATCH warning), and treat any latch warning as a failure in your quality gate.

    Warning

    Do not "fix" a latch warning by assigning the output to itself (y = y;). That keeps the feedback loop and usually re-infers the latch (or a combinational loop). Assign a real value.

    Remember

    • Assign every output before any conditional, then let branches override.

    • Use blocking = in always_comb and nonblocking <= in always_ff, and do not mix them.

    • For next-state logic the natural default is next = state.

    Rule of thumb: treat any latch warning as a failure, and never write y = y; to silence it.

    Keep going

    • Interview: run a mock interview on this topic

    Related topics

    • always_ff and always_comb

    • Intentional latches

    Previous

    55 / 350

    Next: Intentional Latches

    Up next

    Up nextIntentional Latches

    Sign in to save progress

    Practice this lessonReport an error