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. `include & Guard Discipline

Part 7 · Advanced & Integration · Intermediate

`include & Guard Discipline

Textual file inclusion, the double-include failure, guard macros, and search paths.

On this page

    An include is a paste

    ` include "file.svh"`` replaces the directive with the entire contents of the file, verbatim, at that exact spot. It is not an import and it creates no namespace.

    The pasted text compiles in whatever context surrounds the include. Paste order is dependency order: base classes come before derived classes.

    design.sv
    1
    2
    3
    4
    5
    6
    7
    8
    // snippet
    package net_pkg;
      `include "txn_base.svh"   // class txn_base: plain fields, no UVM
      `include "txn_ext.svh"    // class txn_ext extends txn_base: pasted after its base
    endpackage
    
    // Compile the package file only. The .svh fragments never compile standalone:
    // they exist solely as text pasted into the package.

    Pasted twice, declared twice

    Two files including the same header paste the class inside it twice, which is a duplicate-definition error. The ifndef guard fixes it: the first paste defines a marker, and later pastes skip the body.

    design.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // snippet
    `ifndef TXN_BASE_SVH       // first include: not yet defined, so enter
    `define TXN_BASE_SVH       // define the marker immediately
    
    class txn_base;
      int addr;
      int data;
      function new();
        addr = 0;
        data = 0;
      endfunction
    endclass
    
    `endif // TXN_BASE_SVH     // comment the endif: guards nest deeply
    Diagram
    DOUBLE-INCLUDE: FAILURE vs GUARD
    
      WITHOUT GUARD                        WITH GUARD
      -------------                        ----------
      driver.svh:  `include "txn_base.svh"  driver.svh:  `include "txn_base.svh"
      monitor.svh: `include "txn_base.svh"  monitor.svh: `include "txn_base.svh"
           │                                    │
           ▼ both pasted into package           ▼
      class txn_base ...  <- 1st copy      1st paste: TXN_BASE_SVH undefined
      class txn_base ...  <- 2nd copy        -> define it, paste class body
           │                               2nd paste: TXN_BASE_SVH defined
           ▼                                 -> body skipped entirely
      ERROR: 'txn_base' already declared   COMPILES CLEAN

    Search paths and library habits

    The preprocessor finds included files through search directories. Source names only the file, and the build flow supplies the paths.

    Diagram
    iverilog -g2012 -I tb/agents/bus_agent -I tb/env -o simv net_pkg.sv tb_top.sv
    verilator --binary --timing +incdir+tb/agents/bus_agent +incdir+tb/env --top-module tb_top tb_top.sv
    • .sv files are compilation units: packages and modules. .svh files are include-only fragments that never compile standalone.

    • Every .svh file gets a guard whose marker mirrors the file path, so same-named files in different agents cannot collide.

    • One package file per agent includes its .svh fragments in dependency order. Everything else imports the package.

    • Never ` include` a file that declares a module. Modules belong in separately compiled .sv` files.

    Testbench

    One compiled package, used through an import. Inside it, the guarded text of txn_c.svh appears twice, exactly as two ` include`` lines would paste it. The guard skips the second copy, so the package compiles; delete the guard lines and the second copy is a duplicate-class error.

    design.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    // engine: verilator
    package txn_pkg;
      // --- first paste of txn_c.svh ---
      `ifndef TXN_C_SVH
      `define TXN_C_SVH
      class txn_c;
        int addr;
        int data;
        function void set(int a, int d); addr = a; data = d; endfunction
        function int checksum(); return addr ^ data; endfunction
      endclass
      `endif // TXN_C_SVH
    
      // --- second paste of the same header: the guard skips it ---
      `ifndef TXN_C_SVH
      `define TXN_C_SVH
      class txn_c;
        int addr;
        int data;
        function void set(int a, int d); addr = a; data = d; endfunction
        function int checksum(); return addr ^ data; endfunction
      endclass
      `endif // TXN_C_SVH
    endpackage
    
    module tb_pkg;
      import txn_pkg::*;
      int errors = 0;
      txn_c first_h;
      txn_c second_h;
      initial begin
        first_h = new();
        second_h = new();
        first_h.set(32'h1000, 32'h00FF);
        second_h.set(32'h2000, 32'h000F);
        if (first_h.checksum() !== (32'h1000 ^ 32'h00FF)) errors++;
        if (second_h.checksum() !== (32'h2000 ^ 32'h000F)) errors++;
        if (first_h.addr !== 32'h1000) errors++;
        if (second_h.data !== 32'h000F) errors++;
        if (errors == 0) $display("PASS: guarded double paste compiled once; package classes store and checksum independently");
        else $fatal(1, "FAIL: package class state is wrong");
        $finish;
      end
    endmodule

    Common pitfall

    A guard marker copy-pasted between two headers makes the second include vanish silently, because the marker is already defined. Compiling a .svh directly lands its classes in the wrong scope, and pasting derived classes before their bases fails to compile.

    Interview

    Likely question: the vanishing class.

    • `` `include`` pastes text; a package import shares compiled symbols.

    • Double paste of one class errors, which the ifndef guard prevents.

    • One shared marker across two headers skips the second header entirely: one class silently disappears.

    Check yourself Two headers accidentally share one guard marker. The design compiles but a class is missing. What happened?

    The first paste defined the shared marker. The second header saw it already defined and skipped its whole body, so its class never entered the build.

    Check yourself A nested directory holds a needed header, yet the tool reports it cannot find the include file. What is missing?

    A search-path entry for that directory: -I for Icarus or +incdir+ for Verilator. Source keeps bare file names so the flow supplies the paths.

    Related topics

    • Conditional compilation

    • Debugging macros

    Previous

    284 / 363

    Next: Debugging Macro Problems

    Up next

    Up nextDebugging Macro Problems

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • `define & Text Macros
    • Compilation, Elaboration & Optimization Flow