Documente Academic
Documente Profesional
Documente Cultură
Overview..........................................................................................................................................................................1
Keywords........................................................................................................................................................................2
Formal Syntax.................................................................................................................................................................4
Evaluation Model..........................................................................................................................................................37
Literals...........................................................................................................................................................................38
Integer and Logic Literals..................................................................................................................................38
Real Literals.......................................................................................................................................................38
Time Literals......................................................................................................................................................38
String Literals.....................................................................................................................................................38
Array Literals.....................................................................................................................................................39
Structure Literals...............................................................................................................................................39
Arrays of Unpacked Structures...................................................................................................................39
Attributes.......................................................................................................................................................................40
Syntax................................................................................................................................................................40
Examples...........................................................................................................................................................40
Data Types....................................................................................................................................................................41
Integer Data Types............................................................................................................................................41
Non Integer Data Types....................................................................................................................................42
Real and Shortreal Type.............................................................................................................................42
Void Data Type...........................................................................................................................................42
Chandle Data Type.....................................................................................................................................42
Event Data Type.........................................................................................................................................42
Classes.......................................................................................................................................................43
String Type........................................................................................................................................................44
String Methods............................................................................................................................................45
Example................................................................................................................................................46
String Relational Operators.........................................................................................................................46
User-defined Type.............................................................................................................................................47
Enumeration Types...........................................................................................................................................49
Enumerated Type Ranges..........................................................................................................................49
Example................................................................................................................................................50
Example................................................................................................................................................50
Enumeration Methods.................................................................................................................................50
Structures..........................................................................................................................................................52
Packed Structures.......................................................................................................................................52
Signed and Unsigned Structures..........................................................................................................53
Unpacked Structures...................................................................................................................................53
Member Initialization.............................................................................................................................53
Assignment...........................................................................................................................................53
Limitations.............................................................................................................................................54
Unions...............................................................................................................................................................55
Packed Unions............................................................................................................................................55
Unpacked Unions........................................................................................................................................55
Tagged Unions............................................................................................................................................55
Class..................................................................................................................................................................56
Casting..............................................................................................................................................................57
Static Casting..............................................................................................................................................57
Bit-stream Casting.......................................................................................................................................57
Example 1.............................................................................................................................................57
Table of Contents
Data Types
Example 2.............................................................................................................................................58
$cast Dynamic Casting...............................................................................................................................58
Example 3.............................................................................................................................................59
Const Casting..............................................................................................................................................59
Arrays and Queues.......................................................................................................................................................60
Packed and Unpacked Arrays...........................................................................................................................60
Packed and Unpacked Array Dimensions...................................................................................................60
Multiple Dimensions....................................................................................................................................60
Packed Array Properties.............................................................................................................................60
Unpacked Array Properties.........................................................................................................................61
Indexing, Part-selects, and Slices...............................................................................................................61
Parameters of Unpacked Array Type..........................................................................................................61
Limitations.............................................................................................................................................61
Dynamic Arrays.................................................................................................................................................62
Dynamic Array Constructors.......................................................................................................................62
Other Dynamic Array Methods....................................................................................................................62
Associative Arrays.............................................................................................................................................64
Syntax.........................................................................................................................................................64
Associative Array Methods..........................................................................................................................66
Queues..............................................................................................................................................................67
Queue Methods...........................................................................................................................................67
Limitations.........................................................................................................................................................68
Array Querying Functions..................................................................................................................................69
Array Manipulation Methods..............................................................................................................................70
Array Locator Methods................................................................................................................................70
Array Ordering Methods..............................................................................................................................71
Array Reduction Methods............................................................................................................................72
Iterator Index Querying...............................................................................................................................73
Examples:.............................................................................................................................................73
Limitations...................................................................................................................................................74
Array Assignment..............................................................................................................................................75
Fixed-Size Arrays........................................................................................................................................75
Dynamic Arrays...........................................................................................................................................75
Associative Arrays.......................................................................................................................................75
Queues........................................................................................................................................................76
Different Array Kinds in The Assignment....................................................................................................76
Overwriting Existing Elements....................................................................................................................76
Out-of-bounds Elements.............................................................................................................................77
Vectors and Unpacked Arrays..............................................................................................................77
Data Declarations.........................................................................................................................................................78
Constants..........................................................................................................................................................78
Parameter Constants..................................................................................................................................78
Parameter Port List...............................................................................................................................78
Type Parameters..................................................................................................................................78
Omitting Default Parameter Values......................................................................................................79
$ as a Parameter Value........................................................................................................................79
Const Constants..........................................................................................................................................80
Localparam Constants................................................................................................................................80
Variables............................................................................................................................................................81
Nets...................................................................................................................................................................82
Specifying the Net Data Type.....................................................................................................................82
Scope and Lifetime............................................................................................................................................83
ii
Table of Contents
Data Declarations
Specifying the Lifetime of Local Variables..................................................................................................83
Signal Aliasing...................................................................................................................................................84
Type Operator...................................................................................................................................................85
Classes..........................................................................................................................................................................86
Overview............................................................................................................................................................86
Objects, Object Properties and Methods...........................................................................................................87
SystemVerilog Handles vs C Pointers........................................................................................................87
Object Properties and Object Parameters..................................................................................................87
Object Methods...........................................................................................................................................88
Constructors......................................................................................................................................................89
Inheritance.........................................................................................................................................................90
Chaining Constructors.......................................................................................................................................91
Specifying Arguments in the super.new Call...............................................................................................91
Specifying Arguments in the extends Clause..............................................................................................92
Assigning, Renaming, Copying.........................................................................................................................93
Assignment.................................................................................................................................................93
Shallow Copy..............................................................................................................................................93
Full Copy.....................................................................................................................................................94
Static Properties and Methods..........................................................................................................................95
Static Properties..........................................................................................................................................95
Static Methods............................................................................................................................................95
This....................................................................................................................................................................97
Super.................................................................................................................................................................98
Casting..............................................................................................................................................................99
When to Use $cast......................................................................................................................................99
Data Hiding and Encapsulation.......................................................................................................................101
Local and Protected Members..................................................................................................................101
Constant Class Properties...............................................................................................................................103
Overridden Members.......................................................................................................................................104
Virtual Methods................................................................................................................................................105
Default Values for Virtual Method Arguments...........................................................................................106
Abstract Classes and Pure Virtual Methods....................................................................................................107
Class Scope Resolution Operator...................................................................................................................108
Nested Classes...............................................................................................................................................110
Out-of-block Declarations................................................................................................................................111
Parameterized Classes...................................................................................................................................112
Type Parameters in Parameterized Classes.............................................................................................112
Omitting Default Parameter Values...........................................................................................................113
Equivalence of Specializations..................................................................................................................113
Static Properties in Parameterized Classes..............................................................................................114
Benefits of Parameterized Classes...........................................................................................................114
Local Class Parameters............................................................................................................................114
Typedef Class..................................................................................................................................................115
Memory Management......................................................................................................................................116
Assignment Statements.............................................................................................................................................117
Assignment Patterns.......................................................................................................................................117
Assignment Pattern Expressions..............................................................................................................117
Assignment Keys......................................................................................................................................118
Assignment Keys Precedence............................................................................................................119
Assignment Pattern on the left-hand side of an assignment.....................................................................119
Unpacked Array Concatenations.....................................................................................................................121
Limitations.................................................................................................................................................122
iii
Table of Contents
Tasks and Functions..................................................................................................................................................123
Functions.........................................................................................................................................................123
Non-mandatory begin ... end or fork ... join Blocks...................................................................................123
Formal Arguments.....................................................................................................................................123
Lifetime......................................................................................................................................................123
Return Values and void Functions............................................................................................................124
Discarding Function Return Values...........................................................................................................124
Constant Function Calls............................................................................................................................124
Statements Allowed in Functions by SystemVerilog 2009........................................................................124
Tasks...............................................................................................................................................................126
Non-mandatory begin ... end or fork ... join Blocks...................................................................................126
Formal Arguments.....................................................................................................................................126
Lifetime......................................................................................................................................................126
The return Statement................................................................................................................................127
Passing Arguments to Tasks and Functions...................................................................................................128
Pass by Value...........................................................................................................................................128
Pass by Reference....................................................................................................................................128
Limitations...........................................................................................................................................128
Default Argument Values..........................................................................................................................128
Argument Binding by Name......................................................................................................................129
Operators and Expressions.......................................................................................................................................130
Operators Precedence and Associativity.........................................................................................................130
Assignment Operators.....................................................................................................................................131
Wild Equality and Wild Inequality Operators....................................................................................................131
Real Operators................................................................................................................................................132
Concatenation.................................................................................................................................................132
Replication.......................................................................................................................................................132
Tagged Union Expressions and Member Access............................................................................................133
Aggregate Expressions...................................................................................................................................133
Operator Overloading......................................................................................................................................133
Streaming Operators (pack/unpack)................................................................................................................133
Conditional Operator.......................................................................................................................................134
Inside Operator................................................................................................................................................134
Constraint Block Operators.............................................................................................................................135
Behavioral Statements and Control Flow................................................................................................................136
Selection Statements.......................................................................................................................................136
Priority and Unique Keywords...................................................................................................................136
Set Membership Case Statement.............................................................................................................136
Pattern Matching.......................................................................................................................................137
Loop and Jump Statements.............................................................................................................................138
Loop Statements.......................................................................................................................................138
do ... while Loop..................................................................................................................................138
for Loop Enhancements......................................................................................................................138
foreach Loop.......................................................................................................................................138
Jump Statements......................................................................................................................................139
Final Blocks.....................................................................................................................................................140
Example....................................................................................................................................................140
Event and Level Control..................................................................................................................................141
iff Qualifier.................................................................................................................................................141
Sequence Events......................................................................................................................................141
Level-sensitive sequence controls............................................................................................................141
Event Control on Dynamic Class Members.....................................................................................................142
Waiting on a non-event Property...............................................................................................................142
iv
Table of Contents
Behavioral Statements and Control Flow
Waiting on an Event Property...................................................................................................................142
Waiting on a Method.................................................................................................................................143
Other Statements............................................................................................................................................144
Enhancement to Assignments Statements...............................................................................................144
Named Blocks...........................................................................................................................................144
Statements Labels....................................................................................................................................144
Disable Statement.....................................................................................................................................145
Processes....................................................................................................................................................................146
Always Processes...........................................................................................................................................146
always_comb and always_latch................................................................................................................146
always_ff...................................................................................................................................................146
Parallel fork-join Blocks...................................................................................................................................147
Process Control...............................................................................................................................................148
wait fork.....................................................................................................................................................148
disable fork................................................................................................................................................148
Class process..................................................................................................................................................150
Process Methods......................................................................................................................................150
Constrained Random Value Generation...................................................................................................................152
Overview..........................................................................................................................................................152
Rand, randc Modifiers.....................................................................................................................................153
Rand Modifier............................................................................................................................................153
Randc Modifier..........................................................................................................................................153
Disabling Random Variables - rand_mode...............................................................................................153
Random Variables...........................................................................................................................................156
Random Integral Types.............................................................................................................................156
Unpacked Arrays.......................................................................................................................................156
Dynamic Arrays.........................................................................................................................................157
Queues......................................................................................................................................................158
Associative Arrays.....................................................................................................................................158
Randomized Class Objects.......................................................................................................................159
Random Unpacked Structures..................................................................................................................159
Constraints Block.............................................................................................................................................161
External Constraint Blocks........................................................................................................................161
Constraint Inheritance...............................................................................................................................162
Operators..................................................................................................................................................162
Set Membership..................................................................................................................................163
Implication...........................................................................................................................................163
Distribution..........................................................................................................................................164
if-else Constraints...............................................................................................................................164
Iterative Constraints............................................................................................................................164
Global Constraints.....................................................................................................................................164
Variable Ordering......................................................................................................................................165
Static Constraint Blocks............................................................................................................................166
Function Calls in Constraints....................................................................................................................166
Limitations...........................................................................................................................................167
Controlling Constraints - constraint_mode................................................................................................167
Constraint Guards.....................................................................................................................................168
Debugging Constraints..............................................................................................................................169
Randomization Methods..................................................................................................................................170
Randomize Method...................................................................................................................................170
Inline Constraints................................................................................................................................170
In-line Random Variable Control.........................................................................................................171
Table of Contents
Constrained Random Value Generation
Inline Constraint Check.......................................................................................................................171
local:: Scope Resolution.....................................................................................................................172
Restricted inline constraint block........................................................................................................172
Pre_randomize and post_randomize Methods.........................................................................................173
Randomization of Scope Variables std::randomize().......................................................................................174
Syntax.......................................................................................................................................................174
Randomization of Scope Variables std::randomize() with Constraints.....................................................174
Extensions to std::randomize()..................................................................................................................174
System Functions and Methods......................................................................................................................176
$urandom()................................................................................................................................................176
$urandom_range()....................................................................................................................................176
srandom()..................................................................................................................................................176
get_randstate()..........................................................................................................................................176
set_randstate()..........................................................................................................................................177
$get_sv_seed............................................................................................................................................177
$get_random_seed...................................................................................................................................177
Random Weighted Case.................................................................................................................................178
Random Sequence Generation.......................................................................................................................179
Production Statements..............................................................................................................................179
Aborting Productions.................................................................................................................................180
Interleaving Productions............................................................................................................................181
Value Passing between Productions.........................................................................................................182
Random Stability.............................................................................................................................................184
Initialization of The Random Number Generator.......................................................................................184
Thread Stability.........................................................................................................................................184
Object Stability..........................................................................................................................................184
Manual Seeding........................................................................................................................................184
Example 1...........................................................................................................................................184
Example 2...........................................................................................................................................185
Maintaining Random Stability....................................................................................................................185
Changes in The Project Hierarchy......................................................................................................185
Rearrangement of The Code..............................................................................................................186
Code Execution Order........................................................................................................................187
Changes within Object Declarations...................................................................................................187
Preventing Random Stability Loss......................................................................................................187
Interprocess Synchronization...................................................................................................................................188
Semaphores....................................................................................................................................................188
Semaphore Methods.................................................................................................................................188
Mailboxes........................................................................................................................................................190
Mailbox Methods.......................................................................................................................................191
Parameterized Mailboxes..........................................................................................................................192
Non-parameterized Mailboxes..................................................................................................................192
Events..............................................................................................................................................................193
Triggering an Event...................................................................................................................................193
Waiting for an Event..................................................................................................................................193
triggered Property.....................................................................................................................................193
wait_order()...............................................................................................................................................193
Merging Events.........................................................................................................................................194
Reclaiming Events....................................................................................................................................194
Event Comparison.....................................................................................................................................194
vi
Table of Contents
Clocking Blocks..........................................................................................................................................................196
Clocking Block Declaration..............................................................................................................................196
Clocking Block Syntax...............................................................................................................................196
Example....................................................................................................................................................196
Clocking Block Scope and Lifetime...........................................................................................................197
Input and Output Skews..................................................................................................................................198
Input Sampling..........................................................................................................................................198
Cycle Delay Operator......................................................................................................................................199
Syntax.......................................................................................................................................................199
Example..............................................................................................................................................199
Default Clocking..............................................................................................................................................200
Events and Drives...........................................................................................................................................201
Clocking Block Events...............................................................................................................................201
Synchronous Drives..................................................................................................................................201
Clocking Properties.........................................................................................................................................202
Program.......................................................................................................................................................................203
$exit Task........................................................................................................................................................203
Anonymous Programs.....................................................................................................................................203
Example....................................................................................................................................................204
Assertions...................................................................................................................................................................205
Assertion Evaluation Model.............................................................................................................................205
Example....................................................................................................................................................205
Assertions Building Blocks..............................................................................................................................206
Overview...................................................................................................................................................206
Keywords..................................................................................................................................................206
List of Keywords.................................................................................................................................206
Identifiers...................................................................................................................................................207
Example..............................................................................................................................................207
Example 1....................................................................................................................................207
Example 2....................................................................................................................................207
Hierarchical References.....................................................................................................................207
Syntax..........................................................................................................................................207
Boolean Expressions................................................................................................................................207
Restrictions.........................................................................................................................................208
Built-in Functions.......................................................................................................................................208
Sampled value functions.....................................................................................................................208
Syntax..........................................................................................................................................208
$sampled......................................................................................................................................208
Example 1....................................................................................................................................209
Example 2....................................................................................................................................209
$rose, $fell, $stable......................................................................................................................209
Example 3....................................................................................................................................209
Example 4....................................................................................................................................210
$past............................................................................................................................................210
Example 5....................................................................................................................................210
System functions................................................................................................................................211
Example 6....................................................................................................................................211
Example 7....................................................................................................................................211
Sequences.......................................................................................................................................................212
Sequence Declaration...............................................................................................................................212
Syntax.................................................................................................................................................212
Sequence Instance.............................................................................................................................213
Example 1...........................................................................................................................................213
vii
Table of Contents
Assertions
Parameterized Sequences.................................................................................................................214
Untyped Arguments.....................................................................................................................214
Example 2..............................................................................................................................214
Typed Arguments.........................................................................................................................214
Example 3..............................................................................................................................215
Example 4..............................................................................................................................215
Example 5..............................................................................................................................215
Local Variable Formal Arguments................................................................................................216
Example 6..............................................................................................................................216
Sequence Operators.................................................................................................................................216
Syntax.................................................................................................................................................217
Sequence Operator Precedence...............................................................................................................217
Cycle Delay Operator ##...........................................................................................................................218
Syntax.................................................................................................................................................218
Examples............................................................................................................................................218
Example 1....................................................................................................................................218
Example 2....................................................................................................................................219
Example 3....................................................................................................................................219
Repetitions................................................................................................................................................219
Syntax.................................................................................................................................................219
Consecutive Repetition.......................................................................................................................220
Examples............................................................................................................................................220
Example 1....................................................................................................................................220
Example 2....................................................................................................................................221
Example 3....................................................................................................................................221
Example 4....................................................................................................................................222
Example 5....................................................................................................................................222
Nonconsecutive Repetition.................................................................................................................222
Example 6....................................................................................................................................222
Example 7....................................................................................................................................223
Goto Repetition...................................................................................................................................224
Example 8....................................................................................................................................224
And operator.............................................................................................................................................224
Syntax.................................................................................................................................................225
Example 1...........................................................................................................................................225
Intersect Operator.....................................................................................................................................225
Syntax.................................................................................................................................................226
Example..............................................................................................................................................226
Or Operator...............................................................................................................................................226
Syntax.................................................................................................................................................226
Example..............................................................................................................................................227
Example 1....................................................................................................................................227
Example 2....................................................................................................................................227
Throughout Operator.................................................................................................................................227
Syntax.................................................................................................................................................228
Example..............................................................................................................................................228
Within Operator.........................................................................................................................................228
Syntax.................................................................................................................................................228
Examples............................................................................................................................................229
First_match Operator................................................................................................................................229
Example..............................................................................................................................................229
End Point of a Sequence..........................................................................................................................230
Syntax.................................................................................................................................................231
Example..............................................................................................................................................231
viii
Table of Contents
Assertions
End Point of a Sequence in Multiclock Context........................................................................................232
Syntax.................................................................................................................................................232
Example..............................................................................................................................................232
Using Dynamic Variables in a Sequence..................................................................................................232
Assertion Variables Declared in a Named Sequence or Property......................................................233
Declaration Syntax.......................................................................................................................233
Assignment Syntax......................................................................................................................233
Local Variable Flow out Rules............................................................................................................234
Calling Subroutines on Match of a Sequence...........................................................................................235
Properties........................................................................................................................................................236
Property Declaration.................................................................................................................................236
Syntax.................................................................................................................................................236
Example 1...........................................................................................................................................236
Property Instance................................................................................................................................237
Example 2....................................................................................................................................237
Reset Expression................................................................................................................................237
Example 3....................................................................................................................................238
Parameterized Properties...................................................................................................................238
Untyped Arguments.....................................................................................................................239
Example 4..............................................................................................................................239
Typed Arguments.........................................................................................................................240
Example 5..............................................................................................................................240
Local Variable Formal Arguments................................................................................................240
Property Operators....................................................................................................................................240
Syntax.................................................................................................................................................240
Property Operator Precedence.................................................................................................................241
Not Operator.............................................................................................................................................241
Syntax.................................................................................................................................................241
Example..............................................................................................................................................241
And Operator.............................................................................................................................................242
Syntax.................................................................................................................................................242
Example..............................................................................................................................................242
Or Operator...............................................................................................................................................243
Syntax.................................................................................................................................................243
Example..............................................................................................................................................243
Implication Operators................................................................................................................................243
Syntax.................................................................................................................................................243
Examples............................................................................................................................................244
Example 1....................................................................................................................................244
Example 2....................................................................................................................................244
Implies Operator........................................................................................................................................245
Syntax.................................................................................................................................................245
Example..............................................................................................................................................245
iff Property.................................................................................................................................................247
Syntax.................................................................................................................................................247
Example..............................................................................................................................................247
Followed-by Property................................................................................................................................247
Syntax.................................................................................................................................................247
Examples............................................................................................................................................248
always, nexttime, and eventually Properties.............................................................................................248
always Property..................................................................................................................................248
Syntax..........................................................................................................................................248
Example.......................................................................................................................................249
nexttime Property................................................................................................................................249
ix
Table of Contents
Assertions
Syntax..........................................................................................................................................249
Example.......................................................................................................................................250
eventually Property.............................................................................................................................251
Syntax..........................................................................................................................................251
Example.......................................................................................................................................251
If Else Statement.......................................................................................................................................252
Example..............................................................................................................................................252
Case Statement........................................................................................................................................252
Syntax.................................................................................................................................................252
Example..............................................................................................................................................253
Recursive Properties.................................................................................................................................253
Abort Properties........................................................................................................................................253
Immediate Assertions......................................................................................................................................255
Syntax.......................................................................................................................................................255
Examples..................................................................................................................................................255
Concurrent Assertions.....................................................................................................................................257
Overview...................................................................................................................................................257
Syntax.................................................................................................................................................257
Assert Statement.......................................................................................................................................257
Syntax.................................................................................................................................................258
Example..............................................................................................................................................258
Cover Statements.....................................................................................................................................258
Syntax.................................................................................................................................................258
Example..............................................................................................................................................259
Embedding Concurrent Assertions in Procedural Code............................................................................260
Example..............................................................................................................................................260
Vacuity Feature.........................................................................................................................................261
Clocks..............................................................................................................................................................263
Examples..................................................................................................................................................263
Example 1...........................................................................................................................................263
Example 2...........................................................................................................................................263
Example 3...........................................................................................................................................263
Example 4...........................................................................................................................................264
Multiclock Support...........................................................................................................................................265
Multiclock sequences................................................................................................................................265
Example 1...........................................................................................................................................265
Multiclock properties.................................................................................................................................265
Example 2...........................................................................................................................................266
Encapsulating Assertions in Design Units.......................................................................................................267
Example....................................................................................................................................................267
Example 1...........................................................................................................................................267
Example 2...........................................................................................................................................268
Binding Assertions to Modules or Instances....................................................................................................269
Syntax.......................................................................................................................................................269
Example....................................................................................................................................................269
Binding to Specific Instance......................................................................................................................270
Example 1...........................................................................................................................................270
Example 2...........................................................................................................................................271
Binding SystemVerilog Assertions to VHDL..............................................................................................272
Example 1...........................................................................................................................................272
Expect Statement............................................................................................................................................274
Table of Contents
Coverage.....................................................................................................................................................................275
Overview..........................................................................................................................................................275
Covergroup......................................................................................................................................................276
Using Covergroups in Classes..................................................................................................................277
Coverage Points..............................................................................................................................................278
Specifying Bins for Values........................................................................................................................278
Wildcard Specification for Coverage Point Bins........................................................................................279
Specifying Bins for Transitions..................................................................................................................279
Limitations...........................................................................................................................................280
Automatic Bin Creation for Coverage Points.............................................................................................280
Cross Coverage...............................................................................................................................................281
Specifying Bins for Cross Coverage.........................................................................................................281
Coverage Options............................................................................................................................................282
Instance-specific Options..........................................................................................................................282
Type Options.............................................................................................................................................283
Coverage Methods..........................................................................................................................................285
Overriding build-in sample method...........................................................................................................285
Coverage System Tasks and Functions..........................................................................................................287
The Structure of option and type_option Members..........................................................................................288
Coverage Computation....................................................................................................................................289
Coverpoint Coverage Computation...........................................................................................................289
Cross Coverage Computation...................................................................................................................290
Type Coverage Computation....................................................................................................................290
Hierarchy.....................................................................................................................................................................292
Packages.........................................................................................................................................................292
Utilizing Package Contents.......................................................................................................................292
Referencing Package Contents with Scope Operator........................................................................293
Importing Package Contents..............................................................................................................293
Exporting Previously Imported Items..................................................................................................294
Compilation Unit and Top-level Instance.........................................................................................................296
Compilation Unit........................................................................................................................................296
Example..............................................................................................................................................296
Scoping Rules.....................................................................................................................................296
Top-level Instance.....................................................................................................................................297
Example..............................................................................................................................................297
Nested and Extern Modules............................................................................................................................298
Nested Modules........................................................................................................................................298
Binding PSL Units to Nested Modules................................................................................................298
Extern Modules.........................................................................................................................................298
Ports Declarations and Mapping.....................................................................................................................300
Ports Declarations.....................................................................................................................................300
List of Port Expressions......................................................................................................................301
Ports Mapping...........................................................................................................................................301
Implicit Mapping by Name..................................................................................................................301
Implicit Mapping by Wildcard..............................................................................................................301
Parameters in Hierarchical Path Name...........................................................................................................303
Timeunit and Timeprecision.............................................................................................................................304
Configurations.................................................................................................................................................305
Example....................................................................................................................................................305
Important Notes.........................................................................................................................................305
Type Parameters in Parameterized Design Elements.....................................................................................306
xi
Table of Contents
Interfaces.....................................................................................................................................................................307
Interface Declaration.......................................................................................................................................307
Interface Ports.................................................................................................................................................308
Example....................................................................................................................................................308
Modports..........................................................................................................................................................309
Modport Expressions................................................................................................................................309
Example..............................................................................................................................................310
Clocking Blocks and Modports..................................................................................................................310
Tasks and Function in Interfaces.....................................................................................................................311
Tasks and Functions in Modports.............................................................................................................311
Task Export in Modport.............................................................................................................................312
Multiple Tasks Exports..............................................................................................................................312
Parameterized Interfaces................................................................................................................................313
Example....................................................................................................................................................313
Interfaces and Specify Blocks.........................................................................................................................314
Virtual Interfaces..............................................................................................................................................315
Syntax.......................................................................................................................................................315
Virtual interfaces and clocking blocks.......................................................................................................316
Virtual interface modports and clocking blocks.........................................................................................317
System Tasks and Functions....................................................................................................................................318
Display Tasks and Functions...........................................................................................................................318
Overview...................................................................................................................................................318
$display system task...........................................................................................................................320
Example.......................................................................................................................................320
$sformat system task..........................................................................................................................320
Syntax..........................................................................................................................................320
Example.......................................................................................................................................321
$sformatf system function...................................................................................................................321
Syntax..........................................................................................................................................321
Example.......................................................................................................................................321
$psprintf function................................................................................................................................321
Syntax..........................................................................................................................................321
Example.......................................................................................................................................322
Printing Aggregates Using %p and %0p Formats.....................................................................................322
Arrays.................................................................................................................................................322
Structures...........................................................................................................................................323
Packed Unions....................................................................................................................................323
Class Handles.....................................................................................................................................324
Limiting Output with %0p.............................................................................................................325
Circular References.....................................................................................................................325
Truncating %p Field.....................................................................................................................326
Default Mode......................................................................................................................................326
Conversion Functions......................................................................................................................................328
Data Query Functions......................................................................................................................................329
$bits Function............................................................................................................................................329
$typename Function..................................................................................................................................329
$isunbounded Function.............................................................................................................................329
Array Query Functions.....................................................................................................................................330
Severity System Tasks....................................................................................................................................331
Example....................................................................................................................................................331
Assertion Control System Tasks......................................................................................................................332
Assertion Action Control System Tasks...........................................................................................................333
Example 1.................................................................................................................................................334
Example 2.................................................................................................................................................334
xii
Table of Contents
System Tasks and Functions
Example 3.................................................................................................................................................335
Assertion System Functions............................................................................................................................336
Random Number System Functions................................................................................................................337
Enhancements to Verilog System Tasks.........................................................................................................338
$readmem and $writemem Tasks...................................................................................................................340
$readmemb and $readmemh Tasks Enhancement..................................................................................340
$writememb and $writememh Tasks........................................................................................................340
Syntax.................................................................................................................................................340
Using Multidimensional Unpacked Arrays with $readmem and $writemem Tasks...................................340
File Format for Multidimensional Unpacked Arrays..................................................................................340
Miscellaneous Tasks and Functions................................................................................................................341
Syntax.......................................................................................................................................................341
Example....................................................................................................................................................341
Compiler Directives....................................................................................................................................................342
`define macros.................................................................................................................................................342
`include............................................................................................................................................................342
`begin_keywords and `end_keywords.............................................................................................................343
DPI................................................................................................................................................................................344
Overview..........................................................................................................................................................344
Tasks and Functions.................................................................................................................................344
Two Layers of DPI...........................................................................................................................................345
DPI SystemVerilog Layer..........................................................................................................................345
DPI Foreign Language Layer....................................................................................................................345
C/C++ and SystemVerilog Data Types............................................................................................................346
Open Arrays..............................................................................................................................................347
Enumerated Types....................................................................................................................................348
Ref Arguments..........................................................................................................................................348
Imported Tasks and Functions........................................................................................................................349
Function Result Type................................................................................................................................350
Formal Argument Types............................................................................................................................350
Function Arguments............................................................................................................................350
Pure and Context Properties.....................................................................................................................350
Miscellaneous...........................................................................................................................................351
Memory Management.........................................................................................................................351
Reentrancy of Imported Tasks............................................................................................................351
C++ Exceptions..................................................................................................................................351
Hierarchical Names on C++ Side.......................................................................................................351
Exported Tasks and Functions........................................................................................................................352
Name Space of Imported and Exported Functions..........................................................................................353
Disabling DPI Tasks and Functions.................................................................................................................354
xiii
Overview
SystemVerilog is a group of extensions to the Verilog HDL originally developed and approved by Accellera and then
standardized by IEEE.
SystemVerilog extends Verilog into the system-level space and the verification space.
This reference guide has been created based on the two revisions of IEEE Standard for SystemVerilog - Unified
Hardware Design, Specification, and Verification Language: IEEE Std 1800-2005 and IEEE Std 1800-2009.
Keywords
The list below shows Verilog and SystemVerilog keywords marked with two distinct colors. The Verilog-HDL keywords
are distinguished in blue while reserved keywords for SystemVerilog are displayed in black.
accept_on
alias
always
always_comb
always_ff
always_latch
and
assert
assign
assume
automatic
before
begin
bind
bins
binsof
bit
break
buf
bufif0
bufif1
byte
case
casex
casez
cell
chandle
checker
class
clocking
cmos
config
const
constraint
context
continue
cover
covergroup
coverpoint
cross
deassign
default
defparam
design
disable
dist
do
edge
else
end
endcase
endchecker
endclass
endclocking
endconfig
endfunction
endprimitive
endprogram
endproperty
endsequence
endspecify
endtable
endtask
enum
event
eventually
expect
export
extends
extern
final
first_match
for
force
foreach
forever
fork
forkjoin
function
generate
genvar
global
highz0
highz1
if
iff
ifnone
ignore_bins
illegal_bins
implies
import
incdir
include
initial
inout
input
inside
instance
int
integer
interface
intersect
join
join_any
join_none
large
let
liblist
library
local
localparam
logic
module
nand
negedge
new
nexttime
nmos
nor
noshowcancelled
not
notif0
notif1
null
or
output
package
packed
parameter
pmos
posedge
primitive
priority
program
property
protected
pull0
pull1
pulldown
pullup
pulsestyle_ondetect
pulsestyle_onevent
pure
rand
randc
randcase
randsequence
rcmos
real
realtime
ref
reg
reject_on
release
repeat
restrict
return
rnmos
rpmos
rtran
rtranif0
rtranif1
s_always
scalared
sequence
s_eventually
shortint
shortreal
specify
specparam
static
string
strong
strong0
strong1
struct
s_until
s_until_with
super
supply0
supply1
sync_accept_on
sync_reject_on
table
tagged
task
this
throughout
time
timeprecision
timeunit
tran
tranif0
tranif1
tri
tri0
tri1
triand
trior
trireg
type
typedef
union
unique
unique0
unsigned
until
until_with
untyped
use
uwire
var
vectored
virtual
void
wait
wait_order
wand
weak
weak0
weak1
while
wildcard
wire
SystemVerilog Reference
endgenerate
endgroup
endinterface
endmodule
endpackage
longint
macromodule
matches
medium
modport
Keywords
showcancelled
signed
small
s_nexttime
solve
with
within
wor
xnor
xor
Formal Syntax
library_declaration
include_statement
config_declaration
;
module_declaration
udp_declaration
interface_declaration
program_declaration
package_declaration
{ attribute_instance } package_item
{ attribute_instance } bind_directive
config_declaration
|
|
module_nonansi_header
[ timeunits_declaration ]
{ module_item }
endmodule [ : module_identifier ]
module_ansi_header
[ timeunits_declaration ]
{ non_port_module_item }
endmodule [ : module_identifier ]
{ attribute_instance } module_keyword [ lifetime ] module_identifier ( .* ) ;
[ timeunits_declaration ]
{ module_item }
endmodule [ : module_identifier ]
extern module_nonansi_header
extern module_ansi_header
SystemVerilog Reference
Formal Syntax
interface_declaration ::=
|
|
interface_nonansi_header
[ timeunits_declaration ]
{ interface_item }
endinterface [ : interface_identifier ]
interface_ansi_header
[ timeunits_declaration ]
{ non_port_interface_item }
endinterface [ : interface_identifier ]
{ attribute_instance } interface interface_identifier ( .* ) ;
[ timeunits_declaration ]
{ interface_item }
endinterface [ : interface_identifier ]
extern interface_nonansi_header
extern interface_ansi_header
|
|
program_nonansi_header
[ timeunits_declaration ]
{ program_item }
endprogram [ : program_identifier ]
program_ansi_header
[ timeunits_declaration ]
{ non_port_program_item }
endprogram [ : program_identifier ]
{ attribute_instance } program program_identifier ( .* ) ;
[ timeunits_declaration ]
{ program_item }
endprogram [ : program_identifier ]
extern program_nonansi_header
extern program_ansi_header
SystemVerilog Reference
Formal Syntax
{
{
{
{
{
attribute_instance
attribute_instance
attribute_instance
attribute_instance
attribute_instance
}
}
}
}
}
inout_declaration
input_declaration
output_declaration
ref_declaration
interface_port_declaration
module_or_generate_item_declaration
interface_instantiation
program_instantiation
concurrent_assertion_item
bind_directive
continuous_assign
net_alias
initial_construct
final_construct
always_construct
loop_generate_construct
conditional_generate_construct
{
{
{
{
{
attribute_instance
attribute_instance
attribute_instance
attribute_instance
attribute_instance
module_or_generate_item_declaration ::=
|
|
|
non_port_module_item ::=
|
|
|
|
|
}
}
}
}
}
parameter_override
gate_instantiation
udp_instantiation
module_instantiation
module_common_item
package_or_generate_item_declaration
genvar_declaration
clocking_declaration
default clocking clocking_identifier ;
generate_region
module_or_generate_item
specify_block
{ attribute_instance } specparam_declaration
program_declaration
module_declaration
SystemVerilog Reference
Formal Syntax
| interface_declaration
| timeunits_declaration
default_clause liblist_clause ;
inst_clause liblist_clause ;
inst_clause use_clause ;
cell_clause liblist_clause ;
cell_clause use_clause ;
generate_region
interface_or_generate_item
program_declaration
interface_declaration
timeunits_declaration
SystemVerilog Reference
Formal Syntax
| non_port_program_item
non_port_program_item ::=
|
|
|
|
|
|
{ attribute_instance }
{ attribute_instance }
{ attribute_instance }
{ attribute_instance }
{ attribute_instance }
{ attribute_instance }
program_generate_item
continuous_assign
module_or_generate_item_declaration
initial_construct
final_construct
concurrent_assertion_item
timeunits_declaration
{
{
{
{
{
{
;
attribute_instance
attribute_instance
attribute_instance
attribute_instance
attribute_instance
attribute_instance
}
}
}
}
}
}
class_property
class_method
class_constraint
class_declaration
timeunits_declaration
covergroup_declaration
{ method_qualifier } task_declaration
{ method_qualifier } function_declaration
extern { method_qualifier } method_prototype ;
{ method_qualifier } class_constructor_declaration
extern { method_qualifier } class_constructor_prototype
SystemVerilog Reference
Formal Syntax
| foreach ( array_identifier [ loop_variables ] ) constraint_set
SystemVerilog Reference
Formal Syntax
10
SystemVerilog Reference
Formal Syntax
{ :: class_identifier [ parameter_value_assignment ] }
integer_type ::= integer_vector_type | integer_atom_type
integer_atom_type ::= byte | shortint | int | longint | integer | time
integer_vector_type ::= bit | logic | reg
non_integer_type ::= shortreal | real | realtime
net_type ::=
|
|
|
|
|
|
|
|
|
|
|
supply0
supply1
tri
triand
trior
trireg
tri0
tri1
uwire
wire
wand
wor
integer_type
non_integer_type
ps_type_identifier
ps_parameter_identifier
11
SystemVerilog Reference
delay_value ::=
|
|
|
Formal Syntax
unsigned_number
real_number
ps_identifier
time_literal
12
SystemVerilog Reference
Formal Syntax
variable_decl_assignment ::=
|
|
|
unsized_dimension
unpacked_dimension
associative_dimension
queue_dimension
13
SystemVerilog Reference
Formal Syntax
{
{
{
{
attribute_instance
attribute_instance
attribute_instance
attribute_instance
}
}
}
}
data_declaration
local_parameter_declaration
parameter_declaration ;
overload_declaration
14
SystemVerilog Reference
Formal Syntax
sequence_expr
( property_expr )
not property_expr
property_expr or property_expr
property_expr and property_expr
sequence_expr |-> property_expr
sequence_expr |=> property_expr
if ( expression_or_dist ) property_expr [ else property_expr ]
property_instance
clocking_event property_expr
cycle_delay_range ::=
|
|
|
##
##
##
##
integral_number
identifier
( constant_expression )
[ cycle_delay_const_range_expression ]
15
SystemVerilog Reference
Formal Syntax
| subroutine_call
sequence_instance ::= ps_sequence_identifier [ ( [ list_of_arguments ] ) ]
formal_list_item ::= formal_identifier [ = actual_arg_expr ]
list_of_formals ::= formal_list_item {, formal_list_item }
actual_arg_expr ::= event_expression | $
boolean_abbrev ::= consecutive_repetition
| non_consecutive_repetition
| goto_repetition
sequence_abbrev ::= consecutive_repetition
consecutive_repetition ::= [* const_or_range_expression ]
non_consecutive_repetition ::= [= const_or_range_expression ]
goto_repetition ::= [-> const_or_range_expression ]
const_or_range_expression ::= constant_expression
| cycle_delay_const_range_expression
cycle_delay_const_range_expression ::= constant_expression : constant_expression
| constant_expression : $
expression_or_dist ::= expression [ dist { dist_list } ]
assertion_variable_declaration ::= var_data_type list_of_variable_identifiers ;
A.2.11 Covergroup declarations
covergroup_declaration ::= covergroup covergroup_identifier [ ( [ tf_port_list ] ) ] [ coverage_event ];
{ coverage_spec_or_option }
endgroup [ : covergroup_identifier ]
coverage_spec_or_option ::= {attribute_instance} coverage_spec | {attribute_instance} coverage_option;
coverage_option ::= option.member_identifier = expression | type_option.member_identifier = expression
coverage_spec ::= cover_point | cover_cross
coverage_event ::= clocking_event | @@( block_event_expression )
block_event_expression ::= block_event_expression or block_event_expression
| begin hierarchical_btf_identifier
| end hierarchical_btf_identifier
hierarchical_btf_identifier ::= hierarchical_tf_identifier
| hierarchical_block_identifier
| hierarchical_identifier [ class_scope ] method_identifier
cover_point ::= [ cover_point_identifier : ] coverpoint expression [ iff ( expression ) ] bins_or_empty
bins_or_empty ::= { {attribute_instance} { bins_or_options ; } }
| ;
bins_or_options ::= coverage_option
| [ wildcard ] bins_keyword bin_identifier [ [ [ expression ] ] ] = { open_range_list }
[ iff ( expression ) ]
| [ wildcard ] bins_keyword bin_identifier [ [ ] ] = trans_list
[ iff ( expression ) ]
| bins_keyword bin_identifier [ [ [ expression ] ] ] = default
[ iff ( expression ) ]
16
SystemVerilog Reference
Formal Syntax
trans_item
trans_item [ [* repeat_range ] ]
trans_item [ [-> repeat_range ] ]
trans_item [ [= repeat_range ] ]
select_condition
! select_condition
select_expression && select_expression
select_expression || select_expression
( select_expression )
17
SystemVerilog Reference
Formal Syntax
18
SystemVerilog Reference
Formal Syntax
19
SystemVerilog Reference
Formal Syntax
20
SystemVerilog Reference
Formal Syntax
output_symbol ::= 0 | 1 | x | X
level_symbol ::= 0 | 1 | x | X | ? | b | B
edge_symbol ::= r | R | f | F | p | P | n | N | *
A.5.4 UDP instantiation
udp_instantiation ::= udp_identifier [ drive_strength ] [ delay2 ] udp_instance {, udp_instance } ;
udp_instance ::= [ name_of_instance ] ( output_terminal, input_terminal {, input_terminal } )
A.6 Behavioral statements
A.6.1 Continuous assignment and net alias statements
continuous_assign ::= assign [ drive_strength ] [ delay3 ] list_of_net_assignments ;
| assign [ delay_control ] list_of_variable_assignments ;
list_of_net_assignments ::= net_assignment {, net_assignment }
list_of_variable_assignments ::= variable_assignment {, variable_assignment }
net_alias ::= alias net_lvalue = net_lvalue { = net_lvalue } ;
net_assignment ::= net_lvalue = expression
A.6.2 Procedural blocks and assignments
initial_construct ::= initial statement_or_null
always_construct ::= always_keyword statement
always_keyword ::= always | always_comb | always_latch | always_ff
final_construct ::= final function_statement
blocking_assignment ::= variable_lvalue = delay_or_event_control expression
| hierarchical_dynamic_array_variable_identifier = dynamic_array_new
| [ implicit_class_handle . | class_scope | package_scope ]
hierarchical_variable_identifier
select = class_new | operator_assignment
operator_assignment ::= variable_lvalue assignment_operator expression
assignment_operator ::= = | += | -= | *= | /= | %= | &= | |= | ^= | <<= | >>= | <<<= | >>>=
nonblocking_assignment ::= variable_lvalue <= [ delay_or_event_control ] expression
procedural_continuous_assignment ::= assign variable_assignment
| deassign variable_lvalue
| force variable_assignment
| force net_assignment
| release variable_lvalue
| release net_lvalue
variable_assignment ::= variable_lvalue = expression
A.6.3 Parallel and sequential blocks
action_block ::= statement_or_null
| [ statement ] else statement_or_null
seq_block ::= begin [ : block_identifier ]
21
SystemVerilog Reference
Formal Syntax
{ block_item_declaration }
{ statement_or_null }
end [ : block_identifier ]
par_block ::= fork [ : block_identifier ]
{ block_item_declaration }
{ statement_or_null }
join_keyword [ : block_identifier ]
join_keyword ::= join | join_any | join_none
A.6.4 Statements
statement_or_null ::= statement | { attribute_instance } ;
statement ::= [ block_identifier : ] { attribute_instance } statement_item
statement_item ::=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
blocking_assignment ;
nonblocking_assignment ;
procedural_continuous_assignment ;
case_statement
conditional_statement
inc_or_dec_expression ;
subroutine_call_statement
disable_statement
event_trigger
loop_statement
jump_statement
par_block
procedural_timing_control_statement
seq_block
wait_statement
procedural_assertion_statement
clocking_drive ;
randsequence_statement
randcase_statement
expect_property_statement
@ hierarchical_event_identifier
@ ( event_expression )
@*
@ (*)
@ sequence_instance
event_expression ::=
|
|
|
22
SystemVerilog Reference
Formal Syntax
23
SystemVerilog Reference
Formal Syntax
24
SystemVerilog Reference
Formal Syntax
input [ clocking_skew ]
output [ clocking_skew ]
input [ clocking_skew ] output [ clocking_skew ]
inout
production_item
rs_code_block
rs_if_else
rs_repeat
rs_case
25
SystemVerilog Reference
Formal Syntax
specparam_declaration
pulsestyle_declaration
showcancelled_declaration
path_declaration
system_timing_check
26
SystemVerilog Reference
Formal Syntax
$setup_timing_check
$hold_timing_check
$setuphold_timing_check
$recovery_timing_check
27
SystemVerilog Reference
|
|
|
|
|
|
|
|
Formal Syntax
$removal_timing_check
$recrem_timing_check
$skew_timing_check
$timeskew_timing_check
$fullskew_timing_check
$period_timing_check
$width_timing_check
$nochange_timing_check
28
SystemVerilog Reference
Formal Syntax
expression
~ expression
expression == scalar_constant
expression === scalar_constant
expression != scalar_constant
expression !== scalar_constant
scalar_constant ::= 1'b0 | 1'b1 | 1'B0 | 1'B1 | 'b0 | 'b1 | 'B0 | 'B1 | 1 | 0
A.8 Expressions
A.8.1 Concatenations
concatenation ::= { expression {, expression } }
constant_concatenation ::= { constant_expression {, constant_expression } }
constant_multiple_concatenation ::= { constant_expression constant_concatenation }
module_path_concatenation ::= { module_path_expression {, module_path_expression } }
module_path_multiple_concatenation ::= { constant_expression module_path_concatenation }
multiple_concatenation ::= { expression concatenation }
streaming_concatenation ::= { stream_operator [ slice_size ] stream_concatenation }
stream_operator ::= >> | <<
slice_size ::= simple_type | constant_expression
29
SystemVerilog Reference
Formal Syntax
expression
expression : expression
expression +: expression
expression -: expression
empty_queue ::= { }
A.8.2 Subroutine calls
constant_function_call ::= function_subroutine_call
tf_call ::= ps_or_hierarchical_tf_identifier { attribute_instance } [ ( list_of_arguments ) ]
system_tf_call ::= system_tf_identifier [ ( list_of_arguments ) ]
| system_tf_identifier ( data_type [, expression ] )
subroutine_call ::=
|
|
|
tf_call
system_tf_call
method_call
randomize_call
30
SystemVerilog Reference
Formal Syntax
primary
unary_operator { attribute_instance } primary
inc_or_dec_expression | ( operator_assignment )
expression binary_operator { attribute_instance } expression
conditional_expression
inside_expression
tagged_union_expression
primary_literal
ps_parameter_identifier constant_select
specparam_identifier [ constant_range_expression ]
genvar_identifier
[ package_scope | class_scope ] enum_identifier
constant_concatenation
constant_multiple_concatenation
constant_function_call
( constant_mintypmax_expression )
constant_cast
constant_assignment_pattern_expression
type_reference
31
SystemVerilog Reference
|
|
|
|
primary ::=
|
|
|
|
|
|
|
|
|
|
|
|
|
Formal Syntax
module_path_concatenation
module_path_multiple_concatenation
function_subroutine_call
( module_path_mintypmax_expression )
primary_literal
[ implicit_class_handle . | class_scope | package_scope ] hierarchical_identifier select
empty_queue
concatenation
multiple_concatenation
function_subroutine_call
( mintypmax_expression )
cast
assignment_pattern_expression
streaming_concatenation
sequence_method_call
this
$
null
A.8.6 Operators
unary_operator ::= + | - | ! | ~ | & | ~& | | | ~| | ^ | ~^ | ^~
binary_operator ::= + | - | * | / | % | == | != | === | !== | ==? | !=? | && | || | **
| < | <= | > | >= | & | | | ^ | ^~ | ~^ | >> | << | >>> | <<<
inc_or_dec_operator ::= ++ | -unary_module_path_operator ::= ! | ~ | & | ~& | | | ~| | ^ | ~^ | ^~
binary_module_path_operator ::= == | != | && | || | & | | | ^ | ^~ | ~^
32
SystemVerilog Reference
Formal Syntax
A.8.7 Numbers
number ::= integral_number | real_number
integral_number ::= decimal_number | octal_number | binary_number | hex_number
decimal_number ::=
|
|
|
unsigned_number
[ size ] decimal_base unsigned_number
[ size ] decimal_base x_digit { _ }
[ size ] decimal_base z_digit { _ }
33
SystemVerilog Reference
Formal Syntax
34
SystemVerilog Reference
Formal Syntax
35
SystemVerilog Reference
Formal Syntax
36
Evaluation Model
The simulation of SystemVerilog language is based on a discrete event execution model. Processes can be evaluated
and have their own state. They are concurrently scheduled. They are sensitive to update events. Every change of a
net or a variable generates an event (an update event). An evaluation of a process also generates an event (an
evaluation event).
Except for events, an important aspect of the simulation is the simulation time. The simulator maintains the time value
to model the actual time in the design being simulated. The simplest simulation time unit is called a time slot. The time
slot is divided into several regions where events can be scheduled. In appropriate regions of a time slot different kinds
of events are executed. Dividing a time slot into ordered regions helps to provide predictable interactions between the
design and testbench code.
Regions Observed, Reactive and Re-inactive were added to the simulation model by IEEE 1800-2005. The remaining
regions correspond to the IEEE 1364-2005 simulation model.
Evaluation of property expressions is executed in the Observed region.
The pass/fail code from the assertion/cover action blocks is scheduled in the Reactive region of the
current time slot.
A #0 control delay specified in a program block schedules the process for resumption in the Re-inactive
region.
Sampling of signals used in sequences and properties expressions is executed in Preponed region. Sampling of
signals with #1step input skew (see Clocking Blocks chapter) is also executed in the Preponed region.
37
Literals
[7:0] a,b,c;
'0;
'X;
'z;
Real Literals
The default type is real for fixed-point format and exponent format. A cast can be used to convert literal real values
to the shortreal type.
shortreal'(1.23)
shortreal'(1.23e0)
Time Literals
Time literals specify absolute time values, independent of the module timescale. Time literals are constructed from an
integer number followed by the name of time unit (s, ms, us, ns, ps, fs) without an intervening space. Time literals are
interpreted as realtime values
realtime rt;
initial
rt = 340ps;
String Literals
The string literal is enclosed in quotes. The length of a string literal is not limited.
A string literal can be assigned to an unpacked array of bytes.
byte a [0:21] = "It's a string literal\n";
38
SystemVerilog Reference
Escape Sequence
Literals
Corresponding Character
\v
vertical tab
\f
form feed
\\
backslash (\)
\a
bell
\ddd
\xdd
Array Literals
Array literals are array assignment patterns or pattern expressions with constant member expressions. Nesting of
braces must follow the number of dimensions. Replicate operators can be nested.
int n[1:2][1:3] = '{'{0,1,2},'{3{4}}}; // same as '{'{0,1,2},'{4,4,4}}
int n[1:2][1:6] = '{2{'{3{4, 5}}}}; // same as '{'{4,5,4,5,4,5},'{4,5,4,5,4,5}}
Structure Literals
Structure literals are structure assignment patterns or pattern expressions with constant member expressions. A
structure literal must have a type. The type must be explicitly indicated with a prefix or implicitly indicated by an
assignment-like context.
typedef struct { logic a; shortint b; real c; } T;
T t1;
T t2 = '{1'b1, 22, 3.4};
NOTE: The construct is not supported in this release. Please contact Aldec Support to receive the latest status.
39
Attributes
The attributes are properties that can be specified during declaration of the SystemVerilog objects, statements and
groups of statements containing additional information for simulation and synthesis tools.
Syntax
The Syntax is as follows:
attribute_instance ::= (* attr_spec { , attr_spec } *)
attr_spec ::= attr_name [ = constant_expression ]
attr_name ::= identifier
The attributes can appear in SystemVerilog code as a prefix attached to: declarations, module instances, statements
and port connections. The attributes can appear in SystemVerilog code as a suffix attached to: operators and function
calls. The attribute type is determined by the type of the assigned value. If no value is assigned, the attribute type is
bit with a value of 1.
Examples
The performance_opt attribute is specified as a prefix for a block statement. No value is assigned so the attribute
type is bit of a value 1.
always @(clk) (* performance_opt *) begin
// ...
end
In the below example, there are two attributes specified for a port connection .port_a(var_a). It is allowed to
specify more than two parameters within the attribute (* ... *) delimiters. The parameters need to be followed by
commas.
mod2 UUT ( (* drive_Ts, mode="ctl" *) .port_a(var_a), .port_b(var_b), .port_c(var_c) );
The attributes pertaining to the same statement can be also specified within separate delimiters, as it is shown below.
(* no_skew = 0 *)
(* sys_clk = 1 *)
clocking clk_blk @(posedge clk);
// ...
endclocking
40
Data Types
Description
Language
shortint
SystemVerilog
(C-like)
int
SystemVerilog
(C-like)
longint
SystemVerilog
(C-like)
SystemVerilog
(C-like)
bit
SystemVerilog
(C-like)
logic
SystemVerilog
reg
Verilog
Verilog
Verilog
byte
integer
time
The 4-state types include zero, one, unknown (X) and high impedance (Z) values. The 2-state types include only zero
and one values. If a 4-state value is converted into a 2-state value, X and Z values are converted to zero.
In SystemVerilog, operators may be applied to 2-state values or to a mixture of 2-state and 4-state values. The result
is the same as if all values were treated as 4-state values and Verilog operators were applied. In most cases, if all
operand values are 2-state, the result is in the 2-state value set. The only exceptions involve operators where Verilog
produces an X result for operands in the 2-state value set, for example division by zero. (1/0 yields an X in the four
value set and 0 in the two value set.)
41
SystemVerilog Reference
Data Types
If an initial value is not specified then the event variable is initialized to a new synchronization object.
event strobe;
// A new event.
event strobe_1 = strobe; // strobe_1 is now an alias for strobe.
42
SystemVerilog Reference
event empty = null;
Data Types
// Empty event.
Classes
A class is a collection of data and a set of subroutines that operate on that data. A class can also be treated as a
specific data type. For more information about classes see Classes.
43
SystemVerilog Reference
Data Types
String Type
A string in SystemVerilog is an ordered collection of characters. The length of a string may vary during simulation. If a
string literal is assigned to a string variable during simulation, the size of the variable is adjusted so that neither the
literal is truncated nor the variable is padded with zeros.
A variable of type string is declared using the following syntax:
string str;
=
=
i
=
"another value";
{"concatenation", " of", " strings"};
= 5;
{i{"replication "}};
The indices of the string variable are numbered from 0 to N-1, where N is the length of the string. 0 corresponds to
the leftmost character in the string. A single character of a string variable is of type byte.
A string variable can be used in the $display statement, for example:
$display ("str = %s", str);
When the size of the variable where the string literal is assigned, is greater than the literal, the literal is left-padded
with zeros. When the literal is longer than the variable, the literal is truncated on the left.
reg [4*8-1:0] reg_1 = "string";
reg [4*8-1:0] reg_2 = "s";
The first declaration assigns value ring to variable reg_1. Note that the string is truncated on the left, not on the
right.
The second declaration assigns value s preceded with 0's (00000073h).
44
SystemVerilog Reference
Data Types
String Methods
SystemVerilog includes a number of special methods to work with strings. These methods use the built-in method
notation, i.e. they are invoked on the string object (see Example below).
Prototype
Returns the length of the string, i.e., the number of characters in the string.
Replaces the i-th character in string with the given integral value.
Compares str and s, like the ANSI C strcmp function with regard to
lexical ordering and return value, but the comparison is case insensitive.
task itoa(integer i)
task hextoa(integer i)
task octtoa(integer i)
task bintoa(integer i)
task realtoa(real r)
45
SystemVerilog Reference
Data Types
Example
string str = "aBc"; // declare string variables
string new_str;
initial begin
new_str = str.toupper();
new_str = str.tolower();
str.putc(0, "d");
str.putc(4, "d");
i = str.len();
j = str.getc(2);
k = str.icompare(new_str);
//
//
//
//
//
//
//
//
end
46
SystemVerilog Reference
Data Types
User-defined Type
SystemVerilog allows for defining new type using typedef construct as in C, for example:
typedef reg[15:0] bus;
Types can be defined outside the module context. Type definitions can be stored in a separate files and protected with
C-like include guards. For example:
`define _TYPES_VH
`ifdef _TYPES_VH
typedef integer number;
typedef real fraction;
`endif //_TYPES_VH
Forward declarations with an empty typedef statement are not allowed for enumeration values.
User-defined type identifiers have the same scoping rules as data identifiers, but the hierarchical reference to type
identifier is not allowed. References through ports to type identifiers defined within an interface are not considered
hierarchical and are allowed provided they are locally redefined before being used. This is shown in the example
below.
interface iface;
typedef integer number;
typedef real fraction;
//...
endinterface
module m( iface iface_i );
typedef iface_i.number number;
typedef iface_i.fraction fraction;
number x;
fraction z;
//...
endmodule
Interface iface contains a definition of two types: number and fraction. The interface is instantiated in module m
as iface_i. The two types are used in typedef statements; iface_i.number is redefined as number and
iface_i.fraction is redefined as fraction.
The typedef construct can be also used for class specialization.
class A #(int N = 1);
logic [N-1:0] a;
endclass
typedef A #(8) A8;
47
SystemVerilog Reference
Data Types
In the listing above, the typedef statement is used to declare two new types - A8 and A16 that are specializations of
class A.
48
SystemVerilog Reference
Data Types
Enumeration Types
SystemVerilog introduces the enumeration types. The example below shows how to declare variable rcvstate that
can be assigned either of the five enumerated values IDLE, SYNC, HEAD, DATA or CRC:
// declare variable rcvstate
enum {IDLE, SYNC, HEAD, DATA, CRC} rcvstate;
If the data type used with enumerated type in not explicitly declared the default type is int, as in the example above.
An enumeration encoding exceeding specified type range is illegal, as in the example below:
// Illegal enumeration encoding: hold
enum reg [1:0] {idle=2'b00, start=2'b01, hold=4'b1010, stop = 2'b11} states;
An enumerated type can be defined with the typedef construct, for example:
// declare type colors_t
typedef enum {red, yellow, green} colors_t;
// declare two variables of type colors_t
colors_t lightsRoadA, lightsRoadB;
The string representation of the given enumeration value can be read with the name method, for example:
enum {RED, GREEN, BLUE} color;
initial begin
color = GREEN;
$display ("== %s ==", color.name);
end
Behavior
Associates the next consecutive number with name.
name = C
name[N]
Generates N named constants in the sequence: name0, name1, ... name N-1. N must be a positive
integral number.
49
SystemVerilog Reference
Data Types
name[N]=C
Optionally, a constant can be assigned to the generated named constants to associate that
constant to the first generated named constant; subsequent generated named constants are
associated consecutive values. N must be a positive integral number.
name[N:M]
Creates a sequence of named constants starting with name N and incrementing or decrementing
until reaching named constant nameM. N and M must be nonnegative integral numbers.
Optionally, a constant can be assigned to the generated named constants to associate that
name[N:M]=C constant to the first generated named constants; subsequent generated named constants are
associated consecutive values. N and M must be nonnegative integral numbers.
Example
typedef enum {init=1, hold[2], count[4:6]=9,stop=12} fsm_states;
The enumerated type fsm_states assigns number 1 to enumerated constant init and creates two named
constants hold0 and hold1 and assigns values 2 and 3 to them. It also creates three named constants count4,
count5, and count6 and assigns values 9, 10 and 11 to them. Finally value 12 is assigned to the stop constant.
Elements of enumerated type variables can be used in numerical expressions. The value used in the expression is the
numerical value associated with the enumerated value.
Example
typedef enum {white=1, red=2, pink=3, yellow=4, blue=5,
orange=6, gray=7, violet=8} colors;
colors c;
int a,b;
initial begin
a = white + red; // integer value = 3 (pink)
b = blue;
c = colors'(a+b); // a+b=8 (violet)
end
Enumeration Methods
SystemVerilog introduces several methods to enable iterating over the values of enumerated types.
Prototype
Return Value
Returns the N-th next enumeration value (default is the next one)
starting from the current value of the given variable.
50
SystemVerilog Reference
function string name();
Data Types
Returns the string representation of the given enumeration value.
51
SystemVerilog Reference
Data Types
Structures
A structure is a way of grouping several variables. Structures are defined with the struct keyword, for example:
struct {
reg [0:3] preamble;
reg [0:7] addr;
reg [0:63] data;
reg [0:7] crc;
} packet;
The above example defines variable packet. Variable packet is a structure consisting of four fields: preamble,
addr, data, and crc.
Instead of defining a variable directly, you can first define a type using the typedef keyword and then use that type to
define the required variable, for example:
typedef struct {
reg [0:3] preamble;
reg [0:7] addr;
reg [0:63] data;
reg [0:7] crc;
} packet_t;
packet_t srcpacket;
packet_t dstpacket;
You can refer to structure fields (members) using the dot notation, for example:
srcpacket.addr = 8'h0F;
Packed Structures
A packed structure is declared by using keyword packed following keyword structure.
typedef struct packed {
reg [0:3] preamble;
reg [0:7] addr;
reg [0:63] data;
reg [0:7] crc;
} packet_t;
Only structures where all members are packed can be declared packed. Unpacked (noninteger) members such as
type real or unpacked arrays are not allowed.
All fields in a packed structure are packed together in memory without gaps. Consequently, a packed structure can be
treated as a vector of values and used as an operand in arithmetic and logical expressions.
52
SystemVerilog Reference
Data Types
Unpacked Structures
Unpacked structures are structures declared without the packed keyword that contain unpacked fields, such as real,
realtime, or unpacked arrays as shown in the example below:
struct {
real a;
reg [7:0] b;
reg [7:0] c [3:0];
} us;
This structure cannot be declared as packed because it contains two unpacked members: a real number and an array
with an unpacked dimension. (The unpacked dimensions of an array are specified by indexes following the array
identifier.)
Member Initialization
Unpacked structures, unlike packed structures, can contain default assignments to individual members, for example:
typedef struct {
reg a = 1'b1;
real b = 7.1;
reg [7:0]c = 8'hFF;
} s_t;
If an explicit initial assignment is made to an unpacked structure, than the initial values specified at type declaration
are ignored, for example:
s_t s = '{ 0'b1, 8.1, 8'hAA };
Structure s will be assigned values specified in the literal ('{ 0'b1, 8.1, 8'hAA }) rather than the values from
the declaration.
Assignment
SystemVerilog allows assignments not only to an individual structure member but also assignments to a structure as a
whole. This is shown in the listing below.
struct {
bit b;
53
SystemVerilog Reference
Data Types
real r;
} s1;
struct {
bit b2;
real r2;
} s2;
initial
s1 = s2;
Assigning one unpacked structure to another unpacked structure is allowed if the following restrictions are satisfied:
Structure members are of the same type.
Structure members have the same declaration order.
Note that member names need not match.
Limitations
Initialization in the typedef struct statement has no effect on structures declared before the struct type
is resolved. (Such declarations are possible when forward typedef's are used.
Initialization of object handles using new has no effect.
54
SystemVerilog Reference
Data Types
Unions
A union specifies a set of variable values. The variable values are called members of the union. The union, unlike the
structure, can store only one member at a time.
Packed Unions
A packed union is a union declared with keyword packed. All members of a packed union must be packed structures,
packed arrays, or integer types. Moreover, their size must be the same. Otherwise, the union cannot be declared
packed.
An example of a packed union is shown below:
typedef union packed {
int a;
reg [31:0]b;
} u_t;
A packed union can be used as an operand for arithmetic and logical operators. Bits or slices of a packed union can
be selected as if the union were a packed array indexed from n-1 down to 0.
A packed union can be declared either signed or unsigned. By default, unions are unsigned.
Unpacked Unions
NOTE: The construct is not supported in this release. Please contact Aldec Support to receive the latest status.
Unpacked unions (i.e. unions declared without the packed keyword) that have only packed members of the same
size are packed automatically by the compiler. Whenever the compiler encounters such as a union, it prints the
VCP92013 message:
Unpacked unions are not supported in this release, this union is being treated as
packed. Please contact Aldec Support to receive the latest status.
Tagged Unions
NOTE: The construct is not supported in this release. Please contact Aldec Support to receive the latest status.
55
SystemVerilog Reference
Data Types
Class
A class is a type that includes:
Data
Subprograms (tasks and functions) that operate on that data
Class data members are referred to as class properties. Subprograms that operate on that data are class methods.
Properties and methods define capabilities of some kind of an object. Objects can be dynamically created, deleted,
assigned, and accessed via object handles.
For more about classes see chapter Classes.
56
SystemVerilog Reference
Data Types
Casting
Casting converts an expression of one type to another type.
Static Casting
The data type can be statically changed by using the cast (') operator. The apostrophe must be prefixed with the type
of the expression. The expression itself must be enclosed in parentheses.
int i = int'(2.0 * 3.0);
shortint j = shortint'({8'hFA,8'hCE});
The example above shows casts to predefined types int and shortint. User-defined types are also allowed in
static casts. The listing below shows casting to the user-defined type my_reg.
module top;
typedef reg [3:0] my_reg;
my_reg a;
bit [1:0] b = 2'b10;
initial a = my_reg'(b);
endmodule
If a positive decimal number is used instead of a type name, then the cast changes the bit size, for example:
r = 10'(a+b-3)
The size of the expression in the example above is 10 bits. Changing the size does not affect signedness.
Signedness can be changed with signed and unsigned keywords:
rs = signed'(reg_vect_a)
ru = unsigned'(int_b)
Bit-stream Casting
A type casting can be applied to unpacked aggregate types. This can be done with the bit-stream casting which allows
you to convert between various bit-stream types, that is, between types which can be represented as a serial stream
of bits where each bit can be individually addressable. Following data types can be classified as bit-stream types:
Any integral, packed, or string type
Unpacked arrays, structures, or classes of the above types
Associative arrays, dynamic arrays and queues of any of the above types
Example 1
The example below shows how the bit-stream casting can be used to convert an integral type to a structure.
module top;
typedef struct {
logic[3:0] a[4];
57
SystemVerilog Reference
Data Types
shortint s;
integer i;
} T3;
T3 t1;
longint i3;
initial begin
i3 = 64'h0123456789abcdef;
t1=T3'(i3);
end
endmodule
Example 2
Here, the bit-stream casting is used to make a conversion between different aggregate data types.
module top;
typedef bit[7:0] T1[];
typedef struct {
logic[4:0] a[8];
shortint s;
byte b1;
} T3;
T1 t1 = new[8];
T3 t3;
initial
t1=T1'(t3);
endmodule
The dest_var is a variable to which the assignment is made. The src_expr is an expression that is to be assigned
to the destination variable. When the dynamic cast is called as a task, it attempts to assign the source expressions to
the destination variable. If the type cannot be cast, the run-time error message is displayed and the destination
variable is left unchanged.
When the dynamic cast is called as a function, it attempts to assign the source expression to the destination variable.
If the assignment is legal, the function returns 1. If the assignment is illegal, no runtime error message is displayed,
the function returns 0 and the destination variable is left unchanged.
58
SystemVerilog Reference
Data Types
Example 3
In the example below, the value of the int type returned by the f1() function is cast on the variable enum1 of the
enumerated type. If the value cannot be assigned, that can happen when the enumerated type does not have a
named item that corresponds to the assigned value, the value of the enum1 variable is left unchanged and a warning
message is displayed.
Const Casting
NOTE: The construct is not supported in this release. Please contact Aldec Support to receive the latest status.
59
Multiple Dimensions
In a multidimensional array, the packed dimensions, if any, always vary more rapidly than the unpacked dimensions.
Within the set of packed or unpacked dimensions, the dimensions to the right vary quicker than the dimensions on the
left.
The example below declares array arr with two packed dimensions ([3:0][7:0]) and one unpacked dimension
([15:8]). The unpacked dimensions vary quicker than the packed one. Of the two packed dimensions, the rightmost
one ([7:0]) varies quicker than the one the left ([3:0])
bit [3:0][7:0] arr [15:8];
The dimensions can also be specified with a single positive number designating the size of the array. The following
two declarations are synonymous.
int arr1 [8] [32]
int arr2 [0:7] [0:31]
60
SystemVerilog Reference
Limitations
Overriding SystemVerilog module parameters by VHDL generics is not supported yet.
61
SystemVerilog Reference
Dynamic Arrays
A dynamic array is an array whose size can be set during simulation run-time. The following syntax is used for
declaring dynamic arrays:
int arr [];
Note that the size of the array is not specified. No storage is allocated for the array until it is explicitly requested by
using the new function.
Description
Allocates storage for the number of elements specified by int_expr. The int_expr
must evaluate to a non-negative integer. Elements in the array are initialized to their
default values. This method can be used both to allocate a new array and to enlarge or
to shrink an existing array, for example:
// declare an array
// create an array with 10 elements
// grow the array
//shrink the array
// shrink the array and set values of the elements
Allocates storage for the number of elements specified by int_expr. The int_expr
must evaluate to a non-negative integer. An expression specifies an array with which to
initialize the new array arr. This array identifier must be a dynamic array of a data type
equivalent to the array on the left-hand side, but it need not be of the same size. If the
size of this array is less than the size of the new array, the extra elements shall be
initialized to their default value. If the size of this array is greater than the size of the new
array, the additional elements shall be ignored. An (expression) argument is useful when
growing or shrinking an existing array. In this situation, the value of (expression) is the
same as the left-hand side; therefore, the previous values of the array elements are
preserved. For example:
integer arr[];
// declare an array
arr = new[10];
// create an array with 10 elements
arr = new[20](arr); // double the array size, preserving previous values
Description
Returns the number of items in the dynamic array or 0 if the array is empty.
62
SystemVerilog Reference
63
SystemVerilog Reference
Associative Arrays
An associative array is a collection of unique keys and unique values, where each key is associated with one value.
The primary differences between associative arrays and regular arrays are as follows:
The type of the key in an associative array can be arbitrary, unlike in regular arrays, where the type of the key
is always an integer expression.
The storage for elements of an associative elements is not allocated until it is needed.
Associative arrays are best suited for sparse collections of data.
Syntax
element_type associative_array_id [ index_type ];
where
element_type
The type of elements that will be inserted into the associative array.
associative_array_id
The identifier of the array.
index_type
The type of the data to be used for indexing. The index type imposes the ordering of elements.
SystemVerilog also allows using * (a wildcard index) for index_type. Associative array with wildcard index may be
indexed with any integral expression and each index may be of different size. Indexes with the same numerical value
and differing only by width are treated as identical (leading zeros are removed). For example values 1'b0 and 2'b0
point to the same array item.
The following example demonstrates how to declare an associative array colors. The array is indexed by a 24-bit
value. The elements of the array are strings (color names). The initial value is assigned to the array by using an
associative array literal.
string colors [reg[23:0]] = '{
24'hF0F8FF : "Alice Blue",
24'hFAEBD7 : "Antique White",
24'h00FFFF : "Aqua",
24'h7FFFD4 : "Aquamarine",
24'hF0FFFF : "Azure",
24'hF5F5DC : "Beige",
24'hFFE4C4 : "Bisque",
24'h000000 : "Black",
24'hFFEBCD : "Blanched Almond",
24'h0000FF : "Blue"
};
Note that the array is sparse. Only ten 24-bit numbers have been used. The storage has been allocated only for
existing elements.
The default keyword allows defining a default value for nonexistent array elements. When the default is defined
the reference to an uninitialized array element returns the default value:
64
SystemVerilog Reference
If the default value is not specified, the value of an uninitialized array type is returned and a warning is printed to the
console:
typedef enum {A,B,C,D,E,F,G} EnumType;
EnumType letters [byte] = '{
0 : A,
1 : B,
2 : C
};
initial $display("letters[3]=%s",letters[3].name()); // displays letters[3]=A
// a warning will be printed: "Non-existent associative array entry. Returning default value."
An associative array can be written one entry at a time. The whole array contents can be replaced using an array
literal.
class CC;
int i;
function new(int i_);
i = i_;
endfunction
endclass
CC arr1 [EnumType];
CC obj1 = new(1), obj2 = new(2), obj3 = new(3);
initial begin
arr1[A] = obj1;
arr1[B] = obj2;
arr1[C] = obj3;
$display("arr1=", arr1); // displays: arr1='{A:'{i:1}, B:'{i:2}, C:'{i:3}}
arr1 = '{A:obj2, D:obj2}; // replaces previous contents of arr1
$display("arr1=", arr1); // displays: arr1='{A:'{i:2}, D:'{i:2}}
end
Each key in associative array literal can be used only once. Using the same key more than once triggers an error.
typedef int TA1 [string];
function int f1 (string idx, TA1 arr1 = '{"a":10,"b":20,"a":30});
return arr1[idx];
endfunction
// triggers an error about a duplicated key
SystemVerilog allows defining associative arrays that contain structure items. Array literals assigned to these arrays
may include nested structure literals.
typedef struct packed { reg a; EnumType b; } TS;
TS arr2 [byte] = '{0:'{a:1'b0,b:C},1:'{a:1'b1,b:D}};
65
SystemVerilog Reference
Description
Assigns the value of the largest index in the array to the index variable.
Returns 0 if the variable is empty or 1 otherwise.
Finds the entry with the next index greater than the passed index. If no
such entry exists, returns 0. If the entry is found, returns 1 and assigns the
next index to the index variable.
Finds the entry with the previous index greater than the passed index. If no
such entry exists, returns 0. If the entry is found, returns 1 and assigns the
previous index to the index variable.
66
SystemVerilog Reference
Queues
A queue is a variable-size, ordered collection of homogeneous elements. The queue can grow and shrink
automatically as elements are added or removed. Queues are declared similarly to arrays with the dollar sign ($) used
as the array dimension.
element_type queue_name [ $ ];
Queue Methods
Queues support the following methods: size, insert, delete, pop_front, pop_back, push_front, and
push_back. The prototype for each method and a brief description is provided below. element_t indicates the type
of the element inserted into the queue.
Prototype
Description
Removes the first element from the queue and returns it.
Removes the last element from the queue and returns it.
67
SystemVerilog Reference
Limitations
This section lists limitations related to dynamic arrays, associative arrays, and queues. For brevity, dynamic arrays
and associative arrays are referred to as arrays.
Part-selection is not available for arrays.
Array and queue part-selections cannot be used as arguments for system tasks, e.g. the $display task.
Hierarchical references to arrays and queues are allowed only when the array/queue and the reference to it
reside in the same compilation unit (i.e. they are compiled in the same compiler run).
Elements of arrays and queues cannot be passed by reference.
Arrays cannot be concatenated with the concatenation operator.
68
SystemVerilog Reference
Arguments
$left
Returns the left bound (MSB) of the dimension. For queues and dynamic
array dimensions, returns 0.
$right
Returns the right bound (LSB) of the dimension. For empty queues and
empty dynamic or associative arrays, returns -1.
$low
$high
$increment
$size
$dimensions
For an array returns the total number of dimensions in the array (packed
and unpacked, static or dynamic). For the string data type or any other
non-array type that is equivalent to a simple bit vector type returns 1. For
any other type returns 0.
$unpacked_dimensions
In references to multidimensional arrays the packed dimensions vary more rapidly than the unpacked dimensions . In
the list of packed dimensions the rightmost one varies most rapidly. The same rule applies to the list of unpacked
dimensions. This is shown in the listing below where the dimension [1:8] varies most rapidly (4), followed by [1:4]
(3), then [10:16] (@<2>), and then [1:2] (@<1>).
//
(3)
(4)
(1)
(2)
bit [1:4] [1:8] arr5 [1:2] [10:16];
For a fixed-size integer type (integer, shortint, longint, and byte), dimension 1 is predefined. For an integer N declared
without a range specifier, its bounds are assumed to be [$bits(N)-1:0].
69
SystemVerilog Reference
The methods iterate over the array elements which are then evaluated by the expression specified in the with clause.
You can define the iterator_name to specify the name of the variable to designate subsequent array elements
inside the with clause at each iteration. Such defined iterator_name can be used only inside the with clause
expression. If the iterator_name is not specified, the default name item is used. The expression inside the with
clause should not modify the array contents; otherwise, the results may be unpredictable.
find()
The method returns a queue of elements satisfying the specified expression. The use of the with clause is
obligatory:
result = int_arr.find(x) with (x >= 3);
The same method used without the iterator_name explicitly defined (item is assumed by default):
result = int_arr.find() with (item >= 3);
find_index()
The method returns a queue of indices of elements satisfying the specified expression. The use of the with
clause is obligatory:
result = int_arr.find_index() with (item >= 3);
find_first()
The method returns a queue containing the first element satisfying the specified expression. The use of the
with clause is obligatory:
result = int_arr.find_first() with (item > 2);
70
SystemVerilog Reference
find_first_index()
The method returns a queue containing the index of the first element satisfying the specified expression. The
use of the with clause is obligatory:
result = int_arr.find_first_index(x) with (x > 2);
find_last()
The method returns a queue containing the last element satisfying the specified expression. The use of the
with clause is obligatory:
result = int_arr.find_last() with (item < 2);
find_last_index()
The method returns a queue containing the index of the last element satisfying the specified expression. The
use of the with clause is obligatory:
result = int_arr.find_last_index() with (item < 2);
min()
The method returns a queue containing the element with the minimum value or whose expression evaluates
to a minimum:
result = int_arr.min();
s_res = s_arr.min(x) with (x.id); // criteria are 'id' fields of the array items
max()
The method returns a queue containing the element with the maximum value or whose expression evaluates
to a maximum:
result = int_arr.max();
s_res = s_arr.max(x) with (x.id); // criteria are 'id' fields of the array items
unique()
The method returns a queue containing all elements with unique values or whose expressions evaluate to
unique values. The returned queue contains only one entry for each of the values found in the array. The
ordering of the returned queue may not match the original ordering:
result = int_arr.unique();
unique_index()
The method returns a queue containing the indices of all elements with unique values or whose expressions
evaluate to unique values. The returned queue contains only one entry for each of the values found in the
array. The index returned for duplicate valued entries can be an index of any of the duplicates. The ordering of
the returned queue may not match the original ordering:
result = int_arr.unique_index();
71
SystemVerilog Reference
sort()
Sorts an array in ascending order. If the with clause is specified, the array is sorted by the values of the
expression specified in the with clause:
s_arr.sort()
with (item.id);
Sorts the array by the values of the id fields of objects stored in the array.
rsort()
Sorts an array in descending order. If the with clause is specified, the array is sorted by the values of the
expression specified in the with clause:
s_arr.rsort() with (item.id);
Sorts the array by the values of the id fields of objects stored in the array.
reverse()
Reverses the order of elements stored in an array. Specifying the with clause is not allowed:
s_arr.reverse();
shuffle()
Randomizes the order of elements stored in an array. Specifying the with clause is not allowed:
s_arr.shuffle();
sum()
Returns the sum of all elements stored in an array. If the with clause is specified, returns the sum of values
returned by evaluation of the expression specified in the with clause for each of the array elements:
int array[] = '{ 1, 3, 5};
int result;
result = array.sum();
result = array.sum() with (item * 2);
// 1 + 3 + 5 = 9
// 1*2 + 3*2 + 5*2 = 18
product()
Returns the product of all elements stored in an array. If the with clause is specified, returns the product of
values returned by evaluation of the expression specified in the with clause for each of the array elements:
result = array.product();
// 1 * 3 * 5 = 15
result = array.product() with (item + 1); // 2 * 4 * 6 = 48
and()
72
SystemVerilog Reference
Returns the logical conjunction (bitwise AND) of all elements stored in an array. If the with clause is
specified, returns the logical conjunction of values returned by evaluation of the expression specified in the
with clause for each of the array elements:
result = array.and();
result = array.and() with (item - 1);
// 1 & 3 & 5 = 1
// 0 & 2 & 4 = 0
or()
Returns the logical disjunction (bitwise OR) of all elements stored in an array. If the with clause is specified,
returns the logical disjunction of values returned by evaluation of the expression specified in the with clause
for each of the array elements:
result = array.or();
result = array.or() with (item - 1);
// 1 | 3 | 5 = 7
// 0 | 2 | 4 = 6
xor()
Returns the logical exclusive disjunction (bitwise XOR) of all elements stored in an array. If the with clause is
specified, returns the exclusive disjunction of values returned by evaluation of the expression specified in the
with clause for each of the array elements:
result = array.xor();
result = array.xor() with (item + 1);
// 1 ^ 3 ^ 5 = 7
// 2 ^ 4 ^ 6 = 0
If the method is applied to indices of an associative array, the returned value is of the same type as associative array
indices. For other arrays, the function returns indices of the int type. The method cannot be used for associative
arrays with the wildcard index type.
Examples:
The example shows the index method used together with the array querying methods applied to unpacked and
associative arrays.
byte arr_unpacked[0:5] = '{0,1,2,8,8,8};
int arr_assoc[byte]
= '{20:0,0:1,1:2,2:8,4:8,25:8};
byte result[$],result_b;
The find() method returns the elements that indices are equal to their values.
// result is '{0,1,2};
result = arr_unpacked.find(x) with (x.index == x);
The find() method returns the elements that indices are bigger than 2.
// result is '{8,8,8};
result = arr_unpacked.find(x) with (x.index > 2);
73
SystemVerilog Reference
The find_index() method returns the indices that are bigger than 2. The indices returned by the index method
and the whole find_index() method are of the byte type, since the arr_assoc index type is byte.
// result is '{4, 20, 25}
result = arr_assoc.find_index with (item.index > 2);
The unique() method returns elements that evaluate to a unique value. Since the with clause evaluates to the two
unique values: 0 for the indices: 0,1,2 and 1 for the indices: 3,4,5 the possible results are: '{0,8}, '{1,8}, or
'{2,8}.
// result is '{0,8}, '{1,8}, or '{2,8}
result = arr_unpacked.unique with (item.index > 2);
The sum() method below returns the number of even array indices. If the with clause is specified, the method
returns the sum of values returned by evaluation of the expression specified with the with clause. The expression
returns 1 for indices with the 0 value in the least significant bit position, that is, for even indices.
// result_b is 4
result_b = arr_assoc.sum(x) with (byte'(x.index[0]==0));
Limitations
The min(), max(), unique(), unique_index(), sort(), and rsort() methods are executed with an implicit
use of the relational operators: <, >, and ==. When a with clause is specified for one of these methods, the relational
operators must be defined for the type of the expression evaluated inside that clause. When the with clause is not
specified, the relational operators must be defined for the type of the elements stored in the array.
NOTE: Overloading the relational operators is not supported yet. Results returned by the min(), max(), unique(),
sort(), and rsort() functions for arrays containing class, event, or chandle variables are evaluated by comparing
the object addresses. For other data types that have no relational operators defined, e.g. unpacked structures, the
functions will not be executed and an error will be issued. Please contact Aldec Support to receive the latest status.
74
SystemVerilog Reference
Array Assignment
Array assignments are allowed if arrays satisfy following restrictions:
The source and the target arrays have same number of dimensions. Each dimension has equal size.
The element types of the source and the target are equivalent. This means, arrays can be assigned to each
other not only if they are of the same type, but also if arrays are of different types and these types have the
same bit size, both are signed or unsigned and both are either 2-state or 4-state. (e.g. following pairs are
equivalent: bit signed [15:0] and shortint, real and realtime, integer and logic signed
[31:0], bit signed [7:0] and byte, etc.)
Equivalent types are also structures, unions and packed arrays of types that have the same bit size, both are
either signed or unsigned and both are either 2-state or 4-state. Moreover, unpacked fixed-size arrays,
dynamic arrays, queues and associative arrays of such types are also equivalent under certain conditions. For
more specific information refer to the Data Types | Type Compatibility section of IEEE Std 1800-2009.
NOTE: The continuous assignments of arrays of wires to arrays of variables and vice-versa are not supported yet.
Fixed-Size Arrays
byte arr1 [2] = '{1, 2};
byte arr2 [2] = '{3, 4};
initial
arr1 = arr2;
Both blocking and non-blocking assignments are allowed for fixed-size arrays.
Dynamic Arrays
The target of an assignment is resized to the size of the source.
byte dynarr1 [] = new[2]('{8'd1, 8'd2});
byte dynarr2 [] = new[3]('{8'd3, 8'd4, 8'd5});
initial
dynarr1 = dynarr2;
Associative Arrays
Assigning one associative array to another is allowed if arrays keys have the same type.
byte assocarr1 [string] = '{"a":8'd1, "b":8'd2};
byte assocarr2 [string] = '{"c":8'd3, "d":8'd4, "e":8'd5};
initial
assocarr1 = assocarr2;
75
SystemVerilog Reference
Queues
The target of an assignment is resized to the size of the source.
byte queue1 [$] = '{8'd1, 8'd2};
byte queue2 [$] = '{8'd3, 8'd4, 8'd5};
initial
queue1 = queue2;
If a target of an assignment is a dynamic array or a queue, the size of the source and the target may differ. If
size are different, the target will be resized to have the same number of elements as the source expression.
int dynarr[] = new[7], queue[$];
int arr[3] = '{124,3,94};
initial begin
dynarr = arr; //dynamic array is resized to 3
queue = dynarr; //uninitialized queue is resized to actual size of dynamic array dynarr (3)
end
Non-blocking assignments are not allowed if the target of an assignment is a queue or a dynamic array.
76
SystemVerilog Reference
arr_dst = arr_src;
// after the assignment arr_dst has one entry: arr_dst[6] = 5
Out-of-bounds Elements
The index expression is invalid if its value is out of array bounds or one or more of its bits is of the Z or X value.
Specifying an invalid index during the read operation, results in reading the values specified in the table below. The
values depends on the array type.
Type of array
Value
'X
'0
Enumeration
Value specified in this table for the base type of the enumeration.
real, shortreal
0.0
string
An empty string.
class
null
event
null
chandle
null
virtual interface
null
Unpacked struct
Array elements have values depending on the array type as specified in this table.
Associative array
Array of zero size (no elements) or the user-specified default value (if defined).
Writing a value to an element determined by an invalid index does not trigger any specific operation with the exception
of assigning a value to a next element of a queue [$+1] and creating a new element of an associative array which
are the legal operations.
77
Data Declarations
Constants
Constants are named data variables that never change. SystemVerilog provides elaboration time constants and
runtime constants.
The elaboration time constants are referred to as parameter constants. They include:
parameter's
localparam's
specparam's
Runtime constants are declared with the const keyword. A const constant, unlike parameter constants, can be set
during simulation run time, e.g. when an automatic task or function is executed.
Parameter Constants
SystemVerilog introduces a number of enhancements to parameter constants.
An error about a missing keyword would be reported if the declaration was compiled in Verilog mode.
Type Parameters
In SystemVerilog a parameter can also specify a data type. This allows creating multiple instances where the type is
set individually for each instance.
An example with type parameters is shown below. The first parameter (T) in the example is a type (byte), the other
parameter (M) is a value of type T;
module m #(parameter type T = byte, T M = 2);
endmodule
78
SystemVerilog Reference
Data Declarations
Assigning a parameter value by the ordered list implies to specify each parameter that precedes the parameter to be
assigned, since the parameter has to be on the same position in the declaration and in the instantiation.
mod#(8'b01111010,16'h930E,5,8'h7C) m2();
The instance m2 of the module mod, which is shown above, has ports assigned by the ordered list. Even though there
are only two parameters without default values: P2 and P4, parameters P1 and P3 have to be assigned once again
because P2 and P4 have to be placed in the proper position on the ordered list. Only the P5 parameter that is
preceded by the P4 parameter which is the last parameter without a default value, can be omitted.
$ as a Parameter Value
NOTE: $ as a parameter value is not supported in this release. Please contact Aldec Support to receive the latest
status.
$ represents unbounded range specification, where the upper index can be any integer. SystemVerilog introduces the
possibility to assign $ to parameters of integer types. A parameter to which $ is assigned can only be used wherever
$ can be specified as a literal constant.
parameter left_range = 0;
parameter right_range = $;
sequence s1(left_range,right_range);
@(posedge clk) a ##[left_range:right_range] b;
endsequence
SystemVerilog adds also a special system function $isunbounded that tests whether a constant expression is
unbounded ($).
$isunbounded(const_expression);
79
SystemVerilog Reference
Data Declarations
Const Constants
A constant declared with the const keyword can be set to an expression of literals, parameters, local parameters,
genvars, enumerated names, a constant function of these, or other constants. Hierarchical names are allowed
because constants declared with the const keyword are calculated after elaboration.
An automatic constant declared with the const keyword can be set to any expression that would be legal without the
const keyword.
const int a = 9;
const logic q = top.uut.a;
An instance of class object can also be declared as const. If it is done so, the class instance (the object handle) acts
like a variable that cannot be overwritten. Its members, however, can be written unless they are declared as const.
const A a0 = new(7,8);
Localparam Constants
The local parameter is one of the three elaboration-time constants in SystemVerilog. The localparam construct
cannot be changed directly by the values assigned by the instance parameter or by the defparam statements.
The localparam construct can be defined in the parameter_port_list of a module. If a parameter is declared at the
end of the list or between the localparam and the parameter keywords, it will become a local parameter.
module mod1
#(localparam H_B=3, L_B=0)
(input wire [H_B:L_B] in,
input wire clk, set, strb,
output logic [H_B:L_B] out);
endmodule
NOTE: The localparam type declared in a compilation-unit scope, generate block, or package is not supported in
this release. Please contact Aldec Support to receive the latest status.
80
SystemVerilog Reference
Data Declarations
Variables
SystemVerilog provides two forms of variable declarations: with and without the keyword var.
The first form consists of a data type followed by an identifier, for example:
shortint a, b[3:0];
The second form begins with the keyword var, for example:
var shortint a, b[3:0];
When var is used, the data type is optional. When the data type is omitted, the assumed data type is logic. In the
example below i is declared to be of type int. No type is specified for l therefore l is assumed to be of type logic.
var int i;
var l;
A variable assignment at declaration is a procedural assignment, not a continuous assignment. (A variable cannot
have an implicit continuous assignment as a part of its declaration.)
SystemVerilog variables can be written by either one continuous assignment or by one or more procedural
statements. Multiple continuous assignments are illegal, so is a mixture of procedural and continuous assignments.
A variable cannot be connected to either side of an inout port.
81
SystemVerilog Reference
Data Declarations
Nets
A net declaration begins with a net type (wire, trireg, etc.) that determines how the values of the nets in the
declarations are resolved. The net declaration can include optional information, such as delay values and drive or
charge strength.
Several examples of net declarations are shown below. They include nets with unpacked (n2) and packed (n3)
dimensions and a net with a delay value (n4).
wire n1;
wire n2[10];
wire [7:0]n3;
wire #(3) n4;
trireg n5;
82
SystemVerilog Reference
Data Declarations
83
SystemVerilog Reference
Data Declarations
Signal Aliasing
NOTE: The construct is not supported in this release. Please contact Aldec Support to receive the latest status.
84
SystemVerilog Reference
Data Declarations
Type Operator
The construct is supported only in the initialization of the type parameter and type local parameter with the
data_type as an argument.
module m1;
parameter type T = type(bit [1:0]);
typedef int TT;
parameter type T1 = type(TT);
endmodule
85
Classes
Overview
A SystemVerilog class defines properties (data) and methods (behavior). Properties and methods grouped in a class
are inherent to all class instances. An instance of a class is called an object. Objects can be created and deleted
during simulation.
A simple class Point could have one data field (one property) x that stores the coordinate of a point. The coordinate
can be different for each instance of the class. Additionally, the class can provide methods to read, set, or change the
point coordinate, calculate the distance from the origin, etc.
A more complex class could define a USB data packet. A data packet will have a sync field, a PID field, a data field, a
CRC16 field, and an EOP field. Methods provided by the class could be used to send a packet, calculate the CRC for
the data field and compare it against the CRC16 field, etc.
Classes are declared with the class ... endclass keywords. A declaration of a simple class is shown below.
class Point;
int x;
function new (int initial_position);
x = initial_position;
endfunction
function void move (int dx);
x = x + dx;
endfunction
function void rnd_move;
x = $urandom;
endfunction
function int get_position;
return x;
endfunction
endclass
The declaration includes both data (variable x) and methods that operate on that data (functions move, rnd_move,
and get_position). Function new is the class constructor. The constructor is invoked whenever a new instance of
the class is created.
Classes can be declared in the compilation unit scope or in the unit scope (i.e. inside modules, programs, interfaces,
or other classes).
86
SystemVerilog Reference
Classes
Objects in SystemVerilog can also be created by copying existing objects, for example:
initial
h2 = new h1;
The h2 object in the listing above is created by copying the h1 object (h2 = new h1). All properties of h1 are copied
to h2 except for properties that are objects themselves. If h1 contains a property that is an object, h2 will contain a
reference to the same object.
87
SystemVerilog Reference
Classes
endclass
Point p1 = new;
Point p2 = new;
initial begin
p1.x = 0;
p2.x = 22;
end
In parameterized classes (see Parameterized Classes) object parameters can also be accessed by qualifying the
parameter name with the instance name.
For a class declared as
class Point #(parameter step = 2);
endclass
Object Methods
The syntax for accessing object methods is the same as the syntax for accessing class properties, i.e. the name of the
method must be prefixed with the name of the object followed by a dot (.), for example:
Point p;
initial begin
p = new;
p.move( 10 );
end
Each method can only access properties belonging to the object it is invoked against. (It cannot access properties of
other instances of the same class; however, it is possible to share data between all instances of the same class - see
Static Properties and Methods for details.)
The lifetime of methods declared as part of a class type is always automatic. Declaring a class method with a static
lifetime is illegal.
88
SystemVerilog Reference
Classes
Constructors
Whenever a new object (or a new instance of a class) is created, function new associated with the class is called.
A call to function new could look as follows:
Point p = new;
The actual implementation of function new can be provided in class Point, for example:
class Point;
int i;
function new( int _i = 2);
i = _i;
endfunction
endclass
The conventions for the constructor arguments are the same as for any other subroutine calls. The example in the
listing uses function new with one default argument. Consequently, specifying the argument for the constructor is
optional.
Point p = new;
// No actual argument provided; the default (2) will be used.
Point r = new(1); // 1 used as an argument for the constructor.
If a class does not contain a user-defined constructor, an implicit new method is provided automatically.
Object construction involves the following steps:
1. Memory is allocated for all dynamic object properties (local and inherited).
2. The object constructor (either user-defined or implicit) is called.
3. The constructor ports are initialized (if they exist).
4. Constructor local automatic variables are created and initialized (if they exist).
5. The base class constructor (super.new) is called (if the current class extends a base class). The constructor
in the base class can be either user-defined or implicit.
NOTE: The information about the base class constructor is a forward reference. For more information see:
Inheritance, Chaining Constructors, and Super.
6. Local object properties are initialized to their default values (i.e. values defined in the initialization at the
declaration).
7. Execution of the body of the constructor.
Referencing local or inherited dynamic variables prior to returning from the base class constructor triggers a compiler
warning.
89
SystemVerilog Reference
Classes
Inheritance
A class can be extended to form a new subclass. The new subclass will typically contain additional properties and
methods augmenting the base class. All properties and methods defined in the base class are inherited by the
subclass, as if they were defined directly in the subclass.
The example shows class ColorPoint that extends class Point. ColorPoint contains one new property (color),
and three methods to read color components.
class Point;
int pos;
function int get_distance;
if( this.pos < 0 )
return -this.pos;
else
return this.pos;
endfunction
endclass
Property pos and method get_distance from the base class Point are also available in the derived class.
Note that neither the base class nor the derived subclass has a user-provided constructor. For information on how to
use constructors with extended classes, see Chaining Constructors.
A subclass in SystemVerilog can extend only one base class. This language feature is referred to as single
inheritance. Multiple inheritance (where a class inherits properties and methods from more than one class) is not
available.
90
SystemVerilog Reference
Classes
Chaining Constructors
Creation of an object that extends another class involves calling functions new (constructors) for all classes in the
inheritance hierarchy. The first action performed by function new from a subclass is calling method new() for the
superclass. The same rule is then applied to function new from the superclass, which may in turn call another
constructor from the class one level higher in the inheritance hierarchy. This approach ensures calling all constructors
in the proper order and creating objects begging with the root of the base class.
If a subclass does not have a user-defined constructor, a call to the constructor in the base class is inserted
automatically by the compiler. If the superclass does not have a user-defined constructor, the implicit constructor is
called.
If the constructor in the base class requires arguments and the default argument values are not provided, the call to
the constructor in the base class must be explicit (and include all required arguments). If the call is omitted, the
compiler reports an error.
The declaration of class P shown in the code below is invalid and will trigger a compiler error. Class P extends class
Point. The constructor for class Point requires an argument (_pos). Class P does not contain a user-defined
function new. The constructor is generated automatically by the compiler. It contains a call to the constructor in the
base class (Point::new) however, no arguments are passed to Point::new(). Therefore, an error is reported
about an unspecified argument for the formal argument _pos that does not have a default value.
class Point;
int pos;
function new( int _pos );
pos = _pos;
endfunction
endclass
class P extends Point;
endclass // Triggers an error about missing arguments.
Arguments for the base class constructor can be specified in the super.new call or in the extends clause.
91
SystemVerilog Reference
Classes
In this case, a user-defined function new() in class P2 can be omitted and the required arguments for
Point::new() specified in the extends clause.
92
SystemVerilog Reference
Classes
Assignment
The example shows class Point and two variables (A and B) that hold handles to objects of class Point.
class Point;
int x;
int y;
endclass
module m;
Point A, B;
initial begin
A = new;
B = A;
end
endmodule
The initial block calls the constructor (new) only once, for variable A. The constructor is never called for variable B.
Consequently, only one object is created. The assignment B = A; does not create a new object. Instead, it makes
variable B point to the same object as A.
Shallow Copy
A shallow copy is made when a new object is created by copying object properties from another object, as in the
following example:
class Segment;
int color;
Point A;
Point B;
endclass
module m;
Segment ab, cd;
initial begin
ab = new;
cd = new ab;
end
endmodule
All class properties (color, A, and B) of object ab are copied to object cd. However, objects of class Segment
contain two instances (A and B) of objects of class Point. A shallow copy does not copy those objects, only their
handles. Therefore, handles ab.A and cd.A point to the same object and not to separate copies of those objects. The
same applies to handles ab.B and cd.B.
Creating a shallow copy of an object with a null value is illegal and triggers a runtime error. See Full Copy for an
example.
93
SystemVerilog Reference
Classes
Full Copy
Creating a full copy where nested objects are also copied requires a user-defined subroutine. An example using such
a custom routine is shown in the listing below. The name of the routine (copy) is arbitrary.
initial begin
ab = new;
cd = new;
cd.copy( ab );
end
94
SystemVerilog Reference
Classes
Static Properties
A static variable is shared by all instances of a class.
Class Point shown in the listing has two instance properties (x and y) and one static property cnt. The static
property is incremented whenever a new object of class Point is created. Therefore, cnt contains a count of all
objects of class Point created during simulation.
class Point;
int x, y;
static int cnt = 0;
function new();
++cnt;
endfunction
endclass
A static class property can be accessed through an object handle, in the same manner instance properties are
accessed. However, a static property can also be accessed through a scope resolution operator (::), even if no
instance of a class has been created.
initial begin
repeat( 10 ) p = new;
$display( "%d", p.cnt );
$display( "%d", Point::cnt );
end
The initial block in the listing creates 10 instances of class Point. The cnt static property holding the number of
created instances in then displayed once. The first $display statement references the property through the p handle
(p.cnt), the other uses the class name and the class scope resolution operator (Point::cnt). Both references are
valid and both point to the same data item.
See Static Properties in Parameterized Classes for information on how class parameters affect static members.
Static Methods
A static method is subject to all the class scoping and access rules, but behaves like a regular subroutine that can be
called outside the class, even with no class instantiation.
A static method has no access to nonstatic members (properties or methods). It can only access static members of
the class where it is defined. Static methods cannot be virtual.
The example shows class Point with a static method get_cnt.
class Point;
int x, y;
static int cnt = 0;
95
SystemVerilog Reference
Classes
The static method accesses only static members (property cnt). It can be referenced either through an object handle
(p.get_cnt()) or through the class scope resolution operator (Point::get_cnt()) as shown in the listing.
initial begin
repeat( 10 ) p = new;
$display( "%d", p.get_cnt() );
$display( "%d", Point::get_cnt() );
end
The location of the static keyword is important. If it is moved behind the task or function keyword, then it refers
to the lifetime of arguments and variables within the task or function.
class C;
static task t1();
// ...
endtask // static class method with
// automatic variable lifetime
task static t2();
// ...
endtask // nonstatic class method with
// static variable lifetime
endclass
96
SystemVerilog Reference
Classes
This
Keyword this denotes a predefined object handle that refers to the object that was used to invoke the subroutine that
this is used within. Keyword this can be only used within nonstatic class methods.
In the example below, identifier this.x references property x in the instance of class Point. The unqualified
identifier (x) refers to the input argument of function new.
class Point;
int x;
function new (int x);
this.x = x;
endfunction
endclass
In the example below x was renamed to _x. Therefore, keyword this is no longer required to differentiate between
the function argument and the class property.
function new (int _x);
this.x = _x;
endfunction
However, keyword this improves code readability because it clearly indicates that the item that follows is a member
of the current object.
97
SystemVerilog Reference
Classes
Super
The super keyword refers to members of the parent class and is used from within a derived class. It is necessary to
use super to access members of a parent class when those members are overridden by the derived class.
A typical application of the super keyword is reaching for a constructor in the parent class, for example:
class Point2D;
int x, y;
function new( int _x, int _y );
this.x = _x;
this.y = _y;
endfunction
endclass
class Point3D extends Point2D;
int z;
function new( int _x, _y, _z );
super.new( _x, _y );
this.z = _z;
endfunction
endclass
Using super with the constructor (function new) involves a special limitation: super.new must be the first statement
executed in the constructor. (This is required to ensure a proper object construction order.)
The super keyword allows reaching only one level up in the inheritance hierarchy. super keywords cannot be
chained. (super.super followed by a member name is illegal).
98
SystemVerilog Reference
Classes
Casting
A class variable (handle) of one type can be cast to another type. Casting may succeed only for class types within one
inheritance hierarchy.
SystemVerilog provides both the $cast task and the $cast function. The function only checks if casting will succeed.
The actual casting is performed by the $cast system task. The task may fail at run time triggering a fatal error.
Therefore, you may invoke the function prior to the task and call the task only if the function return value indicates that
casting is possible.
Both the task and the function accept two arguments:
The source handle.
The destination handle.
A handle to class CPoint (cp) can always be assigned to a handle to class Point because class Point is a
superclass of CPoint. No casting is required.
Point p;
CPoint pc;
initial begin
CPoint pc = new( 1, 2, blue );
p = pc; // It is always legal to assign a subclass variable
// to a superclass variable.
end
It is illegal to directly assign a superclass variable to a subclass variable. Such assignments must be performed with
the $cast task. The $cast task will succeed if the source handle refers to an object that is of the same type as the
destination handle or a subclass of a destination handle.
This is demonstrated in the listing below.
99
SystemVerilog Reference
Classes
Point p;
CPoint pc1;
CPoint pc2 = new( 8, 9, yellow );
initial begin
p = new( 3, 5 );
pc1 = new( 1, 2, blue );
if(! $cast( pc1, p ) ) begin
$display( "Cast will fail." );
$cast( pc1, p );
end
p = pc2;
if( $cast( pc1, p ) ) begin
$display( "OK to cast." );
$cast( pc1, p );
end
end
The $cast task in the first if statement fails because the source handle (p) is a handle to an object of class Point.
Point is a superclass of CPoint and cannot be assigned to CPoint.
The value of the source handle (p) is then assigned pc2 (and pc2 is a handle to an object of class CPoint). After the
assignment is made, p can be successfully cast to pc2.
100
SystemVerilog Reference
Classes
The Cartesian coordinates and the polar coordinates carry the same information and one can be expressed in terms
of the other. If a coordinate in one system is updated, the coordinates in the other must be updated accordingly. If the
user of class CPoint has access to object properties, he can inadvertently corrupt the data in the object. This is
where data hiding comes into play.
You can declare all data properties in class CPoint local (using keyword local). This will prevent accessing the
properties from outside the body of the class. Then, provide methods get_x and set_x to read and write the
coordinate:
class CPoint;
local real x;
local real y;
local real r;
local real fi;
function real get_x();
return this.x;
endfunction
function void set_x( int _x );
/* Code omitted for brevity */
endfunction
endclass
While the get_x method has only to return the value of x, the set_x method must set the value of x and update the
planar coordinates (r and fi) accordingly.
This approach not only ensures data integrity. It also allows you to change the data structures used in the class
without affecting code using the class. For example, you could get read of data fields <x> and y and have method
get_x calculate x on the fly based on the values of r and fi.
101
SystemVerilog Reference
Classes
Member access rules are demonstrated in the listing below. Lines marked with //Error are incorrect and will not
compile.
class C;
int m;
local int lm;
protected int pm;
function void test ( C _c );
$display( "%d", this.lm ); //OK to access members of the current instance (this)
$display( "%d", _c.lm );
//or any other instance of the same class.
endfunction
endclass
class D extends C;
function void test ( C _c );
$display( "%d", _c.lm ); //Error, cannot access a local member of the base class.
$display( "%d", _c.pm ); //OK, can access a protected member.
endfunction
endclass
module m;
C c;
initial begin
c = new;
$display( "%d", c.m ); //OK, can access a public member.
$display( "%d", c.lm ); //Error, cannot access a local member.
$display( "%d", c.pm ); //Error, cannot access a protected member.
end
endmodule
102
SystemVerilog Reference
Classes
103
SystemVerilog Reference
Classes
Overridden Members
The base class can override properties and methods from its subclasses. The example below shows two classes: C
and D. Class D extends class C. Method whoami is overridden.
class C;
function void whoami;
$display( "Class C." );
endfunction
endclass
class D extends C;
int x = 2;
function void whoami;
$display( "Class D." );
endfunction
endclass
The listing below contains instances of both the base class (C) and the subclass (D) and demonstrates the following:
Subclass objects are valid objects of their base classes, for example handle fp to class D can be assigned to
handle p1 of class C.
The type of the handle determines how references to overridden properties and methods are resolved. If the
type of the handle is that of the subclass (D), then the reference through the handle (p2.whoami()) points to
the subclass member (D::whoami()). If the type of the handle is of the base class (C), then the reference
(p1.whoami()) points to the member overridden in the base class (C::whoami()). The same principle is
used for resolving method references and property references.
See Virtual Methods for related information on virtual methods.
References to property x declared in subclass D are valid only if qualified by handle p2 of class D. Using
handle p1 of class C will trigger an error about an unresolved hierarchical reference. The error is reported at
simulation initialization. (The code compiles cleanly.)
module m;
D fp;
C p1;
D p2;
initial begin
fp = new;
p1 = fp;
p2 = fp;
p1.whoami(); // Displays "Class C.".
p2.whoami(); // Displays "Class D.".
//$display( "%d", p1.x ); // Illegal, would trigger an error at init.
$display( "%d", p2.x );
end
endmodule
Note that assigning a base class handle to a derived class handle (e.g. assigning p1 to fp) is illegal and triggers a
compilation error.
104
SystemVerilog Reference
Classes
Virtual Methods
Methods declared virtual can be overridden by methods in subclasses. This is shown in the listing below. Class D
extends class C. Method whereami from subclass C is declared virtual, therefore it can be overridden by methods
from subclasses, for example method whereami from class D.
class C;
virtual function void whereami();
$display( "Class C." );
endfunction
endclass
class D extends C;
function void whereami();
$display( "Class D." );
endfunction
endclass
In the following listing a handle to class C (i.e. the class with the virtual method) is assigned two handles: a handle to
an object of class C (q = c;) and a handle to an object of class D (q = d;).
module m;
C c = new;
D d = new;
C q;
initial begin
q = c;
q.whereami(); //Displays "Class C.".
q = d;
q.whereami(); //Displays "Class D.".
end
endmodule
This demonstrates a basic polymorphic construct. A call to method whereami qualified by the same handle q
(q.whereami()) calls method C::whereami() or D::whereami() depending on the type of the object assigned
to the handle. If method C::whereami were not declared virtual in class C, then the q.whereami() statement would
always resolve to method C::whereami() because q is a handle to an object of class C.
You should also note the following:
A method declared virtual remains virtual down the complete inheritance tree. If class D is extended by
another subclass, then a call to whereami through a handle of type C (where whereami is declared virtual)
can resolve to C::whereami, D::whereami, or whereami in either of D's subclasses.
Handles of all subtypes of class C are also affected by the fact that whereami is declared virtual in the
superclass (class C). For example, if class D is extended by class E, then a call to whereami through a
handle of type D can resolve either to D::whereami or E::whereami even though D::whereami is not
declared virtual.
The above principles are shown in the listing below. For brevity, function whereami is expanded from the WHEREAMI
macro.
`define WHEREAMI(_N) function void whereami(); $display( `"Class _N.`" ); endfunction
class C;
virtual `WHEREAMI(C)
endclass
class D extends C;
`WHEREAMI(D)
105
SystemVerilog Reference
Classes
endclass
class E extends D;
`WHEREAMI(E)
endclass
module m;
D d = new;
E e = new;
C q1;
D q2;
initial begin
q1 = e;
q1.whereami(); //Displays "Class E.".
q2 = d;
q2.whereami(); //Displays "Class D.".
q2 = e;
q2.whereami(); //Displays "Class E.".
end
endmodule
The default values assigned to argument _str are hello and bye, respectively. In other words, if the call is routed to
method D::say, the default arguments are also read from the prototype of the D::say method. This behavior may
be surprising for C++ users. (The analogous code in C++ also calls methods C::say() and D::say(), however, the
default argument values are in either case read from C::say()).
106
SystemVerilog Reference
Classes
Any non-abstract class that extends class Figure must provide implementations of methods declared pure virtual in
the base abstract class. The example below shows class Circle that extends class Figure. Class Circle provides
implementation of the two pure virtual methods from class Figure.
typedef struct { real x; real y; } vertex_t;
class Circle extends Figure;
vertex_t middle;
real radius;
function new( vertex_t _a, real _r );
this.middle.x = _a.x;
this.middle.y = _a.y;
this.radius = _r;
endfunction
function real get_area();
return (this.radius ** 2) * `PI;
endfunction
function real get_perimeter();
return 2 * this.radius * `PI;
endfunction
endclass
An abstract class may also be extended to another abstract subclass. The subclass does not have to provide
implementations for all pure virtual methods. Implementations for the virtual methods must be available when the
abstract class is eventually extended to a non-abstract class that can be instantiated.
107
SystemVerilog Reference
Classes
The class scope resolution operator :: can also be used to access static class members. They can be read, written
to, or triggered off in event expressions. A class scope can also be used as a prefix to a method call.
class C;
static int i;
static function void hello();
$display( "hello" );
endfunction
endclass
module m;
initial begin
C::hello(); //Call a static method.
#10;
C::i = 10; //Write a static property.
end
always @( C::i ) //Trigger an event.
$display( "%d", C::i ); //Read a static property.
endmodule
Accessing static class members is subject to data hiding rules (see Data Hiding and Encapsulation). Protected
members can only be accessed from derived classes. Access to local members is forbidden.
class C;
static int i;
protected static int j;
local static int k;
endclass
class D extends C;
function new;
$display( C::i ); //OK.
$display( C::j ); //OK.
$display( C::k ); //Error.
endfunction
endclass
module m;
initial begin
$display( "%d", C::i ); //OK.
$display( "%d", C::j ); //Error.
$display( "%d", C::k ); //Error.
end
108
SystemVerilog Reference
Classes
endmodule
The left side of the scope operator may be not only a class name but also a package, a covergroup type name, a
coverpoint name, or a cross name.
109
SystemVerilog Reference
Classes
Nested Classes
Classes in SystemVerilog can be nested. Nesting is useful when the inner class is a part of the implementation of the
outer class and is not intended to be used outside. Nesting can also prevent name collisions by hiding local names
within the outer class scope.
class TestEnv #(type T = int);
int TestQueue[$]; // Basic queue implementation.
class ExtendedTest;
class TestQueue #(type T = int);
// An extended implementation of the queue
// used only by the ExtendedTest class.
endclass
endclass
endclass
Nested classes have access to local and protected members of the nesting class and can access its static members
as well as parameters and local parameters. Direct access to non-static members of the enclosing class is not
allowed, the only way they can be accessed is through a handle.
class CNesting;
local
static
static
local
int
int
int
int
nonStaticPublicProperty;
nonStaticLocalProperty;
staticPublicProperty;
staticLocalProperty;
class CNested;
function void NestingClassAccess( CNesting handle );
staticPublicProperty = 1;
// Allowed.
staticLocalProperty = 1;
// Allowed.
nonStaticLocalProperty = 1;
nonStaticPublicProperty = 1;
handle.nonStaticLocalProperty = 1;
handle.nonStaticPublicProperty = 1;
endfunction
endclass
endclass
//
//
//
//
Not allowed.
Not allowed.
Allowed.
Allowed.
110
SystemVerilog Reference
Classes
Out-of-block Declarations
It is possible to move method definitions out of the body of the class declaration. Furthermore, such declarations can
be compiled independently of the class declaration and independently of the code that instantiates the class. If the
implementation of the method is changed but the method interface stays intact, only the implementation needs to be
recompiled.
To move the method body outside the class, do the following:
Specify the method prototype inside the class using the extern qualifier. A full argument list and other
qualifiers (if any) must be provided.
Provide the method declaration outside the body of the class. The method must be qualified with the class
name followed by a double colon. The argument list must be repeated verbatim and the qualifiers should be
omitted.
This is shown in the example below. The out-of-block method declaration matches the prototype declaration. It is
declared in the same scope as the class declaration.
class Packet;
typedef enum { OK, ERR } status_t;
extern function status_t check_crc();
endclass
function Packet::status_t Packet::check_crc();
status_t s;
//Calculate CRC...
return s;
endfunction
Note that type status_t declared inside the body of class Packet is available to the out-of-block declaration.
Furthermore, if another type status_t were defined outside the Packet class, then status_t used in the
out-of-block declaration would still resolve to Packet::status_t.
111
SystemVerilog Reference
Classes
Parameterized Classes
Class declarations can use parameters, similar to module declarations, for example:
class Buffer #(int size = 8);
reg [size-1 : 0] buff;
function integer get_size;
return $bits (buff);
endfunction
endclass
The declaration shown above declares class Buffer that uses one parameter (size). The default value of the
parameter is 8. This value can be overridden at instantiation. The listing below shows module test with the
instantiation of the class:
module m;
Buffer#(16) p;
initial begin
p = new;
$display ("Size = %d", p.get_size());
end
endmodule
The default value 8 of parameter size is overridden at instantiation with 16. Note that the syntax is consistent with
module instantiation and interface instantiation.
The combination of a generic class and the actual parameter values is called a specialization.
The listing below shows defining a new type (Buffer16 using the typedef statement and a specialization of class
Buffer.
typedef Buffer#(16) Buffer16;
Module m contains two instantiations of the Buffer class: one using Buffer specialized with the default type int
and the other with structure type s_t.
typedef struct {
int i;
real r;
} s_t;
module m;
112
SystemVerilog Reference
Classes
Assigning a parameter value by ordered list implies to specify each parameter that precedes the parameter to be
assigned, since in the instantiation, the parameter has to be on the same position as in the declaration.
In the example below, there is a class instantiation with ports assigned by ordered list. Even though there is only one
parameter without a default value (P2), the parameters T1 and P1 have to be also specified since the P2 parameter
has to be placed on the proper position of the ordered list. Only the T2 parameter that follows after the P2 parameter,
can be omitted.
class B #(type T1 = real, parameter real P1 = 12.41, parameter byte P2, type T2 = reg[7:0]);
endclass
parameter real p = 8.71;
B #(real,p,8'b00110101) cl_b = new();
Equivalence of Specializations
Two class specializations are equivalent if their parameters are identical. The example below shows class C and two
specializations of the class: C1 and C2.
class C#( type T = int, int w = 1 );
endclass
typedef real r_t;
typedef C#( real, 2 ) C1;
typedef C#( r_t, 1+1 ) C2;
Because parameters used for both specializations are the same (although not lexicographically identical) classes C1
and C2 are equivalent. Therefore, a handle to C1 can be assigned to C2 and vice versa.
113
SystemVerilog Reference
Classes
Parameters declared with the parameter and localparam keywords are local to the class and cannot be
overridden when instantiating the class (unlike parameters declared with the parameter port list syntax #(<type>
<name>=<value>)).
114
SystemVerilog Reference
Classes
Typedef Class
The typedef class statement should be used whenever a class variable has to be declared before a complete
class declaration. The example below shows such a scenario. Two classes Node and Root are used. Objects of type
Node contain property r of type Root. On the other hand, objects of type Root reference properties of type Node.
typedef class Root;
class Node;
Root r;
int id;
endclass
class Root;
Node n[];
endclass
The typedef class statement used at the beginning of the listing resolves the circular dependency. It indicates that
Root is a type that will be declared further down in the source code text. This allows a successful compilation of class
Node. A complete declaration of class Root must be provided in the same compilation unit after the declaration of
class Node.
Keyword class (in the typedef class statement) is optional. The example will compile cleanly also if you use
typedef Root; instead of typedef class Root;. However, using the class keyword improves code legibility
by indicating that the forward typedef'ed type is a class.
115
SystemVerilog Reference
Classes
Memory Management
Memory management in SystemVerilog is automatic. The simulator allocates memory when a new object is created.
The memory is reclaimed when the object is no longer needed, for example when it goes out of the scope or all
references to the object are destroyed.
The first listing shows an automatic task t. Whenever the task is called, it creates a new object f of type Frame.
When the task completes, variable f goes out of the scope so the simulator frees the memory allocated for f.
task automatic t( );
Frame f = new( 200, BULK );
f.fill();
#100;
f.send();
endtask
Another example shows an initial block with two instances of the Frame class. Two objects of type Frame are
created and then the handle stored in f is overwritten with the handle stored in g. At that point no handle points to the
first object; there is no way the user code can access that object so the simulator can delete it and reclaim the
memory.
Frame f, g;
initial begin
f = new( 200, HID); //The first object.
g = new( 100, BULK); //The second object.
f = g; //Both handles point to the second object.
//No handle points to the first object.
end
116
Assignment Statements
Assignment Patterns
Assignment patterns allows you to assign a set of values to elements of an aggregate data type. An assignment
pattern is a list of values separated by comas, enclosed in braces and prefixed with an apostrophe. The construct can
be used on both the left-hand or the right-hand side of an assignment if a self-determined data type is placed on the
opposite side.
module top;
int v,x,y,z;
int arr1[4] = '{6, 7, 8, 9};
int arr2[3] = '{1, 2, 3};
initial begin
arr1 = '{v, x, y, z};
'{x, y, z} = arr2;
end
endmodule
It is allowed to use empty assignment patterns on the right-hand side of assignments. Such assignments clear the
contents of an aggregate and set its size to zero. SystemVerilog specification allows assigning empty patterns to
queues. Aldec Inc. extends this functionality to dynamic and associative arrays.
module top;
int que[$] = '{};
byte dyn[];
reg[15:0] asc[string];
initial begin
dyn = '{};
asc = '{};
end
endmodule
Note that assigning an empty pattern to a fixed-size array is not allowed. The assignment below shall trigger an error:
logic arr[4] = '{}; // error
117
SystemVerilog Reference
Assignment Statements
In the below example, an assignment pattern expression is used in the assignment to an assignment pattern. If the
assignment pattern was used instead of the assignment pattern expression an error would be triggered because none
of the assignment sides would determine the type.
module m;
typedef struct {bit [7:0] a; reg [7:0] b; int c;} R;
var byte a, b, c;
var int d;
initial R'{a, b, d} = '{2, 4, 6};
endmodule
It is possible to assign an empty assignment pattern expression to a queue, dynamic array or an associative array to
clean the contents of an aggregate and set its size to zero.
module top;
typedef int T;
typedef int QQ[$];
QQ que;
T dyn[];
T ass[int]=T'{};
initial begin
dyn = T'{};
que = QQ'{};
end
endmodule
Assignment Keys
Assignment keys are colon-separated statements that precedes consecutive values in an assignment pattern.
Assignment keys allows you to assign values to one or more aggregate fields or members.
To indicate a specific field of an array or a specific member of a structure use the index key or the member key,
respectively.
struct {real a1; int a2;} tss;
int arr[2];
initial begin
tss = '{a1:9.72,a2:321}; // member keys
arr = '{0:34,1:54};
// index keys
end
The type key assigns values to all fields or members of the specified data type.
struct {bit [31:0] a1; integer a2; int a3; int a4;} str;
initial str = '{int:12, a1:255, a2:7}; // 12 is assigned to all elements of the int type
Use the default key to assigning values to all aggregate elements that do not have a value specified with the type,
index or member keys.
typedef logic [15:0] T1;
int arr[10];
struct {bit [31:0] c1; int c2; T1 c3; shortint c4;} s1;
initial arr = '{default:5}; // sets all elements to 5
initial s1 = '{T1:11, c4:16 , default:3}; // sets c1 and c2 to 3
118
SystemVerilog Reference
Assignment Statements
If assignment keys are not specified, then the positional notation is used, that is, the position in a pattern assignment
determines to which field or member a value should be assigned.
integer arr[4] = '{1, 5, 8, 11}; // the positional notation
The positional notation and the notation with the assignment keys cannot be used together in one assignment pattern.
If an assignment pattern is used on the left side of an assignment, the following conditions must be met:
The positional notation must be used; It is not allowed to use assignment keys.
module top;
int ABC[2];
119
SystemVerilog Reference
Assignment Statements
int a,b;
initial '{1:a, 2:b} = ABC; // illegal keys on left-hand side are not allowed
initial '{a,b} = ABC;
// legal
endmodule
Each member expression must have a bit-stream data type which is assignment compatible with the
corresponding element on the left side of the assignment.
The number of bits of the corresponding elements must match.
NOTE: There are some differences in the way in which pattern assignments placed on the left-hand side of an
assignment are treated in the default mode and in the strict LRM mode. See User's Guide | SystemVerilog Simulation
| Strict LRM Mode | Assignment Patterns for details.
120
SystemVerilog Reference
Assignment Statements
In some cases, as in the preceding example, both forms give the same effect. Nevertheless, these two constructs
have different properties. The most significant difference is that an unpacked array concatenation can be composed of
both simple elements and arrays.
module top;
int arr1 [$] = '{0, 1, 2};
int arr2 [] = '{8, 9, 10};
initial
begin
arr1 = {arr1, arr2,100}; // '{0, 1, 2, 8, 9, 10,100}
arr2 = {arr1, arr2}; // '{0, 1, 2, 8, 9, 10, 100, 8, 9, 10}
end
endmodule
NOTE: Whole arrays as elements of concatenation are supported only for queues and dynamic arrays.
As in the case of the pattern assignments, unpacked array concatenations can be empty. Assigning an empty array
concatenation results in clearing the contents of an aggregate and setting its size to zero. SystemVerilog specification
allows assigning empty concatenations to queues. Aldec Inc. extends this functionality to dynamic arrays. It is not
allowed to assign an empty concatenations to fixed-size arrays.
module top;
int que[$] = {};
byte dyn[] = {2,3,4};
int arr[3];
initial begin
dyn = {};
arr = {}; // error: assigning empty concatenation
// to fixed-size array is not allowed
end
endmodule
The Following constructs and properties allowed in pattern assignment are forbidden in array concatenation:
a syntax resembling replications i.e
'{ n{element}}
121
SystemVerilog Reference
Assignment Statements
setting array to default values and setting default values for explicit type
int arr3[5] = '{default:2};
Limitations
Use of fixed-size arrays inside an array concatenation or as a target of such assignment is not supported in
the current release.
122
Functions
Formal Arguments
Function ports can be of type input, output, inout, and ref, similarly to task ports. If the direction is not specified
in the argument declaration, the default direction is the input direction. Once a direction is given, subsequent formals
default to the same direction.
function reg [3:0] f2( int a, b, output reg [3:0] c, d );
c = a[4:1];
d = b[9:6];
endfunction
Lifetime
Functions in Verilog can be either static or automatic. Task arguments and local variables are shared between all calls
to a static function and unique for each call to an automatic function.
SystemVerilog adds an additional level of flexibility by allowing you to declare:
Automatic variables within static functions.
Static variables within automatic functions.
123
SystemVerilog Reference
124
SystemVerilog Reference
output c;
endclocking
function void f_ext(reg[3:0] i);
assign a=i;
->e;
r <= i;
r <= #10 i+1;
->>e;
cb.c <= ##2 i;
r <= @e i+2;
endfunction
125
SystemVerilog Reference
Tasks
Formal Arguments
Task ports can be of type input, output, inout, and ref. If there is no direction in function argument declaration,
the default direction is the input direction. Once a direction is given, subsequent formals default to the same direction.
task t1(a, b, output int c, v);
// ...
endtask
Lifetime
Tasks in Verilog can be either static or automatic. Task arguments and local variables are shared between all calls to
a static task and unique for each call to an automatic task.
SystemVerilog adds an additional level of flexibility by allowing you to declare:
Automatic variables within static tasks.
Static variables within automatic tasks.
task automatic t3;
static int x;
int y;
x++;
y++;
endtask
126
SystemVerilog Reference
127
SystemVerilog Reference
Pass by Value
Pass by value works by copying each argument into the subroutine area. If the subroutine is automatic, then the
subroutine retains a local copy of the arguments in its stack. If the arguments are changed within the subroutine, the
changes are not visible outside the subroutine.
Pass by Reference
Passing an argument by reference requires preceding the argument declaration with the ref keyword, for example:
task automatic t( ref int i[1000] );
Arguments passed by reference are not copied into the subroutine. Instead, the routines receives the reference and
can access the argument data via the reference. If the subroutine changes the argument data, that change is visible in
the calling context.
Passing by reference can be used to avoid copying large arguments to the subroutine. It also allows sharing a piece
of data that is not declared global.
If it is desired to prevent task or function from changing passed argument, reference can be declared as constant.
function automatic f(const ref int a);
Limitations
Elements of unpacked arrays are not supported as ref arguments. This applies to fixed-size arrays as well
as dynamic arrays, associative arrays, and queues.
128
SystemVerilog Reference
The optional direction can be input, inout, or ref (defaults are not allowed for output ports). The default_value
expression is evaluated in the scope containing the subroutine declaration each time a call using the default is made.
If the arguments with default values are omitted in the subroutine call, then the default values are used. Omitting an
argument without a default value is illegal.
integer a, b, c;
task automatic t(
input integer _i = 2,
inout integer _j = a,
ref integer _k = b
);
_k = _i + _j;
_j = _i + 2;
endtask
initial begin
t( 1, a, b ); $display( "%0d %0d %0d\n", a, b, c ); // 3 x x
t( 1, a, c ); $display( "%0d %0d %0d\n", a, b, c ); // 3 x 4
t( , a,
); $display( "%0d %0d %0d\n", a, b, c ); // 4 5 4
end
Both positional and named arguments mapping of subroutine call is allowed, but positional binding must precede
name binding.
t( 4, 0, .f(0.5) );
129
**
left
*/%
left
+-
left, binary
left
left
left
&
left, binary
^ ~^ ^~
left, binary
left, binary
&&
left
||
left
?:
-> <->
right
concatenation
is equivalent to
(1 - 2) + 3
130
SystemVerilog Reference
rather than
1 - (2 + 3)
Assignment Operators
SystemVerilog supports the simple assignment operator (=). Additionally, a number of C-like assignment operators
and special bitwise assignment operators are available: +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=, <<<=, and >>>=.
The assignment operator is semantically equivalent to a blocking assignment.
a += b;
c ^= d;
An expression in SystemVerilog can include a blocking assignment, provided it does not have a timing control. These
blocking assignments must be enclosed in parentheses. It is illegal to include an assignment operator in an event
expression, in an expression within a procedural continuous assignment, or in an expression that is not within a
procedural statement.
a = (b = c+5);
SystemVerilog includes increment and decrement assignment operators, both in the prefix and postfix forms: ++i,
--i, i++, and i--. They do not need parentheses when used in expressions. These operators also behave as
blocking assignments.
Usage
Description
==?
!=?
The following assignment will assign value 1 to res. (Z in the right operand is a wildcard that matches 0.)
res = (4'b1110 !=? 4'b111Z);
The ==? and !=? operators may result in X if the left operand contains an X or Z that is not being compared with a
wildcard in the right operand. For example:
res = (4'b111Z ==? 4'b1111);
131
SystemVerilog Reference
Real Operators
The unary operators ++ and -- can have operands of type real and shortreal (the increment or decrement is by
1.0). The assignment operators +=, -=, *=, /= can also have operands of type real and shortreal.
Concatenation
The concatenation is expressed by using brace characters ({ and }) around expressions separated with commas, for
example:
{i, i[7:0], r, 8'h0F }
The result of the concatenation operation is the value resulting from joining together of bits from each expression.
Concatenation can be placed on either side of the assignment.
initial begin
int i, j, k;
k = 10;
{i, j} = {k, k};
end
Concatenation can also be performed on objects of type string. The result of the concatenation is a string if at least
one of the operands is of type string.
string s1
string s2
string s3
$display(
= " ";
= "string";
= {"This is", s1, s2, " s3."};
"%s", s3 ); // Displays 'This is string s3.'
Replication
A replication (also referred to as multiple concatenation) is created by prefixing a concatenation with a constant
expression and enclosing everything with another set of braces. The constant value should be positive. It must not
contain X or Z values.
The example below shows how to concatenate four copies of value 8'hE5. (The result is 32 bit wide.)
{ 4{ 8'hE5} }
A more elaborate example is shown below. The concatenation consists of three elements (r, arr, 1'b0); it is
replicated three times to yield a result that is 30 bit wide.
integer i;
reg r;
reg[7:0] arr;
i = { 3{ r, arr, 1'b0 }};
132
SystemVerilog Reference
If object is of type string, the replication operator can be used with a non-constant multiplier, for example:
int i = 3;
string str = {i{"x y z"}}; // The result is: str = x y zx y zx y z
Aggregate Expressions
The following objects can all be used as aggregate expressions:
An unpacked structure.
An array data object.
An aggregate expression.
A multi-element slice of an unpacked array.
Aggregate expressions can be copied in an assignment, through a port, or as a subroutine argument. They can also
be compared with equality or inequality operators. To be copied or compared, the expressions must be of equivalent
types.
Operator Overloading
NOTE: The construct is not supported in this release. Please contact Aldec Support to receive the latest status.
133
SystemVerilog Reference
//
//
//
//
Conditional Operator
The conditional operator requires three operands separated by ? and ::
<condition> ? <expr> : <expr>
If <condition> is true, the operator returns the value of the first expression without evaluating the second. If it is
false, it returns the value of the second expression without evaluating the first. If <condition> evaluates to an
ambiguous value (i.e. x or z), then both expressions are evaluated and their results are combined bit by bit. A result
bit equals 0 if the respective bits in the first and the second expression equal 0. A result bit equals 1 if the respective
bits in the first and the second expression equal 1. All other bits are set to x.
Note that the conditional assignment and the if statement in the listing below are not equivalent. (The values
assigned to i may be different when cond evaluates to an ambiguous value.)
i = cond? a : b;
if( cond )
i = a;
else
i = b;
SystemVerilog allows using the conditional operator with nonintegral types and aggregate expressions. If both first
expression and second expression are of integral type, the operation proceeds as defined. If first expression or
second expression is an integral type and the opposing expression can be implicitly cast to an integral type, the cast is
made and proceeds as defined. For all other cases, the type of the first expression and second expression must be
equivalent.
Inside Operator
The inside operator checks whether the value of the expression from the left-hand side is present on the right-hand
side list.
The syntax is as follows:
<expr> inside {list}
The left-hand side expression has to be a singular expression (aggregate types are not allowed).
For nonintegral expressions, the inside operator uses the equality (==) operator to perform a comparison. If at least
one value on the list is equal to the left-hand side expression, the inside operator returns 1'b1. Otherwise, 1'b0 is
returned.
real rv = 9.66;
if ( rv inside {9.72, 14.1, 9.66, 1.683} ); // the result is 1'b1
134
SystemVerilog Reference
integer dt = 12;
integer darr[] = new[3]('{11, 12, 16, 18});
if ( dt inside {7, darr} ); // arrays are allowed on the right-hand list
For integral expressions, the wildcard equality operator is used (==?), so that the x or z bits on the right-hand side of
the expression are treated as do-not-care values. On the left-hand side, the x or z bits are treated as they are.
reg [2:0] logvar;
while ( logvar inside {3'b1x1} ); // matches 3'b101, 3'b111, 3'b1x1, 3'b1z1
if ( logvar inside {3'bz01} );
// matches 3'bz01, 3'bx01, 3'b001, 3'b101
If no match is found, but some of the comparisons resulted in x, the inside operator will return 1'bx.
n = 3'b11x;
res = n inside {3'b1z1, 3'b010};
// res = 1'bx
When specifying members of the list, a range of values can be used. The list from the example below contains all
numbers from 2 to 4 and from 7 to 11.
int intvar;
logic logvar = intvar inside { [7:11], [2:4] };
If the left bound is higher than the right bound, the range contains no values.
135
Selection Statements
Keywords unique and priority can be also used with casex and casez constructs.
136
SystemVerilog Reference
See the Operators and Expressions section for information on how the inside operator is evaluated.
int q[$] = '{5,7};
initial
case (case_expr)
[2:4]
:
3, q
:
3'b?00, [1:3] :
inside
statement1;
statement2;
statement3;
//
//
//
//
default : default_statement; //
endcase
Pattern Matching
NOTE: The construct is not supported in this release. Please contact Aldec Support to receive the latest status.
137
SystemVerilog Reference
Loop Statements
Variables declared in the loop are local to the loop and they cannot be modified outside it.
The following syntax introduced in IEEE Std 1800-2012 is supported:
for ( [ for_initialization ] ; [ expression ] ; [ for_step ] )
The statements controlling the execution of the for loop that is: for_initialization, expression and
for_step are optional according to IEEE Std 1800-2012. For more information, see 12.7 in IEEE Std
1800-2012.
foreach Loop
There is a possibility to use the foreach loop in SystemVerilog. The foreach loop specifies an iteration over the
elements of an array. Each loop variable corresponds to one of the dimensions of the array.
foreach (vect_a [i])
vect_a[i] = i+1;
foreach ( arr1 [i,j,k])
arr1[i][j][k] = i+j+k;
138
SystemVerilog Reference
The number of loop variables must match the number of dimensions of the array variable. Empty loop variables can
be used to indicate no iteration over that dimension of the array. Loop variables are automatic and read-only, and their
scope is local to the loop.
Jump Statements
Loops may include break and continue control statements. The break statement terminates the execution of the
enclosing loop. The continue statement terminates the current iteration of the enclosing loop (and resumes the next
iteration).
// SystemVerilog Extension
begin
i = 0;
forever begin
i = i+1;
if (i>5)
break;
if (i % 2)
continue;
end
end
The break and continue statements are not supported in Verilog'95 or Verilog 2001.
Tasks and functions may include the return statement. In a function returning a value, return must have an
expression of the correct type. The return statement can be also used without an expression in tasks and void
functions.
task t1(input byte i1, output string o1);
if (i1 < 5)
begin
o1 = "left";
return;
end
else if (5<=i1 && i1<9)
$fatal(0,"i1 in not allowed range. Exiting");
else
begin
o1 = "right";
return;
end
endtask : t1
139
SystemVerilog Reference
Final Blocks
The final block is executed at the end of simulation time in zero time in a single simulation cycle. The final blocks
can only contain statements allowed in a function. This guarantees that the block will execute within a single
simulation cycle.
Example
assert property (CheckDataSeq) ++pass_count; else ++error_count;
final
begin : final_stat
$display("The CheckDataSeq property was executed %0d times",pass_count+error_count);
$error("The property fails %0d times",error_count);
$warning("The property passes %0d times",pass_count);
end : final_stat
140
SystemVerilog Reference
iff Qualifier
The SystemVerilog iff qualifier enhances the event control, for example:
always @(Q iff EN==1)
D <= Q;
The event expressions triggers only if the condition after iff is true. The iff operator has precedence over or. Note
that in the example shown above, the expression is evaluated only when Q changes, not when EN changes. The event
expression can also denote a clocking block name (with no edge qualifier) to be triggered by the clocking event.
Sequence Events
NOTE: The construct is not supported in this release. Please contact Aldec Support to receive the latest status.
The <eventname.triggered> property remains true throughout the time step. This allows preventing race conditions
such as the race shown in the listing below.
fork
@(e);
->e;
join
The fork-join statement may or may not complete depending on the order of execution of -e> and @(e)
statements. (The simulator is allowed to execute those statements in an arbitrary order.) The example re-written using
the e.triggered property is shown in the listing below:
fork
wait(e.triggered);
->e;
join
The wait (e.triggered) statement (contrary to the @(e) statement) will never block because the e.triggered
property remains true throughout the time step, regardless of the order of execution of the statements in the
fork-join block.
141
SystemVerilog Reference
142
SystemVerilog Reference
initial begin
#1; c2 = watch_me;
#1; ->c2.e; // Event triggered.
#1; watch_me = c1; // Changing the handle does not trigger the event.
#1; ->c2.e; // Event triggered even though watch_me points now to c1.
#1; ->c1.e; // Event triggered. However, this event would not trigger
// should the previous statement be commented out.
end
endmodule
Note that assignment to the handle does not trigger the event.
Waiting on a Method
Let us assume that:
hnd is a class handle.
fn is a method defined inside the class pointed by hnd.
Method fn is not a static method.
If the event control operator is applied to hnd.fn then hnd.fn is treated as an expression.
The method is reevaluated whenever
Any dynamic member in the object pointed by hnd changes.
Any argument changes. (Same as for regular functions used under @.)
Note that changes to static members are ignored.
class C;
bit b1;
bit b2;
function bit fn;
$display("Function evaluated at time %0t.", $time);
return b2;
endfunction
endclass
module top;
C watch_me = new, c2 = new, c3;
always @(watch_me.fn)
$display("Event triggered at time %0t.", $time);
initial begin
c3 = watch_me;
#1; watch_me = c2; // Handle changed but event not triggered.
// (The value returned by watch_me.fn has not changed.)
#1; c2.b2 = 1;
// Function re-evaluated and event triggered.
#1; watch_me = c3; // Handle changed and event triggered again.
end
endmodule
NOTE: The description on this page applies to event control applied via an explicit class handle. It is irrelevant for
event control on the implicit this handle inside class methods.
143
SystemVerilog Reference
Other Statements
Named Blocks
The name of a block statement may be repeated when the block is closed. In the example below block names are
repeated for the fn1 function and the fj1 fork-join block.
// SystemVerilog Extension
function integer fn1 (input integer i);
//...
endfunction : fn1
initial begin
fork : fj1
//...
join : fj1
end
Statements Labels
All SystemVerilog statements (while, if, etc.) can be labeled. In the code below labels l1 through l9 have been
assigned to various behavioral statements.
// SystemVerilog Extension
module labels;
integer a,b,c,i,n;
initial
l1 : begin
l2 : if (a>b)
begin
l8 : c = a;
end
else
l3 : begin
l4 : c <= b;
end : l3
l5 : begin
l6 : for (i=0; i<n; i=i+1)
l7 : a = a+1;
end : l5
end : l1
endmodule
144
SystemVerilog Reference
Disable Statement
SystemVerilog allows using the disable statement with named blocks and labeled statements. Behavior for both
ways is the same. Disabling statement with label is not supported in this release. Please contact Aldec Support to
receive the latest status.
145
Processes
Always Processes
SystemVerilog introduces three new always processes:
always_comb
always_latch
always_ff
The suffixes (_comb), _latch, and _ff) indicate design intent (combinational, latched, or sequential logic) to
synthesis and formal verification tools.
always_ff
The always_ff block models sequential logic, for example:
always_ff @(posedge clock iff reset == 0 or posedge reset) begin
r1 <= reset ? 0 : r2 + 1;
end
The always_ff block can contain only one event control and no blocking timing controls.
146
SystemVerilog Reference
Processes
Description
join
The parent process blocks until all the processes spawned by this fork complete.
join_any
The parent process blocks until any one of the processes spawned by this fork completes.
join_none
The parent process continues to execute concurrently with all the processes spawned by the fork.
The spawned processes do not start executing until the parent thread executes a blocking statement.
A fork-join construct cannot be used inside a function. When used in a task, it must not contain the return statement.
147
SystemVerilog Reference
Processes
Process Control
SystemVerilog provides the following constructs that allow one process to terminate another process or wait for its
completion.
wait fork
disable fork
disable
The wait fork statement waits for completion of processes spawned with a fork statement. The disable fork
statement disables immediate child processes of the current process. The disable statement stops all activity within
a named block or a task without paying heed to parent-child relationships.
wait fork
The wait fork statement blocks the execution flow until all processes forked by the current process complete. The
descendants of forked processes (if any) are ignored and do not block execution.
fork
...
...
join_none
wait fork;
In the following example, the do_test task spawns processes and blocks until either of them (exec1 or exec2)
completes. Next, two more processes are spawned. The wait fork statement following the two fork-joins waits until
all processes in both the fork-join blocks finish execution.
task do_test;
fork
exec1();
exec2();
join_any
fork
exec3();
exec4();
join_none
wait fork; // block until exec1 ... exec4 complete
endtask
disable fork
The disable fork statement terminates recursively all processes forked-off by the current process.
fork
...
...
join_any
disable fork;
In the example below, task get_first spawns three versions of a task that wait for a particular device (1, 7, or 13).
Task wait_device waits for a particular device to become ready and then returns the device address. When the first
device becomes available, task get_first resumes execution and kills the outstanding wait_device processes.
148
SystemVerilog Reference
Processes
149
SystemVerilog Reference
Processes
Class process
Class process is a built-in class that allows one process to control another. The prototype for the process class is
shown below:
class process;
typedef enum { FINISHED, RUNNING, WAITING, SUSPENDED, KILLED } state;
extern
extern
extern
extern
extern
extern
endclass
The user can declare variables of type process and use them in his code, for example:
module top;
process p1;
std::process p2;
initial begin
p1 = process::self();
p2 = process::self();
//...
end
endmodule
Note that it is not possible to create objects of type process. (The process class cannot be instantiated with
operator new.) Neither it is possible to extend the process class.
Process Methods
Prototype
Description
self()
status()
kill()
await()
A task that allows the current process to wait for the completion of another process.
suspend()
resume()
In the example below, the initial block forks three processes. Process handles are stored in the parr array. The
block controls the processes with kill, suspend, and resume methods. The status of all processes is printed by the
150
SystemVerilog Reference
Processes
show_status task.
module top;
parameter numproc = 3;
process parr[0:numproc-1];
task show_status;
process::state status;
for( int i = 0; i < numproc; ++i ) begin
status = parr[i].status();
$display("Process num %0d, status at time %0t - %s.", i, $time, status.name);
end
endtask
initial begin
for ( int i = 0; i < numproc; ++i ) begin
fork begin
automatic process me = process::self();
parr[i] = me;
#35;
end
join_none
#0;
end
#10;
#10; parr[0].kill;
#10; parr[1].suspend;
#10; parr[1].resume;
end
endmodule
show_status;
show_status;
show_status;
show_status;
//
//
//
//
All
0 0 0 -
processes
KILLED; 1
KILLED; 1
KILLED; 1
151
WAITING.
- WAITING;
2 - WAITING
- SUSPENDED; 2 - WAITING
- RUNNING;
2 - FINISHED
Overview
The SystemVerilog constrained random generation feature allows generating complex random stimulus. The user
defines a container for data alongside constraints for data values. The constraints must be observed (or solved) by the
generation process.
The mechanism is based on SystemVerilog classes. Each class member can be marked as a random variable by
using rand or randc modifiers. Constraints are defined in constraint blocks, which are named items declared
inside the class body. An instance of a class with random members and constraints can be randomized by calling the
randomize method against the class handle.
The example below shows class Packet with two properties marked with rand modifiers. The constraint block
inside the class specifies constraints for property address. The randomize method will observe the constraints and
randomize addr with values less than 8'h0f. No constraints are assigned to property data so it will be randomized
with all possible values.
class Packet;
rand reg [7:0] addr;
rand reg [7:0] data;
constraint addr_dist {
addr < 8'h0f;
}
endclass
module top;
Packet p;
initial begin
p=new;
repeat(10)
#10 p.randomize();
end
endmodule
Constraints can be manipulated by the user; for example he can turn them on or off to achieve the desired stimulus.
SystemVerilog supports a wide variety of data types and operators for randomization.
152
SystemVerilog Reference
Rand Modifier
Variables declared with the rand modifier are randomized with a uniform distribution.
class packet;
rand int m_rdata; //random variable
int m_data;
endclass
typedef struct {
rand int f_ra; //random variable
int f_a;
} Ts;
Randc Modifier
Variables declared with the randc modifier are random-cyclic. It means that the variable will not be assigned the
same randomized value until all available values form the declared range are randomized. See the example given
below. Each object instance has its own randc sequence calculated independently for each variable declared with
randc modifier. These sequences are calculated during the first randomization of each variable declared randc. All
types allowed to be declared rand can also be declared randc. Exceptions are unpacked structures and object
handles. Declaring randc any of these will trigger an error.
class C;
randc bit[1:0] a;
endclass
module top;
C c = new;
initial begin
repeat(4) begin
c.randomize();
$display(c.a); // possible values randomized in successive iterations of the loop: 1-2-0-3
end
// for the given example permutation like 1-2-2-3 will never occur
end
endmodule
It is suggested to use randc modifier wisely - randomizing variables wider than 8 bits may drastically slow down the
simulation.
153
SystemVerilog Reference
rand_mode state of the random variable. In this case, the rand_mode argument is obligatory. The argument for
rand_mode can be:
1 turns the variable 'ON' (the random variable is active, all random variables are active by default prior to
calling rand_mode on them).
0 turns the variable 'OFF' (the random variable is inactive, it will be treated as a state variable).
If rand_mode is invoked as a function (in expression context) then it returns the current state of the random variable.
When called in expression context then rand_mode should not have arguments.
class C;
rand int x;
endclass
module top;
C c = new;
initial begin
c.x.rand_mode(0);
variable
c.randomize();
$display(c.x.rand_mode());
inactive now
end
endmodule
If rand_mode is called as a statement, it can be called only on random variables or object handles. If it is called on the
object handle then rand_mode sets the state of all random variables defined inside the object. If rand_mode is called
as a function, it can be called only on singular random variables.
Rand mode, as a statement, can be called on a random variable (declared rand or randc) of type:
Unpacked array - it will change the state of all array elements.
Unpacked array element - it will affect the state of the selected element only.
Unpacked struct - it will change the state of the unpacked struct variable and all its members.
Unpacked struct member - it will change the state of the selected member only.
Object handle - it will change only the state of this handle.
A compile error will occur, if the specified variable does not exist or it exists but it is NOT a random variable (declared
rand or randc, object handles are exceptions to this rule). See the example below:
class B;
rand int i;
int j;
endclass
class C;
int x;
B b;
rand B b_r;
endclass
module top;
C c = new;
initial begin
c.y.rand_mode(1); // An error will occur, variable does not exist
c.x.rand_mode(0); // An error will occur, variable is not declared rand or randc
c.b.rand_mode(0); // This call is correct. b is not a random variable but it is an object handle so
this call sets c.b.i rand state
c.b_r.rand_mode(0); // The object handle is a random variable - such call will affect only the
154
SystemVerilog Reference
If a variable declared rand or randc is static, its rand_mode state is also static. Changing the variable to be active or
inactive will change its behavior in all instances of the base class.
NOTE: The rand_mode() method is built-in and cannot be overridden.
155
SystemVerilog Reference
Random Variables
Random variables are variables randomized with the randomize function. A variable becomes a random variable if it
is passed as an argument to the randomize function or declared with the rand modifier in a class or an unpacked
structure. Types allowed for random variables in SystemVerilog are listed below.
Integral type variables can be declared as rand/randc class properties and randomized with the randomize class
method.
class C;
rand int i;
rand reg [3:0] vec;
endclass
Unpacked Arrays
Unpacked arrays are supported for randomization. This can be done by calling the std::randomize() function with
an array identifier on the argument list or by invoking the randomize() class method. For the latter case, the array
as a class member can be declared with the rand or randc modifier. An unpacked array being an unpacked
structure member can be declared with the rand or randc modifier as well. Randomization of multidimensional
arrays is allowed. As a result, all array elements are randomized.
Example for Unpacked Arrays:
class C;
rand int x[1:0][3:0];
endclass
module top;
reg[3:0] y[7:0];
C c = new;
initial begin
156
SystemVerilog Reference
std::randomize(y);
c.randomize();
end
endmodule
Limitations:
Unpacked arrays of class handles and unpacked arrays of unpacked structures are not supported for
randomization yet.
Dynamic Arrays
Dynamic arrays are supported for randomization. This can be done by calling the std::randomize() function with
an array identifier on the argument list or by invoking the randomize() class method. For the latter case, the array
as a class member can be declared with the rand or randc modifier. A dynamic array being an unpacked structure
member can be declared with the rand or randc modifier as well. Randomization of multidimensional arrays is
allowed. As a result, all array elements are randomized.
Example for Dynamic Arrays:
class C;
rand int a[];
rand int b[][];
function set_size(longint x, longint y);
longint i;
a = new [x];
b = new [x];
for ( i = 0; i < x; i++ ) begin
b[i] = new [y];
end
endfunction
endclass
module top;
int i;
int a[] = new [4];
C c = new;
initial begin
c.set_size(2,4);
std::randomize(a); // all 'a' array elements are randomized
c.randomize();
// all array elements in 'c' are randomized
std::randomize(a) with {a[1] > 0;}; // a[0] must be greater than 0
c.randomize() with {a[0] != a[1];}; // c.a[0] and c.a[1] must not be equal
end
endmodule
Limitations:
Dynamic arrays of class handles and dynamic arrays of unpacked structures are not supported for
randomization yet.
Using whole dynamic arrays inside constraints is not supported yet.
Using dynamic array slices inside constraints is not supported yet.
157
SystemVerilog Reference
Queues
Queues are supported for randomization. This can be done by calling the std::randomize() function with a queue
identifier on the argument list or by invoking the randomize() class method. For the latter case, the queue as a
class member can be declared with the rand or randc modifier. A queue being an unpacked structure member can
be declared with the rand or randc modifier as well. Randomization of multidimensional queues is allowed. As a
result, all queue elements are randomized.
Example for Queues:
class C;
rand int a[$] = '{1, 2, 3};
endclass
module top;
int a[$] = '{4, 5, 6};
C c = new;
initial begin
std::randomize(a); // all 'a' queue elements are randomized
c.randomize();
// all queue elements in 'c' are randomized
std::randomize(a) with {a[1] > 0;}; // a[0] must be greater than 0
c.randomize() with {a[2] != a[1];}; // c.a[2] and c.a[1] must not be equal
end
endmodule
Limitations:
Queues of class handles and dynamic arrays of unpacked structures are not supported for randomization yet.
Using whole queues inside constraints is not supported yet.
Using queue slices inside constraints is not supported yet.
Associative Arrays
Associative arrays are supported for randomization. This can be done by calling the std::randomize() function
with an associative array identifier on the argument list or by invoking the randomize() class method. For the latter
case, the associative array as a class member can be declared with the rand or randc modifier. An associative array
being an unpacked structure member can be declared with the rand or randc modifier as well. Randomization of
multidimensional associative arrays is allowed. As a result, all associative array elements are randomized.
Example for Associative arrays:
class C;
rand int a[int] = '{1:1, 2:2, 3:3};
endclass
module top;
int a[*] = '{1:4, 2:5, 3:6};
C c = new;
initial begin
std::randomize(a); // all 'a' associative array elements are randomized
c.randomize();
// all associative array elements in 'c' are randomized
std::randomize(a) with {a[1] > 0;}; // a[0] must be greater than 0
c.randomize() with {a[2] != a[1];}; // c.a[2] and c.a[1] must not be equal
end
158
SystemVerilog Reference
endmodule
Limitations:
Associative arrays of class handles and dynamic arrays of unpacked structures are not supported for
randomization yet.
Using whole associative arrays inside constraints is not supported yet.
159
SystemVerilog Reference
160
SystemVerilog Reference
Constraints Block
A constraint is an expression affecting generation of random values with the randomize method. The solver must
select random values that satisfy constraints (or return an error if this is impossible). A constraint block is a set of
expressions nested inside a class and designated by keyword constraint. The block must be named.
Expressions in the constraints block can use random variables, state variables, and constants. Random variables are
randomized and assigned in the randomize call. State variables are sampled during randomization, they are not
assigned. State variables can have different values in each randomize call. Constants (literals, parameters, const's)
are sampled during randomization, their values are constant in each randomization call.
class packet;
rand int m_rdata, m_rdata1; //random variables
int m_data;
//non random variable
const int c = 10;
//constant
//both m_rdata and m_rdata1 are random
constraint data1_less_data2 { m_rdata < m_rdata1; }
//m_rdata is a random variable, m_data is a state variable
constraint less_than_m_data { m_rdata < m_data; }
//m_rdata is a random variable, c is a constant
constraint less_than_c { m_rdata < c; }
//m_rdata is a random variable, 0 is a literal (also a constant)
constraint greater_than_0 { m_rdata > 0; }
endclass
When a class object is randomized with the std::randomize function (rather than the randomize method) then the
constraint blocks defined in this class are ignored.
161
SystemVerilog Reference
Constraint Inheritance
Constraint blocks follow general rules for inheritance:
Constraints can be inherited from the base class.
Constraints can be overridden in a child class.
New constraints can be added in a child class.
Constraints themselves are not virtual, but method randomize is virtual and always uses constraints from the object
for which randomize was called.
class CBase;
rand int a;
rand int b;
constraint greater_0 {a>0;}
constraint cc {a<b;}
endclass
class CChild extends CBase;
// Constraint "greater_0" is inherited from the base class.
constraint less_10 {a<10;} // Constraint "less0" is a new constraint
// added in this CChild class.
constraint cc {a+b==10;}
// Constraints "c" from CBase is overridden in CChild.
endclass
CBase b=new;
CChild c=new;
initial begin
// greater_0 and c constraints are valid as b points to the CBase class object.
// Constraint c equals {a<b;}.
b.randomize();
b=c;
//greater_0, less_10, and c are valid as handle b points to the CChild class object.
//The meaning of c has changed, it points to "a+b==10".
b.randomize();
//The same constraints are in effect as handle c points CChild class object.
c.randomize();
end
Constraints in virtual (abstract) classes can be declared as pure constraints. Pure constraints do not have actual
constraint defined it just declares the constraint name. Non-virtual class have to override all pure constraints which
they inherits from base abstract classes.
virtual class CBase;
pure constraint base_constraints;
endclass
class CChild extends CBase;
rand int a;
//CChild class is not virtual so constraint "base_constraints"
//have to be overridden. Otherwise an error will occur.
constraint base_constraints {a>0;}
endclass
Operators
Most SystemVerilog expression are allowed in constraints block. Forbidden operators include:
162
SystemVerilog Reference
constr_expr1
constr_expr2
constr_expr3
constr_expr4
{
{
{
{
Set Membership
Set membership operator inside can be used in constraints to define a set of values for a random variable.
constraint constr_inside{ v1 inside { [v2:v3] } ;} // v1 >= v2 and v1 <= 3
// If v2 > v3 then the set is empty.
If arrays are used in the open_range_list of the inside operator, then all their members define the set of correct
values for the inside left-hand side expression. Consider the following example:
typedef enum {START, SYNC, RESET, TRANSMIT32, TRANSMIT64, NEGOTIATE, IDLE} Tstate;
class C;
rand Tstate state;
Tstate mystates[$]='{TRANSMIT32, NEGOTIATE, SYNC};
constraint c_mystates { state inside {mystates}; }
endclass
module top;
C c = new;
initial begin
c.mystates.push_back(START);
repeat(10) begin
assert(c.randomize) else $error("Randomization failure.");
$display(c.state.name);
end
end
endmodule
Implication
With the implication operator (->) the user can define a condition that implies constraints.
constraint constr_implic{ v1_greater_v2 -> v1 > v2; } // If v1_greater_v2 is true then
// v1 should be greater than v2.
163
SystemVerilog Reference
Distribution
Statistical distribution of the values which a randomized variable can assume can be specified by using the distribution
operator in the form of a distribution list:
std::randomize(a) with { a dist { [12:15]:=4, [8:11]:/4, 7:=2, 6:=1, 5:=0, 4:=2 }; };
The distribution list is a comma-separated list of ranges or integral values an expression can assume. Each item in the
list can have its weight specified, which corresponds to the probability for the variable to accept the corresponding
value during randomization. The weights can be assigned to particular items by using the := or :/ operators. If an
item is a range, the := operator assigns the specified weight to each value in the range, while the :/ operator assigns
the specified weight to the range as a whole. In the latter case, the weight is distributed equally between all the values
in the range. For example, the expression [12:15]:=4 assigns each value from the range 12:15 the weight of 4,
while the expression [8:11]:/4 assigns the weight of 4 to the whole range, thus particular values from the range are
assigned the weight of 1.
Values that are not listed in the distribution list will never be assumed by a random variable.
If no other constraints are specified, the probability that a value in a distribution list will match corresponds to its
specified weight. Otherwise, if any constraint contradicts an item in the distribution list, only the constraint will be
satisfied, for example:
std::randomize(b) with { b dist { 1:=1, 2:=3, 7:=1 }; b > 5; }; // b can only assume the value 7
NOTE: The distribution operator does not work as expected when used in the implication or in the if-else construct.
if-else Constraints
It is possible to use if-else style constraint.
constraint constr_ifelse{
if (v1_greater_v2) // If v1_greater_v2 is true then
v1 > v2;
// v1 should be greater than v2,
else
v1 <= v2; }
// otherwise v2 should be greater than v1 or equal.
Iterative Constraints
NOTE: Iterative constraints are not supported in this release. Please contact Aldec Support to receive the latest
status.
Global Constraints
Member objects of a given class that are declared as rand and that themselves are objects of another class subject
to randomization along with the other members of the given class. When a constraint defined in a given class is
applied to a randomized field of its object member, then such a constraint is called a global constraint.
When an object of a given class is to be randomized, i.e. the randomize() method is to be executed on that object,
first, the set of all its active rand fields is determined and then, if the members themselves contain active rand fields,
these are also added to the randomized set. This operation is performed recursively, as long as given objects contain
randomized members. Next, all of the active constraints that apply to the set of randomized objects are gathered.
164
SystemVerilog Reference
After the constraints are resolved, thus collected objects are randomized.
Consider two classes - class A that contains two randomized fields one of which is constrained within that class:
class A;
rand int i, j;
constraint con_a { i > 10; }
endclass
and class B that contains an object of class A, declared as rand. Within the class B, a constraint is defined that is
applied to a member field of the class A object:
class B;
rand A a = new;
constraint con_b { 10 < a.j && a.j < 20; }
endclass
Randomization of the object of class B results in applying the constraints defined in the class B to member fields of
the object of class A:
B b = new;
initial begin
b.randomize();
end
As a result, b.a.i will have a value larger than 10 (according to the constraint defined in the class A), and b.a.j will
have a value between 10 and 20 (according to the constraint defined in the class B).
Variable Ordering
The solve...before construct changes the probability of occurrence of values specified by a constraint block
without changing the set of possible values. This is done by changing the order in which expressions from a constraint
are solved.
In the below constraint, the j value is equal 0 only when i value is false. Although the expression if(i==0) j==0;
else j!=0 suggest that j is determined by i, in fact, the values are determined independently, because the solver
assures the uniform distribution over legal value combinations.
class A;
rand bit i;
rand bit [15:0] j;
constraint c { if(i==0) j == 0; else j != 0;}
endclass
The total number of legal combinations for the {i,j} pair is 216 but i is false for only one of them so the probability of
the occurrence of i=0, and thus, {i,j}={0,'h0000} is 1/216. The following table lists each of the legal value
combinations and their probabilities:
i value j value Probability
0
'h0000
1/216
'h0001
1/216
'h0002
1/216
165
SystemVerilog Reference
...
...
'hfffe
1/216
'hffff
1/216
The solve...before construct allows you to change the distribution of values by determining the order in which
variables are solved.
class B;
rand bit i;
rand bit [15:0] j;
constraint c { if(i==0) j == 0; else j != 0;}
constraint order { solve i before j; }
endclass
The order {solve i before j;} constraint forces the i value to be solved independently with a uniform
distribution before the j randomization. In this case, the probability that the i value is false and {i,j}={0,'h0000}
is 50%. As it can be seen in the table below, the order constraint does not change the set of the legal values
combinations, but changes the probability of their occurrences.
i value j value
Probability
'h0000
0.5
'h0001
0.5 * 1/(216 - 1)
'h0002
0.5 * 1/(216 - 1)
...
...
'hfffe
0.5 * 1/(216 - 1)
'hffff
0.5 * 1/(216 - 1)
Variable ordering can be used to make a value that is randomized with a relatively small probability to appear more
frequently without changing the solution space.
166
SystemVerilog Reference
Eventually, the remaining variables are randomized according to their constraints and calculated function
values.
Such an approach is also called variable ordering. This case of implicit variable ordering may lead to a randomization
failure if random arguments are connected by constraints with other random variables. Note, that additional steps may
be required if random function arguments are used in expression with other function calls, for instance:
(a==f(b); b==f(c);)
Multiple steps may cause circular dependencies to occur. In such cases, randomization fails. The following restrictions
apply to functions that are inside constraint expressions:
They cannot modify constraints.
They cannot have output, input of ref arguments.
They should be automatic.
class C;
function int countones ( bit[3:0] w );
return $countones(w);
endfunction
rand int ones; //If the variable "ones" is not random, the randomization process may fail because
of variable ordering.
rand bit[3:0] rv;
constraint c_ones { ones == countones( rv ) ; }
endclass
module top;
C c =new;
initial repeat(10) begin
assert(c.randomize) $display("%b %d %d",c.rv, c.ones, $countones(c.rv)); else
$error("Randomization failure.");
end
endmodule
Limitations
Function calls are supported with the following restrictions:
Only integral types are supported as arguments.
Only single level of variable ordering is supported.
System functions are treated in the same way as other function calls but the $countones function is not
supported.
Please contact Aldec Support to receive the latest status.
167
SystemVerilog Reference
If constraint_mode is used as a task, then it requires one argument - 0 or 1 - to disable or enable a constraint block.
See the example below:
class C;
rand bit[3:0] b;
constraint c1 {b >= 2;}
constraint c2 {b <= 7;}
endclass
C c = new;
initial begin
c.c1.constraint_mode(0); // Constraint block c1 is now disabled.
c.randomize; // Randomized value for c.b will be in the [0:7] range.
c.c1.constraint_mode(1); // Constraint block c1 is now enabled.
c.randomize; // Randomized value for c.b will be in the [2:7] range.
end
If constraint_mode acts as a function, then it accepts no arguments and returns the status of a given constraint
block: 0 if the constraint block is disabled or 1 if the constraint block is enabled. See the example below:
class D;
rand bit[3:0] b;
constraint c1 {b >= 2;}
endclass
D d = new;
initial begin
d.c1.constraint_mode(0); // Constraint block c1 is now
$display(d.c1.constraint_mode()); // Check and display
// block c1. (0 will
d.c1.constraint_mode(1); // Constraint block c1 is now
$display(d.c1.constraint_mode()); // Check and display
// block c1. (1 will
end
disabled.
the status of constraint
be displayed.)
enabled.
the status of constraint
be displayed.)
When constraint_mode is used as a task then the constraint block name can be omitted; the task will then enable
or disable all constraint blocks in the object.
Constraint Guards
A mechanism is implemented that prevents null pointer references during calls to the randomize method on a class
handle. If the randomization algorithm determines that the class handle is null, then it excludes such a handle from
randomization without reporting a null pointer access during simulation runtime.
class Member;
rand int b;
endclass
class C;
rand int a;
rand Member memb;
endclass
C c = new;
initial
begin
168
SystemVerilog Reference
randomize(c);
end
In the example above, class handle c.memb is null and it will be ignored during randomization. Note that this
mechanism does not safeguard against accessing a constraint through a null handle, i.e. if the user code attempts to
access such a constraint, then a null pointer access error will be reported during simulation runtime.
To avoid such issues, the if-else construct must be used as a constraint guard. In example below, handle cc is
checked first (if(cc!=null)) and constraint cc.a < 10 is applied only if cc != null.
class CC;
rand int a;
endclass
CC cc;
initial
begin
randomize(cc) with {if(cc!=null){cc.a < 10;}};
end
A failure to add a guard would make the call to randomize unsafe. Such a call would trigger a null pointer access
runtime error if handle cc equaled null.
Debugging Constraints
To facilitate the process of debugging, a message about the cause of randomization failure is printed to the Console.
For more information, refer to the Debugging Randomization Failures section in the Randomization and Seed Control
topic.
169
SystemVerilog Reference
Randomization Methods
Randomize Method
Class objects are randomized by calling the randomize method against the handle. All user-defined classes have a
built-in virtual randomize method. Randomization is successful if all random variable values are assigned values
satisfying the constraints. Randomization fails if the solver is unable to solve the constraints, or if the time elapsed for
solving the constraints exceeds the timeout defined with rc_timeout variable. The randomize method returns 1 if
randomization was successful or 0 if randomization failed.
Additionally, the reason of randomization failure may be printed to the console if the verbosity level is set to 1 or 2 in
the rc_verbose variable.
The example shows the C class with the constraint block cnstr. The class contains one property (data) with the
rand modifier. The constraint expressions in the cnstr block use two data properties (min and max) that are
assigned to before each call to randomize.
The first call will succeed and the random variable will be assigned a value from range 5-10. The second call will fail
because no number exists that could meet the constraints, i.e. to be both greater than and less than 10.
module top;
class C;
rand int data;
int min, max;
constraint cnstr { data > min; data < max; }
endclass
C hnd;
initial begin
hnd = new;
hnd.min = 5; hnd.max = 10;
assert (hnd.randomize()); //This call succeeds.
//The random variable data will be assigned a new value from range 5-10.
hnd.min =10; hnd.max=10;
assert (hnd.randomize()); // This call fails.
//No value exists that could fulfill the constraints.
end
endmodule
Inline Constraints
Additional constraints can be included to the already existing object set of constraint blocks by invoking the
hnd.randomize() with{} method. These constraints must be enclosed in braces ({}).
class C;
rand byte b1, b2;
constraint cc {b1 > b2;};
endclass
module top;
C c = new;
170
SystemVerilog Reference
initial
c.randomize() with {b1 < 10; b2 < 10;};
endmodule
In the above example, during the c.randomize() method calling, the inline constraints {b1 < 10; b2 < 10} are
considered along with the cc constraint block.
In the above example, during the c.randomize method calling, only b2 is considered as random member. In this
case, b1 will be treated as the state member.
171
SystemVerilog Reference
In the above example, during the c.randomize() method calling, the current member values are considered when
constraints checking. No new values are assigned to members.
[3:0] b;
module top;
bit
[3:0] b = 6;
C c1 = new;
initial
begin
c1.randomize(b) with {local::b >= 5;}; // <--- local used to consider 'b' from top instead of 'b'
from c1
c1.randomize(b) with {b >= 5;}; // <--- 'b' from c1 is used
$finish;
end
endmodule
172
SystemVerilog Reference
173
SystemVerilog Reference
Syntax
scope_randomize ::= [ std:: ] randomize( [ variable_identifier_list ] ) [ with constraint_block ]
Arguments to this function specify the variables that are to be assigned random values.
module top;
int i;
byte j;
int ok;
initial begin
ok = std::randomize(i,j);
$display( "%d", ok );
end
endmodule
The std::randomize() function returns 1 if it successfully sets all random variables to valid values; otherwise, it
returns 0. If it is called without arguments, then it returns a status.
The with clause supports the same operators are the constraints block. See Operators for a complete list.
Calling the std::randomize function with no arguments will check the constraints from the with clause. If
constraints are true, then the function returns 1, otherwise 0 is returned.
//This call only checks if i > 0 without randomizing anything.
assert (randomize() with { i > 0; } );
Extensions to std::randomize()
Aldec's simulator provides the following extensions to the std::randomize() call:
Elements of unpacked arrays can be randomized. For example:
174
SystemVerilog Reference
module m;
reg r[][4] = new[3];
bit ok;
initial
// only the first and the last element of the second row is randomized
ok = std::randomize( r[1][0], r[1][3] );
endmodule
initial
res = std::randomize( s1.r );
endmodule
175
SystemVerilog Reference
$urandom()
The function returns a new 32-bit unsigned random number each time it is called.
function int unsigned $urandom [ (int seed ) ] ;
The seed is an optional argument that determines the sequence of random numbers generated.
$urandom_range()
The function returns an unsigned integer within a specified range.
function int unsigned $urandom_range( int unsigned maxval, int unsigned minval = 0 );
The function returns an unsigned integer in the range of maxval ... minval. If minval is omitted, the function
returns a value in the range of maxval ... 0. If maxval is less than minval, the arguments are automatically
reversed so that the first argument is larger than the second argument.
x = $urandom_range( 5 );
y = $urandom_range( 2, 19 );
srandom()
The method sets object randomization seed to value given as argument.
function void srandom( int seed );
This method is a dynamic method built into each SystemVerilog class object.
class C;
rand int i;
endclass
C c;
initial begin
c = new;
c.srandom( seed );
end
get_randstate()
The method returns the Random Number Generator state of an object or a process. The state returned by
get_randstate is a string, similar to a hexadecimal number.
function string get_randstate();
176
SystemVerilog Reference
set_randstate()
The method sets the Random Number Generator state of an object or a process. The state is passed to
set_randstate as string. It is guaranteed that the RNG state is properly set only when the argument passed to the
method is taken from the get_randstate result. In other cases, the behavior of the set_randstate method is
undefined.
function void set_randstate(string state);
$get_sv_seed
Returns the seed for SystemVerilog random number generator. The seed can be set with the -sv_seed argument for
the asim command (that is the command that initializes simulation).
The function usage is presented below:
s = $get_sv_seed;
$display ("$get_sv_seed = %d", s);
$get_random_seed
Returns the seed for the SystemVerilog $random function. This seed can be set either with the -random_seed
argument for the asim command or the random_seed command.
The function usage is shown below:
s = $get_random_seed;
$display ("$get_random_seed = %d", s);
177
SystemVerilog Reference
If a branch specifies a zero weight, then that branch is not taken. If all randcase items specify zero weights, then no
branch is taken.
178
SystemVerilog Reference
In the example above, the definition of the production main consists of two parts. The first part is a choice of
non-terminal prod1 and terminal prod2 which is taken randomly. The second part is a code block.
Non-negative integral value can be assigned to production list in order to specify its weight. A list weight divided by the
sum of all weights within the production gives the probability of taking that list. If no weight is specified, it is equal to 1.
randsequence ()
main:
prod1 | prod2 prod3 := 3 | {$display("1");} := 6;
prod1: {$display("2");};
prod2: {$display("3");};
prod3: {$display("4");};
endsequence
Production main is defined as alternative of three production lists. According to the specified weights probability of
selection list prod1 is 10%, prod2 prod3 is 30% and {$display("1");} is 60%.
The randsequence statement creates an automatic scope. All productions identifiers are local to scope. Each code
block creates an anonymous automatic scope. Hierarchical references to the variables declared within the code block
are not allowed. Static variables are declared using static prefix.
When the randsequence statement is executed, grammar-driven stream of random productions is generated.
Production Statements
Production list may be generated conditionally and iterated specified number of times. if-else, case and repeat
production statements are provided for such facilities.
if-else production statement in the example below generates prod1 when i<5 and prod2 otherwise.
randsequence ()
main:
if(i<5) prod1 else prod2;
179
SystemVerilog Reference
prod1: {$display("1");};
prod2: {$display("2");};
endsequence
case production statement is analogous to procedural case statement. Consider the following example:
randsequence ()
main:
case(i)
1, 3 : prod1;
7, 8 : prod2;
default : prod3;
endcase;
prod1: {$display("1");};
prod2: {$display("2");};
prod3: {$display("3");};
endsequence
When i is equal to 1 or 3 production prod1 is generated, when i is equal to 7 or 8 production prod2 is generated. In
all other cases production prod3 is taken.
The repeat production statement iterates production item specified number of times (it should be integral
non-negative number). For example:
randsequence ()
main:
repeat(3) prod1;
prod1: {$display("1");};
endsequence
Aborting Productions
Production generation may be terminated using break and return procedural statements.
The break statement is executed from within code block and aborts the sequence generation.
randsequence ()
main:
prod1 prod2 prod3;
prod1: {$display("1");};
prod2: {if(i<5) break; else $display("2");};
prod3: {$display("3");};
endsequence
$display("4");
In the above example when i < 5 execution of the statement brakes after prod1 generation and execution
continues with the next statement ($display("4");).
If break statement is called from loop scope, it terminates the smallest enclosing loop statement.
The return statement is also executed from within a production code block but it terminates current production
generation.
randsequence ()
main:
prod1 prod2 prod3;
prod1: {$display("1");};
prod2: {$display("2");} {if(i<5) $display("3"); else return;} {$display("4");};
prod3: {$display("5");};
endsequence
180
SystemVerilog Reference
Interleaving Productions
The rand join production control is used for random interleaving of production lists. At each sequence generation
step one of the left-most items of all interleaved production lists is randomly taken.
randsequence ()
main:
rand join prod1 prod2;
prod1: {$display("1");} {$display("2");};
prod2: {$display("3");} {$display("4");};
endsequence
2
3
3
4
1
1
3
2
4
1
2
4
4
4
2
2
4
2
The optional expression following the rand join keyword is a real number in the range of 0.0 to 1.0 (default 0.5 if
unspecified). The value represents the degree of production length influence on the production item selection
probability.
If the expression value is in the range [0.0 : 0.5), the shortest production has the highest probability.
randsequence ()
main:
rand join (0.0) prod1 prod2;
prod1: {$display("1");};
prod2: {$display("2");} {$display("3");};
endsequence
The above description leads to generation of one of the following sequences (sequences are arranged in the
probability descending order):
1 2 3
2 1 3
2 3 1
If the expression value is in the range (0.5 : 1.0], the longest production has the highest probability.
randsequence ()
main:
rand join (1.0) prod1 prod2;
prod1: {$display("1");};
prod2: {$display("2");} {$display("3");};
endsequence
The above description leads to generation of one of the following sequences (sequences are arranged in the
probability descending order):
2 3 1
2 1 3
1 2 3
181
SystemVerilog Reference
string s;
initial
randsequence ()
main : prod(1,s) | prod(2,s) := 2 | prod(3,s) := 3;
prod(int a, output string o) : {
case(a)
1: o = "first";
2: o = "second";
3: o = "third";
endcase
};
endsequence
always @(s)
$display(s);
The production that returns a value requires a type specification before the production name. If the type is omitted
then a production return type is void. The return statement with an expression is used to return a value from a
production. The expression should have a type corresponding to the production type. The production that triggered
the generation of the production returning value can read this value. The return value can be accessed within the code
block via production name and an optional indexing expression. Each rule production that return a value leads to an
implicit variable declaration. The type of the implicit variable is an array, where the element type is the production
return type. The array index is in the range from 1 to the number of the production appearances within the rule and
follows the order of production occurrences.
In the example below, the generation of the main production causes generation of the arg production that returns the
random value in the range from 1 to 10. The repeat statement uses this random number (returned by the arg
production) to iterate the prod production. The prod production returns a queue of random values, which is used by
the run function.
typedef int arr [$];
arr q;
initial
randsequence ()
main : arg repeat(arg[1]) prod {run(prod[1]);};
arr prod : arg arg {q.push_back(arg[1]);
q.push_front(arg[2]);
return q;};
int arg: {return $urandom_range(1,10);};
endsequence
182
SystemVerilog Reference
NOTE: There are restrictions of the following LRM requirements for production return value access:
Each production that return a value leads to implicit variable declaration. If a production appears once in a
rule, the type of an implicitly declared variable is the same as the production return type. If the production
appears multiple times, the type of the implicit variable is an array where the element type is the production
return type and the index is in the range from 1 to the number of the production appearances within the rule.
Aldec simulator always generates an array where the element type is the production return type. An element
with index 0 exists and stores a default value of the corresponding type.
A production variable can be read-only when the production is generated. Aldec simulator does not produce
any error when this condition is not satisfied.
183
SystemVerilog Reference
Random Stability
Thread Stability
Each thread has an independent RNG for randomization calls invoked from that thread. The threads are seeded
hierarchically:
The RNG for a dynamic thread is seeded with the next random value from its parent thread.
The RNG for a static thread (process) is seeded with the next value from the initialization RNG from the unit
containing the thread.
Thread stability can be achieved when the order of thread creation and the order of number generation do not change.
Object Stability
Each class instance has an independent RNG for all randomization methods in the class. An object created using new
has the RNG seeded with the next random value from the thread that creates the object. When a class object is
created by a static declaration initializer its RNG is seeded with the next random value of the initialization RNG of the
containing unit (module, interface, program, or package).
Object stability can be achieved when the order of thread creation and the order of number generation do not change.
Manual Seeding
Random number generators that are not used for initialization can be manually seeded using a call to srandom().
The example below demonstrates seeding class C.
Example 1
class C;
rand int i1;
endclass
C c1;
initial begin
184
SystemVerilog Reference
c1 = new;
c1.srandom(100); // Seed c1 with 100.
//...
end
The other example shows seeding a process. Note how the process handle is acquired through the predefined
process class.
Example 2
process p1;
initial begin
p1=process::self();
p1.srandom(100);
//...
end
185
SystemVerilog Reference
The instances' RNGs, in turn, are used to create the RNGs associated with objects and processes within instances.
Therefore, the random stability may be affected by changes in the project hierarchy; particularly, by changes that
modifies the instance's hierarchical path. The instance stability is not affected as long as the hierarchical path of an
instance does not change. Adding or removing an instance in another design region will not change randomization
results, but moving or renaming instances that are in the instance's hierarchical path will affect the stability.
186
SystemVerilog Reference
187
Interprocess Synchronization
Semaphores
Semaphore is a built-in class. It can be used for mutual exclusion, to control the access to the shared resources and
for synchronization.
When new semaphore object is created, the set of specified number of keys is created. The process using
semaphore gets key(s) and then can continue the execution. After finishing operations controlled by the semaphore
the process returns the key(s). If more then one process use the declared semaphore processes must wait for free
keys.
The semaphore class includes the following methods:
new()
get()
put()
try_get()
The example below shows two processes synchronized via semaphore data_sem and its put() and get()
methods. The call to get() in one process can block if the other process has already acquired the semaphore with
another call to get(). (The call blocks until the other process releases the semaphore using put().)
semaphore data_sem = new(1);
always @(posedge clk)
if (IN0) begin
data_sem.get(1);
dump_data(data_in);
data_sem.put(1);
end
always @(posedge clk)
if (IN1) begin
data_sem.get(1);
read_data(data_out);
data_sem.put(1);
end
Note that compilation of a module using the semaphore class will yield (at least) two library units: the module itself
and the semaphore class.
Semaphore Methods
Method
Description
new()
Semaphore object constructor. The argument to the constructor specifies the number of keys initially
allocated to the semaphore. The default value of the keys is zero.
188
SystemVerilog Reference
Interprocess Synchronization
The new() function returns the semaphore handle or, if the semaphore cannot be created, null.
Gets a specified number of keys from the semaphore.
task get(int keyCount = 1);
get()
The keyCount specifies the required number of keys to obtain from the semaphore. The default is 1.
If the specified number of keys is available, the method returns and execution continues. If the
specified number of keys is not available, the process blocks until the keys become available.
The semaphore waiting queue is first-in first-out (FIFO). This does not guarantee the order in which
processes arrive at the queue, only that their arrival order is preserved by the semaphore.
Returns keys to the semaphore.
task put(int keyCount = 1);
put()
The keyCount specifies the number of keys being returned to the semaphore. The default is 1.
When the semaphore.put() task is called, the specified number of keys is returned to the semaphore.
If a process has been suspended waiting for a key, that process shall execute if enough keys have
been returned.
Gets a specified number of keys from a semaphore, but without blocking.
function int try_get(int keyCount = 1);
try_get()
The keyCount specifies the required number of keys to obtain from the semaphore. The default is 1.
If the specified number of keys is available, the method returns a positive integer and execution
continues. If the specified number of keys is not available, the method returns 0.
189
SystemVerilog Reference
Interprocess Synchronization
Mailboxes
A mailbox is a built-in class that provides a mechanism of exchanging messages between processes. Data can be
sent to a mailbox by one process and retrieved by another. If there is no data in the mailbox, the retrieving process
can wait for data or continue execution and try to retrieve data at the next attempt.
A mailbox is a FIFO. A message put into the mailbox as first goes out from the mailbox first. The number of messages
in the mailbox can be limited or unlimited. The limit, if any, is specified in the constructor. A bounded mailbox (that is, a
mailbox with a limited number of messages) becomes full when it contains the maximum allowed number of
messages.
The type of the messages stored in the mailbox must be specified in its declaration.
The mailbox class provides the following methods:
new()
put()
try_put()
get()
peek()
try_get()
try_peek()
num()
The example below shows two processes posting and retrieving messages to/from a mailbox. The first process blocks
when the mailbox is full; the other when the mailbox is empty. The time required for each put() and get() operation
is displayed on the Console.
mailbox #(int) MBox = new(2);
initial begin
int i = 0; int delay = 1;
repeat( 12 ) begin
time start;
#( ++delay );
start = $time;
MBox.put( i++ );
$display( "Message posted in %0d time unit(s).", $time - start );
end
end
initial begin
int m; int delay = 10;
repeat( 10 ) begin
time start;
#( --delay );
start = $time;
MBox.get(m);
$display( "Message retrieved in %0d time unit(s).", $time - start );
end
end
190
SystemVerilog Reference
Interprocess Synchronization
Mailbox Methods
Method
Description
new
Mailbox constructor. An optional argument to the constructor specifies the maximum number of
messages in a mailbox. This number must be positive.
function new(int bound = 0);
task put(singular_message);
If the mailbox was created with a limited number of messages, then the process suspends until there
is enough room in the queue.
Attempts to place a message in a mailbox.
function int try_put(singular_message);
try_put()
If the mailbox is not full, then the specified message is placed in the mailbox, and the function returns
a positive integer. If the mailbox is full, the method returns 0. For unbounded mailboxes, this method is
not meaningful.
Gets a message from a mailbox.
task get(ref singular_message);
get()
Removes one message from the mailbox queue. If the mailbox is empty, the process blocks until a
new message is put into the mailbox. If the type of the message variable is not equivalent to the
message type a run-time error is generated.
Tries to retrieve a message from a mailbox; without blocking. Returns a positive integer on success or
zero otherwise.
try_get()
If the mailbox is empty, try_get does not block. (It returns 0 immediately.)
Copies a message from a mailbox without changing the mailbox state.
peek()
If the mailbox is empty, the current process blocks until a message appears in the mailbox.
The try_peek() method tries to copy a message from a mailbox without removing the message from
the queue.
function int try_peek( ref singular message );
try_peek()
If the mailbox is empty, 0 is returned. Otherwise, a positive integer is returned. If the type of the
message variable is not equivalent to the type of the message in the mailbox, the method returns a
negative integer. If a message is available and its type is equivalent to the type of the message
variable, the message is copied, and the method returns a positive integer.
num()
191
SystemVerilog Reference
Interprocess Synchronization
The returned value should be used with care because it can be invalidated when method get(),
try_get(), put(), or try_put() is executed on the mailbox. These methods can be executed by
other processes; therefore the validity of the returned value depends on the time that other methods
start and finish.
Parameterized Mailboxes
The type of messages to be stored in the mailbox is specified at declaration. Any mismatches between the message
type and the argument types for put(), try_put(), peek(), try_peek(), get(), and try_get() methods are
detected by the compiler.
Non-parameterized Mailboxes
Non-parameterized mailbox can store messages of an arbitrary type. This is very useful mechanism, but it can also
cause run-time errors. When a message type and the type of variable used to retrieve the message are not equivalent
error is generated.
mailbox MBox = new;
initial begin
MBox.put(2.3);
MBox.put("short string");
MBox.put(311);
MBox.put(4'b01xz);
end
real x_real;
string x_string;
int x_int;
reg [3:0] x_reg;
initial begin
MBox.get(x_real);
$display( "Message retrieved
MBox.get(x_string);
$display( "Message retrieved
MBox.get(x_int);
$display( "Message retrieved
MBox.get(x_reg);
$display( "Message retrieved
end
192
SystemVerilog Reference
Interprocess Synchronization
Events
Events provide means for describing the communication and synchronization between processes. The triggered state
of an event persists throughout the time step in which the event is triggered. Events can be passed as arguments to
tasks, can be assigned to one another or compared.
Triggering an Event
Named events can be triggered via the -> operator. Triggering an event unblocks all processes currently waiting on
that event. When triggered, the trigger state itself is not observable, only its effect. (For example, the if (e)
statement, where e is an event, is illegal.)
Named events can be also triggered using the nonblocking event operator ->>. The effect of the ->> operator is that
the statement executes without blocking and creates a nonblocking assign update event in the time in which the delay
control expires or the event control occurs.
The nonblocking trigger (unlike the blocking trigger) cannot trigger events that are declared as dynamic class
properties.
triggered Property
The triggered property represents the state of the named event. The property evaluates to true if the given event
has been triggered in the current time step and false otherwise. If event_identifier is null, then the triggered
event property evaluates to false.
The triggered method can be used with the wait statement:
wait(named_event.triggered);
The calling process in blocked until the wait executes before or at the same simulation time as the trigger
operation.
wait_order()
The wait_order() construct suspends the calling process until all of the specified events are triggered in the given
order (left to right) or any of the untriggered events is triggered out of order and thus causes the operation to fail.
193
SystemVerilog Reference
Interprocess Synchronization
The wait_order() succeeds if all untriggered events happen in the prescribed order. Initially, all events are
untriggered and wait_for waits for the first event in the list. If any other event from the list is triggered instead, then
wait_order() fails. After the first event has triggered, wait_for() starts waiting for the second event from the list.
This event must be untriggered or else wait_order() would have already failed. Waiting is repeated until all event
are triggered. Note that events that have already triggered in the correct order are no longer monitored. They may be
triggered again, without causing wait_order() failure.
The wait_order() statement can include the else statement in the action block. If the wait_order() fails, the
action in the else statement is executed. If the wait_order() statement does not include else statement the
failure generates a run-time error.
wait_order( a, b, c ) else $error( "The events a,b,c out of order" );
Merging Events
Two events are merged when one event is assigned to another. After the merge, triggering one event also triggers the
other.
class C;
event a, b;
endclass
initial begin
C c = new;
c.a = c.b; // Events are merged.
-> c.a; // Also triggers b.
-> c.b; // Also triggers a.
end
Reclaiming Events
To break the synchronization queue of the event, assigning the null the event can be used. The resources of the
queue become available for reuse.
Triggering a null event has no effect. Waiting on a null event generates a run-time error.
event a;
initial begin
a = null;
@ a; // undefined: might block forever or not at all
wait( a.triggered ); // undefined
-> a; // no effect
end
Event Comparison
Event variables can be compared against other event variables or the special value null. The following operators are
allowed for comparing event variables:
==
194
SystemVerilog Reference
Interprocess Synchronization
!=
===
!==
An event can be compared with another event or with null.
195
Clocking Blocks
Example
clocking cl_bl_1 @(posedge clk);
default input #10ns output #2ns;
input data, ready, enable = top.mem1.enable;
output negedge ack;
input #1step addr;
endclocking
196
SystemVerilog Reference
Clocking Blocks
Clocking event in a clocking block can be for example, a clocking expression including a posedge or negedge
identifier, it can also be an event variable. Hierarchical identifiers can be assigned to the clocking block inputs. Output
signals in a clocking block cannot be read, input signals cannot be driven.
197
SystemVerilog Reference
Clocking Blocks
A skew must be a constant expression. It can be specified as a parameter. If the skew does not specify a time unit,
the current time unit is used. If a number is used, the skew is interpreted using the timescale of the current scope.
Default input skew is #1step. Default output skew is #0. #1step means that the signal is sampled at the end of the
previous time step, just before the corresponding clocking event. #0 skew for the input signals means that the signals
are sampled at the same time as the clocking event, but in the Observed region. #0 skew for the output signals means
that they are driven at the same time as the clocking event, in the NBA region.
Input Sampling
Clocking block inputs and inouts are sampled at the corresponding clocking event. The signals declared with explicit
#0 input skew are sampled in the Observed region. The signals without explicit #0 skew are sampled in the Postponed
region. Sampled signals values are used when the signal from the clocking block appears in the expression. When the
same signal is an input to multiple clocking blocks, each clocking block samples the corresponding signal with its own
clocking event.
An event associated with the clocking block name is updated in the Observed region. It is made to eliminate potential
races which can occur if values sampled in clocking block are altered by a non-blocking assignment in the same
simulation time. If value is used in process that waits for clocking block, it is guaranteed that expressions inside this
process will use the newly-updated values.
bit clk;
reg v;
clocking cb @(negedge clk);
input v;
endclocking
always @(cb) $display(cb.v);
The next example, as distinct from the first, has a potential risk of races, since values sampled in clocking block can
be changed by concurrent non-blocking assignment.
always @(negedge clk) $display( cb.v);
NOTE: In the Verilog and the SystemVerilog standards preceding IEEE Std 1800-2009 there were no distinction
between these two examples. Both of them worked as the latter one.
198
SystemVerilog Reference
Clocking Blocks
Syntax
cycle_delay ::=
## integral_number
| ## identifier
| ## ( expression )
The expression must evaluate to positive integer number. The default clocking event determines the clock cycle or
clocking event used in the delay. If no default clocking block is declared the usage of cycle delay operator is illegal.
Example
default clocking cl_1 @(negedge clk);
endclocking
initial begin
a = 0;
##1; // wait one clock clk cycle
a = 1;
##3; // wait three clock clk cycles
b = 5;
// ...
end
199
SystemVerilog Reference
Clocking Blocks
Default Clocking
In a SystemVerilog one clocking can be specified as the default for all cycle delay operations within a given module,
interface, or program.
Specifying a default clocking more than once in the same program or module is illegal.
A default clocking is valid only within the scope containing the default clocking specification. This scope includes
the module, interface, or program that contains the declaration as well as any nested modules or interfaces. It
does not include instantiated modules or interfaces.
default clocking d_clk @(posedge clk);
endclocking
initial begin
##1;
a =1;
##1;
a = 0;
##1;
a = 1;
end
200
SystemVerilog Reference
Clocking Blocks
Synchronous Drives
NOTE: The construct is not supported in this release. Please contact Aldec Support to receive the latest status.
201
SystemVerilog Reference
Clocking Blocks
Clocking Properties
The clocking block can include sequences and properties declarations. These sequences and properties are
clocked with the corresponding clocking block event. The signals in sequences and properties expressions are
sampled in the Preponed region.
clocking cl1 @(posedge clk);
input a,b,c,d;
sequence s1;
a ##1 b ##[1:$] c;
endsequence
property p1;
s1 |-> (##[1:5] !d);
endproperty
endclocking
The clocking event from the default clocking block specifies a clocking event for the sequences and properties,
which have no explicit clock (in corresponding scope).
default clocking cl2 @(negedge clk);
endclocking
property p2;
a -> b;
endproperty
202
Program
Program blocks are used to model the design verification environment. A program block provides an entry point to
the execution of testbenches, creates a scope that encapsulates programwide data, tasks, and functions.
A sample program definition is shown below:
program
input
input
input
inout
);
tst_prg(
clk,
[15:0] addr,
EN,
[8:1] data
A program block can only contain initial and final blocks. UDPs, modules, interfaces, always blocks, or other
programs are not allowed.
$exit Task
Calling the $exit() system tasks explicitly terminates a program. All processes spawned by the current program are
terminated. When all initial blocks in a program finish the program implicitly calls $exit.
Anonymous Programs
Anonymous programs allow you to declare data, tasks and functions accessible only by other programs and
unreachable outside the program blocks. Anonymous programs can be declared inside the packages or compilation
unit scopes. The items declared in these programs share the same name space as the package or compilation unit
scope in which they are declared. Therefore, the identifiers used inside an anonymous program cannot be used in
203
SystemVerilog Reference
Program
declarations placed outside the program but inside the package or compilation unit scope in which the program is
declared.
Example
In the below example, there are two declarations of anonymous programs: the first is declared in the pckg package
and the second is declared in the compilation unit scope. The pckg package is imported to the top program so the C
class and ff function declared in anonymous programs are visible in the program top.
package pckg;
program; // anonymous program declared in package
class C;
int x;
endclass
endprogram
endpackage
program;
// anonymous program declared in compilation scope
function int ff(int y);
return 2*y;
endfunction
endprogram
program top;
import pckg::*;
C c = new;
initial
begin
// calling function from anonymous program
c.x = ff(5);
end
endprogram
204
Assertions
Example
property HndShk_1;
@(posedge clk) $rose(RECEIVE)|-> ##2 $fell(RECEIVE);
endproperty
assert property (HndShk_1) else $error("RECEIVE pulse incorrect");
The property HndShk_1 is tied to clock clk. The clock tick for this property is the rising edge of this clock. The
RECEIVE signal is sampled in the Preponed region of each time slot, in which the rising edge of clk appears.
Changes on the signal between clock ticks (for example between the 5-th and 6-th clock tick in the figure above) are
ignored. Signal RECEIVE rises at clock tick 7 exactly on at the positive clock edge. The sampled value of this signal
for clock tick 7 equals zero.
205
SystemVerilog Reference
Assertions
Overview
The basic element in Assertion Based Verification is a Boolean expression. Boolean expressions together with
sequence operators create sequences. The sequences can be also built using other sequences and sequence
instances. All aforementioned elements can be combined to build a property. A property can also include other
properties, property instances, and property operators. The properties describe design behavior but are only
declarations. To use properties in the verification during simulation, the verification directives must be used. The
evaluation of assertions is based on a clock (except for immediate assertions), so the clock expressions are also
important elements of assertions.
Keywords
Keywords are predefined identifiers that are used to define SystemVerilog constructs.
List of Keywords
and
assert
assume
bind
cover
disable iff
ended
endproperty
endsequence
first_match
if ... else
intersect
matched
not
or
property
sequence
throughout
206
SystemVerilog Reference
Assertions
within
Identifiers
Identifiers in SystemVerilog consist of a letter, followed by zero or more alphanumeric characters; each subsequent
alphanumeric character may optionally be preceded by a single underscore character. Additionally, hierarchical
names are allowed for referencing selected HDL objects.
Example
Example 1
BusyPrinter
Check_Full_after_Write4
tb.UUT
Example 2
8ones
two__underscores
Hierarchical References
HDL signals, functions and scopes can be referenced using hierarchical path names.
Syntax
hierarchical_identifier ::= [ $root . ] { identifier constant_bit_select . } identifier
constant_bit_select ::= { [ constant_expression ] }
$root provides unambiguous reference to the top level instance, or to an instance path starting from the root of the
instantiation tree.
Boolean Expressions
Boolean expressions are interpreted in the same way as expressions in a condition of a procedural if statement. If
the expression evaluates to X, Z, or 0, then it is interpreted as being false. Otherwise, it is true.
The boolean expression can include a function call, the function must be automatic.
207
SystemVerilog Reference
Assertions
Boolean expressions are used in sequences and in top-level statement disable iff.
Restrictions
The following restrictions apply:
string, event, handle, and class types are not allowed in expressions.
Associative or dynamic arrays are not allowed in expressions.
Variables used in expressions must be static.
Assignment operator, increment operator, and decrement operator are not allowed.
Built-in Functions
The SystemVerilog includes several built-in functions, which facilitate building sequences and properties - sampled
value functions $sampled, $rose, $fell, $stable, and $past and system functions $onehot, $onehot0,
$isunknown, and $countones.
Syntax
$sampled(expression [, clocking_event])
$rose( expression [, clocking_event])
$fell( expression [, clocking_event])
$stable( expression [, clocking_event])
$past( expression1 [, number_of_ticks] [, expression2] [, clocking_event])
$sampled
Function $sampled returns the value of the expression sampled exactly before the last occurrence of the clocking
event. When $sampled is invoked prior to the occurrence of the first clocking event, the value of X is returned.
The use of $sampled in assertions is redundant, the result of the function is identical to the sampled value of the
expression itself used in the assertion. $sampled can be also used in other, non-assertion expressions.
208
SystemVerilog Reference
Assertions
Example 1
property Load_Data_1;
@(negedge Load) $sampled(QOut)==$sampled(DataIn);
endproperty
property Load_Data_2;
@(negedge Load) QOut==DataIn;
endproperty
The property Load_Data_1 works exactly the same like the property Load_Data_2.
Example 2
Check_Load:
assert property (Load_Data)
else
$display(
"Time=%0t Programmable Counter : Load - violation! QOut=%0d DataIn=%0d",
$time, $sampled(QOut), $sampled(DataIn)
);
In the example 2 $sampled is used in action block of the assert statement, in $display task that displays a
message when the property fails. Here, the $sampled function is very useful. The $display task displays the values
of signals in the postponed region of the timeslot, the signal values for the assertion are taken from the preponed
region of the time slot. If the signal changes at the clocking event, the signal value used for evaluating assertion and
the value displayed in the failure message will be different. When $sampled is used, the correct signal value is
displayed in the message (i.e. the value that was used when the assertion was evaluated).
Example 3
property D2_Pulse_Active;
@(posedge CLK) $fell(D1) |-> $rose(D2);
endproperty
The property D2_Pulse_Active checks that whenever the D1 signal changes to a low value, signal D2 should be set
high in the same clock cycle.
209
SystemVerilog Reference
Assertions
In the figure above the falling edge of the D1 signal is detected on the 2-nd and on the 7-th clock tick. The falling edge
between the 4-th and 5-th clock tick is not detected because the value of the D1 signal is the same at the 4-th and the
5-th clock edge. The rising edge of the D2 signal is detected on the second clock tick.
Example 4
property Active_TXD_1;
@(negedge clk) SEND |-> !$stable(TXD);
endproperty
Signal TXD should change at each clock cycle, always when SEND is active. In the figure below, TXD is stable at the
7-th clock tick.
$past
The past values of the signal can be accessed using the $past function. By default $past returns the signal value
from the previous clocking event, if the number_of_ticks argument is specified, the function returns signal value
that was present number_of_ticks clock cycles in the past.
Example 5
property Count_Down;
@(posedge clk) (!Load & Enable) |-> QOut == $past(QOut)-1;
endproperty
The property in the example 4 describes the behavior of a simple counter. The counter counts down when the
Enable signal is active and Load is not enabled.
210
SystemVerilog Reference
Assertions
System functions
The functions $onehot, $onehot0, $isunknown, $countones, $inset and $insetz check specific features of a
Boolean expression in the current clock tick.
$onehot(expression) returns true if 1 and only 1 bit of expression is high.
$onehot0(expression) returns true if at most 1 bit of expression is high.
$isunknown(expression) returns true if any bit of the expression is X or Z. This is equivalent to
^expression === 'bx.
$countones (expression) counts the number of ones in a bit vector expression. An X and a Z value of a
bit is not counted towards the number of ones.
$inset(expression {, expression }) returns the true value if the first expression is equal to at least
one of remaining expressions.
$insetz(expression {, expression }) acts as the $inset function, but it treats the high-impedance
value Z (sometimes signified by '?') as the do-not-care value.
Example 6
property Incorrect_FSM_State;
@(posedge clk) $isunknown(Current_State);
endproperty
assert property (not Incorrect_FSM_State);
The Incorrect_FSM_State rule reports violation when the FSM register includes X, Z values.
Example 7
property Counter_Fast_Check;
@( posedge Clk ) $fell( Enable ) |-> $countones( Q % 2 ) == 0;
endproperty
Example 7 shows the rule for a simple parity checker - when receiving is finished the number of ones in the counter
should be even.
211
SystemVerilog Reference
Assertions
Sequences
Sequence Declaration
A sequence statement describes a sequence of events changing over time. The sequence is not evaluated
continuously but at discrete time points designated by clocking events. Therefore, it describes design behavior in
consecutive clock ticks.
A simple sequence can be built from Boolean expressions and the cycle delay operator. The cycle delay operator
indicates a shift between clock ticks, for example:
sequence Simple_Seq;
@( posedge clk ) Req ##1 Start ##1 Send ##1 Stop;
endsequence
The sequence starts with a high value on signal Req. In the next clock cycle, signal Start is high. It is then followed
by a high SEND and a high Stop in the next two consecutive clocks.
In the figure above the sequence Simple_Seq starts at clock cycle 2 and completes at clock cycle 5, the second
sequence starts at clock cycle 4 and completes at clock cycle 7. Signal values are checked at positive clock edge.
As shown in the figure, sequences can overlap. This feature allows catching all sequences, even if the evaluation of
the previous sequence is not finished.
To describe more refined behavior, use the Sequence Operators.
A sequence can be declared in a module, in an interface, in a program, in a clocking block, in a package and in a
compilation-unit scope.
Syntax
sequence_declaration ::=
sequence sequence_identifier [ ( [ sequence_port_list ] ) ] ;
{ assertion_variable_declaration }
sequence_expr [ ; ]
212
SystemVerilog Reference
Assertions
endsequence [ : sequence_identifier ]
sequence_port_list ::= sequence_port_item {, sequence_port_item}
sequence_port_item ::= { attribute_instance } [ local [ sequence_lvar_port_direction ] ]
sequence_formal_type formal_port_identifier {variable_dimension} [ = sequence_actual_arg ]
sequence_lvar_port_direction ::= input | inout | output
sequence_formal_type ::= data_type_or_implicit | sequence | untyped
Sequence Instance
Named sequence can be instantiated in other sequences and properties. It increases the readability of the code and
allows building hierarchical, reusable sequences.
Example 1
sequence StartEvent;
!WR && READY ##1 ADDR == ValidAdd;
endsequence
sequence StopEvent;
( Data == 0 )[*2] ##1 !WR_Req & !RD_Req;
endsequence
sequence Window;
StartEvent.triggered ##[1:$] StopEvent.triggered;
endsequence
sequence TrueInWindow;
MinMaxLimit( Counter ) throughout Window;
endsequence
The sequence Window includes the instances of sequences StartEvent and EndEvent used with method
triggered. The sequence TrueInWindow uses the instance of Window sequence and user-defined function
213
SystemVerilog Reference
Assertions
MinMaxLimit.
Parameterized Sequences
A sequence can be declared with the formal arguments. The actual arguments in the sequence instantiations can be
any of the following:
literal
identifier
expression
event control expression
sequence expression
the $ symbol
The data types allowed in the expressions are denoted in the Boolean Expressions section.
Untyped Arguments
A formal argument is said to be untyped if there is no type specified for the given argument in the sequence
declaration or the untyped keyword is used. The type of the references to the untyped formal argument is
determined by the type of the actual argument.
Example 2
In the example below, the two instantiations of the StableAfterChange parameterized sequence checks whether
the MemCL and IN1 signals are stable during the specified time after the value change.
sequence StableState(clk,data,min,max);
@clk $stable(data)[*min:max];
endsequence
sequence StableAfterChange(clk,data,min,max);
@clk $changed(data) ##1 Stablestate(clk,data,min,max);
endsequence
MemCLCov: cover sequence(StableAfterChange(posedge clk,MemCL,1,5));
Data1Cov: cover sequence(StableAfterChange(negedge clk,IN1,3,4));
Typed Arguments
The typed formal arguments can be one of the following types:
data type (the allowed types are denoted in the Boolean Expressions section)
event
sequence
214
SystemVerilog Reference
Assertions
Example 3
The example below is the Example 2 with the typed formal arguments in the sequence declarations.
sequence StableState(event clk,byte data,int min,max);
@clk $stable(data)[*min:max];
endsequence
sequence StableAfterChange(event clk,byte data,int min,max);
@clk $changed(data) ##1 Stablestate(clk,data,min,max);
endsequence
MemCLCov: cover sequence(StableAfterChange(posedge clk,MemCL,1,5));
Data1Cov: cover sequence(StableAfterChange(negedge clk,IN1,3,4));
The formal and the actual argument types must be cast compatible. If the actual and formal arguments are of the
same types, each assignment to a reference to the formal argument will be treated as though there was a subsequent
assignment of the formal argument to the actual argument. If the actual and formal arguments are of different types,
the actual argument will be cast to the type of the formal argument before being used as a substitute for a reference to
the formal argument.
Example 4
In the example below, the actual argument w1 of the 8 bit size is assigned to the formal argument word. Before the
assignment, the w1 actual is extended to 16 bits. Similarly, the actual i argument is truncated to the size of the formal
argument idx.
sequence CompareBit( logic [0:15] word, bit [0:3] idx);
@(posedge clk) $past(word[idx]) === word[idx];
endsequence
reg [0:7] w1;
int i;
sequence Check;
@(posedge clk) enable and CompareBit(w1,i) and CompareBit(w1,i+1);
endsequence
Example 5
The example below shows the Range sequence with the two formal arguments of the event and the sequence type
and a one untyped argument. The keyword untyped is obligatory if an untyped argument is specified on the
argument list along with typed arguments.
There are two instances of the Range sequence. In the first instance, in the CheckAck assertion declaration, the
values returned by the $fell function calls are mapped to the s1 and s2 arguments of the sequence type. The
untyped argument n is assigned with the $ symbol as an actual argument so that the argument is used in the
sequence as the upper bound of the cycle delay constant range expression (##). In the second instance, in the
CheckReq assertion declaration, the actual arguments s1 and s2 are the sequence expressions and the integer
literal constant (2) is assigned to the untyped argument n.
sequence Range(event clk, sequence s1,s2, untyped n);
@clk s1 ##[0:n] s2;
endsequence
215
SystemVerilog Reference
Assertions
Example 6
In the below example, there is a declaration of the s1 sequence. The sequence has the formal arguments declared as
a local variables on its port list. In the first clock cycle of the s1 sequence evaluation, the sequence checks whether
the a variable holds. In the next cycle, the sequence checks whether the b variable and the x variable are equal and
in the next cycle, the sequence checks whether the c variable holds, saves its value to the y variable and the current
simulation time to the z variable.
sequence s1(local input byte x, local output time z, local output byte y);
@(posedge clk) a ##1 b==x ##1 (c,z=$time,y=c);
endsequence
sequence s2;
byte v1=1,v2;
time t1;
@(posedge clk) (d,v2=d) ##0 (s1(.x(v1),.y(v2),.z(t1)),$display(v2,t1));
endsequence
a1: cover sequence(s2);
Sequence Operators
SystemVerilog includes several sequence constructs and operators that facilitate describing the design behavior and
allow creating more sophisticated rules.
216
SystemVerilog Reference
Assertions
Syntax
sequence_expr ::=
cycle_delay_range sequence_expr { cycle_delay_range sequence_expr }
| sequence_expr cycle_delay_range sequence_expr { cycle_delay_range sequence_expr }
| expression_or_dist [ boolean_abbrev ]
| ( expression_or_dist {, sequence_match_item } ) [ boolean_abbrev ]
| sequence_instance [ sequence_abbrev ]
| ( sequence_expr {, sequence_match_item } ) [ sequence_abbrev ]
| sequence_expr and sequence_expr
| sequence_expr intersect sequence_expr
| sequence_expr or sequence_expr
| first_match ( sequence_expr {, sequence_match_item} )
| expression_or_dist throughout sequence_expr
| sequence_expr within sequence_expr
| clocking_event sequence_expr
cycle_delay_range ::= ## integral_number
| ## identifier
| ## ( constant_expression )
| ## [ cycle_delay_const_range_expression ]
sequence_match_item ::= operator_assignment
| inc_or_dec_expression
| subroutine_call
sequence_instance ::= ps_sequence_identifier [ ( [ list_of_arguments ] ) ]
actual_arg_expr ::= event_expression | $
boolean_abbrev ::= consecutive_repetition
| non_consecutive_repetition
| goto_repetition
sequence_abbrev ::= consecutive_repetition
consecutive_repetition ::= [* const_or_range_expression ]
non_consecutive_repetition ::= [= const_or_range_expression ]
goto_repetition ::= [-> const_or_range_expression ]
const_or_range_expression ::= constant_expression | cycle_delay_const_range_expression
cycle_delay_const_range_expression ::= constant_expression : constant_expression | constant_expression :
$
expression_or_dist ::= expression [ dist { dist_list } ]
Operator
Associativity
left
throughout
right
217
SystemVerilog Reference
within
left
intersect
left
and
left
or
left
Assertions
Syntax
sequence_expr ::=
cycle_delay_range sequence_expr { cycle_delay_range sequence_expr }
| sequence_expr cycle_delay_range sequence_expr { cycle_delay_range sequence_expr }
...
cycle_delay_range ::= ## integral_number
| ## identifier
| ## ( constant_expression )
| ## [ cycle_delay_const_range_expression ]
Examples
Example 1
sequence FSM_Cycle_1;
@(posedge clk) `Buffer_Empty ##2 `Wait_For_Free ##2 `Set_Strobe ##2 `Wait_For_Ack ##2 `Shift_Fifo ##2
`Buffer_Empty;
endsequence
The sequence FSM_Cycle_1 describes one of several possible cycles in the finite state machine in a printer buffer.
The device stays in each state for two clock cycles.
218
SystemVerilog Reference
Assertions
Example 2
sequence Next_Ack_Limit;
@(posedge clk) !Ack ##[1:5] $fell(Ack) ;
endsequence
assert property (not Next_Ack_Limit);
The next acknowledge cannot happen earlier than 6 cycles after the previous acknowledge. Otherwise the buffer will
not react and will not shift the next value. The sequence Next_Ack_Limit describes incorrect behavior. Such
behavior should not happen during simulation. This is indicated in the assert statement. The falling edge of the Ack
signal cannot happen one, two, three, four, or five clock cycles after the previous acknowledge !Ack.
In the figure below the first acknowledge happens at clock 3 and is followed by another acknowledge at clock 9, i.e.
six ticks after the acknowledge at clock 3. This behavior is correct. The acknowledge in clock cycle 13 happens too
early after the acknowledge in clock 9. The assertion violation in clock 13 is marked with a red triangular mark.
Example 3
sequence Printer_Ack;
@(posedge clk) $fell(Strobe) ##[2:$] $fell(Ack) ;
endsequence
The printer must send an acknowledge after the Strobe signal. The time when the acknowledge should appear is not
determined precisely, it must happen at least 2 clock cycles after the strobe and not later than the end of simulation
($).
Repetitions
The repetition is a construct that facilitates describing recurrent events. SystemVerilog offers three kinds of repetitions:
consecutive repetitions, nonconsecutive repetitions and goto repetitions. Nonconsecutive and goto repetition
operators can be used only with Boolean expressions, consecutive repetition operator can be used also with
sequences.
Syntax
sequence_expr ::=
...
219
SystemVerilog Reference
Assertions
| expression_or_dist [ boolean_abbrev ]
| ( expression_or_dist {, sequence_match_item } ) [ boolean_abbrev ]
| sequence_instance [ sequence_abbrev ]
boolean_abbrev ::= consecutive_repetition
| non_consecutive_repetition
| goto_repetition
sequence_abbrev ::= consecutive_repetition
consecutive_repetition ::= [* const_or_range_expression ]
non_consecutive_repetition ::= [= const_or_range_expression ]
goto_repetition ::= [-> const_or_range_expression ]
const_or_range_expression ::= constant_expression | cycle_delay_const_range_expression
cycle_delay_const_range_expression ::= constant_expression : constant_expression | constant_expression :
$
expression_or_dist ::= expression [ dist { dist_list } ]
Consecutive Repetition
Consecutive repetition specifies finitely many iterative matches of the operand sequence, with a delay of one clock
tick from the end of one match to the beginning of the next. The overall repetition sequence matches at the end of the
last iterative match of the operand. If a sequence is built only from one Boolean expression the consecutive repetition
repeats this Boolean expression at the specified number of consecutive clock ticks.
The effect of consecutive repetition of a subsequence within a sequence can be achieved by explicitly iterating the
subsequence.
Examples
Example 1
sequence Send_Period;
@(negedge XTAL) $rose(SEND) ##1 SEND[*7] ##1 $fell(SEND);
endsequence
The SEND signal must be active for 8 machine cycles and then should drop to zero.
The equivalent sequence with delay range operator is as follows:
sequence Send_Period_1;
@(negedge clk) $rose(SEND) ##1 SEND ##1 SEND ##1 SEND ##1 SEND ##1 SEND ##1 SEND ##1 SEND ##1
$fell(SEND);
endsequence
220
SystemVerilog Reference
Assertions
Example 2
sequence Busy_Length;
@(posedge clk) Busy[*1:4] ##1 !Busy;
endsequence
The maximal busy period takes 4 clock cycles. The minimal busy period takes 1 clock cycle. The consecutive
repetition with a range helps to specify the rule in a convenient way. The equivalent sequence for Busy[*1:4] is
specified below:
Busy
| (Busy ##1 Busy)
| (Busy ##1 Busy ##1 Busy)
| (Busy ##1 Busy ##1 Busy ##1 Busy)
The completion of each of aforementioned sequences causes that the sequence Busy[*1:4] is treated as completed.
The simulator reports always only first completed sequence.
Example 3
$rose(Req) ##1 Req[*1:3] ##1 !WR
In the figure above sequence $rose(Req) ##1 Req[*1:3] is completed at clock ticks 6, 7, 12, 13, 14. The whole
sequence $rose(Req) ##1 Req[*1:3] ##1 !WR is completed at clock tick 7 (evaluation starting at clock 5) and
at clock ticks 13 and 14 (evaluation starting at clock tick 11). In the case of the second evaluation starting at clock tick
11, the simulator reports only the first completion of the full sequence.
221
SystemVerilog Reference
Assertions
Example 4
It is also possible to declare a repetition with an unlimited range using the $ symbol, for example:
$rose(State==Wait_For_Traffic) ##1 (Traffic_Detected==0)[*1:$] ##1 Traffic_Detected==1
The sequence above describes a situation where the device goes into the Wait_For_Traffic state and waits for
the signal denoting traffic detection. This signal can stay low for any time, until the end of simulation. No time limit is
imposed.
Example 5
sequence TXD_Seq;
@(posedge clk) ($rose(TXD) ##1 TXD[*2] ##1 !TXD[*2])[*3];
endsequence
The sequence ($rose(TXD) ##1 TXD[*2] ##1 !TXD[*2]) is repeated 3 times in the figure above.
Nonconsecutive Repetition
Nonconsecutive repetition specifies finitely many iterative matches of the operand Boolean expression, with a delay of
one or more clock ticks from one match of the operand to the next successive match and no match of the operand
strictly in between. The overall repetition sequence matches at or after the last iterative match of the operand, but
before any later match of the operand.
Example 6
sequence Write_4;
@(negedge clk) (!WR & RD) [=4];
endsequence
There are many sequences with defined (!WR & RD)[=4] repetition in the figure above. The most intuitive are:
222
SystemVerilog Reference
Start Clock
Assertions
Completion Clock
12
13
The sequence (!WR & RD)[=4] can also start or complete at clock cycle, in which expression (!WR & RD) is false:
Start Clock
Completion Clock
10
11
12
12
13
13
14
14
The nonconsecutive repetition can also be defined with a range, either limited or unlimited.
Example 7
sequence Low_Level;
@(posedge clk) IN[=1:3];
endsequence
sequence Medium_Level;
@(posedge clk) IN[=4:6];
endsequence
sequence High_Level;
@(posedge clk) IN[=7:9];
endsequence
sequence Level;
(Low_Level and Level=1) or (Medium_Level and Level=2) or (High_Level and Level=3);
endsequence
223
SystemVerilog Reference
Assertions
The counter counts elements thrown to the container at any time during the simulation. (A high value on the IN signal
denotes the arrival of a new element to a container). The number of these elements is divided into ranges : 0
elements - Level=0, 1-3 elements - Level=1, 4-6 elements - Level=2 and 7-9 elements - Level=3. The sequence
Level describes the correct relation between the number of elements and the Level signal.
Goto Repetition
Goto repetition specifies finitely many iterative matches of the operand Boolean expression, with a delay of one or
more clock ticks from one match of the operand to the next successive match and no match of the operand strictly in
between. The overall repetition sequence matches at the last iterative match of the operand.
The differences between nonconsecutive repetition and goto repetition is, that the sequence with the goto repetition
must always complete on an expression match.
Example 8
sequence Write_4_Goto;
@(negedge clk) (!WR & RD) [->4];
endsequence
Completion Clock
12
13
12
12
13
13
And operator
224
SystemVerilog Reference
Assertions
The binary operator and is used when both operands are expected to match, but the end times of the operand
sequences can be different. The two operands of and are sequences. Both the operands must match. The operand
sequences start at the same time. When one of the operand sequences matches, it waits for the other to match. The
end time of the composite sequence is the end time of the operand sequence that completes last.
Syntax
sequence_expr ::=
...
| sequence_expr and sequence_expr
Example 1
sequence Count_Down;
@(posedge clk) (Counter == $past(Counter)-1)[*4:8];
endsequence
sequence Start_Seq;
@(posedge clk) $rose(State==Start) ##2 $rose(State==Wait);
endsequence
sequence Count_In_Wait;
StartSeq and CountDown;
endsequence
The sequence Start_Seq starts at clock 2, completes successfully at clock 4 and waits for the sequence
Count_Down. The sequence Count_Down starts at clock 2 and completes successfully at clock 9. The sequence
Count_In_Wait starts at clock 2 and succeeds at clock 9.
The length of the "anded" sequences can be different or it can be the same, but they must start at the same clock
cycle.
Intersect Operator
The binary operator intersect is used when both operand sequences are expected to match, and the end times of the
operand sequences must be the same. The two operands of intersect are sequences. Both the operands must match
and the lengths of the two matches of the operand sequences must be the same.
An attempted evaluation of an intersect sequence can result in multiple matches. The results of such an attempt can
be computed as follows:
225
SystemVerilog Reference
Assertions
1. Matches of the first and second operands that are of the same length are paired. Each such pair results in a
match of the composite sequence, with length and end point equal to the shared length and end point of the
paired matches of the operand sequences.
2. If no such pair is found, then there is no match of the composite sequence.
Syntax
sequence_expr ::=
...
| sequence_expr intersect sequence_expr
Example
sequence Window;
@(posedge clk) $rose(StartEvent) ##[1:$] $rose(StopEvent);
endsequence
sequence Input_Seq;
@(posedge clk) IN0[*2:8];
endsequence
sequence IN0_Window;
Input_Seq intersect Window;
endsequence
The sequence Window can have any length, it is limited only with the appearance of StartEvent and StopEvent.
The length of the sequence Input_Seq is also variable and can take from 2 to 8 clock cycles. The sequence
IN0_Window matches only when Window and Input_Seq have the same length. In the figure above successful
IN0_Window sequence starts at clock cycle 10 and completes at clock cycle 14. The evaluation, which starts at clock
cycle 2 fails at clock cycle 8.
Or Operator
The operator or is used when at least one of the two operand sequences is expected to match. The two operands of
or are sequences.
Syntax
sequence_expr ::=
...
| sequence_expr or sequence_expr
226
SystemVerilog Reference
Assertions
Example
Example 1
sequence Forbidden_Changes_from_Normal;
@(posedge clk) (Normal_State ##1 Red_1_State) or (Normal_State ##1 Red_2_State) or (Normal_State ##1
Yellow_Red_State);
endsequence
The sequence above describes forbidden transactions from one of state of finite state machine in a traffic lights
controller. If any of the three forbidden sequences happen the sequence Forbidden_Changes_from_Normal
matches.
Example 2
sequence Seq_1;
@(posedge clk) (IN0==0 ##2 Data0==8'hff) or (IN1==0 ##1 Data1==8'hff) or (IN2==1 ##2 Data2=8'b0);
endsequence
In example 1 the transitions are mutually exclusive and only one sequence can match. In example 2 all three
sequences used as operands of the or operator can match at the same time. (Obviously, for the or operator it is
enough if only one operand matches.)
If more than one of the or'ed sequences starts evaluating at the same clock cycle (in the figure above this happens in
cycles 1, 5, and 11) and the sequences complete at different times, only the first match will be reported. In other
words, sequence Seq_1 matches, when the first of the or'ed components matches.
For the evaluations started at clock 1 and at clock 2, sequence Seq_1 matches at clock cycle 3. For the evaluation
started at clock 5 the match happens at clock 6, and for the evaluation started at clock 11, at clock cycle 12.
Throughout Operator
The composite sequence, exp throughout seq, matches along a finite interval of consecutive clock ticks provided seq
matches along the interval and exp evaluates to true at each clock tick of the interval. This statement is convenient to
227
SystemVerilog Reference
Assertions
define some condition that must be true while processing a transaction or to define assumptions, under which the
sequence must occur. The equivalent temporal expression for the sequence exp throughout seq is
(exp) [*0:$] intersect seq
Syntax
sequence_expr ::=
...
| expression_or_dist throughout sequence_expr
Example
sequence RXD_Active;
@(posedge XTAL) RXD !== 1'bz throughout (Transmit[*8] ##1 $rose(SEND) );
endsequence
RXD_o data output signal is active during transmission, or otherwise it should have the Z value.
The sequence RXD_Active starts at clock 2 and matches at clock 10 - RXD is active during the sequence
Transmit[*8] ##1 $rose(SEND), then next transmission starts at clock cycle 13 and at the same clock fails
because RXD equals 1'bZ.
Within Operator
The composite sequence seq1 within seq2 matches along a finite interval of consecutive clock ticks provided seq2
matches along the interval and seq1 matches along some subinterval of consecutive clock ticks. The construct seq1
within seq2 is equivalent to the following temporal expression:
(1[*0:$] ##1 seq1 ##1 1[*0:$]) intersect seq2
This construct helps to easily define containment of a sequence within another sequence.
Syntax
sequence_expr ::=
...
| sequence_expr within sequence_expr
228
SystemVerilog Reference
Assertions
Examples
sequence Window;
@(posedge clk) $rose(StartEvent) ##[1:$] $rose(StopEvent);
endsequence
sequence Input_Seq;
@(posedge clk) IN0[*2:8];
endsequence
sequence IN0_Window;
InputSeq within Window;
endsequence
The example 1 includes a similar sequences as the example 1 for the Intersect Operator, but the IN0_Window
sequence includes the within operator instead of the intersect operator. In the within operator, the start point
of the Input_Seq must be no earlier than the start point of the Window sentence and the end point of the
Input_Seq must be no later than the end point of the Window sentence. (In the intersect operator, both
sequences must start and end at the same time.)
In the figure above sequence IN0_Window matches twice, at clock 8 and 14.
Sequence Window starts at clock 2 and completes at clock 8, InputSeq also starts at clock 2 and completes at clock
7. Therefore, InputSeq is contained within Window. (It does not intersect with Window because the intersect
operator, contrary to the within operator, requires that both sequences start and complete at the same time.)
Sequence Window starts again at cycle 10 and completes at cycle 14, InputSeq starts later than Window, at clock
cycle 12 and completes earlier than Window, at clock 14. InputSeq is again contained within Window.
First_match Operator
Some of the sequence operators, for instance ##[N:M] or [*N:M] are able to generate multiple matches for a single
sequence start point. The first_match operator discards all sequence matches except the first one. This is
especially useful for the implication operator which by default checks if for all matches on the left-hand side (LHS)
sequence the right-hand side (RHS) property holds. By using the first_match implication, the operator can be
restricted to check just the first match of LHS. For more information, see 16.9.8 in IEEE Std 1800-2012.
Example
module m;
reg clk=0;
always #10 clk=!clk;
reg req=0, data=0, ack=0;
initial begin
229
SystemVerilog Reference
repeat(2)@(negedge
req=1;
@(negedge clk) ;
req = 0;
repeat(3)@(negedge
data=1;
repeat(4)@(negedge
data=0;
repeat(4)@(negedge
$finish;
end
Assertions
clk) ;
clk) ;
clk) ;
clk) ;
initial begin
repeat(7)@(negedge clk) ;
ack=1;
@(negedge clk);
ack=1;
@(negedge clk);
ack=0;
end;
check_req_fm: assert property(@(posedge clk) first_match(req ##[1:$] data) |=> ack);
check_req: assert property(@(posedge clk) (req ##[1:$] data) |=> ack);
endmodule
The assertion check_req_fm tests the following scenario: if the asserted req object is followed by the asserted
data object then the assertion checks if the ack is asserted one clock cycle later. The first_match operator on the
LHS of the implication guarantees that the acknowledge ack is checked only when the data bit is asserted for the first
time. All subsequent clock cycles where the data bit is asserted are ignored. Such case is presented in the figure
below.
Figure 1. The check_req_fm assertion with the first_match operator and the check_req assertion without the
operator.
230
SystemVerilog Reference
Assertions
Syntax
sequence_instance.triggered
Example
sequence Sending;
@(posedge XTAL) $rose(SEND) ##1 SEND[*7] ##1 $fell(SEND);
endsequence
sequence TI_Pulse;
@(posedge XTAL) !TI[*9] ##1 Sending.triggered ##0 $rose(TI) ##2 $fell(TI);
endsequence
TI signal is low and when the sending finishes it is set for two clock cycles and then drops again to zero. In the
TI_Pulse sequence only the point of the completion of the Sending sequence is important so the method
triggered is used.
The evaluation of TI_Pulse sequence starts at first clock cycle, TI is low for 9 cycles, in the next clock is a check if
the Sending sequence is completed, in the same clock cycle the signal TI rises, is high in the next clock cycle and
drops to zero.
The behavior described by the sequence
@(posedge XTAL) !TI[*9] ##1 Sending ##0 $rose(TI) ##2 $fell(TI)
The evaluation of the TI_Pulse sequence starts at first clock cycle, TI is low for 9 cycles and then in the next clock
cycle starts evaluation Sending sequence, after 9 clock cycles Sending sequence is completed and TI rises.
NOTE: IEEE Std 1364-2005 defined the two keywords corresponding to the current meaning of the triggered
keyword: triggered and ended. The ended keyword applied to the sequence method to which currently the
triggered word applies, and the triggered keyword was used in the other contexts. In the IEEE Std 1800-2009
standard, the triggered keyword is allowed to be used in the sequence context and the ended keyword is
deprecated. In the default compilation (the IEEE Std 1800-2009 mode), the ended method is allowed, but it triggers a
warning message informing that the method is obsolete. You may enforce the strict LRM mode (the -j argument for
the alog command) to block the compilation of the code containing the ended keyword or use the -v2k5 argument
to work in the IEEE Std 1364-2005 compatibility mode.
231
SystemVerilog Reference
Assertions
NOTE: Using the triggered sequence method in the procedural context (e.g. in the wait statement inside the
begin...end block) is not supported yet.
Syntax
sequence_instance.matched
Example
sequence Sending;
@(posedge XTAL) $rose(SEND) ##1 SEND[*7] ##1 $fell(SEND);
endsequence
sequence TI_Pulse;
@(posedge SysClk) !TI[*3] ##1 Sending.matched ##0 $rose(TI) ##2 $fell(TI);
endsequence
The Sending sequence is completed at tick 10 of the XTAL clock. The evaluation of the TIPulse sequence starts at
the first tick of clock SysClk, then TI is low for the first 3 cycles of the SysClk clock. There is a check if Sending
sequence is completed in the next SysClk cycle (cycle 4). In the same cycle TI rises and is high for the next SysClk
cycle, then drops at the 6-th SysClk clock. This completes the TI_Pulse sequence.
232
SystemVerilog Reference
Assertions
Declaration Syntax
sequence_declaration ::=
sequence sequence_identifier [ ( [ sequence_port_list ] ) ] ;
{ assertion_variable_declaration }
sequence_expr ;
endsequence [ : sequence_identifier ]
property_declaration ::=
property property_identifier [ ( [ property_port_list ] ) ] ;
{ assertion_variable_declaration }
property_statement_spec
endproperty [ : property_identifier ]
assertion_variable_declaration ::= var_data_type list_of_variable_decl_assignments ;
The data type of the local variable must be one of the types allowed within assertions. The initial value of the local
variable can be applied using the declaration assignment. The initial expression need not be constant.
A new copy of a local variable is created at the beginning of each evaluation of an instance of a named sequence or
property.
The initialization assignment is executed (if present) in the Observed region, the variables are initialized in the order
that they appear in the sequence or property declaration.
If non-local variables are used in the local variable initialization expression then the Preponed values of non-local
variables from the time slot in which the evaluation attempt begins are used.
Local variables do not have default initial values. If a local variable is declared without an initialization assignment it is
unassigned at the beginning of the evaluation attempt.
Local variables can be assigned and re-assigned within the body of the sequence or property where they are
declared, in the sequence match item.
sequence s1;
int x=0;
@(posedge clk) (a,x=1) ##1 (b,x++)[*2:4]
endsequence
##1 (x>=3)&&(x<=5);
Assignment Syntax
sequence_expr ::= // from A.2.10
...
| ( sequence_expr {, sequence_match_item} ) [ sequence_abbrev ]
...
sequence_match_item ::=
operator_assignment
| inc_or_dec_expression
| subroutine_call
233
SystemVerilog Reference
Assertions
The local variable assignments are performed in the order that they appear in the list specified in a sequence match
item at the end of any non-empty match of the subsequence.
It is not allowed to attach a local variable assignment to a subsequence that can have an empty match, for example
(a[*0:1],x=1).
Local variables cannot be referenced outside the sequences of properties where they are declared. They are not
visible in the context where the sequence or property is instantiated.
It is not allowed to reference a local variable after the point from which it does not flow until after it has again been
assigned a value.
Local variable bit-selects and part-selects can be used in expressions. Local variables can be also used as array
indices.
If a composite sequence includes an or operator, the local variable flows out of this sequence if it flows out
from each of the operand sequences. If the local variable is not assigned before the start of the composite
sequence and it is assigned in only one of the operand sequences, then it does not flow out of the composite
sequence.
sequence s4_i;
bit x;
@(posedge clk) (a ##1 (b,x=1)) or (c ##1 d) ##1 (e>=x);
endsequence
// illegal
sequence s4;
bit x;
@(posedge clk) (a ##1 (b,x=1)) or (c ##1 (d,x=0)) ##1 (e==x); // legal
endsequence
Each thread for an operand of an or that matches its operand sequence continues as a separate thread. Each
thread has its own local variables values, not necessary consistent to other threads variables.
If a composite sequence includes an and/intersect operator the local variable flows out of this sequence if it
flows out of at least one operand of the composite sequence unless it is blocked. A local variable is blocked if
The local variable is assigned in and flows out of each operand of the composite sequence, or
The local variable is blocked from flowing out of at least one of the operand sequences.
sequence s5;
reg x;
@(posedge clk) ((a ##1 (b,x=1)) and (c ##1 d)) ##1 (e>=x); // legal
endsequence
sequence s5_i;
reg x;
@(posedge clk) (a ##1 (b,x=1)) and (c ##1 (d,x=0)) ##1 (e==x); // illegal
endsequence
234
SystemVerilog Reference
Assertions
235
SystemVerilog Reference
Assertions
Properties
Property Declaration
A property describes design behavior. The property declaration is more extensive than the sequence declaration and
describes more complex temporal relations between events.
A property can be declared in a module, in an interface, in a program, in a clocking block, a package and in a
compilation-unit scope.
A property can be used for verification as an assumption - with assume directive, as a checker - with assert directive,
or as a coverage specification - with cover directive. A property declaration by itself does not produce any result.
The result of a property is true or false.
The simplest property can be Boolean expression or the simplest sequence.
Syntax
property_declaration ::=
property property_identifier [ ( [ property_port_list ] ) ] ;
{ assertion_variable_declaration }
property_spec [ ; ]
endproperty [ : property_identifier ]
property_port_list ::=
property_port_item {, property_port_item}
property_port_item ::=
{ attribute_instance } [ local [ property_lvar_port_direction ] ] property_formal_type
formal_port_identifier {variable_dimension} [ = property_actual_arg ]
property_lvar_port_direction ::= input
property_formal_type ::=
sequence_formal_type
| property
property_spec ::=
[clocking_event ] [ disable iff ( expression_or_dist ) ] property_expr
Example 1
property Data_Low_Limit;
@(posedge Clk) Data>=4'b0011;
endproperty
property HndShk;
@(posedge Clk) Req ##2 Ack;
endproperty
236
SystemVerilog Reference
Assertions
Property Instance
A named property can be instantiated in another property, but with one restriction. The instantiated property cannot
include a reset expression (disable iff statement). The possibility of creating property instances allows you to
easily build complex properties and facilitates code maintenance.
Example 2
In the below example, the listed properties Start_Seq, Rd_Transaction, Wr_Transaction, Stop_Seq can be
instantiated in other properties. If any changes to the listed properties are necessary, only their declarations need to
be changed. The code where the properties are instantiated does not need to be touched.
sequence Start_WR;
@(posedge clk) $fell(WR);
endsequence
sequence Start_RD;
@(posedge clk) $fell(RD);
endsequence
property Valid_Addr;
@(posedge clk) ~RD|~WR |-> Addr<8'hc;
endproperty
property RD_Transaction;
@(posedge clk) (!RD && Data==OUT1)[*4];
endproperty
property WR_Transaction;
@(posedge clk) (!WR && Data==IN1)[*4];
endproperty
property Full_RD_Transaction;
@(posedge clk) Start_RD |-> ##[1:$] RD_Transaction ;
endproperty
property Full_WR_Transaction;
@(posedge clk) Start_WR |-> ##[1:$] WR_Transaction ;
endproperty
property No_Idle_Mode;
@(posedge clk) ~Idle |->
endproperty
Full_RD_Transaction or Full_WR_Transaction;
Reset Expression
property_spec ::= [clocking_event ] [ disable iff ( expression_or_dist ) ] property_expr
The expression of the disable iff in a property_spec is called the reset expression. It is tested independently
for different evaluation attempts of the property_spec. If the reset expression becomes true, the overall evaluation
of the property_spec is true, even if the evaluation of property_expr is not finished or failed. If the reset
expression is false the evaluation of property_spec is the same as that of the property_expr.
Nesting of disable iff clauses, explicitly or through property instantiations, is not allowed.
If a sampled value function is used in the reset expression, the sampling clock must be explicitly specified in its actual
237
SystemVerilog Reference
Assertions
argument list. The sequence methods matched and triggered and local variables cannot be used in the reset
expression.
For more clarity, the simulator can print special "DISABLED" messages when the reset expression becomes true and
the whole property_spec is also true. To see "DISABLED" messages, use the -dbg argument for compilation and
enable pass messages using the following command:
assertion pass -enable -log on
Example 3
property Not_To_Early_Ack;
@(posedge Clk) disable iff (!Rst) $rose(Req) |-> !Ack[*1:3] ##1 $rose(Ack);
endproperty
The acknowledge Ack cannot appear earlier than 4 clock cycles after request Req. If reset signal becomes low the
whole property Not_To_Early_Ack is disabled (true).
In the figure above the evaluation of the property starts at clock 1 and succeeds at clock 5 - Ack is true 4 clock cycles
after Req, then the evaluation starts at clock 7 and fails at clock 9 - active Ack happens too early. The next evaluation
starts at clock 11, at the negative edge of the clock 12 the Rst signal drops to zero and makes the property true
(without reset it would fail because Ack happens too early). The simulator reports the DISABLED message at the
negative edge of the reset signal and then at the active clock (posedge Clk).
Parameterized Properties
A property can be declared with formal arguments (typed and untyped). Such a parameterized property can be
instantiated with actual arguments, which can be any of the following:
literal
identifier
expression
event control expression
sequence expression
property expression
the $ symbol
The data types allowed in the expressions are denoted in the Boolean Expressions section.
238
SystemVerilog Reference
Assertions
Untyped Arguments
A formal argument is said to be untyped if there is no type specified for the given argument in the property declaration
or the untyped keyword is used. The type of the references to the untyped formal argument is determined by the
type of the actual argument.
Example 4
The below example, shows how the untyped arguments can be used to create generic properties thanks to the fact
that the types are not specified in the property declaration. These properties are then used to rewrite the declarations
from the Example 2.
The parameterized property CondCheck declares behavior that the scheme statement is tested if the condition
statement is true. The both arguments: condition and scheme are untyped, so the actuals can be of any type. The
RepeatScheme sequence executes the sequence specified with the scheme argument the number of times specified
with the number argument. As in the case of the CondCheck property, the both arguments of the RepeatScheme
sequence are untyped.
property CondCheck(condition,scheme);
@(posedge clk) condition |-> scheme;
endproperty
sequence RepeatScheme(scheme,number);
@(posedge clk) scheme [*number] ;
endsequence
In the Full_RD_Transaction declaration, the actual arguments of the CondCheck property for the condition
and the sequence formals are a sequence and a parameterized sequence, respectively.
property Full_RD_Transaction;
CondCheck(Start_RD,RepeatScheme(!RD && Data==OUT1,4));
endproperty
In the Full_WR_Transaction property declaration, the actual arguments of the CondCheck property for the
condition and the scheme formals are a boolean expression returned by a function call and a sequence
expression, respectively.
property Full_WR_Transaction;
CondCheck($fell(WR),(!WR && Data==IN1)[*4]);
endproperty
In the No_Idle_Mode declaration, the subsequent actuals for the CondCheck property are boolean and property
expressions.
property No_Idle_Mode;
CondCheck(~Idle,Full_WR_Transaction or Full_RD_Transaction);
239
SystemVerilog Reference
Assertions
endproperty
Typed Arguments
The types of formal arguments can be explicitly specified in the property declaration. The arguments can be one of the
following types:
data type (the allowed types are denoted in the Boolean Expressions section)
event
sequence
property
The typed arguments restricts the use of a property to the specified types.
Example 5
In the following example, the CondCheck property and the RepeatScheme sequence from Example 4 are declared
using the typed arguments.
property CondCheck(logic condition,property scheme);
@(posedge clk) condition |-> scheme;
endproperty
sequence RepeatScheme(sequence scheme,shortint number);
@(posedge clk) scheme [*number] ;
endsequence
assert property(CondCheck(WR[*4],nexttime(Data==IN1))); // Error: WR[*4] sequence used instead of logic
assert property(CondCheck(!WR,nexttime(Data==IN1)));
// OK: !WR expression is of the logic type
assert property(RepeatScheme(Ack ##1 !Ack,2));
Property Operators
There are several operators that can be used with properties to describe more complex design features.
Syntax
property_expr ::=
sequence_expr
| ( property_expr )
| not property_expr
240
SystemVerilog Reference
|
|
|
|
|
|
|
Assertions
property_expr or property_expr
property_expr and property_expr
sequence_expr |-> property_expr
sequence_expr |=> property_expr
if ( expression_or_dist ) property_expr [ else property_expr ]
property_instance
clocking_event property_expr
Sequence
operators
Property
operators
Associativity
Left
throughout
Right
within
Left
intersect
Left
not
and
and
Left
or
or
Left
if...else
Right
|->, |=>
Right
Not Operator
Negation of a property is used when the property describes an undesirable behavior.
The negation has the following form:
Syntax
not property_expr
The keyword not states that the evaluation of the property returns the opposite of the evaluation of the underlying
property_expr. Thus, if property_expr evaluates to true, then not property_expr evaluates to false; if
property_expr evaluates to false, then not property_expr evaluates to true.
Example
property EN_Pulse_1;
@(posedge clk) (En[*2:$]);
241
SystemVerilog Reference
Assertions
endproperty
Check_Max_EN_Length: assert property (not EN_Pulse_1);
The property checks if EN remains high for longer than one clock cycle.
The assertion Check_Max_EN_Length fails at clock 7 and at clock 12 because the En pulse is longer than 1 clock
cycle.
And Operator
The and operator is used to define a conjunction of a properties.
Syntax
property_expr1 and property_expr2
The property evaluates to true if, and only if, both property_expr1 and property_expr2 evaluate to true.
Example
The following properties describe the implementation of an LRC (longitudinal redundancy check) module.
The LRC check is performed for each record cycle (CMP=1). If the calculated LRC is not equal to the LRC read from
data downloaded data (CMPR==0), the ERR output turns HIGH until the next LRC check.
property LRCErrDurationProp;
@(posedge clk) disable iff (CLR) !CMPR && CMP |=> (ERR[*1:$] ##1 !ERR && CMP);
endproperty
242
SystemVerilog Reference
Assertions
If any of properties LRCErrDurationProp, CmprLogicProp and RLCLEProp fails at any time during simulation the
CheckLRC assertion reports a failure.
Or Operator
The or operator is used to define a disjunction of a properties.
Syntax
property_expr1 or property_expr2
The property evaluates to true if, and only if, at least one of property_expr1 and property_expr2 evaluates to
true.
Example
property Connect_When_Send;
@(posedge XTAL) SEND |-> RXD_o == SBUF_o[0];
endproperty
property Connect_When_Receive;
@(posedge XTAL) RECEIVE |-> RXD_o == SI;
endproperty
property Disconnect;
@(posedge XTAL) !SEND && !RECEIVE |-> RXD_o === 1'bz;
endproperty
property Connect_RXD;
@(posedge XTAL) Connect_When_Send or Connect_When_Receive or Disconnect;
endproperty
Check_Connect_RXD : assert property (Connect_RXD);
RXD output in a buffer device is connected to SBUF output register during sending, to serial input SI during receiving
or has value Z when there is no transmission. Only one property from the properties Connect_When_Send,
Connect_When_Receive, Disconnect should be successful in one time for the correct behavior of the RXD port.
Implication Operators
The implication statement is used to precondition monitoring of a property expression. The result of the implication is
either true or false.
Syntax
property_expr ::= ...
| sequence_expr |-> property_expr
| sequence_expr |=> property_expr
243
SystemVerilog Reference
Assertions
From a given start point, the left sequence_expr can have zero, one, or more than one successful match.
If there is no match of the left sequence_expr from a given start point, then evaluation of the implication from that
start point succeeds vacuously and returns true.
For each successful match of left sequence_expr, the right property_expr is separately evaluated. The end point
of the match of the left sequence_expr is the start point of the evaluation of the right property_expr.
From a given start point, evaluation of the implication succeeds and returns true if, and only if, for every match of the
left sequence_expr beginning at the start point, the evaluation of the right property_expr beginning at the end
point of the match succeeds and returns true.
Two forms of implication are provided: overlapped using operator |-> and nonoverlapped using operator |=>.
sequence_expr |=> property_expr
Examples
Example 1
property RI_Seq;
@(posedge clk) $rose(RECEIVE) ##1 RECEIVE[*7] ##1 $fell(RECEIVE) |-> $rose(RI);
endproperty
In the figure above the evaluation of RI_Seq starts at first clock, but because there is no rising edge of RECEIVE
signal the evaluation succeeds vacuously. The next evaluation starts at clock 2 and the positive edge of RECEIVE is
detected - the evaluation of the left (antecedent) sequence is successfully completed at clock 10. This causes the
check of the right (consequent) side of the implication operand - the rising edge of RI signal is detected and the whole
property holds. At the next clock cycle shown in the figure the property holds vacuously because there has been no
rising edge on the RECEIVE signal.
Example 2
property RI_Seq_1;
@(posedge clk) $rose(RECEIVE) ##1 RECEIVE[*7] ##1 $fell(RECEIVE) |=> $rose(RI);
endproperty
244
SystemVerilog Reference
Assertions
RI_Seq_1 includes nonoverlapped operator |=>. This causes that the rising edge of the RI signal is checked one
clock after a successful completion of the left sequence. This situation is shown in the figure below.
Implies Operator
The property evaluates to true if, and only if, either property_expr1 evaluates to false or property_expr2
evaluates to true.
Syntax
property_expr1 implies property_expr2
If property_expr1 result is false, the implies operator returns true. If property_expr1 result is true,
property_expr2 is evaluated immediately after the evaluation of property_expr1, that is, in the same simulation
time in which the property_expr1 evaluation is completed.
Example
If the left-hand side(LHS) expression of the below property is false, the property returns the value true and the
assertion r passes vacuously. Otherwise, the evaluation of the right-hand side(RHS) expression begins. Since the
LHS operand contains the cycle delay operator (##), the evaluation of the LHS expression lasts one clock cycle. The
RHS evaluation begins after the LHS evaluation completion, so the expressions are evaluated in different simulation
times.
property p;
(a ##1 b) implies (c ##1 d);
endproperty
r: assert property (p);
The example shows how the above property is evaluated when it is applied to the code below. The values for the
property are sampled in the preponed region, that means, if a signal changes in a particular time, the sampled value is
a value that signal had before a value change.
reg clk = 0;
always #5 clk = ~clk;
default clocking @(posedge clk);
endclocking
reg a,b,c,d;
initial begin
a = 1; b = 0; c = 1;
@(posedge clk);
d = 1;
245
SystemVerilog Reference
Assertions
c = 0;
@(posedge clk);
b = 1; c = 1;
repeat (2) @(posedge clk);
d = 0;
repeat (2) @(posedge clk);
d = 1;
end
initial #70 $finish;
The figure below shows the waveform for the assertion r and for the signals a, b, c, and d used in the p property
expression.
The signal values for an assertion check that begins in the 5 time unit are as follows:
time
5
15
15
25
signal value
a is 1
b is 1 from 0
c is 1 from 0
d is 1
a ##1 b is false
The value a at the 5 unit is 1 and the value b at the 15 unit changes from 0 to 1. Hence, the preponed value of b is 0
and the a ##1 b expression, which is evaluated as the logical and function of preponed a and b values in specified
simulation time, is false. The property evaluates to true without checking the RHS expression, and the assertion
passes vacuously.
In the 15 simulation unit, the values of signals in the assertion property expression are as follows:
time
15
25
25
35
signal value
a is 1
b is 1
c is 1
d is 0 from 1
a ##1 b is true
c ##1 d is true
The true value of the LHS expression does not determine the implies operator result, and, therefore, the RHS
expression has to be evaluated. The RHS evaluation begins in the time of the LHS evaluation completion (25 time
unit) and evaluates to true, since the preponed values of the both: c and d signals are 1. If the RHS expression is
true, the implies operator evaluates to true and the assertion r passes nonvacuously.
The preponed signal values used to evaluate the assertion property in the 25 time unit are:
time
25
35
35
signal value
a is 1
b is 1
c is 1
a ##1 b is true
246
SystemVerilog Reference
45
d is 0
Assertions
c ##1 d is false
The preponed signal values used to evaluate the assertion property from the 35 time unit are:
time
35
45
45
55
signal value
a is 1
b is 1
c is 1
d is 1 from 0
a ##1 b is true
c ##1 d is false
For the assertion checks from 25 and 35 time units, the implies operator returns false and the assertion r fails,
since in both assertion checks neither the LHS operand is false nor RHS is true.
iff Property
The property iff evaluates to true, if either both property_expr1 and property_expr2 evaluates to false or both
property_expr1 and property_expr2 evaluates to true.
Syntax
property_expr1 iff property_expr2
Example
property p;
!b[*2] iff ##[4:8] c;
endproperty
The property evaluates to true if either the b signal holds the 0 value during two subsequent clock ticks and the c
signal holds the value 1 within the [4:8] cycle range or there are no two subsequent clock ticks in which the b signal
is 0 and the c signal does not hold the 1 value within the specified range.
NOTE: The iff operator is supported only for boolean expressions in this release. Please contact Aldec Support to
receive the latest status.
Followed-by Property
The followed-by property evaluates to true if there is at least one successful evaluation of the first expression followed
by a successful evaluation of the second expression.
Syntax
The followed-by property evaluates to true if the sequence_expr has at least one successful match and the
property_expr evaluates to true starting from the end point of some successful evaluation of the sequence_expr
expression.
247
SystemVerilog Reference
Assertions
There are two forms of the followed-by property: the overlapped and non-overlapped indicated by the #-# and #=#
operators, respectively. The difference between these two forms lies in the time considered as the start point of the
property_expr evaluation. For the overlapped property, the property_expr evaluation start point is the end point
of the sequence_expr evaluation and for the non-overlapped property is the next clock tick after the end point of the
sequence_expr evaluation.
Examples
The property p1 contains the overlapped following-by operator, which means that the evaluation of the right-hand side
expression will start at the same clock tick in which the successful evaluation of the left-hand side expression has
ended. The p1 property is evaluated to true if the following sequence of events occurs: b is 1 after one clock tick since
the time when a was 1, and in the same clock tick begins another sequence in which d is 1 after two clock ticks since
the time when c was 0.
property p1;
(a ##1 b ) #-# ( !c ##2 d);
endproperty
The following property contains the non-overlapped following-by operator, which means that the evaluation of the
right-hand side expression will start in the next clock tick after the successful evaluation of the left-hand side
expression. The signal values are checked at positive edges of the clock signal clk. The left-hand side expression
will be evaluated to true if the sequence: a is equal 1 followed by b is equal 0 is repeated twice. The right-hand side
expression, whose successful evaluation has to be started at the next clock tick, says that if c is true then d must hold
during two cycles starting with the cycle in which c is true. If c is false, then the right-hand side expression is true
regardless of the d value.
property p;
@(posedge clk) (a ##1 !b)[*2] #=# (c |=> d[*2]);
endproperty
always Property
Syntax
The always property evaluates to true when the expression following the always keyword evaluates to true in the
current and every future clock ticks. There are three variants of the always property:
248
SystemVerilog Reference
Assertions
The property evaluates to true if, and only if, property_expr holds at every current or future clock ticks that
are within the range of clock ticks specified by constant_range. It is not required that all clock ticks within
this range exist.
always [constant_range] property_expr
Example
The p1 property evaluates to true providing that if b and the value of c occurring after two clock ticks after b are true
or a is true, then d will be false at every clock tick until the simulation end.
property p1;
(a or b ##2 c) |=> always !d;
endproperty
The p2 property evaluates to true, if the property nexttime(c) holds in the range that begins after two clock ticks
from the time when property a ##1 b was evaluated to true and lasts until the simulation end. To the successful
evaluation, it is not required that all clock ticks within the range exist.
property p2;
@(posedge clk) (a ##1 b) |=> always[2:$](nexttime(c));
endproperty
The p3 property evaluates to true if all clock ticks specified by the range [3:7] exist and the a property is true at
each clock tick occurrence in the specified range.
property p3;
s_always [3:7] a;
endproperty
nexttime Property
Syntax
The nexttime property is true when the property following the nexttime keyword evaluates to true in the next clock
tick or in a specified future clock. There are four variants of the nexttime property:
249
SystemVerilog Reference
Assertions
Example
The p1 property evaluates to true if the a property is true at every positive clock edge beginning with the next edge or
there are no further positive clock edges.
property p1;
@(posedge clk) nexttime always a;
endproperty
The p2 property evaluates to true in a given simulation time if the property a evaluates to true at the second clock tick
counting from that simulation time or there is no clock ticks during the two forthcoming clock signal periods.
property p2;
nexttime[2] a;
endproperty
The p3 property evaluates to true if the next clock tick exists and the property a evaluates to true at the beginning of
that clock tick.
property p3;
s_nexttime a;
endproperty
The p4 property evaluates to true if clock ticks exist in the three forthcoming time units and the property a evaluates to
true at the beginning of the last of these clock ticks.
property p4;
s_nexttime[3] a;
endproperty
250
SystemVerilog Reference
Assertions
eventually Property
Syntax
The eventually property evaluates to true if there exists at least one current or future clock tick in which the
property expression following the eventually keyword evaluates to true. There are three variants of the
eventually property:
Example
The p1 property evaluates to true if, and only if, there exists a current or a future clock tick in which the sequence: the
true value on the a signal followed by the false value on the signal b occurs.
sequence s1;
@(posedge clk) a ##1 !b;
endsequence
property p1;
@(posedge clk) s_eventually s1;
endproperty
The p2 property evaluates to true, if there exists at least one positive edge of the clk signal for which the property
p2a is true in the specified [2:5] range, that is, if the a property holds the 0 value until the b variable is 1. or not all
the clock ticks within the range exist.
property p2a;
@(posedge clk) !a until b;
endproperty
property p2;
251
SystemVerilog Reference
Assertions
The p3 property evaluates to true in a given simulation time if there exists at least one clock tick in which the p3a
property is true in the range from the second clock tick after that simulation time to the simulation end.
property p3a;
@(posedge clk) a ##1 b |=> c;
endproperty
property p3;
@(posedge clk) s_eventually [2:$] p3a;
endproperty
If Else Statement
An if-else property syntax:
if (expression_or_dist) property_expr1
or
if (expression_or_dist) property_expr1 else property_expr2
In the first case the if property evaluates to true if expression_or_dist is false or when expression_or_dist is
true together with property_expr1. In the second case the property evaluates to true if expressions_or_dist is true
together with true property_expr1 or when expression_or_dist is false together with true property_expr2.
Example
sequence Start;
@(posedge clk) IN_0 ##1 !IN0;
endsequence
property Check_Start;
@(posedge clk)
if (!Strobe)
Start
else
Wait == 2'b00;
endproperty
Case Statement
The case property statement tests whether a Boolean expression matches any of the specified case items and
executes the statement associated with the case item that matches.
Syntax
property_expr ::=
...
| case ( expression_or_dist ) property_case_item { property_case_item } endcase
...
252
SystemVerilog Reference
Assertions
property_case_item ::=
expression_or_dist { , expression_or_dist } : property_expr [ ; ]
| default [ : ] property_expr [ ; ]
The default item is optional. If none of the case items match and the default item is specified, then the default property
statement is executed. If none of the case items match the expression and the default item is not specified, the case
property statement succeeds and returns true (vacuously).
Example
In the following example, the overlapped implication operator (|->) is used in the expression if the mode value is 0, or
the nonoverlapped operator (|=>), if the mode value is 1. If the mode variable has a different value, the m_select
property returns 0.
property m_select(logic [1:0] mode);
case (mode)
2'b0 : (a ##1 b) |-> (!c ##1 d);
2'b1 : (a ##1 b) |=> (!c ##1 d);
default: 0;
endcase;
endproperty
Recursive Properties
NOTE: The construct is not supported in this release. Please contact Aldec Support to receive the latest status.
Abort Properties
The following abort properties are available in SystemVerilog
accept_on ( expression_or_dist ) property_expr
reject_on ( expression_or_dist ) property_expr
sync_accept_on ( expression_or_dist ) property_expr
sync_reject_on ( expression_or_dist ) property_expr
If during the evaluation of properties with accept_on and sync_accept_on operators, the abort condition becomes
true, then the overall evaluation of the property results in true. Otherwise, the overall evaluation of the property is
equal to the evaluation of the property_expr.
If during the evaluation of properties with reject_on and sync_reject_on operators, the abort condition becomes
true, then the overall evaluation of the property results in false. Otherwise, the overall evaluation of the property is
equal to the evaluation of the property_expr.
The operators accept_on and reject_on represent asynchronous resets and are evaluated at the granularity of
the simulation time step. Their abort condition is evaluated using sampled value as a regular boolean expression in
assertions.
253
SystemVerilog Reference
Assertions
The operators sync_accept_on and sync_reject_on represent synchronous resets and are evaluated at the
simulation time step when the clocking event happens, unlike disable iff, accept_on and reject_on. Their abort
condition is evaluated using sampled value as for accept_on and reject_on.
The nesting of abort operators (accept_on, reject_on, sync_accept_on, sync_reject_on) is allowed. Nested
accept_on, reject_on, sync_accept_on and sync_reject_on operators are evaluated in the lexical order (left
to right).
property hndshk;
@(posedge clk) accept_on (!rst) req |-> ##[1:5] ack;
endproperty
check_hndshk : assert property (hndshk);
The abort conditions may contain sampled value functions. Abort conditions cannot contain any reference to local
variables and the sequence methods triggered and matched.
254
SystemVerilog Reference
Assertions
Immediate Assertions
The immediate assertion statement is a test of an expression performed when the statement is executed in the
procedural code. Contrary to the concurrent assertions, an immediate assertion cannot be placed outside procedural
block, is evaluated independently of the clock signal events and cannot check dependencies between logical values
from different points of the simulation time. The immediate assertion expression is evaluated similarly to the
expression of the if statement: if the expression evaluates to X, Z, or 0, then it is interpreted as being false, and the
assertion is said to fail. Otherwise, the expression is interpreted as being true, and the assertion is said to pass or,
equivalently, to succeed. The immediate assertion statements can perform one of the following verification functions:
assert - the statement is treated as a checker that verifies whether the design behavior is correct.
assume - the statement is treated as an assumption for the design.
cover - the statement evaluation is monitored for the functional coverage.
Syntax
procedural_assertion_statement ::=
...
| immediate_assertion_statement
...
immediate_assertion_statement ::= simple_immediate_assert_statement
| simple_immediate_assume_statement
| simple_immediate_ cover_statement
simple_immediate_assert_statement ::= assert ( expression ) action_block
simple_immediate_assume_statement ::= assume ( expression ) action_block
simple_immediate_cover_statement ::= cover ( expression ) statement_or_null
action_block ::= statement _or_null | [ statement ] else statement
Examples
The immediate assert statement below specifies that if CLR is active (reset), the counter's value should equal zero.
always @(posedge CLK or posedge CLR)
begin
if (CLR)
begin
Check_CLR: assert (Q==0);
end
end
In the below example, the immediate assume statement specifies that the expr_1 should be evaluated to 1.
According to the expr_1 result, the proper message is displayed.
initial begin
as1: assume (expr_1)
$info("Immediate assume condition for expr_1 satisfied at %0t time unit", $time);
else
$warning("Immediate assume condition for expr_1 failed at %0t time unit", $time);
end
In the code below, the statements are covered if they are evaluated to one during occurrence of the falling edge of the
CLK signal.
255
SystemVerilog Reference
Assertions
256
SystemVerilog Reference
Assertions
Concurrent Assertions
Overview
Concurrent assertion is a general name for a property with a verification directive. The verification directive instructs
the verification tool how to process the property. SystemVerilog includes three verification directives - assert,
assume and cover. When the assert directive is used, the property is treated as a checker that verifies if the design
behavior is correct. The assume directive converts the property to an assumption for the design. The cover directive
causes the property to be evaluated for functional coverage.
Syntax
procedural_assertion_statement ::= concurrent_assertion_statement | immediate_assert_statement
concurrent_assertion_item ::= [ block_identifier : ] concurrent_assertion_statement
concurrent_assertion_statement ::= assert_property_statement
| assume_property_statement
| cover_property_statement
assert_property_statement::= assert property ( property_spec ) action_block
assume_property_statement::= assume property ( property_spec ) ;
cover_property_statement::= cover property ( property_spec ) statement_or_null
A concurrent assertion statement can be used outside of a procedural context. It can be used within a module, an
interface, or a program. A concurrent assertion statement is an assert, an assume, or a cover statement. Such a
concurrent assertion statement uses the always semantics. The following two forms are equivalent:
assert property ( property_spec ) action_block
always assert property ( property_spec ) action_block ;
Assert Statement
The assert statement is used to inform the verification tool that a property should be processed as a checker. When
the property in the assert statement is evaluated to be true, the pass statements of the action_block are
executed. Otherwise, the fail statements of the action_block are executed. If no statement is specified for else,
then $error is used as the statement when the assertion fails.
By default, execution of both pass and fail action blocks is enabled for both vacuous and nonvacuous evaluations of
assertions. You can control the execution of pass and/or fail action blocks for assertions that are evaluated vacuously
and/or nonvacuously by using the assertion action control tasks.
257
SystemVerilog Reference
Assertions
NOTE: The distinction between vacuously and nonvacuously failed evaluations of assertions is a proprietary
extension to SystemVerilog developed by Aldec. Depending upon the simulation options specified by the user, this
feature can either be enabled or disabled.
Syntax
assert_property_statement::= assert property ( property_spec ) action_block
action_block ::= statement_or_null | [ statement ] else statement_or_null
Example
assert property (Ack_Max_Cycle) begin
$display("Ack_Max_cycle passed at time ",$time);
pass_count++;
end
else
begin
$error("Acknowledge is not asserted within specified maximum max_ack_cycle cycles from request");
fail_count++;
if (failed_count > `ACK_FAILURE_LIMIT)
activate_additional_tests(Ack,5);
end
In the example above property Ack_Max_Cycle is checked. The assert statement includes the action block. If the
property succeeds, the pass message is displayed ($display task) and the variable pass_count is increased. If
the property fails, the error message is displayed and the variable fail_count is increased. If the failure number
exceeds `ACK_FAILURE_LIMIT, the additional tests are activated (using task activate_additional_tests).
The action block allows user to define an action for assertion pass and failure. This can be used for creating smart
testbenches that will react flexibly to different simulation errors.
Cover Statements
The properties and sequences used for functional coverage have the same syntax as properties created for checkers
but the usage rationale is different. Different processing of these properties during simulation is forced by the cover
sequence and cover property statements. The design is monitored during the simulation, if the scenarios of
events described in sequences / properties happen during simulation, the sequences / properties are covered by the
testbench and pass. Otherwise they are not covered.
Syntax
cover_property_statement::= cover property ( property_spec ) statement_or_null
cover sequence ( [clocking_event ] [ disable iff ( expression_or_dist ) ] sequence_expr )
statement_or_null
The difference between cover sequence and cover property is that for sequence coverage, all matches per evaluation
attempt are reported, whereas for property coverage the coverage count is incremented at most once per evaluation
attempt.
258
SystemVerilog Reference
Assertions
Example
sequence Full_Event;
@(posedge clk) Full[*1:$];
endsequence
sequence Empty_Event;
@(posedge clk)Empty[*1:$];
endsequence
sequence Read_Event;
@(posedge clk) RD[*1:$];
endsequence
sequence Write_Event;
@(posedge clk) !WR[*1:$];
endsequence
sequence Read_Write_Event;
@(posedge clk) !WR[*1:$]};
endsequence
property LongWaitAck; @(posedge Clk) $fell(Strobe) ##1 Ack[*15:$] ;endproperty
Check_Full_Event : cover sequence (Full_Event) $display("Full FIFO happened");
Check_Full_Event_Bis : cover property (Full_Event) $display("Full FIFO happened");
Check_Empty_Event : cover sequence (Empty_Event) $display("Empty FIFO happened");
Check_Read_Event : cover sequence(Read_Event) $display("FIFO read happened");
Check_Write_Event : cover sequence (Write_Event) $display("FIFO write happened");
Check_Read_Write_Event : cover sequence (Read_Write_Event) $display("FIFO write happened");
Check_LongWaitAck : cover property (LongWaitAck) $display("Acknowledge after very long time happened");
The example above includes sequences with typical events for a FIFO buffer - buffer full, buffer empty, write to buffer,
etc. All these events should happen during simulation, otherwise the buffer functionality will not be tested well during
simulation. Each match of the sequences will be reported and counted as covered. For example, if the signal Full will
repeat for five clock cycles: 1, 2, 3, 4 and 5, the cover sequence statement will report the following covered results:
Start
(cycle)
Matched
(cycle)
Full[*1:$]
Full[*1]
Full[*2]
Full[*3]
Full[*4]
Full[*5]
Full[*1]
Full[*2]
Full[*3]
Full[*4]
Full[*1]
Full[*2]
259
SystemVerilog Reference
Assertions
Full[*3]
Full[*1]
Full[*2]
Full[*1]
Matched
(cycle)
Full[*1:$]
Full[*1]
Full[*1]
Full[*1]
Full[*1]
Full[*1]
The cover property statement reports the first matched result for an evaluation.
Example
property Reset_Check;
Q==0;
endproperty
always @(posedge CLK or posedge CLR)
begin
if (CLR)
begin
// If CLR is active (reset), the counter's value should equal zero
CheckCLR: assert property (Reset_Check);
end
else
begin
// CLE signals activates loading from determined input bits to some bits of the counter
if (CLE==2'b01)
begin
CheckCLE1: assert property ((##1 Q[3:0]==D[3:0]));
end
else if (CLE==2'b10)
begin
CheckCLE2: assert property ((##1 Q[5:4]==D[1:0]));
end
end
end
260
SystemVerilog Reference
Assertions
The clock in the property is interfered from the event control of an always block, clock expression must be placed as
the first term of the event control as an edge specifier (posedge expression or negedge expression). The variables in
expression must not be used anywhere in the always or initial block.
There is also possibility to put property definition explicitly to the assert statement.
When a property is placed in an if...else block or a case block the enabling condition from these blocks is used as the
antecedent of the property.
property Reset_Check;
Q==0;
endproperty
...
if (CLR)
begin
// If CLR is active (reset), the counter's value should equal zero
CheckCLR: assert property (Reset_Check);
end
Vacuity Feature
An evaluation attempt of a property is either vacuous or nonvacuous.
property p1;
@(posedge clk) a |-> b ##1 c;
endproperty
property p2;
@(posedge clk) c ##1 d |-> e ##2 f;
endproperty
as1: assert property (p1);
as2: assert property (p2);
The example above includes two properties with suffix implication. For these properties the vacuity feature can be
described as follows: if left side of the implication is false the whole property succeeds vacuously. If left side of the
property is true and the right side of the property is true then the whole property succeeds nonvacuously. In other
words the second success is a real success of the evaluation. In the first case, when implication condition fails
vacuously, the property on the right side is just not evaluated and this is named vacuous success.
The table below presents the vacuity feature for the sequence and properties operators.
Operator
Vacuity
sequence
not
"An evaluation of a property of the form not property_expr is nonvacuous if, and
only if, the underlying evaluation attempt of property_expr is nonvacuous."
261
SystemVerilog Reference
Assertions
or
and
if ()
|->
|=>
instance of a property
"An evaluation attempt of an instance of a property is nonvacuous if, and only if,
the underlying evaluation attempt of the property_expr that results from
substituting actual arguments for formal arguments is nonvacuous."
accept_on/sync_accept_on
reject_on/sync_reject_on
disable iff
262
SystemVerilog Reference
Assertions
Clocks
Concurrent assertion is always tied to a clock. Usually the clock expression includes the negedge or the posedge
operator.
The clock can be specified explicitly in the sequence or property declaration.
Examples
Example 1
sequence Write_4_and_Not_Read;
@(negedge SysClk) (!WR && RD)[*4];
endsequence
property Inactive_TXD;
@(posedge clk) !Rst & !SEND & !RECEIVE |-> TXD;
endproperty
The sequences and properties can also use clock from the default clocking block. In such case, the explicit clock in
the sequence or property is not necessary.
Example 2
default clocking Sys_Clock @(posedge SysClk);
property Load_Prop;
Load |-> QOut==1;
endproperty
endclocking
property Count_Down;
disable iff(!Rst) (!Load & Enable) |-> QOut == $past(QOut)-1;
endproperty
property Load_Data;
@(negedge Load) disable iff (!Rst) (QOut==DataIn);
endproperty
The property LoadProp is clocked by the SysClk, because is located in default clocking block. The property
CountDown is clocked with posedge SysClk clock from the default Sys_Clock clocking block. The sequence or
property can have also another explicitly specified clock expression even if there is default clocking block declaration like in the LoadData property;
Example 3
clocking Block_1_Clock @(negedge Clk1);
sequence Start_Addr;
$rose(TX_H) ##1 $rose(TX_L) ##1 Addr==8'hf0;
endsequence
263
SystemVerilog Reference
Assertions
endclocking
If the sequence or property is declared inside a clocking block, the clocking expression is always inherited from this
clocking block. The sequences and properties inside clocking blocks cannot have an explicitly defined clock
expression.
Example 4
always @(negedge clk)
begin
IN0 = data;
assert property (data==8'hff ##1 data==8'h0);
end
The clock expression can be inferred from a procedural block. The property in the example 4 is clocked with negedge
clk from the always statement.
264
SystemVerilog Reference
Assertions
Multiclock Support
SystemVerilog allows defining multiclock sequences and properties. Several restrictions apply.
Multiclock sequences
In multiclock sequences, only the single-delay concatenation operator ##1 can be used. This operator is
nonoverlapping and synchronizes the clocks of two sequences. The single delay indicated by ##1 is understood to be
from the end point of the first sequence, which occurs at a tick of the first clock, to the nearest strictly subsequent tick
of the second clock, where the second sequence begins.
None of the concatenated multiclock sequences can be empty. Sequence
@(posedge clk0) sig0 ##1 @(posedge clk1) sig1[*0:1]
is illegal because of the possibility of an empty match of sig1[*0:1]. Such empty matches would make it impossible
to determine the starting and ending clocking events.
Example 1
sequence Multi_Seq;
@(posedge clk1) sig1 ##1 @(posedge clk2) sig2
endsequence
The sequence starts with sig1 on a posedge clk, then ##1 moves time to the nearest posedge clk2 and then sig2
is checked.
Multiclock properties
The Boolean property operators (not, and, or) and the nonoverlapping implication operator |=> can be used freely to
combine singly clocked and multiclock properties.
Because |-> overlaps the end of left sequence with the beginning of the right property, the clock for the end of the left
sequence must be the same as the clock for the beginning of the right property.
The if/if...else operators overlap the test of the Boolean condition with the beginning of the if clause property and, if
present, the else clause property. Therefore, whenever using if or if...else, the if and else clause properties must begin
on the same clock as the test of the Boolean condition.
265
SystemVerilog Reference
Assertions
Example 2
property Send_Cycles;
@(negedge ClkS1P1) $rose(SEND)|=> SEND[*7];
endproperty
property TI_Pulse_Set;
@(negedge XTAL) $fell(SEND) |=> TI;
endproperty
property Send;
Send_Cycles and TI_Pulse_Set;
endproperty
The SEND signal is high for 8 machine cycles. When the falling edge of SEND is detected (on the negedge XTAL clock)
then, in the next clock cycle (negedge XTAL), TI is high.
266
SystemVerilog Reference
Assertions
Example
Example 1
This example is based on file i_pcounter.v. (See examples/assertions/mix/simple_uart)
interface i_PCounter_asrt (input Clk, ... output Counted);
default clocking i_PCounter_cl @(posedge Clk);
endclocking
sequence RstSeq;
(!Rst) and !(Counted==0 && QOut==0);
endsequence
CheckRst: assert property(not RstSeq)
else $warning(": during reset output different than zero, Counted=%b", $sampled(Counted));
property LoadData;
@(negedge Load) disable iff (!Rst) (QOut==DataIn);
endproperty
CheckLoad: assert property (LoadData)
else
$warning(" Time=%0t Programmable Counter : Load - violation! Rst=%b QOut=%0d DataIn=%0d ", $time,
$sampled(Rst), $sampled(QOut), $sampled(DataIn));
property CountDown;
disable iff(!Rst) (!Load & Enable) |-> QOut == $past(QOut)-1;
endproperty
CheckCountDown: assert property (CountDown)
else $warning( " Time=%0t Programmable Counter : count down - violation! Load=%b Enable=%b QOut=%0d
previous(QOut)=%0d",
$time, $sampled(Load), $sampled(Enable), $sampled(QOut), $past(QOut) );
endinterface
i_PCounter_asrt is a specialized interface used only for debug purposes. It includes only assertions for design
checking.
267
SystemVerilog Reference
Assertions
Example 2
This example is based on file counter.v. (See examples/assertions/sva/verilog/traffic_lights_controller)
module Counter #(parameter N=4,... DIR=1) (input Clk,... output [N:0] QOut);
...
// ---- Specification ---------------------------------------------------------------------property ResetProperty;
@(negedge Clk) not Rst & (QOut != 0);
endproperty
property LoadProperty;
@(negedge Clk) Load |=> (QOut == DataIn);
endproperty
Reset_Check: assert property (ResetProperty) // No failure
// Failure, during resetting the counter's output different than zero
else $error("time=%0d Reset failure", $time);
Load_Check: assert property (LoadProperty) // Loading was done correctly
// Failure, during loading the counter's output different the DataIn input
else $error("time=%0d Loading failure", $time);
// ---- Implementation --------------------------------------------------------------------always @(negedge Clk , posedge Rst , posedge Load) begin : Counter_body
if (Rst)
q = 0;
else if (Load)
q = DataIn;
else if ( Enable && (!EN_Q0 || (EN_Q0 && (q>0))))
begin : Counting_block
if (DIR)
q++;
else
q--;
end : Counting_block
end : Counter_body
assign QOut = q;
endmodule
The listing shows a counter implementation. Assertions are treated as checkers and as documentation of the counter
features.
268
SystemVerilog Reference
Assertions
Syntax
bind_directive ::= bind bind_target_scope [: bind_target_instance_list] bind_instantiation
| bind bind_target_instance bind_instantiation ;
bind_target_scope ::= module_identifier | interface_identifier
bind_target_instance ::= hierarchical_identifier constant_bit_select
bind_target_instance_list ::= bind_target_instance { , bind_target_instance }
bind_instantiation ::= program_instantiation | module_instantiation | interface_instantiation
Example
bind DAT_CNT DAT_CNT_check DAT_CNT_check_Inst(.CLK(SysCLK), .CLR(Rst), .CLE(CLE), .CE(CE), .D(D),
.Q(Q));
The example shows binding assertions in the DAT_CNT_check module to the DAT_CNT design module.
The format of the target name decides if a bind statement is bound to a module or instance. If the target is a simple
identifier then it is bound to a module (scope). If the target is a hierarchical identifier then this bind statement is
bound to an instance. For a top-level, use $root.<top_module_name> to bind to an instance.
269
SystemVerilog Reference
Assertions
Example 1
module bindex (clk, a, b, d1, d2, d);
input logic clk, a, b;
input logic [4:0] d1, d2;
output logic [4:0] d;
always@(negedge clk)
begin
if(a)
d <= d1;
if(b)
d <= d2;
end
endmodule
module mtx_chk(a, b, clk);
input logic a, b, clk;
property p_check;
@(negedge clk) not (a && b);
endproperty
a_mtx: assert property (p_check);
endmodule
module topex;
logic clk=0;
always #10 clk=!clk;
logic a,b;
logic [4:0] d1, d2;
logic [4:0] du1;
bind topex.uut mtx_chk i2 (a, b, clk);
bindex uut (clk, a, b, d1, d2, du1);
initial begin
d1 = 0;
d2 = 0;
#200;
$finish;
end
logic [0:1] temp=0;
always @(posedge clk) temp++;
assign {a,b}=temp;
endmodule
The bind statement binds the p_check property to the instance of the topex module. The assertion p_check is
checked on a negative edge of a clock. The assertion will fail in the 4th and 8th clock cycle in the simulation unit
270
SystemVerilog Reference
Assertions
scope topex.uut.i2.
Example 2
In the following example, the bind statements are used at the end of the file. When the bind statement is bound to
an instance, an additional top-level module containing the checker mapping and bound instance is created. To see the
assertions during the simulation, it has to be initialized by using the asim command with $root or all top-level modules
have to be specified in the asim command.
module bindex (clk, a, b, d1, d2, d);
input logic clk, a, b;
input logic [5:0] d1, d2;
output logic [5:0] d;
endmodule
module mtx_chk(a, b, clk);
input logic a, b, clk;
property p_mtx;
@(negedge clk) not (a && b);
endproperty
a_mtx: assert property (p_mtx);
endmodule
module topex;
logic clk=0;
always #10 clk=!clk;
logic
logic
logic
logic
a,b;
c,d;
[5:0] d1, d2;
[5:0] du1,du2;
271
SystemVerilog Reference
Assertions
Example 1
The following example presents how to bind a SystemVerilog checker module to a VHDL instance. In this case, the
bind statement is not placed inside the module construct. The simulation is initialized by using the asim command
with the name of the VHDL top-level and {$root}.
library ieee;
use ieee.std_logic_1164.all;
entity sub1 is
port (
clk : in std_logic;
a: in std_logic;
b: in std_logic );
end entity;
architecture rtl of sub1 is
begin
...
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity top is
end entity;
architecture rtl of top is
signal
signal
signal
signal
signal
clk : std_logic;
a: std_logic;
b: std_logic;
c: std_logic;
d: std_logic;
component sub1 is
272
SystemVerilog Reference
port (
clk
a
b
end component;
Assertions
: in std_logic;
: in std_logic;
: in std_logic );
begin
...
end process;
sub1_i : sub1
port map(
clk => clk,
a
=> a,
b
=> b );
end architecture;
The checker sv_chk is bound to the VHDL instance of the sub1 entity on the following ports: clk, a, and b. The
used bind statement is presented below:
bind top.sub1_i sv_chk ch_i1 (.clk(clk),.a(a),.b(b));
273
SystemVerilog Reference
Assertions
Expect Statement
The expect statement allows for waiting on a property evaluation. The process execution is blocked until the property
evaluates (with success or with failure). The statement following expect is executed in Observed region.
property Go_To_Idle;
@(posedge clk) $rose(IN_0) |-> ##2 State==Idle;
endproperty
initial begin
rst = 1'b1;
##3;
rst = 1'b0;
##10;
expect (Go_To_Idle) begin
idle=1'b1;
$display("Idle state reached");
Idle_Process(data);
end
// ...
end
It is allowed to use the expect statement any procedural code, including tasks or class methods. Because it is a
blocking statement, the property can refer to automatic variables as well as static variables.
274
Coverage
Overview
Functional coverage provides metrics that show how much of the design specification, as enumerated by features in
the test plan, has been exercised. Interesting scenarios, corner cases, design states and any other test plan features
can be defined in SystemVerilog and checked for coverage during simulation.
The metrics are based on the design specification and define the project designer intent. They are independent of the
actual design code or its structure.
Using SystemVerilog coverage constructs allows you to check coverage of variables and expressions, as well cross
coverage between them. Checked value ranges or transactions of values can be conveniently specified by using
coverage bins. Filtering conditions can be applied at multiple levels in coverage definitions. Sampling of coverage
variables and expressions can be done using clocking events, clocking blocks, or named blocks. It can be automatic
or triggered procedurally. The operation of coverage models can be controlled by a set of options.
275
SystemVerilog Reference
Coverage
Covergroup
The covergroup construct is used to encapsulate definition of a coverage model. It may include an event that triggers
sampling of coverage points and crosses. It can also assign values to coverage options. Covergroup definition may
include one or more formal arguments.
typedef enum {Idle, Start, Count, Wait, Stop} States;
States state;
int i;
covergroup cg1 (int n) @(posedge clk);
option.auto_bin_max = n;
c1 : coverpoint state;
c2 : coverpoint i;
endgroup
cg1 cg1_inst = new( 256 );
A covergroup can be instantiated multiple times. A covergroup instance is created using operator new. A covergroup
can be declared in a module, program, interface, class, or package.
When formal arguments are specified in the covergroup declaration, instances must provide values to all arguments
that have no default value assigned. input or ref argument directions are allowed. input arguments use the value
passed to new operator when the instance is created. ref arguments point directly to the originally passed object and
always read the current value. In the covergroup context ref is automatically treated as const ref.
logic [1:0] a1,a2;
covergroup cg2 (ref logic [1:0] arg1);
a: coverpoint arg1;
endgroup
cg2 cg2_1 = new( a1 );
cg2 cg2_2 = new( a2 );
initial begin
a1 = 1;
a2 = 2;
cg2_1.sample();
cg2_2.sample();
a1 = 0;
a2 = 3;
cg2_1.sample();
cg2_2.sample();
end
In the example above two instances with different argument values are declared. The cg2_1 instance defines
coverpoint for signal a1. The cg2_2 instance defines coverpoint for signal a2. After simulation of the example is
finished values 1 and 0 will be sampled for cg2_1.a and values 2 and 3 - for cg2_2.a.
The triggering event defines the moment when the coverage points from the covergroup should be sampled. If the
event is omitted from the covergroup declaration, then the user must procedurally trigger the sampling by using the
built-in sample() method.
The strobe option may be used to modify sampling scheduling region. When the strobe option is false, then
sampling may happen multiple times within a time slot. Setting the option to true results in scheduling sampling in the
Postponed region. Consequently, a coverpoint will be sampled only once per time slot.
276
SystemVerilog Reference
Coverage
A covergroup can be also triggered by the start or by the end of execution of a given named block, a task, a function,
or a class method. When a covergroup is triggered at the start of a named block, the sampling takes place
immediately before the first statement in the block is executed. When the end of a named block triggers a covergroup,
sampling is performed after the execution of the last statement in the named block.
A coverage point can be a variable or an expression of integral type. Each coverage point includes a set of bins
associated with its sampled values or value transitions. The bins can be explicitly defined by the user or automatically
created by the tool.
Any class properties can be used to declare a coverpoint. The coverpoint may reference any property of the parent
class regardless of access qualifier (local, protected).
An event dependent on non-static members of enclosing class triggers covergroup sampling individually per each
object. Considering an example above inst1.cg3 samples values twice, while inst2.cg3 - three times.
277
SystemVerilog Reference
Coverage
Coverage Points
A coverage point specifies which variable or expression value or sequences of values transitions should be tracked
during the simulation. Each coverage point includes a set of bins associated with its sampled values or its value
transitions. The bins can be explicitly defined by the user or automatically created by the simulator. A coverage point
can be optionally labeled. If the label is omitted and the coverage point is associated with a single variable, then the
variable name becomes the name of the coverage point. Otherwise a name for a coverage point is generated
automatically for reporting purposes.
A coverage point can sample the values by specifying a clocking block signal. If the clocking block specifies a skew of
#1step, the variable/expression in the coverpoint statement is sampled in the Preponed region. If the clocking block
specifies a skew of #0, the sampling is executed in the Observed region.
The coverage point can include a guard expression, when this expression evaluates to false, the coverpoint is
ignored.
covergroup cov1 @(posedge clk);
coverpoint x iff (!rst);
endgroup
A coverage point bin associates a name and a hit count with a set of values or a sequence of value transitions. The
count is incremented every time the coverage point matches one of the values in the set or the entire sequence of
value transitions. The user can define bins for a coverpoint or the bins can be defined automatically. The option
auto_bin_max controls the number of the automatically created bins.
To create a fixed number of bins for a set of values, a number can be specified inside the square brackets.
bins b2[5] = { [1:2], 3, [4:19], 20, 21 };
The fixed number is used to specify the set of values associated with a bin shall be constant expressions, instance
constants (for classes only), or non-ref arguments to the coverage group. If the number of bins exceeds the number of
values, then some of the bins will be empty. If the number of values is not divisible by the number of bins, then the last
bin will include the remaining items.
The expression within the iff construct enables/disables sampling the values for the bin. If the expression is false at
a sampling point, the count for the bin is not incremented.
logic [3:0] x;
covergroup my_cg @(posedge clk);
278
SystemVerilog Reference
Coverage
coverpoint x {
bins a = { [0:6],7 };
bins b[] = { [8:10],[11:12] };
bins c[] = { 13,14,15 };
bins others[] = default;
}
endgroup
In order to exclude bins from coverage the ignore_bins construct is used. Specified values are excluded from
coverage even if they are included in another bins. When ignore bin is hit, runtime warning is produced. Bins may be
also marked as illegal using illegal_bins construct. When value from illegal bin is sampled, runtime error is
produced. Bins marked as illegal take precedence over any other bins.
logic [3:0] x;
covergroup my_cg @(posedge clk);
coverpoint x {
bins a = { [0:6],7 };
ignore_bins ignore_them[] = { [8:10],[11:12] };
illegal_bins illegal[] = { 13,14,15 };
bins others[] = default;
}
endgroup
In the example above bin wb defines the following values: 0, 1, 2, 3, 15, but value 0 is specified within ignore bin
definition and is excluded. Therefore, bin wb is hit with values 1, 2, 3 and 15.
A wildcard bin definition only considers 2-state values. Sampled values containing X or Z are excluded.
Wildcard cannot be used for range specification of bins definition.
279
SystemVerilog Reference
Coverage
DEV_STATES dev_sm;
covergroup cg_dev_sm @(posedge clk);
cp: coverpoint dev_sm iff
{
bins dev_started
=
bins dev_whole_packet =
bins dev_suspended
=
bins dev_resumed
=
}
(rst==1'b0)
(IDLE =>
(IDLE =>
(IDLE =>
(SUSPEND
SEND_PACKET);
SEND_PACKET[*2:1023] => CRC[*2] => IDLE);
SUSPEND[*2000]);
=> IDLE);
endgroup
endmodule
The example above, which contains four transition coverage bins, shows how to check the transitions in a state
machine. The following sequence is associated with the bin dev_started: IDLE => SEND_PACKET. The next bin
construct, dev_whole_packet, waits for the sequence of the following states: IDLE and SEND_PACKET for the
range of repetitions from 2 to 1023 and then the simulator waits for 2 clock cycles of CRC and ends with the IDLE
state. The third bin construct, dev_suspended, waits for the following sequence: IDLE and stays in the SUSPEND
state for 2000 clock cycles. The last sequence is associated with the bin dev_resumed: SUSPEND => IDLE.
For more information about transition bins, see 19.5.1 in IEEE Std 1800-2009.
Limitations
Cross coverage for transition bins is not supported yet.
Transition bins declared inside class templates are not supported yet.
280
SystemVerilog Reference
Coverage
Cross Coverage
Cross coverage between multiple coverage points or variables is defined with the cross construct. If variable is used
in cross, implicit coverpoint is declared for this variable. Expression may not be specified directly in the cross
definition, but coverpoint should be declared for the expression first. Crossing coverpoints is allowed only if they are
defined within the same covergroup.
Crossing any number of coverage points is the coverage of all bins combinations belonging to these coverage points
(Cartesian product of coverage points bin sets). Default, ignore and illegal coverpoint bins are not included to the
cross coverage products. The following example defines cross of single bit variables, therefore four cross bins are
generated.
bit x,y;
covergroup cov1 @(posedge clk);
coverpoint x;
coverpoint y;
cross x,y;
endgroup
Generated cross products: bin <auto(0), auto(0)>, bin <auto(0), auto(1)>, bin <auto(1),
auto(0)>, bin <auto(1), auto(1)>
Total number of automatically generated cross bins may not exceed 2^31.
Cross coverage guard expression is specified with iff clause. Used at the cross level it disables cross evaluation
when the expression is false. Used at cross bin level, guard expression controls hitting of particular bin.
Cross products may be excluded from coverage computation or marked as illegal. In order to exclude coverage
products ignore_bin is used.
cross a, b {
bins my_bins = binsof (a) intersect {[0:3]};
ignore_bins ignore_them = binsof (a) intersect {[4:7]};
}
When ignore bin is hit, runtime warning is produced. When illegal bin is hit, runtime error is issued.
281
SystemVerilog Reference
Coverage
Coverage Options
The SystemVerilog defines a set of options for the coverage. They control the behavior of the covergroup, coverpoint
and cross. They can be applied to a specific instance of a covergroup or to covergroup type as a whole. Specifying
value for determined option more than once in the covergroup declaration scope is not allowed.
Instance-specific Options
Option
LRM
default
value
Simulator
default
value
Description
weight=number
goal=number
100
100
name=string
unique
name
unique name
comment=string
""
""
at_least=number
Minimum number of hits for each bin. A bin with a hit count
that is less than the number is not considered covered.
detect_overlap=boolean
auto_bin_max=number
64
64
cross_num_print_missing
=number
per_instance=boolean
get_inst_coverage=boolean
282
SystemVerilog Reference
Coverage
option.option_name = expression ;
Constant expression only may be used to assign an option value. Covergroup arguments may also be used within an
expression.
The identifier option is a built-in member of any coverage group.
covergroup cov @(posedge clk);
option.per_instance = 1;
coverpoint a {
option.auto_bin_max = 32;
}
endgroup
The per_instance and get_inst_coverage options can only be set in the covergroup definition. The
auto_bin_max and detect_overlap options can only be set in the covergroup or coverpoint definition. Other
options can be set procedurally after a covergroup has been instantiated.
covergroup cov1 @(posedge clk);
cx : coverpoint x;
cy : coverpoint y;
endgroup
// ...
cov1 cov1_inst0 = new;
cov1_inst0.option.comment ="cov1_inst0 instance";
cov1_inst0.x.option.weight = 3;
All instance options can be specified at the covergroup level. Except for the weight, goal, comment, and
per_instance options, all other options set at the covergroup syntactic level act as a default value for the
corresponding option of all coverpoints and crosses in the covergroup during its definition. Individual coverpoints or
crosses can overwrite these default values. When set at the covergroup level, the weight, goal, comment, and
per_instance options do not act as default values to the lower syntactic levels.
Type Options
Option
weight=constant_number
Standard
default
value
Simulator
default
value
Description
100
goal=constant_number
100
comment=string_literal
""
""
strobe=boolean
When true, all samples happen at the end of the time slot,
like the $strobe system task.
283
SystemVerilog Reference
merge_instances=boolean
Coverage
284
SystemVerilog Reference
Coverage
Coverage Methods
The predefined coverage methods are provided for the covergroup and can be invoked procedurally at any time.
Method
covergroup
coverpoint
cross
yes
no
no
yes
yes
yes
yes
yes
yes
yes
yes
yes
void set_inst_name(string)
yes
no
no
void start()
yes
yes
yes
void stop()
yes
yes
yes
void sample()
Description
real get_coverage()
real get_coverage(ref int, ref
int)
real get_coverage(ref int, ref
int)
real get_inst_coverage()
real get_inst_coverage(ref int,
ref int)
The get_coverage() method is a static method. It is available for types via :: operator and for instances via .
operator. The get_inst_coverage() method is available only for a specific instance via . operator. Both methods
can be invoked with optional set of arguments (passed by reference). When the optional arguments are specified, the
get_coverage() and get_inst_coverage() methods assign to the first argument the value of the covered bins
and to the second argument the total number of bins for the given coverage item. These two values correspond to the
numerator and the denominator used when calculating the particular coverage percentage (the return value before
scaling by 100).
285
SystemVerilog Reference
Coverage
In the example above integer values 3 and 5 are sampled by passing actual arguments to an instance sample()
method call.
286
SystemVerilog Reference
Coverage
Description
$set_coverage_db_name(name)
Sets the filename of the coverage database into which coverage information
is saved at the end of a simulation run.
$load_coverage_db(name)
Loads from the given filename the cumulative coverage information for all
coverage group types.
$get_coverage()
Returns as a real number in the range of 0 to 100 with the overall coverage
of all coverage group types (cumulative coverage).
287
SystemVerilog Reference
Coverage
288
SystemVerilog Reference
Coverage
Coverage Computation
The cumulative coverage is calculated using the contribution of covergroup types.
The cumulative coverage - C - is the weighted average of the coverage of all covergroup types:
where:
g - set of covergroup types.
Wg - the weight associated with type g.
Cg - the coverage of type g.
where:
|bins| - the cardinality of the set of bins defined.
|bins covered| - the cardinality of the covered bins - the subset of all (defined) bins that are covered.
If the bins are automatically generated the computation uses the following equation:
where:
|bins covered| is the cardinality of the covered bins - the subset of all (auto-defined) bins that are covered.
M - the minimum number of bits needed to represent the coverpoint.
auto_bin_max - the value of the auto_bin_max option in effect.
The cumulative coverage considers the union of all significant bins; it includes the contribution of all bins (including
overlapping bins) of all instances.
289
SystemVerilog Reference
Coverage
where:
j - belongs to a set of crossed coverpoints.
Bj - the cardinality of coverpoint with j number.
Bc - the number of auto-cross bins.
Bu - the number of user-defined cross bins excluding ignore_bing and illegal_bins, i.e. bins that are relevant
for coverage percentage.
Bb - the number of cross products that includes all user-defined cross bins.
where:
Wi - the weight option of the instance.
Ii - the instance coverage.
Coverpoint or cross type coverage is computed in the same way using coverpoint or cross coverage of each instance.
The return values of get_coverage(ref int, ref int) method are also computed according to the formula
above when type_option.merge_instances is false.
290
SystemVerilog Reference
Coverage
When type_option.merge_instances is true, instances are merged and cumulative coverage is obtained
computing all bins from all instances. When bin name overlapping occurs among instances, cumulative coverage
count of the bin is the sum of the bin counts in all instances containing the bin.
Following formula is used for coverage computation when instances are merged:
where:
i - set of coverage items (coverpoints and crosses).
Wi - the weight associated with item i.
Ci - the coverage of item i.
291
Hierarchy
Packages
SystemVerilog packages are used to group type definitions, data declarations (variables and nets), functions, tasks,
sequence and properties. Packages cannot contain any processes. Wire declarations with implicit continuous
assignments are not allowed.
An example of a package is shown below. The package groups several type definitions and conversion functions.
package colors;
typedef reg [3*8 -1 :0] RGB_t;
typedef reg [3*8 -1 :0] CMY_t;
typedef reg [4*8 -1 :0] CMYK_t;
typedef enum { WHITE, YELLOW, ORANGE, RED, GREEN, BLUE, BLACK } COLORS_t;
function CMY_t rgb2cmy( RGB_t i );
rgb2cmy[23:16] = 8'hFF - i[23:16];
rgb2cmy[15:8] = 8'hFF - i[15:8];
rgb2cmy[7:0] = 8'hFF - i[7:0];
endfunction
function CMYK_t cmy2cmyk( CMY_t i );
reg[7:0] min;
min = i[7:0];
min = (min < i[15:8] ) ? min : i[15:8];
min = (min < i[23:16]) ? min : i[23:16];
cmy2cmyk[31:24] = i[23:16] - min;
cmy2cmyk[23:16] = i[15:8] - min;
cmy2cmyk[15:8] = i[7:0] - min;
cmy2cmyk[7:0] = min;
endfunction
function CMYK_t rgb2cmyk( RGB_t i );
rgb2cmyk = cmy2cmyk( rgb2cmy( i ));
endfunction
endpackage
Packages are declared at the outermost level of source code, alongside modules, interfaces, programs and
user-defined primitives.
It is not allowed to use hierarchical references in packages. Packages can include parameters, nets and variables.
Variable declaration assignments within the package shall occur before initial, always, always_comb,
always_latch, or always_ff processes.
292
SystemVerilog Reference
Hierarchy
The package must be compiled before it is referenced with the scope operator. Otherwise the compiler will report an
error.
The scope where the import keyword is used may contain local declarations that hide declarations from packages.
An explicit import is not allowed if the imported identifier is declared in the same scope or explicitly imported from
another package. Importing an identifier from the same package multiple times is allowed.
The contents of a package can be referenced in a module, an interface, or a program by an import in the header of
such a unit. The contents of such imported packages are visible throughout the unit, including its port and parameter
declarations:
module RGB_2_CMY import colors::*;
// Contents of 'colors' are visible in module's port declarations:
(
output CMY_t out,
input RGB_t in,
input clk
);
// ... and in the module's body:
always @(posedge clk) out = rgb2cmy( in );
endmodule: RGB_2_CMY
Description
Scope containing
a declaration of
Scope
Scope not
the same
containing the
containing the
local declaration local declaration identifier
imported using
of the same
of the same
another package,
identifier, for
identifier, for
for example:
example var1
example var1
o_pckg::var1
293
Scope containing
a declaration of
the same
identifier
imported using
another package
and * symbol, for
example:
o_pckg::*
SystemVerilog Reference
A reference to
package identifier
via the scope
operator ::, for
example my_pckg
:: var1
A package
identifier is
visible in any
scope
Hierarchy
Direct reference
to var1 refers to
the identifier
declared locally.
my_pckg::var1
refers to the
identifier from
package
my_pckg
Direct reference to
var1 refers to the
Direct reference
identifier from the
is illegal.
other package
my_pckg::var1
(o_pckg::var1)
refers to the
my_pckg::var1
identifier from
refers to the
package
identifier from
package my_pckg
Direct reference to
var1 refers to the
identifier from the
other package
(o_pckg::var1)
my_pckg::var1
refers to the
identifier from
package my_pckg
A reference to
package identifier
using import
keyword, for
example import
my_pckg::var1
All package
identifiers are
potentially
directly
Error
visible in the
importing
scope.
Direct reference
to var1 refers to
the identifier
imported from
package
my_pckg.
It is not allowed to
import an identifier
defined in the
importing scope.
The import of
my_pckg::var1
makes any prior
reference to var1
illegal. Otherwise,
direct reference to
var1 refers to the
var1 imported from
package
my_pckg.
A reference to
package identifier
using import
keyword and *
symbol, for
example: import
my_pckg::*;
Imported
identifier is
directly
visible in the
importing
scope.
Direct reference
to var1 refers to
the identifier
imported from
package
my_pckg.
Direct reference to
var1 refers to the
identifier from the
other package
(o_pckg::var1)
It is illegal to
reference var1, it is
undefined.
Direct reference
to var1 refers to
the identifier
declared locally.
294
SystemVerilog Reference
Hierarchy
export p1::*;
endpackage
package p3;
import p1::*;
import p2::*;
export p1::x;
export p2::x;
endpackage
295
SystemVerilog Reference
Hierarchy
Compilation Unit
Compilation unit refers to a set of files compiled together. Compilation-unit scope is local to the compilation unit. It
contains all declarations that lie outside of any other scope. The name $unit used to explicitly access the identifiers
in the compilation-unit scope.
All files on a given compilation command line build a single compilation unit. In this case the declarations within those
files are accessible anywhere else within the constructs defined within those files. Each file is a separate compilation
unit. In this case the declarations in each compilation-unit scope are accessible only within its corresponding file.
Items defined in the compilation-unit scope cannot be accessed by name from outside the compilation unit. Access to
the items in a compilation-unit scope can be accessed using the PLI, which must provide an iterator to traverse all the
compilation units.
Example
const integer i = 1;
module m;
const integer i = 2;
initial $display( "%0d %0d", i, $unit::i );
endmodule
Constant i is declared outside module m. Another constant named i is declared inside module m. The declaration
inside the module scope hides the declaration at the compilation unit scope. However, the declaration at the
compilation unit scope can still be accessed with the $unit:: prefix. When the code shown in the listing is simulated,
the display statement will print 2 1, i.e. the value of the module-local constant i (2) followed by the value of the
constant i declared in the compilation unit scope (1).
Scoping Rules
The compiler sets the compilation unit scope to all files specified on the command line. Assuming that files f1.sv, f2.sv,
and f3.sv are compiled with the following command
alog f1.sv f2.sv f3.sv
then the compilation unit comprises all three files and the compilation unit scope ($unit::) is shared between all
three files. Files included with the `include directives (if any) are also a part of this compilation unit.
To make each file a separate compilation unit (and have a separate compilation unit scope for each file), compile the
files with separate commands, for example:
alog f1.sv
alog f2.sv
alog f3.sv
Each compiler run will use a different compilation unit consisting of the file specified on the command line and files
included with the `include directive (if any).
296
SystemVerilog Reference
Hierarchy
Top-level Instance
SystemVerilog introduces name $root to unambiguously refer to a top-level instance or to an instance path starting
from the root of the instantiation tree. $root is the root of the instantiation tree. $root allows explicit access to the
top of the instantiation tree.
Example
$root.A.B // item B within top instance A
$root.A.B.C // item C within instance B within instance A
297
SystemVerilog Reference
Hierarchy
Nested Modules
SystemVerilog introduces a possibility to declare a module within another module. The outer name space is visible to
the inner module so that any name declared there can be used, unless is hidden by a local name. Nesting of modules
can be used to create logical partitioning of a module without using ports. It can be also used to create a library of
modules that is local to a part of a design.
module device1();
module block1;
interrupts inst1();
reg_block inst2();
always @(posedge clk) o1 = vc[0:3];
endmodule
module block2;
transmitter inst ();
reg_block inst2 ();
assign s1 = t1 & r3;
endmodule
block1 block1_inst ();
endmodule
Extern Modules
Extern modules are introduced to facilitate separate compilation. For regular, non-extern modules, signal connections
are established during the project elaboration when all instances have already been declared. The extern module
declaration allows you to declare a module port list without declaring a module itself, and perform the connection
check earlier, when the project is compiled.
If an instance port does not match an extern module declaration, a warning message is reported:
298
SystemVerilog Reference
Hierarchy
When instantiating a module, the wildcard pattern .* may be used in the same way as in the case of non-extern
modules. The following instantiations are equivalent:
exm mm1 (.*);
exm mm2 (w,x,z);
Names, positions, and variable types of the extern and actual module declarations must match. When specifying
module contents, you may use the wildcard pattern .* instead rewriting variable names:
extern module exm(w, x, z);
extern module expm #(parameter width0 = 8, parameter width1 = 4)
(input wire [width0-1:0] a, output bit [width1-1:0] b);
module exm(.*);
input byte w,x;
output byte z;
//...
endmodule
module expm(.*);
//...
endmodule
// above declarations are equivalent to:
module exm(w, x, z);
input byte w,x;
output byte z;
//...
endmodule
module expm #( parameter width0 = 8, parameter width1 = 4)
(input wire [width0-1:0] a, output bit [width1-1:0] b);
//...
endmodule
The extern modules can appear at any hierarchy level, but are visible only within the region where declared.
299
SystemVerilog Reference
Hierarchy
Ports Declarations
In SystemVerilog, a port may contain declarations of an interface, an event, a variable or net of any allowed data type
including an array, a structure or a union.
typedef enum {start,go,await,stop} states_type;
typedef struct {int a; reg b;} struct_type;
module m (input int i,input states_type state, output struct_type structure);
// ...
endmodule
If no type and direction is specified in the first port, the declaration of type and direction must be located after the ports
list.
module m (a,b,c);
input int a,b;
output reg [3:0] c;
// ...
endmodule
If first port declaration includes the type but there is no direction, the default assumed direction is inout.
module m (wire logic[31:0] a, wire logic[7:0] b);
assign b = a[7:0] & a[15:8];
endmodule
If first port declaration includes the direction but the type is omitted, the wire type is assumed as default.
module m(input a, output b);
// ...
endmodule
If subsequent ports declarations include no type and direction, the type and direction is inherited from the previous
declaration.
module m(input byte a1,a2,a3);
// ...
endmodule
If subsequent ports include type but direction is omitted, it is inherited from the previous port declaration.
module m(input byte a, reg b, int c);
// ...
endmodule
If subsequent ports type include direction but type is omitted the assumed type is wire.
module m(input a, input b, output c);
// ...
endmodule
300
SystemVerilog Reference
Hierarchy
Ports Mapping
SystemVerilog expands Verilog facilities related to port mapping.
The .name syntax can be used if the name and size of a port in the instantiated module matches the name and size of
the connecting port or variable. Note that this eliminates the requirement to list a port name twice while still listing all
ports of the instantiated module.
A .* syntax can be used for all ports in the instantiated module where the name and size of a port matches the name
and size of the connecting port or variable.
Implicit .* port connections can be mixed with named port connections:
module m (output o, input i1, i2);
endmodule
module top;
wire w, i1, i2;
m U1 (.o(w), .*);
endmodule
The .* token can be placed anywhere in the port list but it can only appear at most once in the port list, when it is
mixed with named port connections.
301
SystemVerilog Reference
Hierarchy
A named or implicit .name connection can be mixed with a .* connection in one instance.
302
SystemVerilog Reference
Hierarchy
module sub;
int k;
endmodule
module top;
int a;
localparam M=2;
parameter J=7;
genvar i;
generate
for(i=0;i<4;i++)
begin:gen
sub s[i:J]();
initial #0 s[J-i].k=i;
end
endgenerate
initial #5 a = gen[M].s[J-M].k;
endmodule
Parameters can be used in hierarchical paths to variables declared inside these module instances. It can be done
inside generate block or outside of it. Loop index variables, which are always declared as genvar, also can be used in
such hierarchical references.
303
SystemVerilog Reference
Hierarchy
The Verilog standard (IEEE Std 1364) requires using the `timescale directive:
`timescale 1ns / 1ps
304
SystemVerilog Reference
Hierarchy
Configurations
Configurations are described in Verilog Reference. Additionally, SystemVerilog supports setting parameters in
configurations. For more information, refer to 33.4 in IEEE Std 1800-2009.
Example
config cfg1;
localparam S = 24;
design lib_top.top;
instance top.a1 use
instance top.a2 use
instance top.a3 use
instance top.a4 use
endconfig
#(.W(16),.D(512));
#(.W());
#();
#(.W(S));
For the a1 instance, the use clause sets the values for the W and D parameters.
In the a2 instance, the use clause sets the W parameter to its default value.
In the instance a3, the clause sets the default values for all instance parameters.
The clause applied in the instance a4 assigns the localparam value to the W parameter.
Important Notes
The parameter specified by a configuration will have a priority even if the value of the defparam statement is
passed.
It is impossible to refer to any constructs which are under the generate statement by using the configuration.
Passing parameters in configuration can only be done by name.
305
SystemVerilog Reference
Hierarchy
T o, input T i1,i2);
306
Interfaces
Interface Declaration
SystemVerilog interface encapsulates communication between blocks. The interface can be accessed as a single
port item; using it reduces the size of description and improves the code maintainability.
Using parameters, constants, variables, functions, tasks, assertions, covers and processes in the interface enhances
its functionality isolated from module and can be useful for system-level modeling and testbench applications.
The example below shows a declaration of interface itf.
interface itf;
reg a;
reg b;
reg [1:0] c1;
reg [1:0] c2;
endinterface: itf
An interface can contain a smaller interface and can be passed through ports. It can be used in a declaration of a
module, for example:
module mod1(itf if1, input en);
// ...
endmodule
module mod2(itf if2, input clk);
// ...
endmodule
Interfaces can be instantiated hierarchically, like modules, with or without ports. They can also be nested in a module
instantiation, for example:
module top;
logic clk = 0;
//interface instance
itf sv_itf();
// connect the interface by position
mod1 UUT1(sv_itf, clk);
// or by name
mod2 UUT2(.if2(sv_itf), .clk(clk));
endmodule
Note that only one change in the source code is required if the interface between modules changes. You only need to
edit the declaration of itf. Module declarations and module instantiations will stay intact. Variables declared in the
interface can be referenced by using the dot (.) operator.
module mod1(itf if1, input en);
always @(posedge if1.a)
if1.c1 = if1.c2;
// ...
endmodule
307
SystemVerilog Reference
Interfaces
Interface Ports
Nets and variables declared within the interface can be only used to connect to a port with the same nets and
variables. If the external net variable must be shared using an interface, the port declaration must be used. The
interface ports can be connected externally by name or position when the interface is instantiated.
Example
interface itf ( input clk, input a, input b, output c);
endinterface
module mod1(itf i1);
// ...
endmodule
module top;
logic clk,x,y,z;
itf itf_1 ( .clk,.a(x),.b(y),.c(z));
mod1 mod1_i1 (.i1(itf_1));
// ...
endmodule
308
SystemVerilog Reference
Interfaces
Modports
SystemVerilog introduces modport construct. It provides direction information for module ports and to control the use
of tasks and functions within particular modules.
interface itf;
wire a, b, c, d;
modport master (input a, b, output c, d);
modport slave (output a, b, input c, d);
endinterface
module m (itf.master i);
// ...
endmodule
module s (itf.slave i);
// ...
endmodule
module top;
itf i();
m u1(.i(i));
s u2(.i(i));
endmodule
The modport can also be specified in the port connection with the module instance, where the modport name is
hierarchical from the interface instance.
module m (itf i);
//...
endmodule
module s (itf i);
//...
endmodule
module top;
itf i();
m u1(.i(i.master));
s u2(.i(i.slave));
endmodule
All of the names used in a modport declaration must be declared by the same interface as the modport itself. In
particular, the names used shall not be those declared by another enclosing interface, and a modport declaration shall
not implicitly declare new ports.
Modport Expressions
You can specify the elements of arrays and structures, concatenations of elements, and assignment pattern
expressions of elements declared inside an interface as the modport items. The modport items declared as one of
these constructs are called the modport expressions.
The modport expressions are explicitly named with a port identifier which is accessible only through the modport
connection. The port identifiers exist in their own name space for each modport list. If a modport expression is a
simple port identifier, that identifier is used as both the port identifier and the reference to a variable declared in the
interface. It is not allowed to specify multiple port identifiers of the same name in the modport declaration.
309
SystemVerilog Reference
Interfaces
Example
In the following example, there are two modport expressions: the first one, denoted by the p1 port identifier, is an
element of the a two-dimensional array. The second one, denoted by the p2 port identifier, is a part-select of the b
logic vector.
interface I;
integer a [3:0][2:1];
logic [3:0] b;
modport mp (input .p1(a[0][1]), output .p2(b[1:0]));
initial a[0][2:1] = {36,78};
endinterface
module top;
I I();
m1 m1(I.mp);
endmodule
module m1(I i);
initial begin
i.p2 = '1;
#1 $display("i.p1 = %0d, i.p2 = %0b",i.p1, i.p2);
end
endmodule
310
SystemVerilog Reference
Interfaces
311
SystemVerilog Reference
Interfaces
endmodule
module top();
itf iface();
sub sb(iface.A);
endmodule
312
SystemVerilog Reference
Interfaces
Parameterized Interfaces
The interface declaration can be parameterized as a module or program declaration.
Example
interface itf
#(parameter byte WIDTH = 8, int MIN = 0, int MAX = 10)
(input clk, input ce,input set,inout [WIDTH-1:0] data);
endinterface
module m(interface any_itf);
endmodule
module top;
itf #(4,1,12) itf_i (.set(ld),.*);
m m_inst(.any_itf(itf_i));
// ...
endmodule
NOTE: An interface assignment to another interface with different actual parameters is not allowed in the IEEE Std
1800-2009. You can use this construct, however, in the IEEE Std 1800-2005 compatibility mode (the -sv2k5
acom argument).
virtual itf #(5,3,14) itf_v1;
initial itf_v1 = itf_i;
Above, a virtual interface of the type defined in previous example is initialized with the itf_v1 interface. The
interfaces have different actual parameters. This assignment will trigger an error unless the IEEE Std 1800-2005
compatibility mode is in use.
313
SystemVerilog Reference
Interfaces
314
SystemVerilog Reference
Interfaces
Virtual Interfaces
A virtual interface is a variable that represents an interface instance. Virtual interfaces provide a mechanism for
separating abstract models and test programs from the actual signals that make up the design. By using virtual
interfaces, you can construct a subprogram that operates on different parts of a design, and dynamically control the
set of signals associated with the subprogram.
Syntax
virtual_interface_declaration ::= virtual [ interface ] interface_identifier
list_of_virtual_interface_decl ;
list_of_virtual_interface_decl ::= variable_identifier [ = interface_instance_identifier ]
{ , variable_identifier [ = interface_instance_identifier ] }
data_declaration ::= ... | virtual_interface_declaration
data_type ::= ... | virtual [ interface ] interface_identifier
315
SystemVerilog Reference
Interfaces
//...
endmodule
Virtual interfaces can be declared as class properties, which can be initialized procedurally or by an argument to
new().
interface itf;
logic req, ack;
endinterface
class C;
virtual itf itf_var;
function new(virtual itf itf_in);
itf_var = itf_in;
endfunction
task request();
itf_var.req = 1'b1;
endtask
endclass
module device (itf i);
//...
endmodule
program prog (itf i);
C c = new(i);
initial begin
//...
c.request();
end
endprogram
module top;
logic req, ack;
itf itf_inst ();
device devinst (itf_inst);
prog proginst (itf_inst);
endmodule
316
SystemVerilog Reference
Interfaces
endfunction
task request();
itf_var.cb.req <= ##2 1'b1;
endtask
endclass
317
Overview
Name
Syntax
Description
When one of the display tasks is invoked, it simply prints
its arguments. The $display task adds a new line
character at the end of the output. The display tasks are
very similar to the print functions in the ANSI C language.
$display
$display [(arguments)]
$displayb
$displayb [(arguments)]
$displayh
$displayh [(arguments)]
$displayo
$displayo [(arguments)]
$write
$write [(arguments)]
$writeb
$writeb [(arguments)]
$writeh
$writeh [(arguments)]
$writeo
$writeo [(arguments)]
$fdisplay
$fwrite
$fdisplay (output_var,
format_string [ ,
list_of_arguments ])
318
SystemVerilog Reference
$fwrite (output_var,
format_string [ ,
list_of_arguments ])
$sformat
$sformat (output_var,
format_string [ ,
list_of_arguments ])
$sformatf
$psprintf
$sformatf ( format_string
[ , list_of_arguments ])
$psprintf ( format_string
[ , list_of_arguments ])
319
SystemVerilog Reference
Example
module top;
int r1;
initial begin
r1 = 10;
$display( "Default printing - :%d: :%h:", r1,r1 );
$display( "Printing with minimum size - :%0d: :%0h:", r1,r1 );
$display( "Printing with defined size - :%4d: :%4h:", r1,r1 );
$display( "Printing with defined size (leading zeros for decimal format added) - :%04d: :%04h:", r1,r1
);
end
endmodule
NOTES:
The escape sequence %0<N> works only for the decimal format specifier. For other specifiers, 0 after the %
character is ignored.
For the list of available escape sequences for format specifications, see 21.2.1.2 in IEEE Std 1800-2012.
Syntax
variable_format_string_output_task ::=
$sformat ( output_var , format_string [ , list_of_arguments ]);
320
SystemVerilog Reference
Example
byte dynamic_arr [] = new[2]('{8'd1, 8'd2});
byte assoc_arr [string] = '{"a":8'd1, "b":8'd2};
int intvar = 140;
string a,b,c;
initial begin
$sformat(a, "%p", dynamic_arr);
$sformat(b, "%p", assoc_arr);
$sformat(c, "%d", intvar);
end
Syntax
variable_format_string_output_function ::=
$sformatf ( format_string [ , list_of_arguments ])
Example
byte dynamic_arr [] = new[2]('{8'd1, 8'd2});
byte assoc_arr [string] = '{"a":8'd1, "b":8'd2};
int intvar = 140;
initial begin
$sformatf("%p", dynamic_arr);
$sformatf("%p", assoc_arr);
$sformatf("%d", intvar);
end
$psprintf function
The $psprintf function works in the same way as $sformatf system function. The string result is passed back to
the user as the function return value.
The $psprintf function can be used where a string is valid. Note that at this time, unlike other system tasks and
functions, $psprintf cannot be overridden by a user-defined system function in the PLI.
Syntax
variable_format_string_output_task ::=
$psprintf ( format_string [ , list_of_arguments ]);
321
SystemVerilog Reference
Example
function void ovm_report_warning(string id,
string message,
int verbosity = OVM_MEDIUM,
string filename = "",
int line = 0);
ovm_top.ovm_report_warning(id, message, verbosity, filename, line);
endfunction
ovm_report_warning("CRFLD", $psprintf("The create method failed for %s,
object cannot be cloned", get_name()));
Arrays
Given the following array definition:
reg [7:0] arr [3:0] = '{ 8'bxxxxxxxx, 8'd5, 8'b00zz11zz, 8'b00xx11zz };
you could display the array arr using the following $display statement:
$display( "%p", arr );
322
SystemVerilog Reference
int unpacked_arr [3] [2]= '{'{1, 2}, '{3, 4}, '{5, 6}};
bit [2] packed_arr = '{'b1, 0};
byte dynamic_arr [] = new[2]('{8'd1, 8'd2});
byte assoc_arr [string] = '{"a":8'd1, "b":8'd2};
initial begin
$display("unpacked array = %p", unpacked_arr);
$display("packed array = %p", packed_arr);
$display("dynamic array = %p", dynamic_arr);
$display("assoc array = %p", assoc_arr);
end
unpacked array = '{'{1, 2}, '{3, 4}, '{5, 6}}
packed array = 2
dynamic array = '{1, 2}
assoc array = '{"a":1, "b":2}
Structures
The output of %p format for values that are structures is printed in a form similar to an assignment pattern with named
elements. For example, given the following definition:
typedef struct {
int a;
reg [7:0] arr [7:0];
} s_t;
s_t strt;
Names of structure elements (a and arr) are followed by values. Name-value pairs are separated by commas.
Using the %0p format specifier:
$display( "%0p", strt );
prints the structure data in a format similar to a positional notation of an assignment pattern. Additionally, the array
contents are printed as a simple list:
'{0, x x x x x x x x}
Packed Unions
Using the %p format specifier for a packed union prints the name of the first field of the union and then the actual
value. The %0p format specifier prints only the actual value of a union in a format similar to an assignment pattern.
For example, given the following definition:
typedef union packed {
reg [7:0] r1;
323
SystemVerilog Reference
Class Handles
Uninitialized class handles or handles that have been assigned null are shown by using the string null. Class
handles that are not null are printed similarly to structures, by using name-value pairs.
Given the following definitions:
typedef struct {
int a;
reg [7:0] arr [7:0];
} s_t;
s_t str;
class C;
s_t strt;
reg [7:0] r;
endclass
324
SystemVerilog Reference
endclass
class D;
int i = 1;
C c1 = new;
C c2 = new;
C c3;
endclass
D d = new;
the $display("%p", d) and $display("%0p", d) tasks would produce the following output:
'{i:1, c1:'{foo:0, bar:'{0, 0, 0, 0}}, c2:'{foo:0, bar:'{0, 0, 0, 0}}, c3:null}
'{1, <class handle>, <class handle>, null}
Circular References
Class handles can contain circular references to each other. Consider a class C containing two properties: an int and
a handle to C.
class C;
function new( int id );
this.id = id;
endfunction
int id;
C next;
endclass
325
SystemVerilog Reference
Three instances of the class are created. The handle c1 contains a reference to c2, c2 references c3, and c3
references c1, which makes a circular reference.
C c1 = new(1);
C c2 = new(2);
C c3 = new(3);
initial begin
c1.next = c2;
c2.next = c3;
c3.next = c1;
$display( "%p", c1 );
end
To prevent an infinite loop, the simulator makes sure that each handle is printed only once: The $display statement
will produce the following output:
'{id:1, next:'{id:2, next:'{id:3, next:<circular reference, class already printed>}}}
Truncating %p Field
For large data structures, the text for the %p field could be very large. The simulator imposes a hard-coded limit and
truncates the output when the limit is exceeded. This results in the following message on the console:
Warning: RUNTIME_0195 dty_pformat_ex3.sv (26): The output for the %p field
exceeded the maximum allowed length and was truncated to 69918 characters. If the
output contains class handles, you can limit excessive output by using %0p
instead of %p. (%0p prevents recursive class printing.)
Default Mode
If the format specifier is omitted, %p format is used by default. However, in the case of packed structures and unions,
there are some differences between %p and the default mode.
Printing the contents of a packed structure with or without the format specifier, for example:
struct packed {
reg r1;
reg [7:0] r2;
} s1;
s1.r1=1'b1;
s1.r2=8'hff;
$display("%p",s1);
$display(s1);
Note that in the case of the default output (%p not used), the representation of bits stored in separate fields of the
structure has been merged into a single vector.
Similarly, printing the contents of a union with and without the format specifier:
326
SystemVerilog Reference
union packed {
reg [7:0] r1;
reg [7:0] r2;
} u1;
u1.r1=1'b1;
u1.r2=8'hff;
$display("%p",u1);
$display(u1);
327
SystemVerilog Reference
Conversion Functions
Conversion Function are provided to convert values to and from real number values.
Prototype
Input Argument
Type
Result Type
Description
Converts real value to an integer type by
truncating the real value, e.g 654.32 is
converted to 654.
$rtoi
(input_arg)
real
integer
$itor
(input_arg)
integer
real
$realtobits
(input_arg)
real
64-bit vector
$bitstoreal
(input_arg)
64-bit vector
real
$shortrealtobits
shortreal
(input_arg)
32-bit vector
$bitstoshortreal
32-bit vector
(input_arg)
shortreal
$signed
(input_arg)
$unsigned
(input_arg)
328
SystemVerilog Reference
$bits Function
SystemVerilog introduces expression size system function $bits. The function returns the number of bits required to
hold an expression as a bit stream. A 4-state value counts as one bit.
reg [7:0] a;
typedef struct {
byte b;
reg [1:0] c;
} T;
initial begin
$display( "%0d", $bits( a )); //Displays 8.
$display( "%0d", $bits( T )); //Displays 10.
end
The $bits function can be used as an elaboration time constant when used on fixed-size data types; hence, it can be
used in the declaration of other data types, variables, or nets. The $bits system function returns 0 when called with a
dynamically sized expression that is currently empty. It is illegal to use the $bits system function directly with a
dynamically sized data type identifier.
$typename Function
The $typename system function returns a string that represents the type of its argument. In the returned string, the
default signing is omitted, superfluous white spaces are removed and the array name is replaced with the $ sign. For
example, the $typename result in the below code is int$[-3:4].
module top;
string name;
int arr1[-3 : 4];
initial name = $typename(arr1); // result is: int$[-3:4]
endmodule
NOTE: The types supported by the $typename function are limited to the SystemVerilog built-in types and fixed-size
arrays of these types. Please contact Aldec Support to receive the latest status.
$isunbounded Function
NOTE: $isunbounded is not supported in this release. Please contact Aldec Support to receive the latest status.
329
SystemVerilog Reference
330
SystemVerilog Reference
Description
$fatal(level,
message_args)
Generates a run-time fatal error, which terminates the simulation with an error
code. The first argument, level, specifies the level of diagnostic information to
be reported by the simulator and is consistent with the corresponding argument of
the $finish task. $fatal results in an implicit call to $finish.
$error(message_args)
$warning(message_args)
$info(message_args)
Generates a message.
The message_args argument in the syntax of these commands designates a user-defined message to be printed
when the task is called. The argument is a formatting string with an optional list of expressions to be inserted into the
% fields of the formatting string, and is identical to the argument specified to the $display system task.
Example
CheckCounter: assert property (CheckCnt)
$info("Assertion property CheckCounter passed");
else
begin
++error;
$error("Assertion property CheckCounter failed %0d times", error);
end
331
SystemVerilog Reference
The task is applied to all assertions in the design if is specified without arguments. The levels argument indicates
levels of hierarchy (see $dumpvars system tasks). The list_of_modules_or_assertions determines which
scope of the design should be controlled by the task. It can be a module name, an assertion name, can be also a
hierarchical name.
$assertoff stops (turns off) checking of all assertions mentioned in the task call (or all assertions in the design if no
arguments specified). This action does not affect the assertion evaluations, which are started before $assertoff
call. The assertions stay turned off until the next $asserton execution. The queued reports of a deferred assertion
are not flushed when $assertoff is executed. The reports may still mature until the subsequent $asserton. The same is
for pending procedural assertion instances, queued instances are not flushed, no new instances may be queued until
the $asserton.
$asserton turns on checking of all specified assertions (or all assertions in the design).
$assertkill aborts all pending evaluations of assertions and stops checking of all specified assertions (or all
assertions in the design in the case of no arguments in the task call) until a subsequent $asserton. The
$assertkill flushes all queued pending reports of deferred assertions and all pending procedural assertion
instances that have not yet matured.
Example
property p1;
@(posedge clk) a |-> ##2 !b;
endproperty
asrt1: assert property(p1);
covr1: cover sequence (@(posedge clk) a ##3 b);
asrt2: assert property(@(posedge clk) not (a ##2 b));
initial begin
#100;
$assertoff; /* turns off asrt1, asrt2, covr1 */
#60;
$asserton; /* turns on asrt1, asrt2, covr1 */
#60;
$assertoff(0,asrt1,covr1); /* turns off asrt1, covr1 */
#60;
$asserton(0,asrt1);
/* turns on only asrt1, covr1 is off */
#60;
$asserton; /* turns on covr1 */
#60;
$assertkill; /* kills asrt1, asrt2, covr1 */
#120;
$asserton; /* turns oon asrt1, asrt2, covr1 */
#100;
end
332
SystemVerilog Reference
The levels argument indicates how many levels of the hierarchy below each specified module instance the task
should be applied. Specifying 1 applies the command specified instance only; specifying 2 forces the task to descend
one level below and applies the command to two hierarchy levels (the specified instance and all regions one level
below). An arbitrary number of levels can be specified. Specifying 0 applies the command to a specified module and
all module instances below that module.
The list_of_modules_or_assertions specifies which design regions the task should be applied to; the
arguments can specify a module, a program, an interface, an always or initial procedure, or a specific assertion.
Assertions that are already executing are not affected by the tasks. The tasks do not affect assertion statistics
counters.
Below are descriptions of the operation of particular assertion action control tasks:
$assertpassoff
Disables execution of the pass action for vacuous and nonvacuous success of the specified assertions.
Execution of the pass action can then be re-enabled for nonvacuous ($assertnonvacuouson), vacuous
($assertvacuouson), or both types of evaluation ($assertpasson).
$assertfailoff
Disables execution of the fail action for vacuous and nonvacuous fails of the specified assertions. Execution of
the fail action can then be re-enabled for nonvacuous ($assertnonvacuouson), vacuous
($assertvacuouson), or both types of evaluation ($assertfailon). This task also affects the default fail
action, i.e. the $error task.
$assertvacuousoff
Disables execution of pass and fail actions for vacuous evaluations of the specified assertions. Execution of
assertion actions can then be re-enabled for the pass action ($assertpasson), fail action
($assertfailon), or for both types of actions ($assertvacuouson).
333
SystemVerilog Reference
$assertpasson
Enables execution of the pass action for vacuous and nonvacuous success of the specified assertions.
Execution of the pass action can then be disabled for nonvacuous ($assertnonvacuousoff), vacuous
($assertvacuousoff), or both types of evaluation ($assertpassoff).
$assertfailon
Enables execution of the fail action for vacuous and nonvacuous fails of the specified assertions. Execution of
the fail action can then be disabled for nonvacuous ($assertnonvacuousoff), vacuous
($assertvacuousoff), or both types of evaluation ($assertfailoff). This task also affects the default
fail action, i.e. the $error task.
$assertnonvacuouson
Enables execution of pass and fail actions for nonvacuous evaluations of the specified assertions. Execution
of assertion actions can then be disabled for the pass action ($assertpassoff), fail action
($assertfailoff), or for both types of actions ($assertvacuousoff).
$assertnonvacuousoff
Disables execution of pass and fail actions for nonvacuous evaluations of the specified assertions. Execution
of assertion actions can then be re-enabled for the pass action ($assertpasson), fail action
($assertfailon), or for both types of actions ($assertvacuouson).
$assertvacuouson
Enables execution of pass and fail actions for vacuous evaluations of the specified assertions. Execution of
assertion actions can then be disabled for the pass action ($assertpassoff), fail action
($assertfailoff), or for both types of actions ($assertvacuousoff).
Example 1
$assertvacuousoff;
$assertnonvacuousoff;
Assumed that the commands are invoked from a top-level module, disables execution of all assertion action blocks in
the whole design for all types of assertion evaluations. The same result could be obtained by calling
$assertpassoff and $assertfailoff tasks:
$assertpassoff;
$assertfailoff;
Example 2
$assertnonvacuouson ( 3, top.uut );
$assertfailoff ( 3, top.uut );
Assumed that all action blocks were previously disabled in the whole design (as in Example 1), enables execution of
only pass actions for nonvacuous evaluations of assertions in the design region top.uut and two levels below. The
operation is executed in two steps: first, both pass and fail actions are enabled for nonvacuous evaluations
($assertnonvacuouson); then fail actions are disabled ($assertfailoff).
334
SystemVerilog Reference
Example 3
$assertnonvacuouson ( 0, assert_seq_1 ) ;
Enables execution of fail and pass action blocks for nonvacuous evaluations of assert_seq_1 in the design region
from which the task is called.
335
SystemVerilog Reference
336
SystemVerilog Reference
337
SystemVerilog Reference
Unpacked aggregate type must be used with pattern format specifier (p).
Pattern format specifier (p) is used as default format for $display,
$write, $fdisplay, $fwrite, $swrite, and their variants, tasks
argument.
The string data type can be used as the argument corresponding to a string
% format specifier (s) . The shortreal data type can be used to the real
number % format specifiers (e, f, and g).
The above format specifiers can also be used with user-defined types that
have been defined (using typedef) to be represented using one of these
basic types.
The string data type can be used as the format arguments to these tasks.
A string variable can be used as the first argument of $sscanf.
The integer % format specifiers (b, o, d, and h) may be used to read into any
of the SystemVerilog integral data types, including enumerated types and
packed aggregate data types. They shall not be used with any unpacked
aggregate type.
The string % format specifier (s) may be used to read into variables of the
string data type.
The shortreal data type can be used as the real number % format specifiers
(e, f, and g).
The above format specifiers can also be used with user-defined types that
have been defined (using typedef) to be represented using one of these
basic types.
The $psprintf function can be used in the OVM verification library.
$psprintf
338
SystemVerilog Reference
$fread
339
SystemVerilog Reference
Syntax
$writememb ( " file_name " , memory_name [ , start_addr [ , finish_addr ] ] );
$writememh ( " file_name " , memory_name [ , start_addr [ , finish_addr ] ] );
$writememb and $writememh tasks dump memory contents to files that are readable by $readmemb and
$readmemh, respectively. There is no append mode so if an existing file is used as an argument of $writewmem
tasks, it is overwritten. $writememb and $writememh can write out data corresponding to unpacked arrays of
2-state types, such as int or enumerated types. For enumerated types, values in the file correspond to the ordinal
values of the enumerated type.
340
SystemVerilog Reference
Syntax
$system ( "shell_command_line" )
If $system is called without string argument, the C function system() will be called with the NULL string. $system
can be called as either a task or a function. When called as a function, it returns the return value of the call to
system() with data type int.
Example
module top();
initial $system("cp file.sv counter.sv");
endmodule
341
Compiler Directives
`define macros
The `define macro text can include `` (a double backtick) and `" (a backtick followed by quotes). A double backtick
can be used to delimit lexical tokens without introducing white space. For example:
`define test(no) tb``no
module `test(3);
endmodule
When the above code is compiled, module tb3 will be stored in the library. (Macro `test(3) expands to tb3.)
Sequence `" changes the meaning of the quotation mark and allows the preprocessor to expand macro arguments
inside a string literal. The difference between regular quotes and quotes preceded by a backtick is shown below:
`define msg1(str) "The message is: str."
`define msg2(str) `"The message is: str.`"
The preprocessor will expand str only in the second macro (msg2).
initial begin
$display (`msg1(hello));
$display (`msg2(hello));
end
`include
SystemVerilog introduces angle brackets <> notation for include directive.
`include <filename>
This is referred to as a system include or a library include. System includes are convenient for sharing files used in
different projects. The compiler searches for files listed in system include directives only in the directories specified
with -sysincdir <dir> and +sysincdir+<dir> options. All other directories, including the current working
directory, the directory where the source file is located, and directories specified with -incdir <dir> and
+incdir+<dir> options are ignored.
342
SystemVerilog Reference
Compiler Directives
343
DPI
Overview
DPI, or the Direct Programming Interface, is the next generation interface between SystemVerilog code and foreign
C/C++ code. The DPI specification in IEEE 1800 allows both:
Calling C/C++ foreign code from SystemVerilog.
Calling SystemVerilog tasks and functions from C/C++.
DPI is built around SystemVerilog subroutines (functions and tasks). A subroutine is treated a black box encapsulating
some functionality. That functionality can be implemented either in SystemVerilog or in a foreign language without
affecting the calling code.
Imported functions and tasks are used identically to native SystemVerilog functions. All imported functions must
complete their execution instantly and consume zero simulation time. Tasks can consume nonzero simulation time.
Calls to imported functions or tasks are indistinguishable from calls to SystemVerilog functions.
The other, complementary part of DPI allows calls in the opposite direction, that is calling SystemVerilog tasks and
functions from foreign code. Such tasks and functions must be specified in export declarations, for example:
export "DPI-C" function f1;
export "DPI-C" task t1;
SystemVerilog compiler automatically generates C code matching export declarations. The generated code can be
compiled into a foreign application (i.e. an application written in C) and utilized for calling SystemVerilog subroutines.
Data can be passed between the two domains (SystemVerilog domain and the foreign language domain) through
function arguments and results. For information on result and argument type mapping, see C/C++ and SystemVerilog
Data Types.
344
SystemVerilog Reference
DPI
345
SystemVerilog Reference
DPI
C Type
void
void
byte
char
shortint
short int
int
int
longint
long long
bit
unsigned char
logic/reg
unsigned char
svLogicVecVal* or svLogicVecVal[]
logic vector
(only the latter form is allowed for structure members)
svBitVecVal* or svBitVecVal[]
bit vector
(only the latter form is allowed for structure members)
svLogicVecVal* or svLogicVecVal[]
integer
(only the latter form is allowed for structure members)
real
double
shortreal
time
svLogicVecVal[2]
const char* for input ports
string
const char** for output and inout ports
packed struct 4-state
svLogicVecVal*
svBitVecVal*
svLogicVecVal*
svBitVecVal*
unpacked struct
open array
svOpenArrayHandle
unsigned char
The listings below show type mapping between SystemVerilog and C arrays. The mapping is straightforward; the
number of array dimensions and their size are the same in SystemVerilog and C.
346
SystemVerilog Reference
SystemVerilog
bit a[1:0][1:0]
DPI
C
C++
svBitVecVal a[2][2];
svBitVecVal a[2][2];
An example with a mapping between a SystemVerilog structure and a C structure is shown below.
SystemVerilog
C++
typedef struct {
int a;
int b;
} inner;
typedef struct {
int a;
int b;
} inner;
struct inner {
int a;
int b;
};
typedef struct {
inner i;
int j;
} outer;
typedef struct {
inner i;
int j;
} outer;
struct outer {
inner i;
int j;
};
Arguments of type structure must be passed as pointers to C functions. Accordingly, the SystemVerilog import
declaration on the left, must be matched the following C declaration on the right.
SystemVerilog
import "DPI-C" function
void fn(outer);
C++
extern "C" void fn
(outer *o);
The C/C++ function could then modify the structure using the following assignments:
o->i.a = 1000;
o->i.b = 1001;
o->j = 1002;
Open Arrays
A formal argument of an imported task or a function can be an open array. A formal argument is an open array when
at least one of its dimensions is unspecified (as indicated by empty square brackets [] in SystemVerilog). The actual
argument for an open array can be an array with an arbitrary range.
The example below shows an import declaration for task put_array.
import "DPI-C" task put_array(inout int open_arr[]);
The actual argument for such a task or function can be an array with arbitrary dimensions. For the put_array task in
the listing above, that could be arrays declared as: int a[100];, int a[0:7];, int a[15:8];, etc.
On the C/C++ side, an open array is accessible as a variable of type svOpenArrayHandle. A number of functions is
available to query the array, for example:
347
SystemVerilog Reference
int
int
int
int
int
int
int
int
DPI
For a complete list of functions, see the svdpi.h header file. The header contains a brief description for each function.
Note that exported SystemVerilog routines cannot have formal arguments specified as open arrays.
Enumerated Types
SystemVerilog enumerated types are represented on the C++ side of the interface as enumerations of int type.
There are, however, two exceptions for longint and for time data types. 64-bit long int data type can be
represented by C++ int by assigning 64-bit initial value to at least one of enumerated values:
typedef enum { tla, tlb = 0x100001000ULL, tlc = 0x00001000ULL, tld } td_long;
time data type is both 4-state value and 64-bit length. It can be represented, however, as 4-cell vector. The following
4-value SystemVerilog enumerated type:
enum time { tla = 64'h0, tlb = 64'hFF00FF00FXX00ZFF, tlc = 64'h00FF00FFFXX0FFF0, tld = 64'h0XXX }
td_time;
can be represented by two-dimensional array of int data type (each row represents an enum value):
const int arr[4][4] = {
{0x00000000, 0x00000000,
{0xFF00FF00, 0x00000000,
{0x00FF00FF, 0x00000000,
{0x00000000, 0x00000000,
0x00000000,
0xFFF000FF,
0xFFF0FFF0,
0x00000FFF,
0x00000000},
0x0FF00F00},
0x0FF00000},
0x00000FFF}};
Two 32-bit cells are needed to encode 64-bit value. Another two cells are needed to encode additional states
available for time data type. Following encoding is used: 00=0, 10=1, 11=X, 01=Z. The First bit is taken from
columns 1-2, and the second from corresponding position in columns 3-4.
Ref Arguments
Ref mode is not a legal mode for DPI arguments
348
SystemVerilog Reference
DPI
An import declaration is equivalent to defining a task or function of that name in SystemVerilog. A function imported
through DPI (unlike PLI/VPI routines) is referenced without the preceding $ sign, for example:
initial
$display ("%d", foo(1));
The dollar sign ($) is used in the system $display task; the DPI foo routine is referenced without a dollar sign.
The evaluation order of formal arguments follows general SystemVerilog rules. Argument compatibility and coercion
rules are also the same as for native SystemVerilog functions.
349
SystemVerilog Reference
DPI
Function Arguments
Imported functions can have input, output, and inout arguments. The following rules apply:
Functions should not modify formal input arguments. If they do, changes will not be visible outside the
function.
The initial values of output arguments are undetermined.
Imported functions can access initial values of formal inout arguments. Changes made to a formal inout
argument are visible outside the function.
350
SystemVerilog Reference
DPI
Miscellaneous
Memory Management
The memory spaces owned and allocated by the foreign code and SystemVerilog code are disjoined. SystemVerilog
code has no access to memory space used by the foreign code and vice versa.
C++ Exceptions
DPI imported tasks and functions can be implemented using C++. In this case exceptions must not propagate out of
any imported task or function. Undefined behavior will result if an exception crosses the language boundary from C++
into SystemVerilog.
351
SystemVerilog Reference
DPI
Note that export declarations (unlike import declarations) include neither the function return type nor argument
types. However, the actual subroutine declarations must be present in the same scope as the export declarations.
export "DPI-C" function fnc;
export "DPI-C" task t;
export "DPI-C" fn = function \<funny-name> ;
function void fnc;
// Function body omitted.
endfunction
task t;
// Task body omitted.
endtask
function void \<funny-name> ;
// Function body omitted.
endfunction
The rules for mapping C/C++ and SystemVerilog types are the same as for imported subroutines. For details, see
C/C++ and SystemVerilog Data Types.
352
SystemVerilog Reference
DPI
353
SystemVerilog Reference
DPI
354