← RTL Design Interviews

Interview Question · Code Reading

A Case Statement, a Default Arm and a Latch

L1 JuniorL2 Mid-Levellatchescase statements

The Question

The interviewer asks

This block has a default arm. Does it infer a latch? If so, on which signal?

systemverilog
module opdec (input  logic [1:0] op,
              input  logic [7:0] a, b,
              output logic [7:0] res,
              output logic       valid);
  always @* begin
    case (op)
      2'd0:    begin res = a + b; valid = 1'b1; end
      2'd1:    begin res = a - b; valid = 1'b1; end
      2'd2:    begin res = a & b;               end
      default: begin res = 8'h00; valid = 1'b0; end
    endcase
  end
endmodule
Reveal the Model Answer

Yes, one latch, on valid. The default arm covers values of op that no other arm lists. It does not cover outputs that a listed arm forgets. In the op == 2 arm nothing assigns valid, so it keeps its last value. res is assigned in every arm, so it has no latch.

The Decoder with the Enable LowOne (en, sel) pair per cycle. The first four cycles are the test the team ran. From cycle 4 the enable is 0 and y should be 0000, but it keeps the last value it was given.
01234567clkensel01231y00010010010010000010
  1. Cycle 3

    The last cycle of the test: en is 1, sel is 3, y is 1000. Everything looks right.

  2. Cycle 4

    en falls. The if is false and no statement assigns y, so y keeps 1000. Peripheral 3 stays selected.

  3. Cycle 5

    sel changes to 1 while en is still 0. Nothing changes: a held value does not follow its inputs. That is the definition of a latch.

  4. Cycle 6

    en rises and y follows sel again: 0010.

  5. Cycle 7

    en falls and y holds 0010. Peripheral 1 stays selected this time. Which line is stuck depends on what came before: the mark of memory.

Measured in lesson R1.3 on a decoder with an if and no else. A path that assigns nothing holds the old value, just as valid does here.

The snippet on the pinned Yosys flow: one latch, for valid.

module opdec (input  logic [1:0] op,
              input  logic [7:0] a, b,
              output logic [7:0] res,
              output logic       valid);
  always @* begin
    case (op)
      2'd0:    begin res = a + b; valid = 1'b1; end
      2'd1:    begin res = a - b; valid = 1'b1; end
      2'd2:    begin res = a & b;               end
      default: begin res = 8'h00; valid = 1'b0; end
    endcase
  end
endmodule

Self-Check

Tick each key point you covered in your answer.

What Interviewers Listen For (Junior)

A good junior answer walks the arms one output at a time. It finds the arm that leaves valid unassigned.

Cross-Questions

Where the interviewer goes next. Open a node to practise that follow-up.

WhyWhat IfProve ItBreak ItCompare

  1. A Case Statement, a Default Arm and a Latch
  2. WhyWhat a Default Arm CoversL1 Junior

    Why does a default arm not prevent a latch on an output that one arm forgets?

    Reveal the Model Answer

    Latch inference is decided per variable, per path. The default arm adds one path: the case values no other arm lists. Each listed arm is still its own path. If a listed arm skips an output, that path still holds the output.

    Self-Check

    Tick each key point you covered in your answer.

    Half-Truth

    "A full case can never infer a latch."

    A full case covers every value of the case expression. It still infers a latch when some arm leaves an output unassigned.

    Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 9.2 Unintentional latch inference

  3. CompareDefaults at the Top vs Unique CaseL2 Mid-Level

    Compare fixing the block with defaults at the top against adding unique to the case.

    Reveal the Model Answer

    Defaults at the top give every output a value on every path, so the latch goes away. unique only makes promises about which arms match. It does not assign valid in the op == 2 arm, so the latch stays. Use the defaults to remove the latch, and add unique only if the arms truly cannot overlap.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "unique case removes latches because it means full case."

    unique tells synthesis that some arm always matches. A matching arm that skips an output still leaves that output unassigned.

    Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 9.3.5 Latch avoidance style 3, unique and priority decision modifiers

  4. What IfAssigning X in the Default ArmL2 Mid-LevelL3 Senior

    What if someone fixes it by assigning valid = 'x in the default and at the top?

    Reveal the Model Answer

    The latch goes away, because every path now assigns something. Synthesis reads X as "don't care" and may pick any value that gives smaller logic. Simulation shows X, which helps catch a path that should never run. The guideline today is unique or priority instead, because they give the same freedom with built-in checks.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "An X assignment makes the gates output X."

    Gates cannot output X. Synthesis replaces it with a 0 or 1, chosen for the smallest logic, so RTL and gates may disagree on that path.

    Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 9.3.6 Latch avoidance style 4, X assignments for unused decision values

  5. Break ItHow an X Default Can Hide a BugL2 Mid-LevelL3 Senior

    Break it: show how the 'x default can hide a real bug in simulation.

    Reveal the Model Answer

    Downstream logic such as if (valid) treats X as false and takes the else branch. So the path that should never run looks harmless in simulation. Synthesis may choose 1 for that X, and the gates then assert valid there. An assertion that valid is never unknown catches it at the source.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "An X default makes any bad path show up as X downstream."

    An if on X takes the else branch, so the X can disappear one stage later.

    Source IEEE 1800-2017 §12.4

  6. Prove ItSolve R1.3.2: The Interrupt That Never ClearedSimulator-graded

    Show it, don't just say it: this Silicon Lab problem is graded by the simulator.

    Open Problem R1.3.2

What People Get Wrong

Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.

Misconception

"There is a default arm, so every output is covered."

A default arm handles case values, not outputs. The twin goes from op = 3 to op = 2 and valid keeps the 0 from the default arm.

Run It

The snippet, simulated, then the fix with defaults before the case.

RUNIcarus Verilog · in your browser
Edit the code, then run it
Expected: op=2 after op=3: valid=0 FAIL: the default arm did not cover op=2; valid kept its old value
See the Fix
module opdec (input  logic [1:0] op,
              input  logic [7:0] a, b,
              output logic [7:0] res,
              output logic       valid);
  always @* begin
    res = 8'h00; valid = 1'b0;      // the fix: defaults before the case
    case (op)
      2'd0:    begin res = a + b; valid = 1'b1; end
      2'd1:    begin res = a - b; valid = 1'b1; end
      2'd2:    begin res = a & b; valid = 1'b1; end
      default: begin res = 8'h00; valid = 1'b0; end
    endcase
  end
endmodule
module tb;
  logic [1:0] op; logic [7:0] a = 8'd6, b = 8'd3, res; logic valid;
  opdec dut (.op(op), .a(a), .b(b), .res(res), .valid(valid));
  initial begin
    op = 2'd3; #1;       // default arm: valid = 0
    op = 2'd2; #1;       // the AND arm
    $display("op=2 after op=3: valid=%b", valid);
    if (valid !== 1'b1) $display("FAIL: the default arm did not cover op=2; valid kept its old value");
    else $display("PASS: valid is 1 in the op=2 arm");
  end
endmodule

Prints: op=2 after op=3: valid=1 PASS: valid is 1 in the op=2 arm

Misconception

"res and valid both get latches: 9 in total."

res is written in every arm, including the default, so every path assigns it. Only valid has a path with no assignment. The run counts one latch.

Source Measured: the run on this question, Yosys 0.70+290 (OSS CAD Suite 2026-11-02), slang front end, synth -flatten with ABC, ltp -noff

Delivery

Answers "no latch, there is a default" in two seconds, without reading each arm.

The interviewer chose this code to see whether you trace outputs arm by arm. A quick pattern match is the answer they expect to reject.

Learn It, Then Prove It