Portable Stimulus
| |

Portable Stimulus (PSS) Guide 2026: Working Examples and How AI Helps

By Hardik Trivedi, The Art of Verification. Updated October 2026.

PSS in 60 seconds

Portable Stimulus Standard (PSS) is an Accellera language for writing test intent once and turning it into real tests for many places: UVM at block level, bare-metal C on the CPU at SoC level, and the same C on silicon in the lab.

You describe what should happen (actions), what gets passed between them (flow objects), what is shared (resources), and the rules (constraints). A solver then builds every legal scenario for you.

The current approved version is PSS 3.0, released in August 2024. The working group is already previewing PSS 3.1 features.

In 2025 and 2026, AI tools started helping engineers write PSS models from plain English. They are good at the typing. A human still has to own the intent.

Key takeaways

  • PSS does not replace UVM. It sits on top and tells UVM (and C) which scenarios to run.
  • You need PSS when the same scenario is written in more than one language, or when your worst bugs live between blocks. Its value to your strategy is reuse from IP to silicon.
  • The big win is reuse: one scenario from IP level all the way to post-silicon.
  • The solver adds missing steps for you. You ask for the goal, it finds the path.
  • Most PSS test failures early in a project are model bugs, not RTL bugs. Read the solver report before the waveform.
  • AI is useful for first drafts, register-to-exec code, and coverage gap ideas. Always run the draft through a parser and a human review.
  • Every PSS example in this post was checked with the free pssparser tool. You can copy, paste, and run the same check.

Table of contents

What is Portable Stimulus (PSS)?

PSS is a language for test intent, standardized by Accellera. Its full name is the Portable Test and Stimulus Standard.

A UVM sequence says how to wiggle the pins of one interface. A PSS model says what the chip should do as a whole: “copy this block of memory with the DMA, while the CPU is busy, then check the result.”

That intent is not tied to any one testbench. A PSS tool reads it, solves it, and writes the test in the language each platform understands.

Portable Stimulus flow: one PSS model goes through a solver and becomes UVM sequences, bare-metal C for SoC, and post-silicon tests
Figure 1: One PSS model, many targets.

Why do we need PSS? The “four rewrites” problem

Here is the pain every SoC verification engineer knows.

  • The IP team writes a DMA test in UVM.
  • The subsystem team rewrites it because the testbench changed.
  • The SoC team rewrites it again as C code for the embedded CPU.
  • The post-silicon team rewrites it a fourth time for the lab board.

Four teams. Four languages. One scenario.

Every rewrite is a chance to test something slightly different from what the first author meant. That is exactly where coverage holes hide: in the gaps between levels.

PSS breaks that cycle. You write the scenario once, above any one testbench, and let the tool project it down onto each target.

The value is not the syntax. The value is that the same intent travels from block to silicon without being retyped.

Five signs your project needs PSS

  1. The same scenario exists in two or more languages. A UVM version for the block, a C version for the SoC, a script for the lab. Each one drifts a little from the others.
  2. Your worst bugs show up late. They appear in emulation or on silicon, and they involve two or more blocks fighting over something: memory bandwidth, a bus, a power domain, an interrupt line.
  3. The chip has lots of shared, limited things. DMA channels, CPU cores, memory controllers, clocks and power states. Hand-written tests rarely try every legal mix of these.
  4. Firmware and bring-up teams wait for tests. When first silicon arrives, the lab needs tests that run on the board on day one, not tests that still need porting.
  5. Test count grows faster than coverage. Every new feature adds ten directed tests, but the coverage report barely moves. That is a sign you are writing scenarios by hand that a solver could produce.

If two or more of these sound familiar, PSS will likely pay back the time you put into learning it.

When PSS is not the right tool

Being honest about this builds trust with your team, so say it out loud in planning meetings:

  • Deep protocol checking of one interface. A PCIe or AXI compliance check is UVM and assertion work. PSS adds little there.
  • Small, self-contained IP with no reuse plan. If the block will never be tested at SoC level or on silicon, the reuse benefit disappears.
  • Control logic that formal can prove. If a property can be proven for all inputs, do that first. PSS is for scenarios, not proofs.
  • No time to set it up. A first PSS model plus its C or UVM hookup takes real effort. Start it early in the project, not two weeks before tape-out.

What value PSS adds to your verification strategy

A verification strategy answers four questions: what do we test, at which level, with which tool, and how do we know we are done. PSS changes the answer to all four.

Think about building a house. The architect, the builder, the electrician and the inspector all work from one blueprint. Nobody redraws the house in their own notation. PSS is that blueprint for your test scenarios.

Where Portable Stimulus fits in a verification strategy: formal at IP level, UVM at block and subsystem, PSS across IP, subsystem, SoC and silicon, firmware at SoC and silicon
Figure 6: PSS is the one layer that runs across every level.

Strategy without PSS vs with PSS

Strategy questionWithout PSSWith PSS
Where do system scenarios live?Spread across UVM sequences, C tests and lab scriptsOne model, owned by one team, version controlled
How do scenarios move from IP to SoC?Someone rewrites them by handRetarget the same model with new exec blocks
Who decides which mixes of traffic to test?Whoever writes the test, from memoryThe solver, inside rules taken from the spec
How do we measure “done”?Code and functional coverage per blockPlus scenario and behavioral coverage across the system
What does the lab get on day one?A porting taskC tests that already ran in simulation and emulation
How does the plan stay in sync with the spec?Manual review of hundreds of testsReview one short model, line by line with the spec

Seven kinds of value PSS brings

  1. Reuse across levels. The same scenario runs at IP, subsystem, SoC and on silicon. You stop paying for the same test four times.
  2. A new class of bugs. PSS is strongest at bugs between blocks: arbitration, starvation, ordering, resource conflicts and power state mixes. These are the bugs block-level testbenches cannot see.
  3. Earlier firmware and bring-up. Generated C exercises real register sequences long before silicon. Firmware engineers can read those tests to learn how the hardware really behaves.
  4. Coverage in the language of the spec. With PSS 3.0 behavioral coverage, you can measure “a DMA transfer completed while the UART was exiting low power” directly, instead of guessing from signal bins.
  5. Fewer tests to maintain. One model with good constraints replaces piles of near-identical directed tests. When the spec changes, you change a constraint, not fifty files.
  6. One language for many teams. Design, DV, firmware, post-silicon and architects can all read an action list. Reviews get shorter and arguments get more specific.
  7. A better target for AI. A short, declarative model with a solver behind it is much easier for AI to draft and for a human to check than thousands of lines of testbench code. More on that later in this post.

Volleyball taught me this long before chips did. The team that wins the long rally is rarely the one with the best attacker. It is the one where all six players are running the same play. PSS gets your IP, SoC and lab teams running the same play.

How to add PSS to your strategy without a big-bang change

PhaseScopeGoal
1. PilotOne block with shared resources, like a DMAModel it, drive the existing UVM bench, compare coverage with the old tests
2. Go verticalSame block at SoC levelRetarget to C on the CPU. Measure how much of the model changed
3. Connect blocksTwo or three blocks sharing memory or powerAdd states and resources. Look for interaction bugs
4. Make it standardNew IP from day onePSS model is a sign-off item next to the UVM bench and the test plan

How to show the value to your manager

Do not promise a percentage up front. Track these numbers from the pilot and let them speak:

  • Number of scenarios reused at two or more levels without rewriting.
  • Number of hand-written directed tests retired.
  • Bugs found by PSS scenarios that no block-level test caught.
  • Days from first silicon to the first passing system test in the lab.
  • Time to close scenario coverage on a new feature, before and after.

A Volleyball Playbook

I played competitive volleyball for years. So this is the analogy I use when a new engineer asks me what PSS is.

A coach draws a play in the notebook: pass, set, attack.

That one drawing works in the practice gym, at the district tournament, and on a beach court. The players change. The floor changes. The play stays the same.

The notebook also has rules. No player touches the ball twice in a row. Only six players on court. A back-row player cannot jump and attack from in front of the 3 metre line.

A good setter reads the rules and the situation and picks a legal play on the spot.

Now map it:

VolleyballPSS
The play in the notebookThe PSS model (actions + activity)
The rules of the gameConstraints, resources, states
The setter picking a legal playThe solver
Practice gym, tournament, beachUVM simulation, SoC emulation, real silicon
Players on courtThe testbench or the CPU running the test

Write the play once. Run it everywhere. That is PSS in one line.

What is new in PSS 3.0 (and what is coming in 3.1)

Accellera approved PSS 3.0 on August 29, 2024. If your tool or your team still thinks in PSS 1.0 or 2.0 terms, here is what changed, in plain words.

PSS 3.0 featureWhat it means for you
Behavioral coverageThe biggest addition. You can describe a pattern of behavior you want to see (an order of actions, plus data conditions) and measure whether your tests hit it. One spec, many scenarios.
Formal semantics of behavioral coverage (new annex)Tools now agree on what “covered” means. Fewer arguments between vendors.
Cooperative multitasking (yield)Long-running actions can hand control back so other actions get a turn. Closer to how real firmware behaves.
Address space groupCleaner modeling of memory regions shared by several address spaces.
String methods and sub-string operatorEasier log messages and naming in generated tests.
Collections of reference typesLists and arrays of handles, handy for “pick any 3 of these 8 channels”.
Platform qualifiers on function prototypesSay clearly “this function exists only on the target” or “only in the solver”.
PSS to SystemVerilog mapping for listsSmoother handoff between PSS and a UVM testbench.
Comments in template blocks, clearer static const rulesSmall quality-of-life fixes you will notice in real code.

The Accellera PSS working group has been showing “upcoming features in PSS 3.1” in public talks. Until it is approved, write models against 3.0 and check your vendor’s release notes for what they support.

The building blocks, one analogy each

PSS has a small vocabulary. Learn these eight words and you can read almost any model.

PSS termPlain meaningEveryday picture
componentA block of the design and the actions it can doA team in the school sports meet
actionOne thing the chip can doOne move: a serve, a set, a spike
activityThe order actions run in (sequence, parallel, select, repeat)The play drawn in the notebook
bufferData one action leaves for the next, after it finishesA relay baton
streamData passed while both actions run at the same timeA phone call
stateA value everyone can see, one at a timeA traffic light
resource + poolSomething limited that actions must bookBooking 1 of 4 badminton courts
exec blockThe real code (C or SV) an action turns intoThe translator who speaks each target’s language
PSS flow objects explained: buffer as relay baton, stream as phone call, state as traffic light, resource as court booking
Figure 3: The four PSS ideas behind almost every scenario.

Working example 1: a DMA test in 50 lines

Every PSS course starts with a DMA. That is not laziness. A DMA has data, a limited resource (channels), and a clear “did it work” check. Perfect for learning.

Our DMA has 4 channels and copies memory to memory. The spec says:

  • Transfer length is 64 to 4096 bytes, in steps of 64.
  • Source and destination must not overlap.
  • One channel runs one transfer at a time.

Here is the full model. It passes the open-source pssparser front end with 0 errors.

// dma.pss : memory-to-memory DMA, the "hello world" of PSS
buffer mem_buf_s {
    rand bit[32] addr;
    rand bit[16] size;
    constraint size_c { size in [64..4096]; size % 64 == 0; }
    constraint addr_c { addr in [0x8000_0000..0x8FFF_0000]; addr % 64 == 0; }
}

resource dma_chan_r { }          // one DMA channel

component dma_c {
    pool [4] dma_chan_r chan_p;  // the DMA has 4 channels
    bind chan_p *;

    pool mem_buf_s buf_p;
    bind buf_p *;

    action fill_mem_a {
        output mem_buf_s out_buf;
        exec body C = """
    fill_pattern({{out_buf.addr}}, {{out_buf.size}});
""";
    }

    action copy_a {
        input  mem_buf_s src;
        output mem_buf_s dst;
        lock   dma_chan_r chan;      // must own a channel while copying
        constraint dst.size == src.size;
        constraint (dst.addr >= src.addr + src.size) || (src.addr >= dst.addr + dst.size);
        exec body C = """
    dma_copy({{chan.instance_id}}, {{src.addr}}, {{dst.addr}}, {{src.size}});
""";
    }

    action check_a {
        input mem_buf_s in_buf;
        exec body C = """
    check_pattern({{in_buf.addr}}, {{in_buf.size}});
""";
    }
}

component pss_top {
    dma_c dma;

    action one_check_a {             // simplest test: just ask for a check
        activity {
            do dma_c::check_a;
        }
    }

    action four_parallel_a {         // stress: 4 copies fight for 4 channels
        activity {
            parallel {
                do dma_c::check_a;
                do dma_c::check_a;
                do dma_c::check_a;
                do dma_c::check_a;
            }
        }
    }
}

What just happened

Look at one_check_a. It asks for only one thing: check_a.

But check_a needs an input buffer. Someone must have produced it. The only action that outputs mem_buf_s after a copy is copy_a. And copy_a needs its own input, which comes from fill_mem_a.

So the solver quietly builds the chain: fill, copy, check. This is called action inference, and it is the single most useful idea in PSS.

PSS action inference: asking for check_a makes the solver add fill_mem_a and copy_a so the DMA test is legal
Figure 2: You ask for the goal, the solver finds the path.

Now look at four_parallel_a. Four checks in parallel means four copies in parallel. Each copy must lock a channel, and the pool has exactly 4. The solver gives each copy a different channel. Change the pool to [2] and the solver will refuse, or serialize the copies, depending on the tool. Either way you learn something about your design before you run a single cycle.

What the tool writes out

Every vendor formats its output a little differently, but a generated C test for one_check_a looks roughly like this:

/* Illustrative output: what a PSS tool typically emits for one_check_a.
   Exact format differs per vendor. Values come from the solver. */
void pss_test_one_check_a(void) {
    /* fill_mem_a (inferred) */
    fill_pattern(0x80A31C40, 1536);
    /* copy_a (inferred), solver picked channel 2 */
    dma_copy(2, 0x80A31C40, 0x8F000200, 1536);
    /* check_a (requested) */
    check_pattern(0x8F000200, 1536);
}

And this is the only C you write by hand: three small functions that the exec blocks call.

/* hal_dma.c : the only hand-written C you need for the example */
#include <stdint.h>
#include "dma_regs.h"

void fill_pattern(uint32_t addr, uint32_t size) {
    volatile uint32_t *p = (uint32_t *)addr;
    for (uint32_t i = 0; i < size / 4; i++) p[i] = addr ^ (i * 0x9E3779B9u);
}

void dma_copy(int ch, uint32_t src, uint32_t dst, uint32_t size) {
    DMA_SRC(ch)  = src;
    DMA_DST(ch)  = dst;
    DMA_LEN(ch)  = size;
    DMA_CTRL(ch) = DMA_CTRL_START;
    while (!(DMA_STAT(ch) & DMA_STAT_DONE)) { }   /* add a timeout in real code */
}

void check_pattern(uint32_t addr, uint32_t size) {
    /* compare against the pattern written at the source; report on mismatch */
}

Notice the split. The scenario lives in PSS. The register details live in a tiny hardware layer. When the register map changes, you touch the C file. When the scenario changes, you touch the PSS. They do not get in each other’s way.

Working example 2: states, like a traffic light

Many bugs live in “what mode was the block in when this happened?” PSS handles that with a state object.

Here a UART can be OFF, LOW, or FULL power. It wakes up OFF. It can only send data in FULL.

// uart_state.pss : a state object, like a traffic light everyone can see
enum pwr_e { OFF, LOW, FULL };

state uart_pwr_s {
    rand pwr_e mode;
    constraint initial -> mode == OFF;     // chip wakes up with UART off
}

component uart_c {
    pool uart_pwr_s pwr_p;
    bind pwr_p *;

    action power_up_a {
        input  uart_pwr_s prev;
        output uart_pwr_s next;
        constraint prev.mode != FULL;
        constraint next.mode == FULL;
        exec body C = """
    uart_set_power(FULL);
""";
    }

    action power_down_a {
        input  uart_pwr_s prev;
        output uart_pwr_s next;
        constraint prev.mode == FULL;
        constraint next.mode in [OFF, LOW];
        exec body C = """
    uart_set_power({{next.mode}});
""";
    }

    action send_a {
        input uart_pwr_s cur;
        rand bit[8] nbytes;
        constraint cur.mode == FULL;       // can only send when fully on
        constraint nbytes in [1..64];
        exec body C = """
    uart_send_random({{nbytes}});
""";
    }
}

component pss_top {
    uart_c uart;
    action send_twice_a {
        activity {
            do uart_c::send_a;
            do uart_c::power_down_a;
            do uart_c::send_a;
        }
    }
}

Read send_twice_a carefully. It says: send, power down, send. That is illegal as written, because the UART starts OFF and is OFF or LOW after a power-down.

The solver does not give up. It inserts power_up_a before each send. You asked for the story. The solver added the missing steps so the story makes sense.

On a real project this is how you get “send data right after a low-power exit” tests for free, which is exactly the kind of corner that breaks clock gating and reset logic.

Working example 3: same intent, UVM target

At block level you probably do not have a CPU. You have a UVM testbench. The trick is that the exec block can emit SystemVerilog instead of C:

// uvm_target.pss : same idea, but the exec block writes SystemVerilog
component dma_sv_c {
    action copy_a {
        rand bit[32] src;
        rand bit[32] dst;
        rand bit[16] len;
        rand bit[2]  chan;
        constraint len in [64..4096];
        constraint len % 64 == 0;
        exec body SV = """
    begin
      dma_copy_seq seq = dma_copy_seq::type_id::create("seq");
      seq.src = {{src}}; seq.dst = {{dst}}; seq.len = {{len}}; seq.chan = {{chan}};
      seq.start(env.vsqr);
    end
""";
    }
}

The solver picks legal values for src, dst, len and chan. The generated SV starts your existing dma_copy_seq on the virtual sequencer. Your drivers, monitors and scoreboards do not change at all.

That is the quiet beauty of PSS. It does not throw away your UVM investment. It drives it.

Run these examples yourself

You do not need a commercial license to check that a PSS model is legal. The open-source pssparser package (version 3.5.0 at the time of writing) parses and type-checks PSS files.

# Check every example in this post with a free, open-source PSS front end
python3 -m pip install pssparser
pssparser dma.pss uart_state.pss uvm_target.pss
# Output with pssparser 3.5.0:
# 0 errors in 1 file   (printed once per file)

To actually solve and generate tests, you need a PSS tool. The main commercial ones are Siemens Questa One (Portable Stimulus), Cadence Perspec System Verifier, and Breker Trek. There are also open-source projects in the Zuspec family if you want to see how a solver works inside.

PSS vs UVM: who does what

This is the most common interview question on PSS, and the most common confusion on real teams.

QuestionUVMPSS
What does it describe?How to drive and check one interfaceWhich scenarios the whole system should go through
LevelTransactions, cycles, pinsActions, data flow, shared resources
Where does it run?Simulation (and some emulation)Anywhere the tool can target: UVM, C on a CPU, silicon
RandomizationPer transaction or sequenceAcross the whole scenario, including order and resource use
Who checks results?Scoreboards and assertionsStill your scoreboards, plus checks in the generated code
Best atDeep protocol checking of one blockMany blocks working together, reused across levels

Simple rule: UVM is the hands. PSS is the brain that decides what the hands should do next.

How the solver thinks (no math needed)

When you ask for a top-level action, the tool does roughly four things:

  1. Build the graph. It lists every action that could legally appear and how they connect through buffers, streams, states and resources.
  2. Fill the gaps. If an action needs an input nobody provided, it searches for a producer and adds it (inference).
  3. Pick values. It solves all constraints together: sizes, addresses, channel numbers, modes.
  4. Schedule. It decides what runs in parallel and what must wait, based on locks and shares.

Think of planning a school trip. You decide the goal (the museum). Someone has to book the bus (resource), make sure lunch is packed before leaving (buffer), and check the museum is open that day (state). The solver is the teacher who fills in all of that so the trip actually works.

How AI can help with Portable Stimulus

This is the section most readers asked me about, so let me be direct about what is real today, what works, and where it goes wrong.

What changed in 2025 and 2026

  • Siemens Questa One, Portable Stimulus Assist. Siemens launched the Questa One verification portfolio in May 2025. Its Portable Stimulus Assist is an AI feature that guides engineers, especially PSS beginners, to build PSS models from natural language prompts. Siemens published a white paper on it, “Better Stimulus Generation Through AI”, on Verification Academy.
  • Why “AI to PSS” beats “AI to UVM”. Bernard Murphy at SemiWiki (December 2025) made a sharp point: a short PSS model is far easier for a DV engineer to read and check than hundreds of lines of AI-written UVM. Once the PSS intent is right, the step to UVM or C is pushbutton and deterministic.
  • Breker’s two-track approach. Breker’s test synthesis engine is rule-based, which makes it deterministic and free of hallucination. In 2025 Breker described a plan to turn specs into its scenario graphs, plus partnerships with agentic AI companies for the spec-reading part. In March 2026 Breker announced a partnership with Moores Lab AI on AI-driven SoC verification.
  • Automation before AI. At DVCon Europe 2023, Infineon engineers presented MetaPSS, a Python framework that generates standard PSS models. They cited industry data showing engineers spend about 20% of project time just creating stimulus. That number is the reason everyone is chasing automation here.

Why PSS and AI fit together so well

Large language models are good at producing text that looks right. They are not good at guaranteeing it is right.

PSS gives you two safety nets that most code does not:

  • It is short and declarative. A 60-line PSS model can replace thousands of lines of directed tests. A human can actually review 60 lines.
  • The solver checks the logic. If the AI writes a constraint that makes the scenario impossible, the solver says so. If it forgets a producer, inference either fixes it or fails loudly.

So the deal is simple: AI writes the recipe. The solver tests whether the recipe can be cooked. You decide whether it is the dish you wanted.

AI-assisted Portable Stimulus workflow loop: spec, AI draft, parser and lint, human review, solve and run, AI reads coverage
Figure 4: Where AI helps in a PSS flow, and where a human must stay in charge.

Seven practical ways AI helps a PSS engineer

  1. Spec to first draft. Paste the legal rules from a block spec. Ask for buffers, resources, actions and constraints. You get a skeleton in minutes instead of a day.
  2. Register map to exec blocks. Give it the register list (or IP-XACT) and the HAL function names. It writes the boring exec body lines and the matching C stubs.
  3. Explain a solver failure. “No legal solution” messages can be cryptic. Paste the error and the related constraints. Ask: “which two constraints fight each other?” This alone saves hours.
  4. Coverage hole to new constraint. Share the uncovered bins or behavioral coverage report. Ask for constraint changes or a new top action that would reach them.
  5. Translate old UVM virtual sequences. Most teams have years of virtual sequences. AI is decent at pulling out the intent (“configure, start two channels, wait, check”) and proposing PSS actions for it.
  6. Model review. Ask it to check for the classic bugs listed later in this post: pool too small, missing bind, unconstrained enums, states with no initial value.
  7. Write the test plan back in English. Ask it to describe each top action in plain words. If the English sounds wrong, the model is wrong. This is my favorite review trick.

A prompt that works

Vague prompts give vague PSS. This one gives a usable first draft because it names the language, lists the syntax traps, and asks the AI to list its own assumptions:

You are helping me write a PSS 3.0 model (Accellera Portable Test
and Stimulus Standard). Use PSS syntax only, not SystemVerilog.
Rules: "in [a..b]" not "inside", "bit[N]" or "bit[msb:lsb]",
no "int unsigned", every pool needs a bind.

Block: DMA with 4 channels, memory-to-memory copy.
Registers: SRC, DST, LEN, CTRL.START, STAT.DONE (per channel).
Legal rules from the spec:
- LEN is 64 to 4096 bytes, multiple of 64
- SRC and DST must not overlap
- a channel can run one transfer at a time

Give me:
1. buffer, resource and component declarations
2. actions fill_mem_a, copy_a, check_a with exec body C
   calling fill_pattern(), dma_copy(), check_pattern()
3. a top action that runs 4 copies in parallel
4. a list of every assumption you made that is NOT in the rules above

That last line matters most. The assumptions list is where the AI admits what it guessed. Those guesses are exactly what you must confirm with the designer.

Where AI goes wrong (and how to catch it)

The most common failure is SystemVerilog leaking into PSS. The two languages look alike, and most training data is SV. Here is a typical first try from a general chatbot:

// A typical first try from a general chatbot
buffer mem_buf_s {
    rand bit[31:0] addr;
    rand int unsigned size;                  // SystemVerilog habit
    constraint c { size inside {[64:4096]}; } // SystemVerilog habit
}

Run it through the parser and both mistakes show up in under a second:

ai_bad.pss:3:23: error: unexpected 'size' in buffer 'mem_buf_s'
 3 |     rand int unsigned size;
   |                       ^~~~
ai_bad.pss:4:25: error: syntax error at 'inside' in constraint 'c'

Other mistakes I keep seeing in AI-written PSS:

  • A pool with no bind, so nothing connects.
  • Resource pools sized to 1 “to be safe”, which quietly kills all parallelism.
  • Constraints that are legal but wrong for the design, like allowing a reserved channel number.
  • Made-up library functions in exec blocks that do not exist in your HAL.
  • Correct syntax, wrong intent. The parser cannot catch this one. Only you can.

Guardrails I follow

  • Parser first, eyes second. Never review AI-written PSS that has not passed a parser. Let the tool catch syntax so your brain is free for intent.
  • The human owns constraints. AI can suggest them. A person who has read the spec signs off on every one.
  • Keep company data in company tools. Specs and register maps are confidential. Use the AI tools your company has approved, such as the ones built into your EDA flow, not a public chatbot.
  • Treat AI output like a junior engineer’s first pull request. Helpful, fast, and always reviewed.

Debugging PSS tests: report before waveform

If you remember one rule from this post, make it this one.

When a PSS-generated test fails, your first instinct will be to open the waveform and hunt for an RTL bug. Resist it. Early in a project, the model is wrong far more often than the design.

PSS debug order: solver report, generated test source, simulation log, then waveform
Figure 5: Debug PSS tests from the report down, not from the waveform up.

A real debug story: the innocent DMA

On a subsystem project, a PSS scenario failed about one seed in twenty with a scoreboard mismatch on transfer size. Everyone assumed a DMA RTL bug.

Two days of waveform staring found nothing. The data that landed in memory matched exactly what the registers were programmed with. The hardware was doing its job.

The break came from reading the solver report instead. On the failing seeds, two copy actions ran in parallel, but the buffer pool could only hold one buffer object. The tool reused it. The second action picked up a buffer whose size field the first one had already changed.

So the register write used one size and the scoreboard expected another. The generated test was fighting itself.

The fix was one line: size the pool to match the number of parallel transfers. Two days lost, one line changed. I have never opened a waveform first on a PSS failure since.

Real project patterns: IP, subsystem, SoC

IP level: the solver has no favorites

On a DMA IP, PSS generated the same “descriptor, then transfer” scenario across many channels and sizes as UVM sequences. The win was not writing speed. The solver produced overlap patterns across channels that the hand-written virtual sequences never tried.

One of those overlaps exposed an arbiter starvation bug: the lowest priority channel could be blocked forever under one specific traffic mix. Humans write fair scenarios without noticing. The solver has no such habit.

Subsystem level: add a state, reuse everything else

At subsystem level the same DMA sat next to an SRAM controller and a peripheral. The model gained one shared state for the peripheral’s mode, so the solver would never start a transfer while the peripheral was reconfiguring.

The IP-level actions dropped straight in. Only the exec blocks and one new rule changed. That is what PSS reuse looks like day to day: a thin new layer, not a rewrite.

SoC level: same intent, a whole new class of bug

At full chip, the DMA actions were retargeted to C and run by firmware on an embedded core, while a separate CPU traffic action hammered the same memory controller.

The scenario “large peripheral-to-memory transfer under heavy CPU load” was the same intent from IP level. It found a bandwidth arbitration corner where the DMA missed its latency budget only under one CPU burst pattern.

No IP-level test could have found it. At IP level, the CPU does not exist. Same model, new target, new bug. That is the whole argument for PSS on a big chip.

Common PSS modeling bugs

BugSymptomFix
Pool too smallRandom mismatches only in parallel scenariosSize pools to the max parallelism you allow
Missing bind“No producer found” or inference never happensBind every pool, usually bind pool_name *;
Unconstrained enum or fieldTests hit reserved encodings and hangConstrain to legal values from the spec
State with no initial ruleFirst action runs in an impossible modeAdd constraint initial -> ...
Over-constrained scenarioSolver fails, or every seed looks the sameRemove constraints one at a time to find the fighter
lock where share was meantNo parallel traffic ever runsUse share for read-only use of a resource
Exec block assumes old register layoutWorks in sim, fails on siliconKeep register access in one HAL file, generated from the register map

Design assumptions that break PSS tests

  • “Registers are ready right after reset.” Many blocks need a clock enable or a power-up sequence first. Model it as a state.
  • “Interrupts always arrive.” Generated C often polls. Decide early: poll or interrupt, and model both if the design supports both.
  • “Memory is flat and coherent.” At SoC level, caches and address windows matter. Use PSS address spaces and flush in exec blocks where needed.
  • “Cores start at the same time.” They do not. Add explicit sync points for multi-core scenarios.

Regression strategy and runtime

  • Generate once, run many. Solving is fast but not free. Generate a batch of tests per model change and reuse them across seeds of the testbench.
  • Keep a “smoke” top action. One short scenario per block that runs on every commit. If it fails, the model or HAL broke.
  • Grow scenarios with coverage. Add new top actions when coverage (including PSS 3.0 behavioral coverage) shows a hole, not because a new feature “feels important”.
  • Watch the solver time. If generation time jumps, look for a wide unconstrained field or a large parallel block. Narrow it.
  • Same tests, three platforms. Run the SoC C tests in simulation, then emulation, then on silicon. When results differ, the difference itself is your bug report.

Best practices checklist

  • One component per design block. Name actions with verbs: copy_a, power_up_a.
  • Put spec rules in constraints, and put a comment with the spec section number next to each.
  • Keep exec blocks one line long. Real logic goes in the HAL.
  • Size every pool on purpose and write down why.
  • Give every state an initial constraint.
  • Run a parser on every commit (pssparser works in CI and can output SARIF and GitHub annotations).
  • Review the English description of each top action with the designer.
  • Read the solver report before the waveform. Always.

Your first 30 days with PSS

WeekGoalDo this
1Read and runInstall pssparser. Type in the three examples above. Break them on purpose and read the errors.
2Model your own blockPick one simple IP you know well. Write actions and constraints from its spec. Use AI for the first draft if you like, then fix it by hand.
3Drive your UVM benchUse SV exec blocks to start your existing sequences. Compare coverage against your old tests.
4Go verticalRetarget the same model to C and run it on the CPU in your SoC sim. Note every change you had to make. That list is your reuse cost.

PSS interview questions (with short answers)

  1. What problem does PSS solve? Rewriting the same scenario for every verification level and platform. PSS writes intent once and reuses it.
  2. Does PSS replace UVM? No. PSS decides what scenario to run. UVM still drives and checks the interfaces.
  3. Buffer vs stream? Buffer: producer finishes before consumer starts. Stream: both run at the same time.
  4. What is action inference? The solver adds missing actions so every input has a legal producer.
  5. lock vs share? Lock is exclusive use of a resource. Share allows others to share it at the same time.
  6. What is an exec block? The target code (C, SV) an action expands into when the test is generated.
  7. What is new in PSS 3.0? Mainly behavioral coverage, plus yield-based multitasking, address space groups, string methods and more.
  8. How would you debug a failing PSS test? Solver report, then generated source, then logs, then waveform.
  9. How can AI help with PSS? First drafts from spec, exec code from register maps, explaining solver failures, and suggesting constraints for coverage holes, always with parser checks and human review.

Frequently asked questions

What is Portable Stimulus (PSS) in simple words?

PSS is a language for writing test intent once and turning it into real tests for many platforms. You describe what the chip should do, and a tool generates UVM sequences or C code that does it.

Is PSS worth learning in 2026?

Yes, if you work on SoC or subsystem verification. Chips have more blocks sharing more resources every year, and PSS is the standard way to reuse scenarios from IP level to silicon. AI assistants built into EDA tools are also lowering the learning curve.

Why do we need PSS if we already have UVM?

UVM is great at checking one interface deeply, but its tests do not move to the SoC CPU or to silicon. PSS captures the scenario once and generates UVM sequences, C tests and lab tests from it, and its solver tries legal mixes of shared resources that hand-written tests usually miss.

What value does PSS add to a verification strategy?

Reuse of scenarios from IP to silicon, a better chance of finding bugs between blocks, earlier tests for firmware and bring-up, coverage written in the language of the spec, and fewer directed tests to maintain.

What is the latest version of the Portable Stimulus Standard?

PSS 3.0, approved by Accellera on August 29, 2024. Its biggest addition is behavioral coverage. The working group has been previewing PSS 3.1 features.

Does PSS replace UVM?

No. PSS decides which scenarios to run across the system. UVM still drives the interfaces and checks results at block level. PSS can generate UVM sequence calls directly.

Can AI write a PSS model for me?

AI can write a useful first draft from a spec, especially with a clear prompt. It often mixes in SystemVerilog syntax and guesses missing rules, so run the output through a PSS parser and have an engineer review every constraint.

Which tools support PSS?

The main commercial tools are Siemens Questa One (with Portable Stimulus Assist), Cadence Perspec System Verifier and Breker Trek. The open-source pssparser package can parse and check PSS files for free.

What is the difference between a buffer and a stream in PSS?

A buffer is passed after the producer finishes, like a relay baton. A stream is passed while producer and consumer run at the same time, like a phone call.

How do I start learning PSS?

Install pssparser, type in a small DMA example, and break it on purpose to read the errors. Then model one simple block you already know and use it to drive your existing UVM testbench.

Summary

PSS lets you write a test scenario once and run it at every level of a chip: UVM at block level, C on the CPU at SoC level, and the same C on silicon.

The ideas are small: actions, flow objects, resources, states, constraints, and exec blocks. The solver does the heavy lifting by adding missing steps and picking legal values.

PSS 3.0 added behavioral coverage, so you can now measure patterns of behavior, not just values.

AI has become a real helper in 2025 and 2026, from Siemens’ Portable Stimulus Assist to custom prompts against your own specs. It is fastest at drafts and slowest at judgment. Keep the parser and the human review in the loop.

The first time a PSS model finds a bug that no block-level test could reach, you stop thinking of it as “one more language” and start seeing it as the playbook your whole team was missing.

Quick revision notes

  • PSS = Accellera Portable Test and Stimulus Standard. Current version 3.0 (Aug 2024).
  • Component = block. Action = one thing it does. Activity = the order.
  • Buffer = baton. Stream = phone call. State = traffic light. Resource = court booking.
  • Inference = solver adds missing producers.
  • lock = exclusive. share = shared.
  • Exec blocks turn actions into C or SV.
  • Debug order: report, generated code, log, waveform.
  • AI: drafts, exec code, solver error help, coverage ideas. Parser plus human review, always.

References and further reading

Leave a Reply

Your email address will not be published. Required fields are marked *