PSS 3.0 Migration Guide¶
This guide helps users migrate from PSS 2.x to PSS 3.0 with pssparser.
Backward Compatibility¶
PSS 3.0 is designed to be largely backward compatible with PSS 2.x. Existing PSS 2.x code should continue to work without modification in most cases.
Breaking Changes¶
Reserved Keywords¶
The following keywords are newly reserved in PSS 3.0:
monitor- Used for behavioral coverageyield- Control flow in target executionrandomize- Procedural randomizationatomic- Atomic activity blockseventually- Monitor temporal operatorconcat- Monitor temporal concatenationoverlap- Monitor temporal overlapschedule- Monitor temporal scheduling
Action Required: If your PSS 2.x code uses any of these as identifiers, you must rename them.
// PSS 2.x - May need updating if 'monitor' is used as identifier
action monitor { } // ERROR in PSS 3.0
// PSS 3.0 - Use different identifier
action monitor_action { } // OK
New Features¶
Monitors for Behavioral Coverage¶
PSS 3.0 introduces monitors as a first-class construct for behavioral coverage. This replaces ad-hoc coverage approaches.
PSS 2.x Approach (manual coverage):
component pss_top {
action A { }
action B { }
// Manual tracking via constraints or actions
covergroup my_coverage {
// Manual coverage points
}
}
PSS 3.0 Approach (monitors):
monitor SequenceMonitor {
activity {
concat {
A;
B;
}
}
}
component pss_top {
action A { }
action B { }
cover SequenceMonitor;
}
Migration Strategy:
Identify behavioral patterns you’re tracking manually
Create monitor declarations for those patterns
Use cover statements to instantiate monitors
Remove manual coverage tracking code
String Enhancements¶
PSS 3.0 adds built-in string methods and substring operator.
PSS 2.x Approach (limited string operations):
// String operations were limited
action my_action {
string s = "hello";
// No way to get length, search, or manipulate strings
}
PSS 3.0 Approach (rich string API):
action my_action {
string s = "hello world";
int len = s.size(); // 11
int idx = s.find("world"); // 6
string sub = s[0..4]; // "hello"
string upper_s = s.upper(); // "HELLO WORLD"
}
Migration Strategy:
Review string handling code
Replace workarounds with built-in methods
Use substring operator for extraction
Leverage string methods in constraints
Reference Collections¶
PSS 3.0 allows reference types in collections.
PSS 2.x Approach (handles only):
component pss_top {
pool[10] A actions;
// No direct collection of references
}
PSS 3.0 Approach (explicit reference collections):
component pss_top {
action A { }
array<ref A, 10> action_refs;
list<ref A> action_list;
map<string, ref A> action_map;
}
Migration Strategy:
Identify action handle usage patterns
Consider using explicit reference collections
Leverage null reference capability for optional references
Procedural Randomization¶
PSS 3.0 adds randomize statement for procedural randomization.
PSS 2.x Approach (declarative only):
action my_action {
rand int x;
constraint {
x > 0;
x < 100;
}
}
PSS 3.0 Approach (procedural randomization):
action my_action {
int x; // Non-rand field
exec body {
randomize(x) {
x > 0;
x < 100;
}
}
}
Migration Strategy:
Identify cases where procedural randomization is beneficial
Use
randomizefor dynamic constraint-based randomizationKeep declarative
randfor static randomization
Activity Atomic Blocks¶
PSS 3.0 adds atomic blocks for atomic activity execution.
PSS 2.x Approach (no atomic guarantee):
action my_action {
activity {
// No way to guarantee atomic execution
do A;
do B;
}
}
PSS 3.0 Approach (explicit atomic):
action my_action {
activity {
atomic {
do A;
do B;
}
}
}
Migration Strategy:
Identify activities that require atomic execution
Wrap them in
atomicblocksDocument atomicity requirements
Yield Statements¶
PSS 3.0 adds yield for explicit scheduling points in target execution.
PSS 2.x Approach (implicit scheduling):
action my_action {
exec target {
// Scheduler decides when to suspend
}
}
PSS 3.0 Approach (explicit yield):
action my_action {
exec target {
// Do work
yield; // Explicit scheduling point
// Continue work
}
}
Migration Strategy:
Identify long-running target exec blocks
Insert
yieldstatements at appropriate pointsTest scheduling behavior
Platform Qualifiers¶
PSS 3.0 adds target and solve qualifiers for functions.
PSS 2.x Approach (no context specification):
import function int utility_func(int x);
PSS 3.0 Approach (explicit context):
import target function int read_hw(int addr);
import solve function int compute_value(int x);
import target solve function int utility_func(int x);
Migration Strategy:
Review imported functions
Add appropriate platform qualifiers
Validate usage contexts
Common Migration Patterns¶
Pattern 1: Coverage to Monitors¶
Before (PSS 2.x):
component pss_top {
action A { }
action B { }
// Manual coverage tracking
int coverage_counter;
constraint {
// Complex constraints to track patterns
}
}
After (PSS 3.0):
monitor ABSequence {
activity {
concat {
A;
B;
}
}
}
component pss_top {
action A { }
action B { }
cover ABSequence;
}
Pattern 2: String Processing¶
Before (PSS 2.x):
// Limited string operations
action my_action {
string filename;
// No way to extract extension or validate format
}
After (PSS 3.0):
action my_action {
string filename;
exec body {
int dot_pos = filename.find_last(".");
if (dot_pos != -1) {
string extension = filename[dot_pos..];
// Process extension
}
}
}
Pattern 3: Dynamic Reference Management¶
Before (PSS 2.x):
component pss_top {
pool[10] A actions;
// Limited reference handling
}
After (PSS 3.0):
component pss_top {
action A { }
list<ref A> active_actions;
map<string, ref A> action_registry;
exec init {
// Dynamic reference management
active_actions.clear();
}
}
Testing Your Migration¶
Validation Checklist¶
Parse Check: Verify all files parse without errors
from pssparser import Parser parser = Parser() try: parser.parses([("file.pss", content)]) print("✓ Parse successful") except Exception as e: print(f"✗ Parse error: {e}")
Keyword Check: Ensure no reserved keywords used as identifiers
# Search for potential conflicts grep -E '\b(monitor|yield|randomize|atomic)\b' *.pss
Feature Check: Verify new features work as expected
Regression Check: Run existing test suite
Known Migration Issues¶
Issue 1: Monitor Keyword Conflicts¶
Symptom: Parse errors on identifiers named “monitor”
Solution: Rename identifiers
// Before
action monitor { }
// After
action monitor_action { }
Issue 2: Implicit String Operations¶
Symptom: Code expected string operations that weren’t available
Solution: Use new string methods
// Now available
int len = my_string.size();
string sub = my_string[0..10];
Issue 3: Reference Type Cloning¶
Symptom: Warnings about “TaskCopyAst: Error: copy(DataType) failed”
Impact: Benign - does not affect functionality
Solution: No action required - will be addressed in future release
Performance Considerations¶
The PSS 3.0 parser maintains performance characteristics similar to PSS 2.x:
Parse time: No significant change
Memory usage: Minimal increase for new AST nodes
Linking time: Comparable to PSS 2.x
Getting Help¶
If you encounter migration issues:
Check this guide for common patterns
Review the PSS 3.0 Features documentation
Examine the test suite in
tests/src/TestPSS30Grammar.cppFile an issue on the project repository
Best Practices¶
Incremental Migration: Migrate one feature at a time
Test Early: Validate changes frequently
Document Changes: Note PSS 3.0 features used
Leverage New Features: Don’t just maintain compatibility - use new capabilities
Review Monitors: Consider behavioral coverage opportunities
Example: Complete Migration¶
Original PSS 2.x Code:
component pss_top {
action ReadReg {
rand bit[31:0] addr;
constraint { addr % 4 == 0; }
}
action WriteReg {
rand bit[31:0] addr;
rand bit[31:0] data;
constraint { addr % 4 == 0; }
}
}
Migrated PSS 3.0 Code:
// Add behavioral coverage
monitor ReadWriteSequence {
activity {
concat {
ReadReg;
WriteReg;
}
}
}
component pss_top {
action ReadReg {
rand bit[31:0] addr;
constraint { addr % 4 == 0; }
}
action WriteReg {
rand bit[31:0] addr;
rand bit[31:0] data;
constraint { addr % 4 == 0; }
}
// Enable behavioral coverage
cover ReadWriteSequence;
// Use reference collection for tracking
list<ref ReadReg> read_history;
exec init {
read_history.clear();
}
}
Summary¶
PSS 3.0 migration is straightforward for most codebases:
✅ High backward compatibility
✅ Minimal breaking changes (reserved keywords only)
✅ Significant new capabilities (monitors, strings, references)
✅ Clear migration patterns
✅ Good performance characteristics
See Also¶
PSS 3.0 Features - Complete feature reference
Quickstart - Getting started guide
AST Structure - AST structure details