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 Foundations28
  • Object-Oriented SystemVerilog for Verification30
  • Constraint Randomization — Interview-Critical Deep Dive36
  • SystemVerilog Assertions — Interview-Critical Deep Dive40
  • Functional Coverage in SystemVerilog22
  • Testbench Architecture in SystemVerilog23
  • Advanced Language & Integration25
    • DPI-C: Calling C from SystemVerilog
    • bind: Attaching Verification to RTL
    • Macros, Defines & Compilation
    • Plusargs, Files & Runtime Configuration
      • $test$plusargs & $value$plusargs
      • File I/O
      • Config Architecture: Files vs Plusargs vs Objects
      • Wave Dumping & Runtime Control
    • Simulation Performance & TB Memory
    • RTL/TB Boundaries, Races & Timing
  • Senior & Interview Preparation21
  • Principal-Level Verification28
Loading lesson

‹Plusargs, Files & Runtime Configuration
  1. Topics
  2. SystemVerilog
  3. Advanced Language & Integration
  4. Plusargs, Files & Runtime Configuration
  5. $test$plusargs & $value$plusargs

Part 7 · Advanced & Integration · Intermediate

$test$plusargs & $value$plusargs

Existence vs value plusargs, formats, defaults, numbered scans and a knob registry.

On this page

    Existence checks and value parsing

    $test$plusargs answers one question: was +NAME given on the command line. It returns 1 or 0.

    $value$plusargs goes further: it matches the prefix, parses the rest through a format string into a variable, and returns nonzero on a match. Existence flags switch features on. Value plusargs carry numbers, strings and hex values into the run.

    Format

    Parses

    Into

    %d

    Decimal integer

    int or integer

    %h

    Hexadecimal

    Any vector or integer

    %o

    Octal

    Any vector or integer

    %b

    Binary

    Any vector or integer

    %s

    Word string

    string

    %e, %f

    Real

    real

    Defaults and return codes

    Give every knob its default at the declaration. A successful parse overwrites it, so absence leaves a sane value behind.

    design.sv
    // snippet
    if (!$value$plusargs("NUM_TXNS=%d", num_txns))
      $display("NUM_TXNS not given, keeping default %0d", num_txns);

    Treat the return as a match report, not a validity proof. A malformed value can return nonzero while the variable stays untouched on some tools, so check ranges after parsing.

    Mandatory knobs test the return and stop without the value. Optional knobs ignore the return and keep the default.

    Check yourself What does $value$plusargs return when the plusarg is absent, and what happens to the variable?

    It returns 0 and the variable keeps its old value. That is why defaults live in the declaration: absence leaves them intact.

    Names, scans and the registry

    $test$plusargs matches prefixes, not whole names. +ENABLE_COVERAGE_X also satisfies a check for ENABLE_COVERAGE, so keep knob names apart.

    Type hex values without underscores, as in +BASE_ADDR=20000000. Some tools reject the underscore form during %h parsing.

    A family of numbered plusargs accepts a variable-length list. The loop stops at the first missing index.

    design.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // snippet
    // Accept +ERR_ADDR0=... +ERR_ADDR1=... up to 8 injection points
    bit [31:0] err_addr[$];
    initial begin
      bit [31:0] val;
      string key;
      for (int i = 0; i < 8; i++) begin
        key = $sformatf("ERR_ADDR%0d=%%h", i);
        if (!$value$plusargs(key, val)) break;
        err_addr.push_back(val);
      end
    end

    Production testbenches parse once into one registry and print it. The registry below is a class with no top module, so it is not run in this course's checks.

    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
    // not-run: class-only listing with no top module to run (Verilator 5.048 compiles it)
    class knob_registry;
      int    num_txns   = 100;
      int    verbosity  = 1;
      string test_name  = "smoke";
      bit    enable_cov = 0;
    
      function void parse();
        void'($value$plusargs("NUM_TXNS=%d",  num_txns));
        void'($value$plusargs("VERBOSITY=%d", verbosity));
        void'($value$plusargs("TESTNAME=%s",  test_name));
        enable_cov = $test$plusargs("ENABLE_COVERAGE");
        print();
      endfunction
    
      function void print();
        $display("=== KNOBS ===========================");
        $display("  TESTNAME        = %s",  test_name);
        $display("  NUM_TXNS        = %0d", num_txns);
        $display("  VERBOSITY       = %0d", verbosity);
        $display("  ENABLE_COVERAGE = %0b", enable_cov);
        $display("=====================================");
      endfunction
    endclass

    Common pitfall

    Prefix collisions such as +DUMP with +DUMP_START: a $test$plusargs gate on the short name matches both, so a window-only rerun silently enables full dumps. Gate on the longer, non-prefix name instead.

    Check yourself Why does parsing a hex command-line value with %d fail?

    The format must match how the value is typed. %d stops at hex digits past 9, so the parse fails or truncates. Use %h for hex values.

    Common mistakes

    Interview

    Likely questions: the difference between the two plusarg functions and their returns, how a knob gets a default, the prefix-matching gotcha, and where parsing lives in a layered environment (one knob class at time zero, never inside components).

    Check yourself A driver calls $value$plusargs on every transaction to read a delay knob. What is wrong with that?

    Two things: it pays parse overhead per transaction, and it scatters configuration across components. Parse once at time zero into a registry and hand the value down.

    Check yourself Two components parse NUM_TXNS with different defaults, 100 and 1000. No plusarg is given. What runs?

    Each component runs with its own default, so the testbench disagrees with itself. One registry with one default per knob removes the drift.

    Testbench

    Four knobs are parsed once with no plusargs on the command line. Every return reads 0 and every default survives, which the checks confirm.

    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
    module tb_plusargs;
      integer num_txns = 100;                // default: small smoke count
      integer verbosity = 1;                 // default: normal logging
      reg [31:0] base_addr = 32'h10000000;   // default base
      reg enable_cov = 0;                    // default: coverage off
      integer errors = 0;
      integer matched;
    
      initial begin
        // Each knob is parsed at most once, at time zero.
        // With no plusargs given, every call returns 0.
        matched = $value$plusargs("NUM_TXNS=%d", num_txns);
        if (matched != 0) errors++;
        matched = $value$plusargs("VERBOSITY=%d", verbosity);
        if (matched != 0) errors++;
        matched = $value$plusargs("BASE_ADDR=%h", base_addr);
        if (matched != 0) errors++;
        if ($test$plusargs("ENABLE_COVERAGE") != 0) errors++;
    
        // Defaults survive untouched.
        if (num_txns != 100) errors++;
        if (verbosity != 1) errors++;
        if (base_addr != 32'h10000000) errors++;
        if (enable_cov != 0) errors++;
    
        if (errors == 0) $display("PASS: 4 knobs held defaults with no plusargs given");
        else $fatal(1, "FAIL: %0d default checks did not hold", errors);
        $finish;
      end
    endmodule

    Related topics

    • Plusargs and knobs

    Previous

    199 / 259

    Next: File I/O

    Up next

    Up nextFile I/O

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Config Architecture: Files vs Plusargs vs Objects
    • Wave Dumping & Runtime Control