← RTL Design Interviews

Interview Question · Code Reading

Is the If Chain Slower Than a Case?

L1 JuniorL2 Mid-Levelcase statementsmuxsynthesis

The Question

The interviewer asks

A reviewer says: "Rewrite this as a case to get rid of the priority chain." Is the reviewer right?

systemverilog
module mux4 (input logic [1:0] sel, input logic [7:0] a, b, c, d, output logic [7:0] y);
  always_comb begin
    if      (sel == 2'd0) y = a;
    else if (sel == 2'd1) y = b;
    else if (sel == 2'd2) y = c;
    else                  y = d;
  end
endmodule
Reveal the Model Answer

Not here. Every condition compares the same 2-bit sel with a different constant, so at most one can be true. Synthesis sees that and builds a plain 4:1 mux. On this flow the chain is 27 cells and 4 levels, the same depth as the case. Priority is real only when conditions can be true together.

An 8:1 Mux as a TreeEach box is a 2:1 mux for every bit of the word. Arrows carry words; each column uses one select bit.
An 8:1 mux as a treeEach box is a 2:1 mux for every bit of the word. Arrows carry words; each column uses one select bit. mux d0 / d1 sel[0] mux d2 / d3 sel[0] mux d4 / d5 sel[0] mux d6 / d7 sel[0] mux low half sel[1] mux high half sel[1] mux y sel[2]
  1. Level 1

    Four muxes pick within the pairs, all at once, using sel[0].

  2. Level 2

    Two muxes pick a pair from each half, using sel[1].

  3. Level 3

    One mux picks the half, using sel[2]. Seven muxes, three levels: log2(8).

Read the diagram as text
  • d0 / d1: sel[0]
  • d2 / d3: sel[0]
  • d4 / d5: sel[0]
  • d6 / d7: sel[0]
  • low half: sel[1]
  • high half: sel[1]
  • y: sel[2]
  • d0 / d1 → low half
  • d2 / d3 → low half
  • d4 / d5 → high half
  • d6 / d7 → high half
  • low half → y
  • high half → y

From lesson R5.5: a mux is a tree of 2:1 muxes, one select bit per level, with no priority. A 4:1 mux on a 2-bit sel has two such levels.

Where order costs depth
FormCan conditions overlap?CellsLevels
if-else chain on one 2-bit selNo274
case (sel)No604
if-else chain on separate request bitsYes215
unique case on separate request bitsYes (but promised not to)283

Measured on the pinned Yosys flow by the runs in this tree. The order adds levels only when conditions can be true together.

The snippet on the pinned Yosys flow.

module mux4 (input logic [1:0] sel, input logic [7:0] a, b, c, d, output logic [7:0] y);
  always_comb begin
    if      (sel == 2'd0) y = a;
    else if (sel == 2'd1) y = b;
    else if (sel == 2'd2) y = c;
    else                  y = d;
  end
endmodule

Self-Check

Tick each key point you covered in your answer.

What Interviewers Listen For (Junior)

A good junior answer notices that the conditions can never be true together, so their order does not matter.

Cross-Questions

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

WhyWhat IfCompareScale It

  1. Is the If Chain Slower Than a Case?
  2. CompareThe Case Version of the Same MuxL1 JuniorL2 Mid-Level

    Compare the case version of the mux with the if chain. Which is smaller on this flow?

    Reveal the Model Answer

    The case version has the same 4 levels but 60 cells, against 27 for the chain. The tool built it as decoders plus an AND-OR, not as a mux tree. Another synthesizer may give other numbers. The lesson is to measure your own flow, not to trust a style rule.

    module mux4 (input logic [1:0] sel, input logic [7:0] a, b, c, d, output logic [7:0] y);
      always_comb begin
        case (sel)
          2'd0: y = a;
          2'd1: y = b;
          2'd2: y = c;
          2'd3: y = d;
        endcase
      end
    endmodule
    

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "The case version is faster, so it must also be smaller."

    It is neither here: same depth, more cells. Speed and size claims about coding style need a measurement.

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

  3. WhyWhen the Order of Conditions Costs DepthL2 Mid-Level

    Then when does writing conditions in order really cost depth?

    Reveal the Model Answer

    When the conditions test different signals that can be true together, such as separate request bits. Then the order is part of the function, because it decides who wins. Synthesis must keep it, and each extra condition adds a stage. That is the selector in the twin: 5 levels, not 3.

    Self-Check

    Tick each key point you covered in your answer.

    Half-Truth

    "Use unique to remove the cost."

    Only if the requests really cannot overlap. If they can, unique makes the gates mix data words, which is a functional bug.

    Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 7.4.2 The unique and unique0 decision modifiers

  4. What IfThe Parallel_case PragmaL2 Mid-LevelL3 Senior

    What if someone adds // synopsys parallel_case instead of unique?

    Reveal the Model Answer

    The pragma is a comment that only synthesis reads. It makes the same promise as unique: the items never overlap. But the simulator ignores it, so nothing checks the promise. If it is false, RTL and gates disagree with no warning. Use unique, which makes the same promise and gets checked.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "A pragma and unique are interchangeable."

    They have the same synthesis effect, but only unique is checked in simulation. The pragma hides a false promise.

    Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 7.4.3 The obsolete parallel_case synthesis pragma

  5. CompareThe full_case Pragma Next to parallel_caseL2 Mid-LevelL3 Senior

    Compare full_case with parallel_case. What trap does full_case add?

    Reveal the Model Answer

    full_case tells synthesis that unlisted values never happen, so it builds no latch for them. Simulation ignores the comment and still holds the old value for those values, as a latch would. So the RTL holds a value that the gates do not. A default assignment, or unique, makes both agree.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "full_case removes the latch, so the design is fixed."

    It removes the latch only in the gates. The RTL still holds the old value, so simulation and silicon differ.

    Source Cummings, "full_case parallel_case", the Evil Twins of Verilog Synthesis (SNUG 1999)

  6. Scale ItVery Wide MuxesL2 Mid-LevelL3 Senior

    Scale it up: a 64-input, 32-bit mux sits on a critical path. How do you think about it?

    Reveal the Model Answer

    A binary select feeds a tree of 2:1 muxes, about six deep for 64 inputs. If the select is already one-hot, an AND-OR structure avoids the decode. If the path is still too long, register the select early or split the mux across a pipeline stage. Lesson R5.5 measures these choices.

    Self-Check

    Tick each key point you covered in your answer.

    What Interviewers Listen For (Senior)

    A good senior answer first asks where the select comes from and how early it is ready. Only then does it choose the mux structure.

    Misconception

    "A mux is one gate delay, however wide."

    A 64:1 mux is a tree. Its depth grows with the log of the input count, plus the select decode.

    Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 5.3 Conditional (ternary) operator

What People Get Wrong

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

Misconception

"A case statement always gives parallel logic."

A case runs the first matching item too. With overlapping items such as case (1'b1) over request bits, the twin shows the priority kept.

Run It

case (1'b1) with two requests, then unique case with one-hot requests.

RUNIcarus Verilog · in your browser
Edit the code, then run it
Expected: req=0110: y=0010 FAIL: a case statement is not parallel by itself; case (1'b1) kept first-match priority
See the Fix
module sel4 (input logic [3:0] req, input logic [3:0] d0, d1, d2, d3, output logic [3:0] y);
  always_comb begin
    unique case (1'b1)
      req[0]:  y = d0;
      req[1]:  y = d1;
      req[2]:  y = d2;
      req[3]:  y = d3;
      default: y = 4'b0000;
    endcase
  end
endmodule
module tb;
  logic [3:0] req; logic [3:0] d0 = 4'b0001, d1 = 4'b0010, d2 = 4'b0100, d3 = 4'b1000, y;
  sel4 dut (.req(req), .d0(d0), .d1(d1), .d2(d2), .d3(d3), .y(y));
  initial begin
    int bad = 0;
    for (int i = 0; i < 4; i++) begin
      req = 4'b0001 << i; #1;   // the promise unique makes: one request at a time
      if (y !== (4'b0001 << i)) bad++;
    end
    $display("one-hot requests: %0d wrong", bad);
    if (bad == 0) $display("PASS: with requests one-hot, unique case lets synthesis drop the order");
  end
endmodule

Prints: one-hot requests: 0 wrong PASS: with requests one-hot, unique case lets synthesis drop the order

Misconception

"An if chain always becomes a chain of muxes in the written order."

Synthesis removes the order when it can prove the conditions exclusive. The run shows 4 levels, not a chain of 3 muxes per bit.

Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 7.4 Combinational logic decision priority

Delivery

Rewrites the block on the reviewer's word, without measuring.

A style rewrite with no measurement can make things worse. The case version on this flow is bigger, as the next question shows.

Learn It, Then Prove It