SV Concepts
SV Concepts
-- Preetham Lakshmikanthan
© Mirafra Technologies 1
Table of Contents
1. Introduction to SV
3. Data Types
© Mirafra Technologies 2
Table of Contents Continued…
7. Verification Specific SV Constructs
8. Functional Coverage
11. Assertions
© Mirafra Technologies 3
References
1. SystemVerilog for Verification: A Guide to Learning the Testbench
Language Features
Author(s): Chris Spear and Greg Tumbush
ISBN-10: 1461407141
ISBN-13: 978-1461407140
Publisher: Springer Publications (3rd Edition 2012)
Weblink: http://www.chris.spear.net/systemverilog/default.htm
© Mirafra Technologies 4
References Continued…
3. “SystemVerilog – UNIFIED HARDWARE DESIGN, SPECIFICATION,
AND VERIFICATION LANGUAGE” – The IEEE 1800-2012 LRM
Weblink: http://standards.ieee.org/getieee/1800/download/1800-2012.pdf
© Mirafra Technologies 7
1. Introduction to SystemVerilog (SV)
© Mirafra Technologies 8
Need for Verification
Today, the verification effort takes almost 70% of the total design cycle time. This stringent verification is needed
• Due to the complex functionality of present-day designs that could lead to more bugs
– Increase in features lead to an increase in logic functionality – more gates and flip-flops
– Multiple clocks and deeper pipelines are being introduced to improve performance
– Numerous power states are being added in designs to save energy
• To verify numerous interfaces and bus transactions present in SoCs, due to the integration of multiple
functional components on the chip
© Mirafra Technologies 9
Need for Verification Continued…
Verification Gap - the big challenge confronting the industry
Diagram Reference:
© Mirafra Technologies 10
Deliverables of an RTL Verification Engineer
– Develop a verification plan by reviewing the design specification
• Done by the verification lead by extracting features from the design specification
– Design and develop the various testbench components in the verification
environment
• These components must be bug free and designed in such a way that they are usable at
both the block level as well as the full-chip level
– Understand the working of various IPs, Bus Protocols and Interconnection
Architectures to develop concise and complete test-cases to achieve the coverage
goals
– Maintain the verification environment and append test-cases to the repository in
order to enhance the coverage
– Develop scripts to automate job submission for regressions and analyze reports
– Find bugs in the RTL code and report them to the RTL designer. A key point to note
is that it is not the job of a verification engineer to fix the bugs found
© Mirafra Technologies 11
Limitations of Verilog for Verification
Weak randomization
o No constructs to easily constrain randomization.
For e.g.: Consider the case of a RAM with 1024 locations. Random numbers in Verilog are generated in the signed
range of values from -(2**32 – 1) to (2**32). Randomly generating addresses for testing of the RAM DUV is of no use
unless the address is constrained in the 0 to 1023 range.
Code re-use is very minimal, requiring repeating similar code for different
tests
o Lack of an Object Oriented Programming approach severely limits the amount of code that can be re-used in
Verilog.
© Mirafra Technologies 13
Slide ref. from: “SystemVerilog Introduction & Usage” by Johny Srouji in an IBM Verification Seminar
http://www.research.ibm.com/haifa/Workshops/verification2004/papers/system_verilog_overview-ibm-symposium-johny_srouji.pdf
Evolution
of
Language
Features Verilog 2001
14
© Mirafra Technologies
Features of SV over Verilog Continued…
• With SystemVerilog, a complete verification environment can be built with its
new features such as:
– Dynamic data types and dynamic memory allocation
– Interfaces
– Object Oriented Programming (OOP)
– Constraint Randomization
– Functional Coverage constructs
– Assertions
© Mirafra Technologies 15
History of SystemVerilog
• Background:
– It was developed originally by Accellera (www.accellera.org) to dramatically improve productivity in
the design of large gate-count, IP-based, bus-intensive chips
– Originally intended to be the 2005 update to Verilog
– Contains hundreds of enhancements and extensions to Verilog
– It was standardized by IEEE -1800 and published in 2005
– Officially superseded Verilog in 2009
– The current standard is IEEE 1800-2012
• Purpose:
– Is a Hardware Design and Verification Language (HDVL)
– Provides system-extensions to Verilog 2001 (IEEE 1364-2001). The IEEE 1364-2001 Verilog
standard is a proper subset of SystemVerilog.
• Backward Compatibility:
– Backward compatible with Verilog 1995 / Verilog 2001
• Tool Support:
– Supported by most Electronic Design Automation (EDA) tool vendors: Mentor Graphics, Cadence
Design Systems and Synopsys
© Mirafra Technologies 16
2. Commonly Used Terminologies in SV
© Mirafra Technologies 17
Diagram ref. source: http://www.cirrus.com/en/pubs/proBulletin/EP9312_PB.pdf
SoC: System-on-Chip
Definition: System-on-Chip or SoC is an integrated circuit which incorporates all necessary components of
a computing system
Typical components found on an SoC are:
– A microcontroller, microprocessor or DSP core(s);
– Memory blocks including ROM, RAM, EEPROM and flash memory;
– Interconnection buses;
– Timing sources including oscillators and Phase-Locked Loops (PLLs);
– Peripherals including counter-timers, real-time timers and power-on reset generators;
– External interfaces including industry standards such as USB, FireWire, Ethernet, UART and SPI; Timing sources
– Analog interfaces including ADCs and DACs; and
– Voltage regulators and power management circuits.
Interface
Memory
© Mirafra Technologies 19
Protocol
Definition: Protocol is a “set of rules” defined that govern the transfer of data as well as control information between
devices. For proper communication to happen, the protocol must define the syntax of data and address formats, and
the semantics of transfer operations which includes the arbitration behavior when device contention occurs.
Features:
• Protocols help eliminate bus contention issues and also help avoid deadlock between devices.
• The transfers or transactions associated with a protocol can be represented with a behavioral model that accepts
signal inputs and produces outputs.
• This behavioral model helps in analyzing the system prior to building and testing the actual hardware. It is
commonly referred to as the Bus Functional Model (BFM) or Transaction Verification Model (TVM).
Consider the various components of a design communicating with each other through a common bus. In such a case,
to ensure that proper communication happens, a bus protocol such as AHB is used. Based on the design’s bandwidth
and other constraints, an appropriate protocol can be chosen. Features of the AHB protocol are listed here:
– AHB stands for Advanced High-performance Bus.
– It is a revised version of the AMBA (Advanced Micro-controller Bus Architecture) protocol from ARM (www.arm.com).
– Supports several bus masters, burst transfers and pipelined operations.
– When multiple components communicate with each other on a common bus in a master-slave configuration, AHB uses an arbitration scheme
to avoid bus contention issues.
– For more information, please refer http://en.wikipedia.org/wiki/Advanced_Microcontroller_Bus_Architecture and also go through the references
and links given on that page.
20
© Mirafra Technologies
Protocol Continued…
An example of the resolution of a bus contention issue in an AMBA AHB based system is explained. The
main components of the system, as seen from the block diagram, are two masters (Master1 and Master2),
a slave and an arbiter. The data transfer between a master and the slave is through a common bus.
© Mirafra Technologies 21
BFM-Bus Functional Model
Definition: The Bus Functional Model or BFM is a behavioral description of the functionality of a given bus protocol
Features:
• The purpose of these models is to simulate system bus transactions prior to building and testing the actual
hardware
• Bus functional models are simplified simulation models that accurately reflect the I/O level behavior of a device
without modeling its internal computational abilities
• A BFM has two interfaces. On one side is a functional interface that accepts transactions and on the other side is
a pin interface that operates the requisite bus protocol. The functionality of the BFM is to bridge those two
interfaces
• BFMs are pre-verified and commonly used in testbenches as drivers and monitors
• Use of BFMs speeds up the process of verification
• For many standard protocols, BFMs are available as off-the-shelf Intellectual Properties (IPs)
• They are non-synthesizable
Examples:
A microprocessor BFM, a RAM BFM, a BFM for the AHB protocol explained on the previous slide. The
bus functional model of a microprocessor would be able to generate Peripheral Component Interconnect (PCI) read
and write transactions to a PCI device model to initialize and test its functionality
22
© Mirafra Technologies
VIP-Verification Intellectual Property
Definition: VIP is an acronym for Verification Intellectual Property. VIPs are a set of completely verified, fully
functional, re-usable and ready to use verification modules that typically consist of BFMs, traffic drivers, protocol
monitors, and functional coverage blocks that easily plug into testbenches.
Characteristics:
• VIPs are standards-compliant, plug and play modules that help in reducing the overall verification time
• They enable verification engineers to completely focus their efforts in verifying designs rather than setting up
complex verification environments
• VIP blocks integrate seamlessly into advanced verification environments, where testbenches are built using a mix
of languages and methodologies like VHDL, Verilog, SystemC and UVM
• In order to support a mix of languages and methodologies, translation wrappers are written resulting in a multiple
layered implementation. This layered approach limits simulation speed
• VIPs are analogous to design IPs or Implementation IPs (IIPs)
The AHB protocol BFM is an example of a VIP which can drive transactions on the AHB bus
DUV
© Mirafra Technologies 23
Regression
Definition: Regression is the process of re-running verification of the DUV DUV RTL
with a known set of test cases. This is done in order to ensure that the Code Change
functionality of the DUV is correct, and that new code changes have not
introduced any new bugs in the design.
© Mirafra Technologies 24
Randomization
Definition: Randomization is the process of creating random stimuli.
Consider that all positive 32-bit integers need to be verified for some purpose. The range for this is from 0 to
(2^32)-1. In exhaustive testing, all the 2^32 integer values need to be verified. However, in random testing
only a few random values from the range are verified, as long as they are valid and legal values and satisfy
the coverage metrics. For the above example, the coverage metrics state that 1000 unique representative
positive integers are good enough to verify all the positive 32-bit integers. Then random testing would involve
randomly generating 1000 unique values within the 0 to (2^32)-1 range for verification.
Exhaustive testing, which, in many cases is impossible to do, or takes humongous amounts of time, could
thus be replaced with random testing.
In Verilog, the $random() function is used to generate random numbers. The function returns a new 32-bit
random number each time it is called. This random number is a signed integer - it can be positive or negative.
Randomization can be applied on data and control signals and is extensively used during verification.
Directed testing checks specific features of a design and can only detect expected bugs. Random testing
detects bugs that one did not anticipate.
© Mirafra Technologies 25
Constrained Random Verification
Definition: Verification using automatically generated constrained random stimuli is called as Constrained
Random Verification. The constraints or rules determine the legal values that can be assigned to those
random variables.
Consider a machine whose instructions have an opcode and two 32-bit operands, op_a and op_b. The
constraint here is that it is necessary for ‘op_a’ to only take values less than h’ff, while ‘op_b’ has to only take
values greater than h’ff.
– Generating random numbers for the above example and then constraining them in a Verilog testbench is tedious involving many
lines of code
– Imagine specifying the constraint ((op_a < h’ff) && (op_b > h’ff)) such that the generated random numbers automatically adhere to
those constrained values. Much easier, isn’t it ?
© Mirafra Technologies 26
Assertion Based Verification (ABV)
Definition: An assertion is a statement that specifies behavior of a design. Verification of a design using
assertions is called as Assertion Based Verification.
Features of Assertions:
• Analogous to assertions used in programming languages like C, C++ or Java
• They are used to:
– Document the functionality of the design
– Check whether the intent of the design is met over simulation time
• They can be specified by:
– The design engineer as part of the RTL design
– The verification engineer as part of the testbench
• An assertion is a behavioral statement that is required to be true, and a directive to verification tools to
verify that this statement holds true
Examples:
1) Assert the bus grant happens not more than 6 clock cycles after the bus request arrives
2) Assert that the divide by zero condition never occurs during the division operation
© Mirafra Technologies 27
3. Data Types
© Mirafra Technologies 28
Overview of Verilog data types
Data Types
© Mirafra Technologies 29
Overview of Verilog data types Continued…
The value set for variables and nets contains 4-values: 0, 1, x, and z
0 — represents a logic zero value or a false condition
1 — represents a logic one value or a true condition
x — represents an unknown logic value
z — represents a high-impedance or open circuit value
Verilog data types lead to increased simulation run times and more
memory utilization because they are static in nature - all variables are
alive for the entire simulation time
© Mirafra Technologies 30
New data types in SystemVerilog
The following SV data types were introduced to help in efficient coding of testbenches, in reducing
simulation run times and in reducing memory usage.
Logic
Two-state
int, shortint, longint, bit, byte
Packed arrays, Unpacked arrays, Mixed Multi-dimensional arrays, Dynamic arrays,
Associative arrays and Queues
Structures and Unions (Aggregate types)
Strings (Enhanced from Verilog)
Events (Enhanced from Verilog)
User-defined data type
Enumerated data type
Classes (explained in detail in the next Chapter)
© Mirafra Technologies 31
Logic
Need for the Introduction of the Definition: The logic data type is a 4-state type that can take values 0, 1, x and z. It
Logic data type in SV can inter-changeably be used in place of the wire and reg data types as long as the
Verilog 2001 has wire and reg data types and users are wire data type does not have multiple drivers.
confused with the rules on their usage. SystemVerilog
has introduced the logic data type which can be used in Syntax : logic variable_name;
place of both the wire and the reg data types, with the
caveat that the wire does not have multiple drivers. Examples:
Verilog 2001: logic rst_n, clk; // 1-bit wide 4-state variables – ‘rst_n’ and ‘clk’
module pl_soc (input wire ip1, input wire ip2, logic [31:0] word32; // A 32-bit wide 4-state variable – ‘word32’
output reg op1, output wire op2);
Examples:
Verilog 2001 required that the low and high array limits must be part of the array declaration. SystemVerilog has introduced
the compact array declaration style, where just giving the array size along with the array name declaration is enough
Examples:
© Mirafra Technologies 34
Packed Arrays
Need for the Introduction of Definition: A packed array is one where the dimensions of the array is declared
Packed Arrays in SV before the array object name
SystemVerilog has introduced packed arrays as a <range (optional)>*
mechanism for sub-dividing a vector into sub-fields, Syntax : <data_type> <range (optional)>* <array_name>; implies 0 or more
which are accessed as array elements. The vector range declarations
can be accessed as a whole (single value) as well Examples:
as individual array elements. A packed 64-bit
register can be accessed as a single entity or as reg single; // A packed 1-bit register
bit [31:0] word_arr; // Packed array of 32-bit vectors
parr[3] parr[2] parr[1] parr[0]
eight 8-bit values or as sixteen 4-bit values.
reg [0:15] myreg; // A packed 16-bit register [7:0] [7:0] [7:0] [7:0]
Characteristics of a Packed Array: logic [3:0][7:0] parr = 32’h0; // Initializing a packed 32-bit vector with
// four 8-bit sub-fields
• It is stored as a contiguous set of bits
• It can be made of only single bit data types (bit, logic, reg), enumerated types (explained later), and recursively other packed
arrays
• If a packed array is declared as signed, then the array viewed as a single vector shall be signed. The individual elements of the
array are unsigned unless they are of a named type declared as signed
• Packed arrays allow arbitrary length integer types; therefore, a 48-bit integer can be made up of 48 bits
• The maximum size of a packed array can be limited, but shall be at least 65536 (2^16) bits
• The following operations can be performed on packed arrays. Assume the declaration of an 8-bit packed array ‘MPA’ for the
examples shown.
– Assignment of an integer value. Example: MPA = 8'b10101010;
– Use of the packed array as an integer in an expression. Example: if ((MPA + 4) > 16) ….. ;
Applications of Packed Arrays:
35
• They are used to store packet structures on which bit-select and part-select operations could be performed
Unpacked Arrays
Need for the Introduction of Definition: An unpacked array is one where the dimensions of the array is declared
Unpacked Arrays in SV after the array object name
SystemVerilog has introduced unpacked arrays so
that one can assign to or manipulate entire arrays Syntax : <data_type> <array_name> <range> ; + <range>+ implies 1 or
at once more range declarations
Examples:
int uparr[0:15][0:31]; // Unpacked array declaration using ranges
int uparr[16][32]; // Same as the above declaration, but using array sizes
real float_point[0:1023]; // Unpacked array of real type
int iuarr[4]=‘{4,3,2,1}; // Initializing an unpacked array of 4 elements
byte banner[0:12] = "hello asics\n"; // String literal assigned to an unpacked array of bytes
© Mirafra Technologies 37
Operations on Arrays
SystemVerilog allows the following operations to be performed on all arrays, packed or unpacked. Assume that arrays X and Y
in the examples below are of the same type and size.
• Equality operations on the array or slice of the array. E.g., (1) if (X==Y)……
(2) while (X[0:7] != Y[8:15])…..
These are the most commonly used operations on arrays. A few other operations are present, the details of which the learner
can obtain from page 110 of reference [3] - The SystemVerilog IEEE 1800-2012 LRM.
© Mirafra Technologies 38
Mixed Multi-Dimensional Arrays
SystemVerilog allows the mixed use of packed and unpacked dimensions in an array definition
leading to a mixed multi-dimensional array
Example:
logic [2:0][9:0] mymix_array [0:3] [0:5] [0:7]; // Is a mixed 5-dimensional array with 2 packed
// dimensions – [2:0] and [9:0], and 3 unpacked
// dimensions - [0:3], [0:5] and [0:7]
Multi-dimensional array access via indexing must adhere to the following rules:
– All unpacked dimensions are first referenced from the left-most to the right-most dimension in that order
– All packed dimensions are then referenced from the left-most to the right-most dimension in that order
Example:
Left Right Left ….….. Right
logic [2:0][9:0] mymix_array [0:3] [0:5] [0:7];
The 0 index of the array is from the 1st unpacked dimension [0:3]
The 4 index of the array is from the 2nd unpacked dimension [0:5]
The 6 index of the array is from the 3rd unpacked dimension [0:7]
mymix_array [0] [4] [6] [2] [7] = 1’b1; The 2 index of the array is from the 1st packed dimension [2:0]
The 7 index of the array is from the 2nd packed dimension [9:0]
© Mirafra Technologies
39
Mixed Multi-Dimensional Arrays Continued…
Examples to see how different dimensions of mixed arrays are laid out in memory to understand how the array
elements are accessed
bit [0:2]mix_arr1[0:1][0:3];
(Ex1)
3 2 1 0
0
1
0 2
bit [3:0][7:0]mix_arr2[0:2];
(Ex2)
mix_arr2[0][3] mix_arr2[0][0]
mix_arr2[0][1][6]
mix_arr2[0] 7 65 4 3 21 0 7 65 4 3 21 0 7 65 4 3 21 0 7 654 3 21 0
mix_arr2[1] 7 65 4 3 21 0 7 65 4 3 21 0 7 65 4 3 21 0 7 654 3 21 0
mix_arr2[2] 7 65 4 3 21 0 7 65 4 3 21 0 7 65 4 3 21 0 7 654 3 21 0
SystemVerilog provides a constructor and built-in methods to manipulate dynamic arrays. The methods or functions are called
after the dynamic array object name with a period “.” between the object name and the function name.
• Constructor new[value]: Sets the size of a dynamic array and initializes its elements or changes the size of the array at
run-time. If the value is zero, the array shall become empty. If the value is negative, then it is an error.
• Function int size(): The size() method returns the current size of a dynamic array or returns zero if the array has not been
created
• Function void delete(): The delete() method empties the array, resulting in a zero-sized array.
© Mirafra Technologies 42
Dynamic Array Methods Continued…
dyn1 dyn2 0
1
Example:
2
int dyn1[], dyn2[]; // Declare 2 dynamic arrays – dyn1 & dyn2 3
int size1;
0
initial 1
begin 2
dyn1=new[4]; // Allocate space for 4 elements
3
size1 = dyn1.size(); // Returns size of dyn1, which is 4
dyn1=new[7](dyn2); // Allocate space for 7 elements & copy the existing elements 5 0
10 1
copied elements
15 2
dyn1.delete(); // Delete elements of the dynamic array 20 3
end
4
5 new elements
© Mirafra Technologies dyn1 6 43
Associative Arrays
Need for the Introduction of Definition: An associative array is an unpacked array data-type in SV. It does not have
Associative Arrays in SV any storage allocated until it is used, and the index type used to access elements is not
In addition to being able to handle to a very large
restricted to integers.
address space, SystemVerilog introduces
associative arrays that are used to store sporadic Syntax : <data_type> array_name [index_type];
where, index_type is the data_type to be used or can be the wildcard “*”
or sparse data entries. SV allocates memory for an
element only when data is written into the
associative array. This is a big advantage in that it Examples:
saves tremendous amounts of memory space in integer i_array[*]; // Un-initialized associative array of integers (unspecified index)
comparison with dynamic arrays where the full integer array_s[string] = `{“INIT”:0, “DEEPSLEEP”:30, “FULLPOWER”:10, “MEMSLEEP”:20“, default:-1};
memory is allocated even if only one element is // Initialized associative array of integers, indexed by string
written into it. In Verilog array indices can only be bit [3:0] array_a[int]; // Un-initialized associative array of a 4-bit vector, indexed by int
integer values. However, associative array indices initial
in SV can be of any type. begin
array_a[0] = 4’b0101;
Memory allocation depiction if “array_a” from the array_a[8] = 4’b0111;
example was declared using: array_a[30] = 4’b1101;
array_a[31] = 4’b0110;
end
A standard array (Contiguous) An associative array (Non-Contiguous)
0 4’b0101 0 4’b0101
Memory :::
No memory allocated
allocated for 8 4’b0111 8 4’b0111
:::
for unused
even unused elements
elements :::
30 4’b1101 30 4’b1101
44
31 4’b0110 31 4’b0110 © Mirafra Technologies
Associative Arrays Continued…
Characteristics of an Associative Array:
• It can be stored by the simulator as a hash (lookup) table for extremely fast access of its elements. A hash table
contains an array of groups of elements. A function called hash function generates a unique key to compute the index
into this array, from which the correct array element value is obtained
• Associative array elements are unpacked
• The type of the array index used to access elements is restricted to int, integer, string, class and the wildcard “*”
– For a wildcard associative array, non-integral index values are illegal and a string literal index is automatically cast to a bit vector of equivalent size
• Elements in an associative array can be accessed in a similar way as those in a one-dimensional array
• If an attempt is made to read an invalid (non-existent) associative array entry, then the simulator will issue a warning and
will return the value ‘x’ for a 4-state integral type or a value ‘0’ for a 2-state integral type
© Mirafra Technologies 45
Examples adapted from source: [3] The SystemVerilog IEEE 1800-2012 LRM, Pages 121 and 122
• Function void delete(): The delete() function removes all the elements in the array
• Function void delete(data_type index): Removes the entry at the specified index. If the entry to be deleted does not exist,
the function issues no warning.
Example 2:
integer map[string];
map[ “data" ] = 1;
map[ “address" ] = 2;
map[ “control" ] = 3;
map.delete( “control" ); // Remove entry whose index is “control" from array "map“, i.e., value 3
map.delete(); // Remove all entries from the associative array "map"
© Mirafra Technologies 46
Examples adapted from source: [3] The SystemVerilog IEEE 1800-2012 LRM, Page 122
Example 4:
string s;
integer map[string];
map[ “address" ] = 1;
map[ “control" ] = 2;
map[ “data" ] = 3;
if(map.first(s)) // Assigns the first index “address” to the string ‘s’ and returns 1 as the array is not empty
$display( "First entry is : map[ %s ] = %0d\n", s, map[s] ); // Display statement is executed to show “First entry is : map[address] = 1”
© Mirafra Technologies 47
Examples adapted from source: [3] The SystemVerilog IEEE 1800-2012 LRM, Page 123
• Function int next(data_type index): Finds the smallest index whose value is greater than the given index argument. If there is a
next entry, the index variable is assigned the index of the next entry, and the function returns 1. Otherwise, the index is
unchanged, and the function returns 0
Example 6:
string s;
integer map[string];
map[ “address" ] = 1;
map[ “control" ] = 2;
if(map.first(s)) // Assigns the first index “address” to the string ‘s’ and returns 1 as the array is not empty
do
$display( "%s : %d\n", s, map[s]);
while(map.next(s)); // This do-while loop iterates twice, the first time for “address” and the second time for “control”. 48
// After that the map.next(s) function returns a 0 as there are no more indices, and the loop terminates.
Examples adapted from source: [3] The SystemVerilog IEEE 1800-2012 LRM, Page 123
© Mirafra Technologies 49
Queues
Definition: A queue is a variable-size, ordered collection of homogeneous (same type)
Need for the Introduction of
Queues in SV unpacked array elements. It supports constant time access to all its elements as well as
constant time insertion at the beginning and removal at the end of the queue respectively.
The queue data type was introduced in
SystemVerilog to combine the dynamic storage ctrl_names
property and fast access of elements. The main Syntax : <data_type> queue_name [$]; Position 0 Position 1
advantage is that one can add or remove elements
anywhere in a queue, without the storage penalty control enable
of a dynamic array which has to allocate a new
array and copy its entire contents. Also, as done in
a fixed-size array, any element in the queue can be Examples:
accessed directly using an index without any need string ctrl_names[$] = { “control", “enable"}; // An initialized queue of
for accessing elements before it. // strings called “ctrl_names”
// with two elements
integer Q[$] = { 4, 2, 7 }; // An initialized integer queue called “Q”
// containing three integers
byte bytq[$]; // A queue of bytes
Characteristics of a Queue:
Q
• Each element in a queue is identified by a number that represents its position within the
Position 0 Position 1 Position 2
queue, with 0 representing the first, and $ representing the last. In the second example
4 2 7
shown, the integer queue ‘Q’ stores the value 4 at position 0. This is the first element of
the queue. Value 2 is stored at position 1 and finally value 7 is stored at position 2,
which is the last element of the queue
• A queue can have variable length, including a length of zero. This makes the queue
data type an ideal candidate that can be shrunk or grown as elements are deleted or
added to it, without fixing an upper limit on its size 50
© Mirafra Technologies
Queues Continued…
Characteristics of a Queue (Cont’d):
• The empty array literal {} is used to denote an empty queue
• If known, an upper limit index ‘N’ of the queue can be set. This is known as a bounded queue and shall be limited to
have indices not greater than ‘N’ (its size shall not exceed N+1)
– For e.g.: bit limitq[$:255]; // A bounded queue whose maximum size is 256 bits
• SystemVerilog automatically allocates space if the queue runs out of memory when adding additional elements.
Hence, the new[] constructor used in allocating memory for arrays, is never used for queues
• A queue is similar to a one-dimensional unpacked array, except that it grows and shrinks automatically. Therefore,
like arrays, queues can be manipulated using the indexing, concatenation, slicing and equality operators
• Elements of a queue are stored in contiguous locations in memory
– Adding an element to the front of the queue or deleting an element from the back of the queue therefore takes a fixed amount of time
– Adding or deleting an element from the middle of the queue requires shifting the data already present in the queue. The time to do this depends on
the size of the queue
Applications of Queues:
• They are used to model Last In First Out (LIFO) and First In First Out (FIFO) behavior, typically buffers
• Queues are commonly used in various testbench components like scoreboard, monitor, driver – explained further in a
later segment of this course
© Mirafra Technologies 51
Queue Operations
Queues support the same operations that are performed on unpacked arrays. In addition to those, queues also
support the following operations:
• It will resize itself to accommodate any value that is written to it, provided that it is within its maximum bound size
• In a queue slice expression, the slice bounds may be arbitrary integral expressions and are not required to be
constant expressions
• Queues support additional built-in methods described in the next few slides
Consider a queue ‘Q’ whose range is bounded between ‘a’ and ‘b’. The following rules govern queue operators:
• If b > a, then Q[a : b] yields a queue with “b - a + 1” elements
• If a > b, then Q[a : b] yields the empty queue {}
• If a = b, then Q[a : b] is the same as Q[a : a] and it yields a queue with one item, the one at position ‘a’.
• If ‘n’ lies outside Q’s range (n < 0 or n > $), then Q[n:n] yields the empty queue {}
• Q[ a : b ] where a < 0, is the same as Q[ 0 : b ]
• Q[ a : b ] where b > $, is the same as Q[ a : $ ]
• An invalid index value will cause a queue read operation to return the value ‘x’ for a 4-state integral type or a
value ‘0’ for a 2-state integral type
• An invalid index value will cause a queue write operation to be ignored and a run-time warning to be issued
© Mirafra Technologies 52
Examples adapted from source: [3] The SystemVerilog IEEE 1800-2012 LRM, Page 128
int q[$] = {2, 4, 8}; // Initialized integer queue ‘q’ with 3 elements – 2, 4 and 8
int p[$]; // Un-initialized integer queue ‘p’
int e, pos;
e = q[0]; // read the first (left-most) element of ‘q’; ‘e’ gets the value 2
e = q[$]; // read the last (right-most) element of ‘q’; ‘e’ gets the value 8
q[0] = e; // write the value of ‘e’ as the first element in ‘q’
p = q; // copy contents of ‘q’ to ‘p’
q = { q, 6 }; // insert ’6’ at the end of the queue ‘q’ (append the value 6)
q = { e, q }; // insert the value of ’e’ at the beginning of the queue ‘q’ (prepend the value of ‘e’)
q = q[1:$]; // delete the first (left-most) element of ‘q’
q = q[0:$-1]; // delete the last (right-most) element of ‘q’
q = q[1:$-1]; // delete the first and last elements of ‘q’
q = {}; // clear the queue contents, i.e., delete all elements of ‘q’
q = { q[0:pos-1], e, q[pos,$] }; // insert ’e’ in the queue ‘q’ at the position ‘pos’
q = { q[0:pos], e, q[pos+1,$] }; // insert ’e’ in the queue ‘q’ after the position ‘pos’
© Mirafra Technologies 53
Queue Methods
SystemVerilog provides several built-in methods to manipulate queues. These methods or functions are called after the queue
object name with a period “.” between the object name and the function name. The function arguments (if any) are inputs.
• Function int size(): Returns the number of items in the queue. If the queue is empty, it returns 0.
– Q.size() returns 4 for the integer queue, Q[$] = {8, 2, 1, 20}; containing 4 integer values - 8, 2, 1 and 20
• Function void insert (int index, queue_type item): Inserts the given item at the specified index position
– Q.insert (i, e) is equivalent to Q = {Q[0:i-1], e, Q[i:$]}
• Function void delete (int index): Deletes the item from the specified index position
– Q.delete (i) is equivalent to Q = {Q[0:i-1], Q[i+1:$]}
Use of queue
methods enables
• Function queue_type pop_front(): Removes and returns the first element of the queue one to perform
– e = Q.pop_front () is equivalent to e = Q[0]; Q = Q[1:$] queue operations
in a much easier
• Function queue_type pop_back(): Removes and returns the last element of the queue manner
– e = Q.pop_back () is equivalent to e = Q[$]; Q = Q[0:$-1]
• Function void push_front (queue_type item): Inserts the given element at the front of the queue
– Q.push_front (e) is equivalent to Q = {e, Q}
• Function void push_back (queue_type item): Inserts the given element at the end of the queue
– Q.push_back (e) is equivalent to Q = {Q, e} 54
© Mirafra Technologies
Queue Methods Continued…
Examples of queue methods:
integer int_q[$] = {20, 30, 40, 50}; // Initialized integer queue ‘int_q’ with 4 elements – 20, 30, 40 and 50
integer qs, val;
qs = int_q.size(); // The queue ‘int_q’ has 4 elements and hence the size is 4. ‘qs’ gets the value 4.
int_q.push_front(10); // Inserts the value 10 at the beginning of the queue ‘int_q’. Now ‘int_q’ has
// 5 elements – 10, 20, 30, 40 and 50 in that order.
int_q.push_back(60); // Inserts the value 60 at the end of the queue ‘int_q’. Now ‘int_q’ has
// 6 elements – 10, 20, 30, 40, 50 and 60 in that order.
int_q.insert(3, 35); // New element 35 added at index position 3 in the queue ‘int_q’. Now ‘int_q’ has
// 7 elements – 10, 20, 30, 35, 40, 50 and 60 in that order.
int_q.delete(3); // Deletes the element from index position 3 in the queue ‘int_q’. Now ‘int_q’ has
// 6 elements – 10, 20, 30, 40, 50 and 60 in that order.
val = int_q.pop_front(); // Removes and returns the first element of the queue ‘int_q’. ‘val’ now holds the
// value 10, while ‘int_q’ has 5 elements – 20, 30, 40, 50 and 60 in that order.
val = int_q.pop_back(); // Removes and returns the last element of the queue ‘int_q’. ‘val’ now holds the
// value 60, while ‘int_q’ has 4 elements – 20, 30, 40 and 50 in that order.
© Mirafra Technologies 55
Array Classification – Quick Reference
Array Type Example Application(s)
Packed Array bit [31:0] word_arr; // Packed array Such arrays could be used to store packet structures on which bit-
of 32-bit vectors select and part-select operations could be performed
Unpacked Array real float_point[0:1023]; // Such arrays could be used to model Random Access Memories
Unpacked array of real type (RAMs), Read Only Memories (ROMs) and register files where
one element is accessed at a time
Dynamic Array integer i_dynarr[]; // Dynamic array Say random control signals need to be generated by the testbench
of integers during simulation. If a fixed-size array is used, it would have to be
sized large enough to hold the maximum number of signals
possible. In reality, only a subset of control signals would be used,
thus wasting the remaining memory. Hence a dynamic array that
can be allocated and re-sized during simulation will avoid this
unnecessary memory allocation
Associative Array bit [3:0] array_a[int]; // Un- Such arrays could be used to model CAMs. Random read or write
initialized associative array of a 4- tests for verification of memories could use associative arrays for
bit vector, indexed by int storing data only for addresses which have been written
Queue integer Q[$] = { 4, 2, 7 }; // An Such arrays could be used to model Last In First Out (LIFO) and
initialized integer queue called “Q” First In First Out (FIFO) behavior, typically buffers
containing three integers
© Mirafra Technologies 56
Array Locator Methods
These are methods that traverse the array in an unspecified order and search an array for elements or their indices based on
a given search (filter) expression. The array locator methods operate on any unpacked array, including queues, but their
return type is a queue. If no elements satisfy the given filter expression or the array is empty, then an empty queue is
returned. These methods or functions are called after the array object name with a period “.” between the object name and
the function name.
The ‘with’ clause is mandatory in the following methods:
• find() with (filter_expr): Returns all the elements satisfying the given expression
• find_index() with (filter_expr): Returns the indices of all the elements satisfying the given expression
• find_first() with (filter_expr): Returns the first element satisfying the given expression
• find_first_index() with (filter_expr): Returns the index of the first element satisfying the given expression
• find_last() with (filter_expr): Returns the last element satisfying the given expression
• find_last_index() with (filter_expr): Returns the index of the last element satisfying the given expression
For the following methods, the ‘with’ clause can be omitted if the relational operators (<, >, ==) are defined for the element
type of the given array. If the ‘with’ clause is specified, the relational operators shall be defined for the type of the expression.
• min(): Returns the element with the minimum value or whose expression evaluates to a minimum
• max(): Returns the element with the maximum value or whose expression evaluates to a maximum
• unique(): Returns all elements with unique values or whose expression evaluates to a unique value
• unique_index(): Returns the indices of all elements with unique values or whose expression evaluates to a unique
value
© Mirafra Technologies 57
Examples adapted from source: [3] The SystemVerilog IEEE 1800-2012 LRM, Pages 130 and 131
Examples:
packet
Applications of Structures:
• An ethernet packet can declared as a struct with its constituent elements like packet length, header, footer etc. as fields
of the packet
© Mirafra Technologies 62
Unions
Definition: A union is a data type that can be pictured as a chunk of memory that is used
Need for the Introduction of
Unions in SV to store fields of different data types. Once a new value is assigned to a field, the existing
data is overwritten with the new data.
Unions are similar to structures, but with one major
difference. The size of an object of the union data
type is the size of its largest field. In contrast, the Syntax : union packed(optional) {<data_type> <range(optional)> element1,element2,…;
size of an object of the structure data type is the <data_type> <range(optional)> element1,element2,…;
sum of the size of all its fields put together. Unions …
are therefore more memory efficient than structures
and that is why they were introduced in SV. } union_name;
Examples:
packet
63
© Mirafra Technologies
Unions Continued…
Characteristics of a Union:
• The declaration of a union is similar to that of a structure and its various fields are referenced the same way as structures
• A union can store only one value – the size of the largest data field in it. Hence the memory usage is reduced
• By default, a union is unpacked
• It can be synthesized
Applications of Unions:
• Unions are useful when frequent reads and writes are done to a register in several different formats – the largest format
determines the storage size.
© Mirafra Technologies 64
Strings
Need for the Enhancement of Definition: A string type is a variable-length ordered collection of characters. The length
Strings in SV of a string is the number of characters in the collection.
Verilog 2001 supports only string literals.
SystemVerilog adds support for string as a built-in Syntax: string variable_name = initial_value(optional);
data type. Also added are a lots of operators and
functions for string manipulation.
Examples:
string soc_name; // Un-initialized string variable ‘soc_name’
string module_name = “video_RAM”; // Initialized string variable
string blp = “BLENDED learning PROgram”;
Characteristics of Strings:
• The memory space for strings is dynamically allocated
• The indices of string variables shall be numbered from 0 to N–1 (where N is the length of the string) so that index 0 is the
first (leftmost) character of the string and index N–1 is the last (rightmost) character of the string
• An un-initialized or empty string is represented with the special value “”. An empty string has 0 length
• An individual character is of type ‘byte’
• Unlike the ‘C’ programming language, there is no “null” character at the end of a SystemVerilog string
Applications of Strings:
• They are used to report the status of verification, to trace how far along in its execution a test case is, and most
importantly to display error messages that helps in debug
65
© Mirafra Technologies
String Operators
SystemVerilog provides a set of operators that can be used to manipulate combinations of string variables and string
literals. They are listed in the table below:
Operator Description
Str1 == Str2 Equality Operation: Checks whether the two string operands are equal. Result is
1 if both strings are composed of the same character sequence and 0 if not
Str1 != Str2 Inequality Operation: This is the exact opposite of the equality operation
Str1 < Str2 Comparison Operation: Returns a 1 if the result of the given comparison is true
Str1 <= Str2
Str1 > Str2
Str1 >= Str2
{Str1,Str2,...,Strn} Concatenation Operation: Appends the ‘n’ individual string operands together.
The operands can be of string type or can be string literals
{multiplier{Str}} Replication Operation: Str is a string literal or a string expression and the
multiplier is an integer ‘N’. The result of this operation is a string containing ‘N’
concatenated copies of Str
Str[index] Indexing Operation: Str is a string literal or a string expression and index is an
integer from 0 to ‘N-1’, where ‘N’ is the number of characters in the string. The
result returned is a byte, which is nothing but the character at the given index 66
© Mirafra Technologies
String Methods
SystemVerilog provides special built-in methods to work with strings. These methods or functions are called after the
string object name with a period “.” between the object name and the function name.
• function int len(): Returns the length of the string, i.e., the number of characters in the string as an integer
value
• function void putc(int i, byte c): Replaces the ith character in the string with character ‘c’
• function byte getc(int i): Returns the ith character of the string
• function string toupper(): Returns a string with characters in the string converted to uppercase. The original
string remains unchanged
• function string tolower(): Returns a string with characters in the string converted to lowercase. The original
string remains unchanged
• function int compare(string s): str1.compare(str2) – compares strings str1 and str2. Return '0' if equal, a
positive value if str1 comes after str2, and a negative value if str1 comes before str2
• function int icompare(string s): str1.icompare(str2) – case insensitive comparison of strings str1 and str2
• function string substr(int i, int j): str.substr(i,j) - returns a new string that is a sub-string consisting of
characters in position i through j in string str
• function integer atoi(): String to integer conversion – returns the integer corresponding to the ASCII decimal
representation of the string
• function void itoa(integer i): Integer to string conversion. This is the inverse of the function atoi()
© Mirafra Technologies 67
String Methods Continued…
Examples of String Methods:
string a = “AEIOU”;
string b = “alonso”;
string c = “123”;
byte subs1;
string subs2, lc, uc;
asiz = a.len(); // asiz is assigned the value 5 as the string ‘a’ initialized to “AEIOU” has 5 characters
subs1 = b.getc(5); // subs1 gets ‘o’ which is the 5th character of string ‘b’ initialized to “alonso”
subs2 = a.substr(1,3); // subs2 gets “EIO” which is the 1st to 3rd characters of string ‘a’
© Mirafra Technologies 68
Examples adapted from source: [3] The SystemVerilog IEEE 1800-2012 LRM, Page 76
Events
Definition: An event is a powerful means of synchronizing two or more concurrently
Need for the Enhancement of
Events in SV
active processes. This synchronization is done through an object and the event data type
provides a handle it.
Events are used to synchronize processes or
threads. In Verilog 2001 there is a possibility of a Syntax: event event_name = initial_value(optional);
race condition where one process blocks on an
event at the same time that another process
triggers it. SystemVerilog introduces a function to Examples:
check for the triggered status of an event. A
process can wait on this function rather than block event done; // Declare a new event object called done
operation, thereby avoiding the race condition. event redone = done; // Declare redone as an alias to done
event emptyevnt = null; // event variable emptyevnt has no synchronization object
Characteristics of Events:
• The synchronization object referenced by an event variable can be explicitly triggered and waited for.
• When one event variable is assigned another event variable, both event variables refer to the same synchronization object
• When assigned null, the association between the synchronization object and the event variable is broken
• An identifier declared as an event data type is called a named event
• The duration of an event persists throughout the time-step in which it was triggered
• If there is a need to send multiple synchronization notifications in a single time slot, do not use events. Instead use other
built-in synchronization methods like semaphores and mailboxes (explained later in this course)
Applications of Events:
• They are used to synchronize the testbench and the DUV. Sending a burst of data from the testbench and waiting on an
event response from the DUV are some common scenarios encountered. 69
© Mirafra Technologies
Event Operators and Triggered Property
SystemVerilog enhances Verilog events by providing a set of operators that can be used to manipulate events. They
are listed below:
• Operators for triggering an event (-> and ->>)
– Named events are triggered using the -> operator
– Nonblocking events are triggered using the ->> operator
– Triggering an event unblocks all processes currently waiting on that event
• Operator for waiting for an event (@)
– The basic mechanism to wait for an event to be triggered is via the event control operator, @
– ‘@ hierarchical_event_identifier;’ is the syntax and the @ operator blocks the calling process until the given event is triggered
– For a trigger to unblock a process waiting on an event, the waiting process must execute the @ statement before the triggering
process executes the trigger operator, ->. If the trigger executes first, then the waiting process remains blocked
© Mirafra Technologies 70
Examples adapted from source: [3] The SystemVerilog IEEE 1800-2012 LRM, Page 327
fork
@ redone; // wait for done through redone
#100 trigg(done); // trigger ‘done’ using the ‘task’ trigg
join
fork
-> sync; // trigger sync
wait (sync.triggered); // wait on the persistent trigger
© Mirafra Technologies join 71
User-defined Data Type
Definition: User-defined types allow new type definitions to be created from existing data
Need for the Introduction of User-
defined Data Type in SV types. A ‘typedef’ declaration is used to define a user-defined type as similarly done in the
‘C’ programming language
Verilog 2001 does not allow users the freedom to
extend net and variable types to create their own Syntax : typedef <base_data_type> <user_defined_type_name>;
data types for some specific purpose.
SystemVerilog introduces user-defined data types
like those present in the ‘C’ programming language. Examples:
Here users can create and manipulate their own typedef int unsigned unsint; // Define a new 32-bit unsigned 2-state integer type
complex data types for specific purposes like typedef bit [31:0] uint; // Equivalent to the above definition – a new 32-bit
simulation, emulation etc. // unsigned 2-state integer type
typedef logic [15:0] bits16; // Defining a new 16-bit type called ‘bits16’
bits16 word1, word2; // These are 2 16-bit words
typedef logic [3:0] nibble; // Defining a new 4-bit type called ‘nibble’
nibble [15:0] vec; // vec is a 64-bit vector made from 16 nibble types
Characteristics of User-defined Data Types:
• They can be defined locally or in a package
• All of SystemVerilog’s data types can be extended with user-defined type declarations
• The new type names are intended to provide additional descriptive information for the object declarations that use them
• Sometimes a user-defined type needs to be declared before the contents of the type have been defined. Support for this is
provided by a forward typedef. More information about this can be obtained from page 77 of reference [3], the 72
SystemVerilog IEEE 1800-2012 LRM © Mirafra Technologies
User-defined Data Type Continued…
Applications of User-defined Data Types:
• Most values in a testbench are positive integers and so having a signed integer could cause problems. So the unsigned,
2-state 32-bit integer type ‘uint’ or ‘usint’ (as shown in the example) is used in such testbenches.
© Mirafra Technologies 73
Enumerated Data Type
Definition: Enumerated data types defines a set of named values. It assigns a symbolic
Need for the Introduction of
Enumerated Data Type in SV name to each legal value taken by the data type
An enumerated type in SystemVerilog allows one Syntax : enum enum_base_type(optional) { <enum_name_declaration> = constant_expr(optional),
to create a named set of related but unique <enum_name_declaration> = constant_expr(optional),
Syntax : typedef <base_data_type> <user_defined_type_name>;
constants. Verilog 2001 has text macros for :
names and parameters to define constants, but <enum_name_declaration> = constant_expr(optional)
relating both of them is extremely difficult.
} <enum_type_identifier>;
Examples:
enum {red,amber,green} tlc; // anonymous int type used for a traffic light controller
If a value is not specified for a name, it gets // Opcodes can be stored as an enum declaration
the value of the previous name in the list enum logic [2:0] {ADD, SUB, MUL, MOV, LD, AND, XOR, NEG} opcode;
incremented by 1. The value of W is 1. X is not
specified and hence it is 1+1, i.e., 2. Similarly Y // Declaring a boolean type below
is 8 and Z is not specified. Hence its value is enum bit {FALSE=1’b0, TRUE=1’b1} boolean;
8+1, i.e., 9 74
enum {W=1, X, Y=8, Z} missing_val; // Missing values for enum names
Enumerated Data Type Continued…
Characteristics of Enumerated Data Types:
• An enumerated type is stored as type ‘int’ unless specified as something else
• This type automatically gives a unique value to every name in the list
• Values default to the ‘int’ type starting at 0 and then incrementing by 1
• If a value is not specified for a name, it gets the value of the previous name in the list incremented by 1
• They are strongly typed, i.e., a variable of type ‘enum’ cannot be directly assigned a value that lies outside the
enumeration set
• 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
© Mirafra Technologies 75
Enumerated Type Methods
SystemVerilog provides a set of specialized methods to iterate over and
manipulate the values of enumerated types. These methods or functions are
called after the enumerated object name with a period “.” between the object
name and the function name.
Example of Enumerated Data Type Methods:
• function enum first(): Returns the value of the first member of the
enumeration enum {init,start,stop} fsm_states;
fsm_states ctrl;
• function enum last(): Returns the value of the last member of the int total;
• function enum next(int unsigned N = 1): Returns the Nth-next ctrl = ctrl.first();
enumeration value (default is the next one) starting from the current $display("%s",ctrl.name); // Displays ‘init’