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
    • Testbench Anatomy & Layering
    • Stimulus: Generators, Transactions & Drivers
    • Monitors, Scoreboards & Reference Models
    • Self-Checking Tests & Regression
      • Self-Checking Discipline
      • Seeds & Reproducibility
      • Logging & Verbosity Strategy
      • The Regression Flow
    • From Hand-Built TB to UVM
  • Advanced Language & Integration25
  • Senior & Interview Preparation21
  • Principal-Level Verification28
Loading lesson

‹Self-Checking Tests & Regression
  1. Topics
  2. SystemVerilog
  3. Testbench Architecture in SystemVerilog
  4. Self-Checking Tests & Regression
  5. Seeds & Reproducibility

Part 6 · Testbench Architecture · Intermediate

Seeds & Reproducibility

Seed every run, print the seed, and replay any failure with the same seed and knobs.

On this page

    One seed, one stream

    Constrained-random stimulus is only useful if it is reproducible. The random behavior of a simulation derives from one root seed, so a logged seed turns a random failure into a replayable bug report.

    The precise rule is narrower than folklore: same code plus same seed plus same tool, version, and options gives the same RNG streams. Identical timing additionally needs a race-free testbench, since races, wall-clock seeding, and multithread ordering can all shift a run.

    Tool

    Seed flag

    Scope note

    VCS

    +ntb_random_seed=N

    Seeds the solver and the testbench RNG.

    Xcelium

    -svseed N

    Seeds the solver and the testbench RNG.

    Questa

    -sv_seed N

    Seeds the solver and the testbench RNG.

    Verilator 5.048

    +verilator+seed+N

    Runtime seed for its random generator; +ntb_random_seed is ignored.

    Icarus 13

    No seed flag

    Ignores +ntb_random_seed. The testbench reads its own +SEED knob instead, as below.

    The testbench seed knob keeps working everywhere. The tool flags differ per simulator and Icarus has none, so every runnable block here uses +SEED.

    A seeded testbench

    The listing below extends the adder check with a +SEED knob. It parses the seed with $value$plusargs, prints it in the header, and drives 32 vectors from the seeded stream.

    It runs under Icarus 13 and Verilator.

    adder8s.sv
    1
    2
    3
    4
    5
    6
    7
    module adder8s (
      input  logic [7:0] a, b,
      output logic [7:0] sum
    );
      timeunit 1ns; timeprecision 1ps;
      assign sum = a + b;
    endmodule
    

    The default seed 1 keeps smoke runs deterministic. Any other +SEED=N explores a different stream, and the header makes the log self-describing.

    Replaying a failure

    Triage is mechanical: read the seed from the failing log header, rerun the same test with the same seed and debug knobs up, and the failure reproduces at the same point.

    Diagram
    # Nightly run that failed (dispatcher picked the seed)
    simv +SEED=482931 > run.log
    # log header: SEED : 482931 ... FAIL: adder8 produced a wrong sum
    
    # Replay: same seed, more visibility
    simv +SEED=482931 +VERBOSITY=2 +DUMP_WAVES=1 > replay.log
    
    # Same stream, same result, now with waves and a full log

    One seed explores one path through the stimulus space. A seed sweep runs the same test across many seeds and merges the results, which beats hand-writing hundreds of directed tests for breadth.

    Random stability is hierarchical and fragile to edits. Replay on the exact failing commit, and debug with extra display output rather than new randomization calls or reordered construction, which re-seed everything downstream.

    Sweeps, knobs, and one parser

    One compiled image serves smoke, stress, and replay runs through runtime knobs. The testbench parses each knob once at time zero into a config object, and components read only that object.

    Knob

    Typical values

    Effect

    +SEED

    1, 7, 42, 991

    Selects the random stream; logged in the header.

    +NUM_TXNS

    50, 200, 5000

    Scales the same test from smoke to soak.

    +ERROR_RATE

    0, 10

    Percent of stimulus carrying injected protocol problems; 0 for clean runs.

    +VERBOSITY

    0 to 3

    Log level; quiet in regression, loud in replay.

    +DUMP_WAVES

    Flag

    Waveform capture, off by default; regressions at scale cannot afford waves.

    Keep defaults sane so a bare run with no knobs passes. Gate error injection behind error_rate > 0, since a zero distribution weight is legal but some solvers warn about it.

    Two parsing cautions: $test$plusargs does prefix matching, so +DUMP also matches +DUMP_WAVES; and a misspelled knob is silently ignored, so print every effective value at time zero on a [CFG] line.

    Check yourself A regression failure does not reproduce on rerun. Name three causes.

    A different seed, a different code revision, or a random-stability shift from an edit made during debug. The log header plus the exact commit disambiguate them.

    Check yourself Why must the seed live in the log header rather than only in the dispatcher database?

    Logs outlive dispatch records. A failing log must contain its own replay recipe years later.

    Common mistakes

    Common pitfall

    Running everything on the tool default seed explores the identical stream every time. Randomize the seed per run at dispatch, and record it in the log so each run stays replayable.

    Interview

    Likely questions: “A regression failure does not reproduce, why?”, “Why print the seed instead of trusting the dispatcher?”, and “How do seeds relate to coverage closure?”. Each answer traces seed to stream to replay recipe.

    Check yourself The knob +ERR_RATE=10 is passed but the run injects nothing. What happened?

    The testbench expects +ERROR_RATE, so the misspelled knob was silently ignored and the default 0 applied. The [CFG] printout at time zero would have shown it.

    Check yourself Why does $test$plusargs("DUMP") also fire when only +DUMP_WAVES was passed?

    Presence matching is by prefix. Test for the full flag name to avoid accidental matches.

    Previous

    180 / 259

    Next: Logging & Verbosity Strategy

    Up next

    Up nextLogging & Verbosity Strategy

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • The Regression Flow