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

  • Start Here6
  • SystemVerilog Language Foundations35
  • Object-Oriented SystemVerilog for Verification35
  • Constraint Randomization — Interview-Critical Deep Dive66
  • SystemVerilog Assertions — Interview-Critical Deep Dive63
  • Functional Coverage in SystemVerilog28
  • Testbench Architecture in SystemVerilog38
  • Advanced Language & Integration30
    • DPI-C: Calling C from SystemVerilog
    • bind: Attaching Verification to RTL
    • Macros, Defines & Compilation
      • `define & Text Macros
      • `ifdef & Conditional Compilation
      • `include & Guard Discipline
      • Debugging Macro Problems
      • Compilation, Elaboration & Optimization Flow
    • Plusargs, Files & Runtime Configuration
    • Simulation Performance & TB Memory
    • RTL/TB Boundaries, Races & Timing
  • Senior & Interview Preparation34
  • Principal-Level Verification28
Loading lesson

‹Macros, Defines & Compilation
  1. Topics
  2. SystemVerilog
  3. Advanced Language & Integration
  4. Macros, Defines & Compilation
  5. Compilation, Elaboration & Optimization Flow

Part 7 · Advanced & Integration · Intermediate

Compilation, Elaboration & Optimization Flow

Compile, elaborate, optimize, simulate stages — which errors appear where, incremental compile, libraries, and debug-vs-speed trade-offs.

On this page

    The four stages

    Every simulator runs your code through the same conceptual pipeline: compile (parse each file into a library), elaborate (build the design hierarchy, bind instances, resolve parameters), optimize (flatten, inline, and strip for speed), then simulate (execute the event scheduler). Knowing which stage produced an error tells you immediately where to look — a syntax error and an unresolved-instance error need completely different responses.

    Diagram
    COMPILE → ELABORATE → OPTIMIZE → SIMULATE
    
      source files (.sv)
           │  preprocessor: `define / `ifdef / `include resolved here
           ▼
      ┌──────────┐  per-file: parse, type-check, store in library
      │ COMPILE  │  errors: syntax, unknown types, bad port widths
      └────┬─────┘
           ▼
      ┌──────────┐  whole-design: build hierarchy from top module,
      │ELABORATE │  bind instances, resolve parameters & defparams
      └────┬─────┘  errors: missing module, port mismatch, bad param
           ▼
      ┌──────────┐  flatten hierarchy, inline always blocks, dead-code
      │ OPTIMIZE │  strip — may REMOVE signals you wanted to see
      └────┬─────┘  knobs: debug-access options re-preserve visibility
           ▼
      ┌──────────┐  event-driven execution of the elaborated design
      │ SIMULATE │  errors: null handle, X-propagation, assertion
      └──────────┘  failures, $fatal — anything needing live values

    Which errors appear at which stage

    Stage-to-error map

    • Compile errors — missing semicolon, undeclared identifier, unknown class, macro expansion failures: fixed file-by-file, fast iteration.

    • Elaboration errors — module not found in any library, port connection width/direction mismatch, parameter override of nonexistent parameter, hierarchical reference to a missing scope: these need the whole design, so they appear only after every file compiles.

    • Optimization surprises — not errors but missing visibility: a signal optimized away cannot be waved or forced until you rebuild with debug access enabled.

    • Run-time errors — null object dereference, out-of-bounds dynamic array index, constraint solver failure, assertion fail, $fatal: only reproducible by running, often seed-dependent.

    design.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // COMPILE-stage error: visible from this file alone
    logic [7:0] data
    logic [7:0] mask;      // ERROR: syntax error near 'logic' (missing ;)
    
    // ELABORATION-stage error: legal file, broken hierarchy
    module tb_top;
      // ERROR at elaboration: module 'fifo_wrap' not found —
      // the file defining it was never compiled into the library
      fifo_wrap #(.DEPTH(32)) u_fifo (.clk(clk), .rst_n(rst_n));
    endmodule
    
    // RUN-time error: compiles and elaborates clean, dies at t=0
    initial begin
      my_txn t;            // never constructed
      t.addr = 32'h100;    // FATAL: null object access at run time
    end

    Libraries, incremental compile, and speed knobs

    Compiled units land in a library (traditionally named work). Large projects map RTL, testbench, and vendor IP to separate libraries so each can be cleaned and rebuilt independently. Incremental compile then recompiles only files whose text — or whose included headers — changed, which is why a one-line edit in a widely included .svh file can trigger a near-full rebuild.

    terminal
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # Three-step flow (Questa-style; VCS/Xcelium have equivalents)
    vlib work_rtl  && vmap rtl  work_rtl
    vlib work_tb   && vmap tb   work_tb
    
    vlog -work rtl  rtl/*.sv                   # compile RTL into its library
    vlog -work tb   +incdir+tb tb/my_pkg.sv tb/tb_top.sv
    
    # Elaborate + optimize: -debug keeps signal visibility (slower),
    # omitting it lets the optimizer strip internals (faster)
    vopt tb.tb_top -o tb_top_opt -debug
    vsim tb_top_opt -do "run -all"
    
    # Incremental: re-run vlog only for changed files; elaboration
    # re-runs whenever any compiled unit it depends on changed.

    Debug visibility vs simulation speed

    • Full debug access preserves every signal for waves, forces, and interactive stepping — at a significant run-time cost (often 2x or more).

    • Optimized builds inline and strip aggressively — fastest regressions, but a failure may need a rebuild with debug enabled to wave the relevant signals.

    • Common compromise: regressions run optimized; the failure-reproduction flow rebuilds with debug access and reruns the failing seed.

    • Per-instance or per-module debug scoping (where the tool supports it) buys visibility on the suspect block without paying the full-design penalty.

    Key takeaways

    • Compile is per-file, elaboration is whole-design — 'module not found' is a library/compile-order problem, not a syntax problem.

    • Run-time errors (null handles, constraint failures) cannot be caught earlier — they need live execution.

    • Editing a widely included .svh invalidates every file that includes it — header hygiene controls incremental-build speed.

    • Regressions run optimized; debug reruns rebuild with visibility enabled for the failing seed only.

    Common pitfalls

    • Hunting a 'module not found' elaboration error inside the module's source file — the file simply was not compiled, or went to the wrong library.

    • Forcing or waving a signal that optimization removed — silently ineffective or unfindable until rebuilt with debug access.

    • Stale incremental builds after switching branches — when behavior makes no sense, a clean rebuild is the first sanity check.

    • Assuming elaboration order equals execution order — initial blocks across modules have no defined relative ordering.

    Interview angle

    Standard questions: walk through compile vs elaboration vs run time and give one error from each; why does 'module not found' appear only at elaboration (hierarchy binding needs all units); what trade-off do optimization switches make (speed vs signal visibility) and how does your regression flow handle a failure that needs waves.

    Previous

    286 / 363

    Next: Plusargs, Files & Runtime Configuration

    Up next

    Up nextPlusargs, Files & Runtime Configuration

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • `define & Text Macros
    • `ifdef & Conditional Compilation
    • `include & Guard Discipline