STRUMENTA LANGUAGE ENGINES · ACCELLERA PSS

A front end for the Portable Test and Stimulus Standard.

PSS is Accellera’s language for describing verification intent once and generating tests for many execution contexts — a UVM testbench in simulation, C on the embedded processor in emulation, a post-silicon test on real hardware. This engine parses the full PSS 3.2 language and hands you a typed, positioned model of it.

Everything else in this catalog reads a legacy business language. This one does not, and the page is not going to pretend otherwise. The buyer here is usually a verification-tool vendor who needs a conformant reader without writing one.

The engine at a glance
STANDARDAccellera PSS 3.2
INPUTthe DSL · .pss
COVERAGEthe full language · 277 parser rules
MODELStarlasu AST, positioned
OUTPUTAST · JSON · XML · LionWeb
BINDINGSJava, Kotlin, Python, TypeScript, C#

One model, many execution contexts

Accellera Systems Initiative · Portable Test and Stimulus Standard

A PSS model is a declarative description of what a chip or system should be made to do — actions, the objects that flow between them, the resources they contend for, and the constraints that make a legal scenario. Tools solve that model and generate concrete tests from it. “Portable” means the same description targets block level, subsystem level, SoC level and post-silicon.

One PSS model generating tests for several execution contexts A single PSS model, written once, is solved by a tool that generates a UVM sequence for simulation, C code running on the embedded processor for emulation, and a post-silicon test for real hardware. one PSS model solver UVM sequence, simulation C on the target, emulation post-silicon test actions · flow objects · constraints THIS ENGINE READS THE MODEL. WHAT GENERATES THE TESTS FROM IT IS YOUR TOOL, OR YOUR VENDOR’S.

PSS is standardized by the Accellera Systems Initiative, the same organization behind SystemVerilog’s early standardization and UVM. The standard is defined by a Language Reference Manual whose annexes carry the formal grammar. Two concrete syntaxes exist: a domain-specific language, which is the .pss text people write by hand and the input this engine reads, and a C++ input form built on a class library.

The language itself is modern and unremarkable to look at: free-format text, braces and semicolons, // and /* */ comments, UTF-8, package declarations with ::-qualified paths and import statements. There is no card image, no column rule and no encoding archaeology. Nothing about this page belongs in the legacy-modernization register and we have written it accordingly.

What is unusual is the shape of the semantics. There is no control flow to follow in the ordinary sense — an action declares fields, a constraint block over them and an activity describing how sub-actions are scheduled. What you are reading is a solve space, not a program, and a model of it has to preserve that rather than flatten it into statements.

Strumenta’s presence in this domain is not as odd as it may look from the rest of the catalog: the same organization maintains a Verilog parser, and the interchange argument at the bottom of this page is the practical reason an EDA toolchain would want both from one source.

Four places a naive PSS front end produces the wrong tree

Not errors — wrong trees, which is worse. Each of these is a construct where a generated-from-the-annex parser silently gives you a shape that is not what the model means.

activity is a second grammar

sequence, schedule, parallel, select, repeat, repeat … while, foreach, replicate, and the join_branch, join_first, join_none and join_select specifications. Several of these — select, repeat, foreach — exist in the activity grammar and in the procedural grammar, with different meanings. Telling them apart by context is the whole difficulty.

activity {
  schedule {
    do uart_c::configure;
    repeat (4) { do uart_c::send; }
  }
}

A brace is not always a block

{1, 2, 3, 4} is an aggregate literal in one position, a block in another and a constraint body in a third. With array<T,N>, list<T>, map<K,V> and set<T> all taking literal forms, this is the single most reliable way to get a plausible-looking tree that is wrong. The repository’s very first example fixture is about exactly this.

int c1[4] = {1, 2, 3, 4};   // OK
int c2[4] = {1};               // too few
int c3[4] = {1,2,3,4,5,6};   // too many

No file is a complete declaration

extend reopens an action, component, struct, enum or covergroup declared elsewhere and adds members or constraints to it. compile if, compile has and compile assert make the set of declarations in a scope conditional, at four different body levels. Templates add type and value parameters on top. Resolution is whole-project by construction.

extend action uart_c::send {
  constraint { length <= 32; }
}
compile if (HAS_DMA) { import dma_pkg::*; }

Foreign source travels inside strings

exec blocks come in ten kinds — pre_solve, post_solve, body, header, declaration, run_start, run_end, init_up, init_down, init — and three of them carry literal C, C++, SystemVerilog or SystemC source to be emitted into the generated test, plus target-file blocks and template functions with substitution. The engine models the blocks; the payload stays a string, deliberately.

exec body C = """
  uart_set_mode({{mode}});
""";

Two more are worth naming. Constraints are a language of their own — implication with ->, if/else constraints, forall, unique, dist, set membership in [a..b] and solve … before ordering. And the coverage constructs — covergroup, coverpoint, cross, bins, ignore_bins, illegal_bins, with option blocks and iff guards — are borrowed from SystemVerilog and inherit its ambiguities along with its syntax.

Coverage of the language

PSSParser.g4 · 1,571 lines · 277 parser rules

The grammar we ship is 1,571 lines with 277 parser rules, and they implement the formal syntax of the standard comprehensively, area by area. The table says what is covered; the figure says how much grammar sits behind it. Every rule name in the middle column is a rule in that file, and the syntax annex of the standard is on the public record — so this is a claim you can hold against the source rather than take from us.

Coverage here means grammar coverage: what the engine reads and turns into a model, across 277 parser rules. It is a statement about the language, not a claim about your particular model — for that, send us the model.
Area of the standard Grammar rules Status
Compilation units and packages compilation_unit, portable_stimulus_description, package_declaration, import_stmt Supported
Actions, including abstract actions action declarations with template parameters Supported
Activities, in all their statement forms parallel, schedule, select, repeat, replicate, foreach, join_branch, join_first, join_none, join_select Supported
Scheduling constraints on activities activity_scheduling_constraint Supported
Constraints implication, if/else, forall, foreach, default, default disable, dynamic constraints Supported
Coverage constructs covergroup, coverpoint, cross, bins, portmaps Supported
Components and pools component_declaration, pool declarations, bind Supported
Flow objects and resources buffer, stream, state, resource, with lock and share Supported
Structs, enums, inheritance and extend struct and enum declarations, extend Supported
Functions, prototypes and imported functions import_class_decl, import_function Supported
Exec blocks, in all ten kinds exec_block, target_code_exec_block, target_file_exec_block, target_template_function Supported
Compile-time forms package_body_compile_if, compile_assert_stmt, compile has Supported
C, C++, SystemVerilog or SystemC inside an exec Preserved as a string; not parsed by this module
The C++ input form of the standard Not covered — this engine reads the DSL
Solving a model, or generating tests from it Not what this is — that is the tool you build on top

What a PSS model looks like going in

Composed from constructs in the grammar and the standard’s own examples rather than taken from a customer — but every marked line is a rule the engine implements.

Input — a component, its actions, and a top-level scenario

illustrative PSS, DSL form

enum config_modes_e {UNKNOWN, MODE_A=10, MODE_B=20};

component uart_c {
  action configure {
    rand config_modes_e mode;
    constraint { mode != UNKNOWN; }
    exec body C = """
      uart_set_mode({{mode}});
    """;
  }

  action send {
    input data_buf_s in_data;
    rand int in [1..64] length;
    constraint { length <= in_data.size; }
  }
}

component pss_top {
  uart_c uart;

  action entry {
    activity {
      do uart_c::configure;
      repeat (4) { do uart_c::send; }
    }
  }
}
Six marked constructs, six different parts of the standard. A random field with a constraint over it; a target-language payload carried inside a string with template substitution; a directional flow-object port; and an activity that schedules sub-actions rather than calling them. The engine produces a typed node for each, with a position on the original source, and returns a partial model plus a positioned issue list rather than an exception when it meets something it cannot read.
WHY IT IS IN THIS CATALOG AT ALL

The same model shape as every other engine we license.

PSS has nothing to do with COBOL or RPG. What it shares with them is the framework underneath — and for a toolchain that already has more than one language in it, that is the practical part.

Every Strumenta engine is built on Starlasu, so the PSS AST has the same shape, the same traversal model and the same API as every other tree we produce. If a verification toolchain also carries Verilog or SystemVerilog models, one traversal and one set of idioms covers both rather than two unrelated front ends meeting in a file format somebody designed on a Friday.

The engine supports LionWeb, so the model interchanges with LionWeb-compliant tooling instead of being locked inside one process — which for an EDA flow is the difference between a model you can hand to the next stage and one you have to re-serialize by hand.

And it is available through bindings from Java, Kotlin, Python, TypeScript and C#. Verification tooling is written in all of those and more; the host application should pick the language, not the parser.

One framework underneath

same AST shape, same traversal

Starlasu →
The framework every engine here is built on.

LionWeb →
The interchange standard the models speak.

The whole catalog →
15+ engines, one AST framework underneath.

Parsers and transpilers →
If what you need is a language we do not list.

What you receive

A language module, a model, an interchange story and a license. Deliberately fewer promises than the other pages in this catalog make, because we would rather under-describe this one than over-describe it.

01 The engine

A Starlasu language module for the JVM

The PSS DSL in, a Kolasu AST out — Kolasu being the JVM implementation of Starlasu. Use it as a library from Java or Kotlin; the parse result carries the model root and an issue list, so it behaves exactly like every other engine in this catalog.

JVM library · .pss in, AST out
02 The model

A typed AST with positions on every node

Parse-tree-to-AST mapping is a separate layer, so the model is designed rather than a renamed parse tree. Difficult input returns a partial model plus a positioned issue list instead of an exception — which is what an editor or a linter needs, not what an exception gives you.

positions · issues · JSON · XML
03 The interchange

LionWeb, and five language bindings

The model interchanges through LionWeb with tooling we did not write, and the engine is reachable from Java, Kotlin, Python, TypeScript and C#. For a verification flow assembled from several tools in several languages, this is usually the deciding property rather than a footnote.

LionWeb · Java, Kotlin, Python, TypeScript, C#
04 The license

Standard, Distribution or Service — support included

On this language the middle tier is usually the relevant one: Distribution covers the engine shipping inside a product you sell, which is the normal case for an EDA tool vendor. Standard covers use inside your own organization, Service covers a service you operate. The terms are identical to every other engine in this catalog, license-file mechanism included: a license file is registered once per process and refreshed from our license service.

Distribution is the usual tier here

Why license this when there is a public PSS grammar

There is one, it is good, and pretending otherwise would be the fastest way to lose a technical reader. PSSTools/pssparser is an ANTLR-based PSS parser under Apache 2.0. We will also say the part most vendors leave out: our grammar is not written from nothing either — it carries an Apache 2.0 header and descends from publicly licensed work. “You cannot get a grammar” is not the argument here, and we are not going to make it.

The argument is what sits between a grammar file and a product. The standard’s formal syntax is not directly implementable: a working grammar has to diverge from it in specific places, and those divergences — where a component declaration is ambiguous because component is also a package body item, where the annex’s rule shape cannot be expressed as written — are the expensive part, and they have to be re-resolved every time the standard moves.

A grammar also gives you a parse tree, which is not a model. The two places a generated front end goes quietly wrong on PSS are the context-dependent brace and the overlap between the activity grammar and the procedural one. In both, the failure mode is a wrong tree rather than an error, which means you find it downstream, in a tool, in front of a customer.

Then there is everything a shipped product carries and a grammar does not: a designed AST rather than raw parser contexts, positions on every node, an issue list instead of console errors, serialization, LionWeb interchange, bindings in five languages, and a version of it that will still be maintained when the standard moves again.

And someone to call. If you are shipping a verification tool to your own customers, the front end is the part you least want to own and the part your customers will notice first. That is the trade this license is for.

If PSS is one of several languages your tool has to read, the more useful conversation is about the catalog rather than this page: see the engines we license, or Parsers and transpilers if the language you need is not on the list.

What to discuss before you license

Five things we would rather tell you now than have you find in week three.

  • This is a front end, not a solver. The engine reads a PSS model and gives you a typed, positioned representation of it. Solving the constraint space and generating tests is the tool you build on top — and if you were hoping to buy the second thing, this is not it.
  • The DSL, not the C++ input form. The standard defines two concrete syntaxes. This engine reads the .pss DSL. If your models are written against the C++ class library, that is a different piece of work.
  • Target-language payloads stay strings. The C, C++, SystemVerilog and SystemC carried inside exec blocks and target-file blocks is preserved verbatim and positioned, not parsed. That is deliberate, but if you need those payloads analyzed, say so and we will scope it.
  • Whole-project resolution is inherent to this language. extend, import, templates and compile if mean no single file’s tree is the definition of anything. How much your models rely on those decides whether you need parsing or parsing plus resolution — and that is the first thing we will ask.
  • You do not receive the grammar. This is a commercial engine. You extend behavior by walking and transforming the AST, which is what Starlasu is for. If you need coverage the engine does not have, that is work we scope rather than a file we hand over.

What we will ask you

  1. Which PSS version do your models target, and are you expecting to move with the standard?
  2. DSL input only, or do you also need the C++ input form?
  3. How much of your model uses extend across files, templates and compile if?
  4. Do you need the exec target-language payloads parsed, or preserved as strings?
  5. Do you need coverage constructs modeled in detail, or only recognized?
  6. Are you building a tool you will ship to your own customers? That is a Distribution license.
  7. Which platform consumes the model — JVM, Python, .NET, TypeScript? Do you need LionWeb interchange?

Straight answers

What is PSS, exactly?

The Portable Test and Stimulus Standard, published by the Accellera Systems Initiative. It is a declarative language for describing verification intent — actions, the objects that flow between them, the resources they contend for, and the constraints that make a scenario legal — from which tools generate concrete tests for different execution contexts: a UVM testbench in simulation, C running on the embedded processor in emulation, or a post-silicon test. It is a hardware verification language, and it is the one engine in this catalog that has nothing to do with legacy modernization.

How much of the language does it cover?

The engine parses the full PSS 3.2 language. The grammar is 1,571 lines with 277 parser rules, implementing the standard’s formal syntax comprehensively: actions and abstract actions, activities in all their statement forms, constraints including forall and the dynamic and default forms, covergroups with coverpoints, crosses and bins, components and pools, flow objects and resources, exec blocks in all ten kinds, functions and prototypes, enums and structs, extend and inheritance, packages and imports, and the compile-time forms.

Does it generate tests, or solve the model?

No. It is a front end. It reads PSS and produces a typed, positioned model of it, with an issue list rather than an exception on difficult input. Solving the constraint space and generating stimulus is the job of the tool you build on this — which is exactly the split most verification-tool vendors want, because the solver is their differentiator and the parser is not.

Is your grammar written from scratch?

No, and we would rather say so than be asked. It carries an Apache 2.0 header and descends from publicly licensed work, as does the well-known open-source PSS parser. What a license buys is not the grammar file: it is a designed AST rather than raw parser contexts, positions on every node, an issue list, serialization, LionWeb interchange, bindings in five languages, the resolution of the places where the standard’s formal syntax is not directly implementable, and maintenance when the standard moves again.

Can we use it from Python, TypeScript or C#?

Yes. The engine is built on Starlasu and is available through bindings from Java, Kotlin, Python, TypeScript and C#, and it supports LionWeb, so the model interchanges with LionWeb-compliant tooling rather than being locked inside one process.

Usually a Distribution conversation the front end is the part you do not want to own

Building a tool that has to read PSS? Send us a model.

A representative model — the one with the awkward extend chains and the exec blocks you would rather not think about — and we will tell you what the engine reads, what it hands back, and what embedding it inside a product you ship would look like commercially.

Scroll to Top