Skip to content

Verilog · Chapter 14.5.3 · Behavioural Modeling

Multiway Advanced Techniques in Verilog — full_case, parallel_case & Priority vs Parallel

This lesson closes the branching section with the advanced patterns and the synthesis pragmas, along with the discipline of mostly avoiding them. The full-case pragma tells synthesis that a case statement covers every possible value, so it need not infer a latch for unlisted ones, and the parallel-case pragma tells it the branches are mutually exclusive, so it can build a parallel mux rather than a priority cascade. Both are dangerous, because they make promises to the synthesizer that the simulator does not honour, creating a mismatch when the promise is false and an unlisted value is actually hit or cases actually overlap. The modern discipline is to avoid the pragmas and instead write a real default and genuinely non-overlapping cases, so simulation and synthesis agree by construction. This page also covers the choice between priority and parallel structures and how to handle don't-care values.

Foundation13 min readVerilogfull_caseparallel_casePriorityParallelSynthesis Pragma

Chapter 14 · Section 14.5.3 · Behavioural Modeling

1. The Engineering Problem

Synthesis pragmas like full_case and parallel_case promise the synthesizer things about a case — but the simulator ignores them, so a false promise makes RTL simulation and hardware disagree:

full_case/parallel_case make promises to synthesis that the simulator does not honour — if the promise is false, sim and synth diverge. The discipline is to avoid the pragmas and instead write a real default and non-overlapping cases.

This page drills the pragmas, their dangers, the priority-vs-parallel choice, and the avoidance discipline.

2. Mental Model — Pragmas Promise Synthesis What the Simulator Ignores

3. The full_case Pragma

full_case tells synthesis all values are covered:

full-case.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   // RISKY — full_case promises completeness:
   always @(*)
       case (sel)  // synopsys full_case
           2'd0: y = a;
           2'd1: y = b;
           2'd2: y = c;
           // 2'd3 NOT listed; full_case says "treat as don't-care"
       endcase
 
   // BETTER — a real default:
   always @(*)
       case (sel)
           2'd0: y = a;
           2'd1: y = b;
           2'd2: y = c;
           default: y = 8'h00;     // explicit, sim and synth agree
       endcase

With full_case, synthesis treats 2'd3 as a don't-care (no latch), but simulation (which ignores the pragma) leaves y unassigned for 2'd3, holding the old value — a latch-like behaviour that differs from the synthesized hardware. A real default makes both agree.

4. The parallel_case Pragma

parallel_case tells synthesis cases are mutually exclusive:

parallel-case.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   // RISKY — parallel_case promises mutual exclusion:
   casez (req)  // synopsys parallel_case
       4'b1???: grant = 3;        // these patterns OVERLAP (1100 matches both)
       4'b?1??: grant = 2;
   endcase

If the patterns actually overlap (e.g. 4'b1100 matches both), simulation uses priority (first match wins) while parallel_case makes synthesis build a parallel structure that may pick differently — a mismatch. If you want priority, write overlapping casez patterns without the pragma (simulation and synthesis both treat it as priority). If you want parallel, write genuinely non-overlapping cases. The pragma is unnecessary and dangerous either way.

5. Priority vs Parallel — The Real Choice

The deliberate structural choice, without pragmas:

  • Priority (first match wins): use if/else if/else, or a case/casez with overlapping patterns. Synthesizes to a priority cascade. For prioritized decisions (interrupts, error handling).
  • Parallel (mutually exclusive): use a plain case with non-overlapping values. Synthesizes to a parallel mux/decoder. For value selection (opcodes, states).
priority-vs-parallel.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   // PARALLEL — non-overlapping case → parallel mux:
   case (op)  2'd0: y=a; 2'd1: y=b; 2'd2: y=c; default: y=d; endcase
 
   // PRIORITY — overlapping casez patterns → priority encoder:
   casez (req)
       4'b1???: g=3; 4'b01??: g=2; 4'b001?: g=1; default: g=0;
   endcase

The structure follows from how you write the cases — non-overlapping for parallel, overlapping (or if/else) for priority — so the code expresses the intent, and simulation and synthesis agree. No pragma needed.

Visual A — pragmas vs real code

Pragma promises vs honest code

data flow
Pragma promises vs honest codefull_case /parallel_casepromise to synthesis onlysim ignores →mismatch riskif promise is falsereal default +non-overlapsim and synth agree
full_case/parallel_case bias synthesis but are ignored by simulation, so a false promise causes a sim/synth mismatch. Writing a real default (for completeness) and genuinely non-overlapping cases (for parallelism) makes the intent explicit in the code, so simulation and synthesis agree by construction — the modern discipline.

6. Common Mistakes

  1. Using full_case/parallel_case — risk of sim/synth mismatch; use a real default and non-overlapping cases (§2-§4, DebugLab 1).
  2. Relying on a pragma instead of a default — the simulator still infers latch-like behaviour (§3).
  3. parallel_case on overlapping patterns — sim priority vs synth parallel disagree (§4).
  4. Not choosing priority vs parallel deliberately — let the case structure express intent (§5).

7. Debugging Lab

One advanced-branching debug post-mortem

8. Interview Q&A

9. Exercises

Exercise 1 — Replace the pragma

Rewrite a case that uses // synopsys full_case to be complete without the pragma.

Exercise 2 — Priority or parallel?

For (a) a 4:1 mux on a 2-bit select and (b) a priority interrupt decoder, state whether you want a priority or parallel structure and how to write it without a pragma.

Exercise 3 — Spot the mismatch

Explain how // synopsys parallel_case on a casez with overlapping patterns causes a sim/synth mismatch.

10. Summary

Advanced branching is mostly about avoiding the synthesis pragmas:

  • full_case/parallel_case promise completeness/mutual-exclusion to synthesis, but the simulator ignores them — a false promise causes a sim/synth mismatch.
  • The discipline — avoid the pragmas; write a real default (completeness) and non-overlapping cases (parallelism), so sim and synth agree.
  • Priority vs parallel is a deliberate choice expressed by the code: if/else or overlapping case/casez for priority; non-overlapping case for parallel.

Multiway branching complete

This closes Chapter 14.5 Multiway Branchingif/else (priority, 14.5.1), case/casez/casex (parallel, 14.5.2), and the advanced pragmas and priority/parallel choice (14.5.3) — unified by the latch-avoidance discipline: assign every output on every path in combinational blocks.

The chapter now turns to iteration: Chapter 14.6 Loops drills for, while, repeat, and forever — the looping constructs of behavioural code.