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 Here4
  • UVM Foundations14
  • UVM Phases & Simulation Lifecycle26
  • Factory & Configuration15
  • Transaction-Level Modeling (TLM)13
  • UVM Sequences & Stimulus21
  • UVM Agents & Protocol VIP21
  • Environment & Test Classes11
  • Checking & Coverage in UVM21
  • UVM Register Abstraction Layer (RAL)22
  • Advanced UVM in Practice13
    • Callbacks, Command Line, Seeds and Versions
    • Synchronisation and Reporting
    • Testbenches at Scale
      • Testbench Code Quality
      • Stimulus at Scale
      • VIP and IP Reuse at Scale
  • Debug & Regression10
  • Coding Practice47
  • Verification in Industry Practice10
  • Senior Prep: Architecture, Leadership and Interviews32
Loading lesson

‹Testbenches at Scale
  1. Topics
  2. UVM Verification
  3. Advanced UVM in Practice
  4. Testbenches at Scale
  5. Stimulus at Scale

Part 10 · Advanced Topics · Intermediate

Stimulus at Scale

Sequence libraries, layered virtual sequences and the Accellera Portable Test and Stimulus Standard: what PSS models, how a tool generates UVM sequences or C tests, and when it pays off.

On this page

    A team verifies a DMA subsystem with four channels, three power states, two memory types and an interrupt controller that can coalesce. Their virtual sequences cover each feature well. Then the SoC integration plan asks for "every channel pair in parallel, in every power state, with and without coalescing, from both memories". That is hundreds of combinations, each with its own legal ordering rules, and the virtual sequence that tries to encode them becomes a 2,000-line randcase nobody dares to touch.

    This lesson is about choosing the right tool for stimulus as it grows: sequence libraries, layered virtual sequences, and portable stimulus (the Accellera Portable Test and Stimulus Standard, PSS). It is honest about the last one, which depends on a commercial tool to be useful.

    The idea: a cookbook, a menu planner, and a kitchen scheduler

    A sequence library is a cookbook: a set of recipes for one cook (one sequencer), and a rule for picking which to cook next. A layered virtual sequence is a menu planner: it composes recipes across several cooks into a meal, in an order a person wrote down. Portable stimulus is a kitchen scheduler that knows the dependencies: you tell it that dessert needs the oven, the oven needs preheating and only two burners exist, and it plans many different legal meals for you, including ones you would not have thought of.

    The difference that matters is who writes the scenario. With libraries and virtual sequences, an engineer writes each scenario's structure, and randomisation varies the details. With PSS, the engineer writes the rules (actions, what each needs and produces, which resources they lock), and a tool's solver generates the scenarios, then emits code for a UVM bench, for a C test on an embedded processor, or for both.

    The picture: how a PSS model reaches a UVM bench

    Flowchart: a PSS model and coverage goals feed a PSS tool, which generates SystemVerilog that starts UVM sequences through a realization layer into the UVM env, and C tests that run on an embedded CPU; both drive the DUT.
    One abstract model, several targets. The UVM bench keeps its agents and checkers; the realization layer maps each atomic PSS action onto an existing, separately tested UVM sequence.

    Build it: three tiers, one bench

    Tier 1: sequence libraries

    A uvm_sequence_library holds registered sequences of one item type and, when started, runs a chosen number of them in random, random-cyclic or user-defined order. It is cheap breadth on one interface: a library of APB register sequences, or of stream packet shapes. Its limit is that it knows nothing across interfaces and nothing about ordering rules. The mechanics, including the selection-mode trap, are in Sub-sequences and sequence libraries.

    Tier 2: layered virtual sequences

    Virtual sequences scale further when they are built in layers, each layer a small sequence with one job: atomic sequences that do one thing on one interface (program a job, handle an interrupt), scenario sequences that compose atomics with the ordering rules of one feature, and a top sequence that picks scenarios from a configuration. A test is then a configuration plus a top sequence, not new code:

    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
    // snippet: a top-level virtual sequence choosing scenarios by weight
    class dma_soc_top_vseq extends uvm_sequence;
      `uvm_object_utils(dma_soc_top_vseq)
      dma_soc_cfg cfg;                        // weights and counts come from the test's config
      function new(string name = "dma_soc_top_vseq");
        super.new(name);
      endfunction
      task body();
        repeat (cfg.n_scenarios) begin
          randcase
            cfg.w_single:   run_scenario(dma_single_job_vseq::type_id::create("single"));
            cfg.w_parallel: run_scenario(dma_parallel_jobs_vseq::type_id::create("parallel"));
            cfg.w_lowpower: run_scenario(dma_job_across_sleep_vseq::type_id::create("lowpower"));
          endcase
        end
      endtask
      task run_scenario(dma_scenario_vseq s);
        s.cfg = cfg;
        if (!s.randomize()) `uvm_fatal("RAND", {"randomize failed: ", s.get_name()})
        s.start(null, this);                  // virtual sequence: no sequencer of its own
        `uvm_info("SCEN", {"done: ", s.get_name()}, UVM_MEDIUM)
      endtask
    endclass

    This works well into the hundreds of scenarios. It strains when the combinations of scenarios carry rules: channel 2 may not start while channel 0 holds the shared buffer, a sleep request must wait for outstanding jobs, an interrupt coalescing window must span two completions. Each rule becomes code in some scenario, and scenarios that combine features duplicate each other's rules. Coverage of which combinations ran is another hand-written covergroup.

    Tier 3: portable stimulus

    PSS was released by Accellera in 2018 and has been revised since. It defines one semantic model with two input formats, a domain-specific language and a C++ class library. A model is made of components holding actions; actions declare the flow objects they consume and produce (buffers, streams, states), the resources they lock or share (a channel, a bus), constraints on their fields, and exec blocks that say what code to emit for a target. An activity composes actions with sequence, parallel, select, schedule and repeat. A sketch of the DMA in the DSL, simplified:

    Diagram
    // PSS DSL sketch (simplified): the DMA moves a buffer and locks one of four channels
    buffer data_buf_s {
      rand bit[31:0] addr;
      rand bit[15:0] words;
    }
    resource channel_r {}
    
    component dma_c {
      pool [4] channel_r chan_p;
      bind chan_p *;
    
      action xfer_a {
        input  data_buf_s src;
        output data_buf_s dst;
        lock   channel_r  chan;
        rand bit[15:0] len;
        constraint { len in [1..16]; dst.words == len; }
        exec body SV = """
          start_dma_job({{chan.instance_id}}, {{len}});
        """;
      }
    }
    
    component pss_top {
      dma_c dma;
      mem_c mem;                    // has an action that outputs data_buf_s
      pool data_buf_s buf_p;
      bind buf_p *;
      action two_parallel_xfers_a {
        activity {
          parallel {
            do dma_c::xfer_a;
            do dma_c::xfer_a;
          }
        }
      }
    }
    • Inference. Each xfer_a needs an input buffer, and the activity never says where it comes from. The tool infers an action from mem_c that produces one. That is the scheduler adding "preheat the oven" by itself.

    • Resources. Two parallel transfers each lock a channel; the pool has four, so the tool picks two different channels. With a pool of one, it would refuse to schedule them in parallel.

    • Graph-based stimulus. The tool sees the model as a graph of legal action sequences and can walk paths not yet covered, instead of hoping random selection reaches them. Scenario coverage is a property of the model, not a separate covergroup.

    • Exec blocks are templates. The {{...}} fields are filled in per generated scenario; the same action can have an SV exec for the UVM bench and a C exec for the embedded processor.

    The hand-off to UVM is through a realization layer: each atomic action maps to an existing UVM sequence (here, start_dma_job would start the bench's job sequence on the right agents). The generated code calls those sequences in the solved order; the UVM env keeps its agents, monitors, scoreboards and coverage, which still judge every transfer. PSS replaces the top of the stimulus stack, never the checking.

    When each tier pays off

    Situation

    Best fit

    Why

    One block, one or two interfaces

    Sequences and a library

    Few cross-interface rules; PSS would be overhead.

    Subsystem with a handful of interacting features

    Layered virtual sequences

    Rules fit in scenario sequences; everything stays in SystemVerilog and any simulator runs it.

    SoC with many IPs, shared resources and many configurations

    PSS on top of the UVM bench

    Combinations and resource rules are modelled once; the tool generates and covers them.

    Same scenarios needed in simulation, emulation and on silicon

    PSS with C targets

    One model, retargeted; the UVM bench is one target among several.

    Common pitfall

    Be honest about tool dependence. The standard defines the language and its semantics. The solver, inference quality, coverage closure, debug views and the UVM integration layer all come from a tool, today almost always a commercial one from a major EDA vendor. A model is portable between tools only as far as both support the same subset of the standard version. Budget for a license, training and a realization layer written by your team before promising a schedule.

    What breaks: the scenario nobody could debug

    A common first-year failure with generated stimulus looks like this. A generated SoC scenario fails after 18 ms: one DMA transfer's data mismatches. The generated SystemVerilog is 9,000 lines of calls with solver-chosen values, and the failing transfer cannot be traced back to an action in the model. Two days go into reading generated code.

    The teams that recover make two changes. Every atomic action logs itself: the realization sequence prints the action name, its instance and its solved fields with a stable message ID at start and end, so the log reads as a scenario. And every atomic action is an existing UVM sequence with its own directed test, so when a generated scenario fails, the question is only which combination broke, never whether the building block works. A third, quieter fix closes a drift: the model's constraint said len in [1..16] while the UVM sequence it mapped to also allowed len == 0, so the two definitions of "legal" disagreed; constraints on an action are checked against the sequence's own constraints in review.

    Interview

    "What is portable stimulus, and would you use it on this project?"

    A weak answer: "It's the new standard that replaces UVM." It does not replace UVM, and the answer does not address the project.

    A strong answer: "PSS is the Accellera standard for modelling the legal actions of a system, what each consumes and produces, which resources they lock, and their constraints. A tool solves the model, infers missing actions and generates scenarios as UVM sequence calls or C tests, so one model serves simulation, emulation and silicon. It sits on top of UVM: the agents and checkers stay. For a block like this DMA I would use virtual sequences; for an SoC with shared channels, power states and many configurations, where combinations are the risk, PSS pays off if we have the tool and a realization layer where each action is a tested UVM sequence."

    Expect the follow-ups: What is inference? (the tool adds actions needed to satisfy an action's inputs) and How does a PSS scenario check anything? (it does not; the UVM monitors and scoreboards check every transfer it causes).

    Check yourself A team proposes PSS for a single APB-to-I2C bridge block. What do you ask before agreeing?

    What combinations or resource rules the block has that virtual sequences cannot express, whether the scenarios must be reused in emulation or on silicon, and whether a tool license and a realization layer are budgeted. For one block with two interfaces the usual answer is that constrained-random sequences and a small virtual sequence are cheaper and run on any simulator.

    Check yourself Why should each atomic PSS action map to an existing UVM sequence that has its own directed test?

    So a failing generated scenario can only mean a combination problem, not a broken building block, and so the action's behaviour and constraints are defined and checked once, in the bench, rather than re-implemented in generated code.

    Check yourself A virtual sequence library picks scenarios with randcase weights from a config object. What do you lose compared with a PSS tool's graph-based selection?

    Random weights reach common combinations quickly and rare ones slowly or never, and nothing records which combinations ran unless you write that coverage yourself. A graph-based tool knows the space of legal scenarios and can target the paths not yet covered.

    Next: stimulus and checking are only as reusable as the agents underneath them. The last lesson turns an agent into VIP that other projects can adopt: VIP and IP Reuse at Scale.

    Related topics

    • Up: Testbenches at Scale

    • Virtual sequence scenario patterns

    • Virtual sequences without a virtual sequencer

    • Regression merge and closure

    Previous

    180 / 280

    Next: VIP and IP Reuse at Scale

    Up next

    Up nextVIP and IP Reuse at Scale

    Sign in to save progress

    Practice this lessonReport an error