By SCVN Reddy
By SCVN Reddy
Article-21
System Verilog
(For Design Verification)
Semiconductor
Industry
Written By-
DAY-51
SYSTEM VERILOG: REFERENCE GUIDE
#100DAYSRTL
Predefined Datatypes:-
• 2 Valued :- Digits : 0 or 1
• 4 Valued :- Digits : 0 or 1 or X or Z
Code Practising:-
• 2 Valued Data Type:-
4 Valued Data Type:-
Console:-
2 Valued Data Type:-
Signed/Unsigned Integers:-
• byte, shortint, int, integer and longint defaults to signed
▪ Use unsigned to represent unsigned integer value
Example: int unsigned a;
• bit, reg and logic defaults to unsigned
• To create vectors, use the following syntax:
✓ Eg:- logic [1:0] L; // Creates 2 bit logic vector
• To use these types as unsigned, user has to explicitly declare
it as unsigned.
✓ Eg:-int unsigned a;
String Data Types:-
• In Verilog, string literals are packed arrays of a width that is a
multiple of 8 bits which hold ASCII values.
• In Verilog, if a string is larger than the destination string
variable, the string is truncated to the left, and the leftmost
• characters will be lost.
• System Verilog adds new keyword "string" which is used to
declare string data types unlike verilog.
• String data types can be of arbitrary length and no truncation
occurs.
Code Practising:-
Console:-
String:-
• In Verilog, string literals are packed arrays of a width that is a
multiple of 8 bits that hold ASCII values.
• In Verilog, if a string is larger than the destination string
variable, the string is truncated to the left, and the leftmost
characters will be lost.
• System Verilog adds a new keyword "string" which is used to
declare string data types, unlike Verilog.
• System Verilog String data types can be of arbitrary length
and no truncation occurs.
Methods:-
1. str.len() :- returns the length of the string, i.e., the number of
characters in the string.
2. str.putc(i, c) :-replaces the ith character in str with the given
integral value.
3. str.getc(i) :-returns the ASCII code of the ith character in str.
4. str.toupper() :-returns a string with characters in str
converted to uppercase.
5. str.tolower() :-returns a string with characters in str converted
to lowercase.
6. str.compare(s) :-compares str and s, and returns a value. This
comparison is case-sensitive.
7. str.icompare(s) :-compares str and s, and returns a value.
This comparison is case-insensitive.
8. str.substr(i, j) :-returns a new string that is a substring
formed by index i through j of str.
9. str.atoi() :-returns the integer corresponding to the ASCII
decimal representation in str
10. str.atoreal() :-returns the real number corresponding to the
ASCII decimal representation in str.
11. str.itoa(i) :-stores the ASCII decimal representation of i
into str (inverse of atoi).
12. str.hextoa(i) :-stores the ASCII hexadecimal representation
of i into str (inverse of atohex).
13. str.bintoa(i) :-stores the ASCII binary representation of i
into str (inverse of atobin).
14. str.realtoa(r) :-stores the ASCII real representation of r into
str (inverse of atoreal).
Code Practising:-
Result:-
DAY-54
#100DAYSRTL
Enumerations:-
• Need for variables that have a limited set of possible values
that can be usually referred to by name.
• There's a specific facility, called an enumeration in System
Verilog .
• Enumerated data types assign a symbolic name to each legal
value taken by the data type.
Syntax:-
▪ enum <data-type> {<elements>} <name>;
▪ enum {IDLE, SETUP, ACCESS} state; // example 1
▪ enum bit[1:0] {IDLE, SETUP, ACCESS} state; // example 2
In the above example, the Enum type state has 3
elements, IDLE, SETUP and ACCESS. By default, the first
element is Enum gets the value of 0 and the value increments for
other following elements. Values can be manually assigned to
Enum elements as shown below. If the value is only defined for
the first element, the following elements get incremented value
unless otherwise stated
Eg:-
▪ enum {IDLE=6, SETUP, ACCESS} state; // example 3 - IDLE=6, SETUP=7, ACCESS=8
▪ enum {IDLE=6, SETUP=9, ACCESS} state; // example 3 - IDLE=6, SETUP=9, ACCESS=10
▪ enum {IDLE=6, SETUP=9, ACCESS=14} state; // example 4 -IDLE=6,SETUP=9, ACCESS=14
Some other important points:-
1. Enums can be used as a data type only when the typedef
keyword is used to define the enum. Otherwise, it’s a simple
variable.
2. Elements defined inside Enum can be referenced directly. It
will return the value that it holds.
3. Elements having the same name cannot be defined inside 2
different enums. It is because the element of an enum has
visibility in the entire block inside which the enum is defined.
▪ enum bit[2:0] { RED , BLUE } color_1;
▪ enum bit[2:0] { RED , GREEN } color_2; // Will show error
▪ enum bit[2:0] { VOILET , GREEN } color_2; // Will work fine
If the value for an element is not mentioned explicitly it will
automatically take the incremented value of the previous element
for which the value is mentioned.
Methods:-
Enum provides various in-built system functions that can be
used to iterate within elements of the Enum. Let’s see these in-
built functions in detail.
1. first() – return the value of the first element of the Enum
2. last() – returns the value of the last element of the Enum
3. prev(int N) – returns the value of the Nth element before the
current element of Enum
4. next(int N) – returns the value of the Nth element after the
current element of Enum
5. num() – returns the number of element in the Enum
6. name() – returns the name of the element
Code Practising:-
Enum using Typedef:-
Result:-
Result:-
DAY-55
#100DAYSRTL
Introduction:-
Structures and unions are special data types
which are used to group variables having different data types. We
have seen that arrays also provide the grouping of various
variables or elements. But in arrays, the data type of each element
is the same, whereas structure and unions can have elements
having different data types
Structure:-
A structure is a collection of elements having
different data types. These elements can be accessed as a whole
or individually. Like Enums these can be used to make user-
defined data types. When a structure is declared, the memory is
allocated for all the elements.
Syntax:-
<typedef> struct { <element1>; <element2>; ... } <name>;
Code practising :-
Result:-
Result:-
Result:-
Structure vs Union:-
Introduction:-
In Verilog, we have seen that only static arrays
can be created. Static arrays have a major drawback as the size of
the arrays once defined cannot be changed. This wasted a lot of
memory space as at times the entire size of the array is not used.
Dynamic arrays were introduced in the System Verilog along
with a few other array constructs like associative arrays and
queues.
Packed Array:-
Packed arrays can be considered as a single
dimensional memory, in which the index i represents the ith bit
of the memory. Packed arrays can only be used with data types
having width of one bit, i.e., only logic, bit, reg can be used. Any
other data type cannot be used.
In the figure below, we see that all the data are closely packed
with each address or index having one bit data. Thus, we cannot
use multiple bits data type such as int, byte, etc to declare a
packed array.
Syntax:-
bit [<index of MSB>:<index of LSB>] <identifier>;
Multidimensional Packed Arrays:-
In System Verilog, packed arrays can be of multiple dimensions.
Multiple dimensions should not be confused with the physical
layout. Physically it will be single dimension only
Result:-
Unpacked Arrays:-
Unpacked arrays can be considered as a 2-dimensional memory.
A 2 -dimensional memory means that each address of the
memory can hold one or more than one bits of data, i.e., there is
a width of memory. In simpler terms, it is the same type of array
we are acquainted with in other programming language like C or
Java. Unpacked arrays can be used with any data types, even 1bit
data types.
Syntax:-
bit <identifier> [<index of MSB>:<index of LSB>];
Multidimensional UnPacked Arrays:-
Just as the packed array, unpacked arrays can also be of multiple
dimensions. Again, physically it can be visualized as 2-
dimensional matrix which is split in various blocks
Result:-
Mixed Arrays:-
Mixed arrays are the combination of packed and unpacked array.
In most of the cases it will not be possible to use the inbuilt data
types for array creation. In these cases, we can combine both the
types in single array.
Code Practising:-
Result:-
DAY-57
#100DAYSRTL
Introduction:-
An array is several memory addresses grouped. Thus, before
entering the data into the array, the size of the array needs to be
defined so that the compiler knows how much memory it needs
to allocate. But in the case of the dynamic array the size of the
array is known only during the run time. This makes it very hard
for the simulator to assign continuous memory addresses.
Static Arrays:-
In static arrays, the size of the array is known in the compilation
time. This makes it possible for the simulator to ensure that a
continuous chunk of memory is allocated for the arrays. Also, as
the size is defined in the compile-time, it is not possible to change
the size of the array later on during run-time. Thus these are
known as static arrays.
Syntax:-
• <datatype> [<packed_arr_size>] <identifier> [<unpacked_arr_sizes>]
• <datatype> <identifier> [<unpacked_arr_sizes>]
Code Practising:-
Result:-
Dynamic Arrays:-
In dynamic arrays, the size of the array is known only in the run-
time, which makes it difficult for the simulator to ensure that a
continuous chunk of memory is allocated to the array. The size of
the array can be easily changed during the run time thus giving it
the name dynamic arrays
Syntax:-
• <datatype> <identifier>[] = ‘{<elements of array>};
• <datatype> <identifier>[];
• <identifier>[] = new [<size of array>];
Note :-
Packed array can not be a dynamic array. As discussed earlier
packed arrays must have a continuous memory chunk which is
not ensured in dynamic arrays. Also if a mixed array is declared
only the unpacked part of the array can be dynamic.
▪ bit [] arr ; // illegal.
▪ bit [7:0] arr[]; //Legal
Code Practising:-
Result:-
Introduction:-
Associative arrays are an extension of dynamic arrays which
provide more flexibility in the way in which data can be stored.
In associative arrays, the index can be of any data type including
strings which makes it very beneficial for certain scenarios.
Associative Arrays:-
• Associative arrays are a special type of dynamic arrays in
which the memory is not allocated immediately when the array
is declared. Instead, the memory is allocated as and when data
is stored in the array. As the memory is not allocated
immediately the allocated memory is not continuous, which
makes it slower than dynamic arrays.
• This can be compared to key: value pairs in another language.
The index can be used as a key to get the value stored. The
index can be referred to as a key to get the value stored.
• Also, the key data type should not necessarily be an int, but it
can be any data type including string or real
Syntax:-
• [value datatype] [arr_name] [index datatype];
Code Practising:-
Result:-
Important Note:-
Associative arrays are very useful when we want to model
memories on the test bench.
This is because memories are arrays having a large number of
elements. If the dynamic array is used, then the memory will be
allocated immediately after the array is defined which can lead to
system failures. In an associative array, the memory will be
allocated only when some value is stored in a particular key.
Thus the memory requirement in the associative array will be on
a need basis
Methods:-
1. int num() - returns the number of values or entries stored in
the associative array.
2. int size () - Also returns the number of values stored in the
associative array. Returns 0 for empty array
3. int delete([key]) - If the key is passed to this function then the
value associated with the key is deleted. If no key is provided,
then it deletes the entire array.
4. int exists(key) - checks whether a value is associated with the
given key or not. If no value is present, it returns 0.
5. int first (ref key) - assigns the key variable passed with the
first key of the associative array. If the array is empty 0 is
returned
6. int last(ref key) - assigns the key variable passed with the last
key of the associative array. If the array is empty 0 is returned.
7. int next(ref key) - assigns the key variable passed with the
key which comes just after the specified key. If the array is
empty or if the specified key is last, 0 is returned.
8. int prev(ref key) - assigns the key variable passed with the
key which comes just before the specified key. If the array is
empty or if the specified key is first, 0 is returned.
Code Practising:-
Result:-
Dynamic Array inside Associative Array :-
Code Practising:-
Result:-
Result:-
DAY-59
#100DAYSRTL
Introduction:-
The queue is a special data type in System Verilog that works on
the principle of FIFO (First in First Out). Thus, the element that
is stored first in the queue is retrieved first, just as the case in the
real-life queue.
Queues:-
• Queues are based on the concept of a linked list in which the
elements consist of 2 parts. 1st part is the value that needs to
be stored, and the 2nd part is the address of the next element of
the list. If the element is the last one, then the 2nd part is null
otherwise it points to the next item.
• Queue in system Verilog, handles all the address-related
operations internally which makes using queue a lot easier.
Queue like an associative array has no specific size and the size
grows and shrinks dynamically depending upon the number of
elements stored. But in queues, the index is continuous in
nature, unlike the associative arrays.
Concept of push and pop:-
• As discussed, queues work on the concept of FIFO, i.e., first in
first out. This means that a new element can be added at the
end of the queue. Also, the element which is first in queue
means that it was inserted earlier than other elements and thus
this element will be removed from the queue first.
• Push in queue means inserting a new element at the end of the
queue.
• Pop in queue means getting the first element present in the
queue and removing it from the queue.
Syntax:-
• <element datatype> <queue_name> [$];
Code Practising:-
Result:-
Important Note:-
Using the $symbol for adding new elements in the queue may not
produce the same result in different simulators. Thus, it is
recommended to use the built-in functions to add or remove
elements from a queue so that the output is the same on all
simulators.
Methods:-
1. int size() - returns the number of elements present in the
queue.
2. element_t pop_front() - returns the first element present in
the queue and deletes it.
3. element_t pop_back() - returns the last element present in the
queue and deletes it.
4. void push_front(element_t item) - Inserts the item in the first
position of the queue. Index of all other item shifts by 1.
5. void push_back() - inserts the item in the last position of the
queue. All other items present in the queue are unaffected.
6. void insert(int index, element_t item) - inserts the item in the
specified index.
7. void delete([int index]) - if index is provided as input, it
deletes the item present in specific index otherwise it delete
the entire queue.
Code Practising:-
Result:-
Example:-
• Let’s suppose there is a process that samples data and sends it
to the processing unit. It is not necessary that the data sent by
the sampling unit would be processed immediately.
• In this scenario we don’t know exactly how many elements we
need to store thus dynamic array is not a good option. Also, an
associative array is not good for this scenario as we don’t need
the elements after the element has been processed. In the case
of an associative array, the size will increase, and it is slower.
• Thus, queues are the best option for this scenario as the
sampling unit can push data once it has sampled it and the
processing unit can pop it whenever it can process the data.
Code Practising:-
Result:-
DAY-60
#100DAYSRTL
Introduction:-
The queue is a special data type in System Verilog that works on
the principle of FIFO (First in First Out). Thus, the element that
is stored first in the queue is retrieved first, just as in the case of
the real-life queue.
With Keyword:-
Basically, with keyword is used to pass a condition. This keyword
is used with a function to put some constraint for the argument
that we are passing as the function. These keywords are not only
used with the array manipulation functions but also with some
other constructs which we will see later in this series.
Syntax:-
function_name([argument]) with ([argument condition]);
Ordering Functions:-
1. reverse():-This function reverses the order of the array. This
means that the first element will be shifted to the last position
and the last element will come to the first position.
2. sort():-This function sorts the array in the ascending order.
This can be used in conjunction with the keyword.
3. rsort():-This function sorts the array in descending order. This
also supports the keyword optionally.
4. shuffle():-Randomly changes the order of the elements present
in the array.
Note:- We cannot use the keyword with reverse and shuffle functions.
Code practicing:-
Result:-
Searching Functions:-
find():-This function returns all the elements which satisfy a given
condition.
find_index():-Returns the index of all the elements which satisfy
a given condition. This is somewhat similar to find() but returns
the index instead of actual elements.
find_first():-returns the first element which satisfies the given
condition.
find_first_index():-returns the index of the first element which
satisfies the given condition.
find_last():-returns the last element that satisfies the given
condition.
find_last_index():-returns the index of the last element which
satisfies the given condition.
Note:- The “with” clause is important with all these functions.
Code practicing:-
Result:-
Result:-
Result:-
DAY-61
#100DAYSRTL
“Introduction”:-
• Improperly coded Verilog case statements can frequently cause
unintended synthesis optimizations or unintended latches.
These problems, if not caught in pre-silicon simulations or gate-
level simulations, can easily lead to a non-functional chip. The
new System Verilog unique and priority keywords are designed
to address these coding traps.
• The System Verilog unique and priority modifiers are placed
before an if, case, casez, casex.
• With the if…else statement, the System Verilog unique or
priority keyword is placed only before the first if but affects all
subsequent else if and else statements.
“Unique”:-
Unique causes a simulator to add run-time checks that will report
a warning if any of the following conditions are true:
1. More than one if/case item matches the case expression
2. No if/case item matches the case expression, and there is no
default case/else
Firstly, by adding the System Verilog unique keyword, the
designer asserts that only one case item can match at a time. the
unique keyword tells the tool that all valid case items have been
specified and can be evaluated in parallel. Synthesis is free to
optimize the case items that are not listed.
“Code Practising”:-
//
“Result”:-
“Code Practising”:-
“Result”:-
“Priority”:-
The priority keyword instructs all tools that support System
Verilog that each selection item in a series of decisions must be
evaluated in the order in which they are listed, and all legal cases
have been listed.
Unique causes a simulator to add run-time checks that will report
a warning if any of the following conditions are true:
1. If the case/if expression does not match any of the case/if item
expressions, and there is no default case/else
“Code Practising”:-
“Result”:-
“Code Practising”:-
“Result”:-
DAY-62
#100DAYSRTL
“Introduction”:-
Loops are statements that help to perform repetitive tasks by
writing them once. In testbench, loops are very important as we
must perform lots of repetitive tasks such as sampling a signal
after a certain duration. So, this sampling should happen
repeatedly until the simulation ends.
“Types Of loops”:-
1. Finite loop – this type of loop will repeat for certain number
until some conditions are not met. Once the condition evaluates
to be false it will move out of the loop and execute the
statements present after loop.
2. Infinite loop – this type of loop basically run for infinite
iterations or until the simulation ends. In this type of loops either
there is no condition evaluation, or the condition evaluates to
true every time. Infinite loops can be exited with the help of
break statement if required. Infinite loops should be used with
great care because using it in a wrong way can lead to
unexpected results or also hang the simulation.
“Forever”:-
This is an infinite loop, just like while (True) .
Note that your simulation will hang unless you include a time
delay inside the forever block to advance simulation time
Code practicing:-
Result:-
“Repeat”:-
Used to repeat statements in a block a certain number of times.
Code practicing:-
Result:-
“While”:-
It'll repeat the block as long as the condition is true
Code practicing:-
Result:-
“For Loop”:-
“For loop”:-
It'll repeat the block as long as the condition is true
Code practicing:-
Result:-
“For Loop”:-
“Do While”:-
Repeats the given set of statements at least once, and then loops
as long as the condition is true
Code practicing:-
Result:-
“Foreach”:-
Used mainly to iterate through all elements in an array
Code practicing:-
Result:-
DAY-63
#100DAYSRTL
“Introduction”:-
Often we find certain pieces of code to be repetitive and
called multiple times within the RTL. They mostly do not
consume simulation time and might involve complex
calculations that need to be done with different data values. In
such cases, we can declare a function/task place the repetitive
code inside the function/task, and allow it to return the result.
This will reduce the number of lines in the RTL drastically since
all you need to do now is to do a function call and pass the data
on which the computation needs to be performed.
“Function”:-
The purpose of a function is to return a value that is to be used
in an expression. A function definition always starts with the
keyword function followed by the return type, name, and port list
enclosed in parentheses. Verilog knows that a function definition
is over when it finds the end function keyword. Note that a
function shall have at least one input declared and the return type
will be void if the function does not return anything.
“Automatic Function”:-
The keyword automatic will make the function reuse and
items declared within the task are dynamically allocated rather
than shared between different invocations of the task.This will be
useful for recursive functions and when the same function is
executed concurrently by N process when forked.
“Declaration”:-
“Function Rules”:-
• A function cannot contain any time-controlled statements like
#, @, wait, posedge, negedge
• A function cannot start a task because it may consume
simulation time, but can call other functions
• A function should have at least one input
• A function cannot have non-blocking assignments or force-
release or assign-design
• A function cannot have any triggers
• A function cannot have an output or input
Code practicing:-
Result:-
“Recursive Functions”:-
Functions that call itself is called recursive function
Code practicing:-
Result:-
“Task”:-
A function is meant to do some processing on the input and
return a single value, whereas a task is more general and can
calculate multiple result values and return them using the output
and inout type arguments. Tasks can contain simulation time-
consuming elements such as @, posedge, and others.
“Declarations”:-
“Automatic Task”:-
The keyword automatic will make the task reentrant,
otherwise, it will be static by default. All items inside automatic
tasks are allocated dynamically for each invocation and not
shared between invocations of the same task running
concurrently. Note that automatic task items cannot be accessed
by hierarchical references.
“Static Task”:-
If a task is static, then all its member variables will be shared
across different invocations of the same task that has been
launched to run concurrently static, then all its member variables will be shared across diff
“Static vs Automatic”:-
• If the task is made automatic, each invocation of the task is
allocated a different space in simulation memory and behaves
differently.
• If the task is made static, each invocation of the task is
allocated a same space in simulation memory and behaves
identically
Code practising:-
Result:-
“Task rules”:-
• A task can contain time-controlled statements like #, @, wait,
posedge, negedge.
• A task can start a task.
• A task can have any number of inputs, outputs, and inout ports.
• A task can have non-blocking assignments, force-release, and
assign-design.
• A task can have any number of triggers.
• A task can have any number of outputs and inout ports.
“Function Vs Task”:-
DAY-64
#100DAYSRTL
“Introduction”:-
System Verilog enables versatile argument passing in
functions and tasks. It supports passing by value, reference, and
position, facilitating diverse data handling methods. Additionally,
it allows default argument values, offering flexibility. These
features empower efficient hardware description and verification
methodologies within System Verilog designs.
“Argument pass by value”:-
• The argument-passing mechanism works by copying each
argument into the subroutine area.
• If any changes to arguments within the subroutine, those
changes will not be visible outside the subroutine.
Code practicing:-
Result:-
“Argument pass by reference”:-
• In pass-by-reference, a reference to the original argument is
passed to the subroutine.
• As the argument within a subroutine is pointing to an original
argument, any changes to the argument within the subroutine
will be visible outside.
• To indicate argument pass by reference, the argument
declaration is preceded by keyword ref
Code practicing:-
Result:-
Note:-
Any modifications to the argument value in a pass-by-reference
can be avoided by using the const keyword before ref, any attempt
to change the argument value in the subroutine will lead to a
compilation error.
“Default Argument Values”:-
• The default value can be specified to the arguments of the
subroutine.
• In the subroutine call, arguments with a default value can be
omitted from the call.
• If any value is passed to an argument with a default value, then
the new value will be considered.
Code practicing:-
Result:-
Result:-
DAY-65
#100DAYSRTL
“Introduction”:-
System Verilog provides support for parallel or concurrent
threads through fork-join construct. Multiple procedural blocks
can be spawned off at the same time using fork and join. There
are variations to fork-join that allow the main thread to continue
executing the rest of the statements based on when child threads
finish.
“Fork-Join”:-
• The join statements are executed only after completing all the
fork statements
• The statements in the join and fork executed concurrently
“Code Practising”:-
“Result”:-
“Fork-Join any”:-
• The join statements are executed if at least one statement in the
fork is executed completely
“Code Practising”:-
“Result”:-
“Fork-join_none”:-
• The join statements are executed without depending on fork
statements
“Code Practising”:-
“Result”:-
DAY-66
#100DAYSRTL
“Introduction”:-
In System Verilog IPC(Inter process communication), when
creating multiple processes that run simultaneously, they might
need to communicate or share resources. To facilitate this, System
Verilog introduced tools like mailboxes and semaphores.
Mailboxes, specifically, are useful in test benches where various
components run in separate processes and need a way to
communicate with each other.
“Mailbox”:-
Mailboxes are like a direct line of communication between two
parallel processes. Picture them as a real mailbox: just like how
you send and receive letters, in a mailbox, there's a sender and a
receiver. The receiver can only get mail when the sender sends it.
If the mail hasn’t arrived yet, the receiver has two options. They
can wait for the mail or they can go and do other tasks and then
later check for the .Similarly, if the mailbox is full the sender can't
add new mail until there's space available.
“Establishing IPC via Mailbox”:-
There will be a parent process which will start the sub-process.
Mailbox is defined and declared inside the parent process. This
mailbox handle can then be used by the sub-processes to
communicate with each other.
“Methods of mailbox”:-
1. new() - This function creates a new instance of the mailbox and
returns the handle. If no parameter is passed unbounded mailbox is
created else bounded mailbox is created which can store max
number of elements as specified.
2. put() – This is a blocking task and is used to write some data to the
mailbox. If the mailbox is full it will wait for the mailbox to have
some space.
3. try_put() - This is a non-blocking function. This will try to write a
message in the mailbox. If the mailbox is full or due to some reason
it cannot write it will return a status value of 0 or else return a
positive value.
4. get() – This is a blocking task and is used to get data from the
mailbox. This method also deletes the data from the mailbox after
retrieving it.
5. try_get() – Same as get() method but this is non-blocking function.
The function returns positive number if data is retrieved from the
mailbox else returns zero.
6. peek() – This is similar to the get() method in nature but this task
does not delete the data from the mailbox. As the name suggests it
just peeks into the mailbox and gets back data without changing
any contents of the mailbox
7. try_peek() – Similar to peek() method but is non-blocking
function. Returns a positive number if any data can be retrieved
from the mailbox else returns 0.
8. num() – This function returns the number of data elements that are
currently present in mailbox.
Code Practising:-
Result:-
“Parameterized Mailbox”:-
Parameterized mailboxes offer a solution by being more specific.
They work like a labeled container, where you define the type of data
that can be sent. Just as a package marked with clear instructions on
its content, parameterized mailboxes allow senders to only send data
of a specified type. This restriction prevents mismatched data and
potential errors, ensuring that the receiver is always prepared to
handle the expected content.
“Mailbox Vs Queue”:-
✓ The queue is an array, memory can be operated like a FIFO or
LIFO using the non-blocking methods, whereas the Mailbox is
a class that can be used to communicate between TB
components for sharing the transactions or data.
✓ Mailbox has both blocking and non-blocking methods. Mailbox
is implemented with queues and semaphores.
DAY-67
#100DAYSRTL
“Introduction”:-
We have seen that in System Verilog various processes can run
in parallel. This can create a problem if 2 processes access some
variables. Semaphore provides a solution to this problem.
semaphores can also help in synchronization of different
processes mainly used in test bench design where different
components of the test bench need to be synchronized with each
other.
“Semaphore”:-
Semaphores are basically a way to prevent unintended access
to shared variables by different processes. This can be considered
as a bucket having keys. The process will first need to get a key
from this bucket and then only it can continue to execute the
remaining code lines. If there are no keys left in the bucket, the
process will have to wait until a key is back in the bucket.
semaphore sem;
sem = new();
“Methods of Semaphore”:-
1. new(int key count = 0)- This method creates a new handle of
semaphore. This handle will be used to get or put keys back
into the semaphore. The number of keys stored by semaphore
can be passed as an argument.
2. get(int keyCount = 1)- This method gets the number of keys
passed as an argument from the semaphore. If the mentioned
number of keys is not present in the semaphore then it will
wait for the specified number of keys to be available in the
semaphore.
3. try_get(int keyCount = 1) - this is a non-blocking function
that returns 0 if the number of keys is not available it will
return 1. This will not wait for the number of keys to be
available.
4. put(int key count = 1) - this is a task that will put the
specified number of keys back into the semaphore. This is also
a blocking method that will block the execution of further
statements until the specified number of keys are returned to
the semaphore.
Code practicing:-
Result:-
Note:-
In semaphore, the no of keys given inside the new is just the initial
no of keys. More no of keys can be added to the semaphore
pushing put() task. If the no of keys inside put() is more than what
we have removed from the semaphore the total no of keys gets
increased as seen in the below code.
Code practicing:-
Result:-
DAY-68
#100DAYSRTL
“Introduction”:-
Events in System Verilog, similar to Verilog, are static entities.
However, System Verilog has improved upon the basic
functionalities of events. Think of events as markers or flags that
help control the flow of actions in your code. They're like signals
that trigger specific actions to occur in your program or hardware
design. They've got a few enhancements in System Verilog,
making them more versatile and powerful for managing the
execution sequence in your code.
“Events”:-
✓ Events act like flags that help two different tasks or processes
in a program or hardware design to work together smoothly.
They make sure these tasks stay in sync, just like a countdown
timer used by two people to start an activity together.
✓ In System Verilog, you can 'raise' an event using “->” or “->>”
to signal that something has happened, while you can 'listen' for
that event using @ or wait() to make sure you don't proceed
until that event has been 'raised'.
event ev;
-> ev;
Result:-
“-> Vs ->>”:-
➢ (Non-blocking Event Control)->: It schedules the event to
trigger, but does not wait for the event to be processed
immediately. It's like leaving a note or a message about the
event but continuing with other tasks without waiting for it to
be handled right away.
➢ (Blocking Event Control) ->>: It schedules the event and then
waits for it to be processed before moving on to the next task.
It's like sending a message and then waiting until the receiver
acknowledges it before continuing with your own tasks.
➢ Both -> and ->> are used to trigger events. The difference lies
in whether the current process waits for the event to be
processed immediately (->>) or not (->).
“@ Vs wait”:-
➢ An event's triggered state persists throughout the time step, until
simulation advances. Hence if both wait for the event and the
trigger of the event happen at the same time there will be a race
condition and the triggered property helps to avoid that.
➢ A process that waits on the triggered state always unblocks,
regardless of the order of wait and trigger.
Code Practising:-
Result:-
“Wait Order”:-
Waits for events to be triggered in the given order, and issues an
error if any event executes out of order.
wait_order(a,b,c)
Code Practising:-
Result:-
DAY-69
#100DAYSRTL
“Introduction”:-
In System Verilog, a language used for complex design testing,
they added Object-Oriented Programming (OOP) concepts. This
means they included a way to build components that can inherit
characteristics from other components and have more flexible
behaviors. In traditional Verilog, the components, called modules,
couldn't do this, making it harder to reuse them efficiently for
complex tests.
“OOPs”:-
✓ System Verilog, primarily an HDL for hardware design,
incorporates certain Object-Oriented Programming (OOP)
features but not all.
✓ OOP, inspired by real-world objects, simplifies coding by
resembling real objects. Key OOP features include Inheritance,
Polymorphism, Encapsulation, and Data Abstraction, found in
languages like C++, C#, and Java.
✓ In System Verilog, supported OOP elements include Single and
Multi-level Inheritance, Function Overriding, Virtual Classes,
and Virtual Functions.
✓ These features allow defining blueprints called "classes" that
specify an object's properties and behaviors.
For example, a car, an object created from a car blueprint (class),
shares common attributes like wheels, brakes, and steering. Yet,
individual cars have unique features like color and configuration.
Exploring these OOP features through real-life examples, such as
cars and their varying properties, helps us understand how classes
define objects and their distinct characteristics.
“Polymorphism”:-
Poly means many and morph means form. Thus, polymorphism is
a concept in which the same method can act differently in a child
class or when inputs are different. OOPs provide us with two ways
to enable polymorphism – function overloading and function
overriding.
“Abstraction”:-
Data Abstraction means hiding unnecessary and representing only
what is necessary for the user basically that particular use case.
“Encapsulation”:-
This is a property by which we can bundle all the data and methods
into one unit. This also helps in black boxing a unit where users
can focus more on using the unit without knowing the underlying
process or complexity.
DAY-70
#100DAYSRTL
“Introduction”:-
System Verilog introduces class and object-oriented
programming paradigms to hardware description languages,
facilitating modular design, encapsulation, and reusability in
hardware development. Classes define structures, behaviors, and
hierarchies, while objects instantiate these classes, enabling robust
and efficient design methodologies in System Verilog.
“Class”:-
• Class is a blueprint that defines the properties and behavior of
an object.
• The class encapsulates properties and methods in a single entity.
In System Verilog, all classes are dynamic in nature by default
• A class will define all the properties and methods that will be
present in the object
Eg:-
“Object”:-
• Objects are a unique entity of the class.
• They are created dynamically whenever needed and destroyed
when their need is over
“Constructors”:-
• Constructors are in-built methods that are called to create a new
object
• Basically, when we use new() to create a new class this acts as
a constructor.
• In contrast to a default constructor, a parameterized constructor
allows specific properties to be defined upon object creation.
Code Practising:-
Result:-
“Automatic”:-
When a method is automatic in nature these variables won’t be
allocated memory when we create an object but rather when the
methods are called. Once the method call is over the memory is
released.
Code Practising:-
Result:-
If we have a fork_join inside a for loop and we are using the loop
variable inside fork_join then changes made by any one of the
processes to that loop variable will be reflected on all other
processes. But if we declare that variable as automatic, then all
processes will have individual memory space for that variable, and
thus, changes in the variable won't be reflected in other processes.
“Static”:-
• Static keyword is used to make a method or class static in nature.
• Static methods would share internal variables between different
method calls. Thus, if we set some internal value of the method
to some value, it will be reflected on all other method calls.
• Similarly, we can use static keyword for class as well. This makes
class of static nature and thus can be used without making objects
Code Practising:-
Result:-
“Introduction”:-
In System Verilog, inheritance serves as a pivotal feature
enabling the creation of hierarchical relationships among classes.
This concept allows derived classes to inherit properties and
behaviours from base classes, promoting code reusability,
modularity, and efficient design in hardware description and
verification methodologies.
“Inheritance”:-
• This is the property of OOP by virtue of which a class can
inherit properties and behaviour of another class called parent
or base class.
• The child or derived class can add more properties or behaviour
to the base class.
“Child Class or Sub Class”:-
• Subclasses, like children, inherit traits from parent classes.
• In verification, we often start with a basic reference class and
gradually add more features to build a stronger base class.
• It's similar to how kids inherit characteristics from their parents
and grow with added attributes over time
class <class name> extends <base_class_name>;
endclass
“Super Keyword”:-
• Super keyword is kind of like this keyword except it is used to
access property or method present in the parent class.
class abc extends xyz;
function test();
super.test1();
endfunction
endclass
“Multi-level Inheritance”:-
• In multi-level inheritance child class can also be the parent of
another child
• In multi-level inheritance it is not allowed to reach a class
higher than the immediate parent class. This means that
super.super.new() or similar is not allowed.
• In multi-level inheritance it is not allowed to reach a class
higher than the immediate parent class. This means that
super.super.new() or similar are not allowed.
“Code practicing”:-
“Result”:-
DAY-72
#100DAYSRTL
“Introduction”:-
In System Verilog, polymorphism is primarily achieved
through function overriding, enabling varied function
definitions in child classes, known as static polymorphism.
Parameterized classes also offer versatility by allowing different
class behaviors based on parameters. However, function
overloading, a means of polymorphism, isn't supported in the
latest System Verilog version (IEEE 1800-2008), restricting
dynamic polymorphism. This language leans towards static
polymorphism through overriding and parameterization, steering
away from runtime-defined function behaviors, and emphasizing
compile-time decision-making for function execution.
“Polymorphism”:-
• Polymorphism means many forms. Polymorphism in System
Verilog provides the ability for an object to take on many
forms.
• Method handle of super-class can be made to refer to the
subclass method, this allows polymorphism or different forms
of the same method.
“Virtual”:-
• In SV, to override a function present in parent class, we need to
use virtual keyword in the function declaration present in parent
class.
• Note:-It is not necessary for the child class to have the virtual
keyword, but if we intend to create a child class from this class
then we must use virtual keyword to enable function overriding.
“Code Practising”:-
“Result”:-
“Code practising”:-
“Result”:-
DAY-73
#100DAYSRTL
“Introduction”:-
System Verilog has a feature called virtual classes that can be
used for data abstraction. These classes are like templates that can
be used to create other classes. They define common behavior
and interfaces for their subclasses but leave some details to be
implemented by the subclasses. However, virtual classes cannot
be directly used to create objects. Instead, they are used as base
classes for other classes. Think of them as a blueprint for creating
other classes. The subclasses can then be used to create objects.
This way, you can create a hierarchy of classes that share
common behaviors and interfaces.
“Abstraction”:-
• An abstract class sets out the prototype for the sub-classes.
• An abstract class cannot be instantiated, it can only be derived.
• An abstract class can contain methods for which only a
prototype and no implementation, just a method declaration.
“Code practising”:-
“Result”:-
“Code practising”:-
“Result”:-
“Result”:-
DAY-74
#100DAYSRTL
“Introduction”:-
Encapsulation is a programming practice that involves the
concealment of data within a class, making it exclusively
accessible through the class's methods. This technique effectively
safeguards the data (along with internal methods) within the
"capsule" of the class, thereby limiting access solely to
authorized users, typically the methods of the class.
“Encapsulation”:-
Frequently, we utilize Base Classes or Base Class libraries offered
by third-party sources. Typically, the Class Members in these
libraries are inherently public, allowing direct access from outside
the Class. However, there are instances where the providers of
these Base Classes might impose restrictions on how external
entities can access the Class members. This is implemented as a
safety and security measure to prevent unauthorized alterations
to internal states and logic. These restrictions are put in place to
fortify the integrity of the Class and uphold its intended
functionality, promoting a more controlled and secure
environment for the users and maintainers of the code.
Class Members can be declared with the following two Qualifiers:
• Local: It is available only to methods inside the class. Further,
these local members are not visible within subclasses.
• Protected: It is a property or method that has all of the
characteristics of a local member, except that it can be inherited;
it is visible to subclasses.
“Local”:-
• External access to the class members can be avoided by
declaring members as local, Within the class is allowed
• Any violation could result in a compilation error.
“Code Practising”:-
“Result”:-
“Code Practising”:-
“Result”:-
“Protected”:-
• In some use cases, it is required to access the class members
only by the derived class’s, this can be done by prefixing the
class members with the protected keyword.
• Any violation could result in a compilation error.
“Code Practising”:-
“Result”:-
“Code Practising”:-
“Result”:-
DAY-75
#100DAYSRTL
“Introduction”:-
Explore System Verilog's prowess in designing complex digital
systems, focusing on its dynamic randomization feature. From
syntax insights to practical examples, this article navigates the
basics, revealing how controlled randomness enhances flexibility
and aids in uncovering design flaws. Stay tuned for advanced
constraint discussions.
“Randomization”:-
• System Verilog employs randomization to assign unpredictable
values to variables or objects, serving a dual purpose.
• It generates dynamic inputs for the DUT and introduces
diversity into testbench elements such as monitors and
checkers.
• This process enhances code coverage and unveils elusive corner
cases, unraveling unexpected behaviors for comprehensive
testing.
• Test benches demand extensive stimuli for the DUT, making
directed scenarios impractical and prone to missing corner
cases.
• Randomization offers a succinct solution, enabling the creation
of unpredictable and realistic test scenarios without extensive
code.
• To declare a variable as random we use rand or randc keyword
“rand”:-
• The rand keyword means that the variable or object can take
any value within its range
• the same value may repeated until the possible random values
have been used.
“randc”:-
• The randc keyword means that the variable or object can take
any value within its range, but not the same value until the
possible random values have been used.
• Using randc ensures that we get unique random values.
“randomize()”:-
• every class incorporates the built-in "randomize" method,
facilitating variable randomization. If this method remains
uninvoked, variables retain their default values.
• This design choice permits the utilization of random variables
with specified values without randomization. Moreover, the
"randomize" method doubles as an error indicator by returning
the randomization status.
• This feedback proves invaluable, offering insights into
unsuccessful randomization caused by conflicting constraints or
solver-related issues, enabling effective error handling in the
design and verification process.
“Code practising”:-
“Result”:-
“Disable randomization”:-
• We can disable randomization for any of the random variables
using the rand_mode() method. This ensures that we have finer
granularity in randomizing variables and randomization for
some variables can be enabled/disabled for specific scenarios.
• <var>.rand_mode(0); will disable the randomization
• <var>.rand_mode(1); will enable randomization for variable
“Code practising”:-
“Result”:-
“Static Randomization”:-
SV also provides a static randomization function which can be
called from any class and can be used to randomize variables. It is
different from the normal randomization function as in this we
explicitly pass the variables which we want to randomize. Even
variables which are declared as random can be used with this static
function.
“Code Practising”:-
“Result”:-
DAY-76
#100DAYSRTL
“Introduction”:-
Constraints are a pivotal facet of randomization. Constraints
serve as the avenue through which we articulate specific
conditions or limitations on the randomness imbued in our
values. Given the expansive nature of this subject, we've opted
for a phased approach, unraveling the intricacies of constraints
across multiple articles.
“Constraints”:-
During randomization, it might require to randomize the variable
within a range of values or with an inset of values or other than a
range of values. this can be achieved by using constraints inside
the operator. With the System Verilog inside operator, random
variables will get values specified within the inside block.
• values within the inside block can be variable, constant, or
range
• the inside block is written with an inside keyword followed by
curly braces {}
“Constraint Blocks”:-
• Constraint blocks are class members like tasks, functions, and
variables
• Constraint blocks will have a unique name within a class
• Constraint blocks consist of conditions or expressions to limit
or control the values for a random variable
• Constraint blocks are enclosed within curly braces { }.
• Constraint blocks can be defined inside the class or outside the
class like extern methods, a constraint block defined outside
the class is called an extern constraint block
“Code Practising”:-
“Result”:-
“Code Practising”:-
“Result”:-
“Constraint Inheritance”:-
• Like class members, constraints also will be inherited from
parent class to child class.
• Constraint blocks can be overridden by writing constraint
blocks with the same name as in the parent class
“Code Practising”:-
“Result”:-
“Constraints inside”:-
• values within the inside block can be variable, constant or
range
• the inside block is written with an inside keyword followed by
curly braces {}
constraint addr_range { addr inside { ... }; }
“Code Practising”:-
“
“Result”:-
DAY-77
#100DAYSRTL
“Introduction”:-
Constraints are a pivotal facet of randomization. Constraints
serve as the avenue through which we articulate specific
conditions or limitations on the randomness imbued in our
values. Given the expansive nature of this subject, we've opted
for a phased approach, unraveling the intricacies of constraints
across multiple articles.
“Dist Constraints”:-
• Constraint provides control on randomization, from which the
user can control the values on randomization.
• It would be good if it's possible to control the occurrence or
repetition of the same value on randomization.
• It is possible, with a dist operator, that some values can be
allocated more often to a random variable.
• This is also known as weighted distribution.
• dist is an operator, it takes a list of values and weights,
separated by := or :/ operator
“:= Operator”:-
The “:= operator” assigns the specified weight to the item, or if
the item is a range, specified weight to every value in the range.
“:/ Operator”:-
The “:/ operator” assigns the specified weight to the item, or if
the item is a range, specified weight/n to every value in the range.
where n is the number of values in the range.
“Code Practising”:-
“Result”:-
“Implication if else Constraints”:-
The implication operator can be used to declare conditional
relations between two variables.
• implication operator is denoted by the symbol ->.
• The implication operator is placed between the expression and
constraint.
• If the expression on the LHS of implication operator (->) is
true, then the only constraint on the RHS will be considered
“Code practising”:-
“Result”:-
“Code Practising”:-
“Result”:-
“Code Practising”:-
“Result”:-
“Constraint modes”:-
• The constraint_mode() method can be used to disable any
particular constraint block.
• By default, the constraint_mode value for all the constraint
blocks will be 1.
• constraint_mode() can be used as follow,
✓ addr_range.constraint_mode(0); //disable
✓ packet.addr_range.constraint_mode(0);
“Static Constraints”:-
• A constraint block can be defined as static, by including a static
keyword in its definition. static constraint addr_range { addr >
5; }
• Any mode change of static constraint will afect in all the
objects of same class type
“Code Practising”:-
“Result”:-
DAY-78
#100DAYSRTL
“Introduction”:-
System Verilog revolutionized hardware description languages
by introducing powerful assertion constructs. These built-in
assertions, including constraints, streamline the creation of
intricate designs, enhancing readability and fostering consistency
in System Verilog code. This advancement facilitates the
seamless development of complex hardware systems with
improved reliability and efficiency.
“Assertions”:-
• In hardware verification, checkers traditionally focus on
validating design functionality by comparing outputs to
expected results.
• However, they often fall short in assessing design behavior.
Assertions become crucial in such cases.
• For instance, if a specification mandates that an output toggles
precisely after 2 clock cycles of a valid input, assertions enable
precise behavior verification.
• By embedding assertions in the testbench, designers can ensure
adherence to specified temporal and logical conditions,
enhancing the verification process.
• This approach goes beyond mere output validation, providing
a robust means to verify intricate behavioral requirements and
promoting more comprehensive and accurate verification
methodologies in hardware design.
“Advantages of Assertions”:-
✓ Precision in Issue Localization: Assertions capture design
flaws at their source, minimizing debugging time.
✓ Targeted Debugging: Assertion failures identify specific
signals, streamlining the debugging process.
✓ Functional Coverage: Assertions serve as effective tools for
covering complex behavioral properties.
✓ Formal Verification Integration: Assertions play a crucial
role in Formal verification, a distinct and assertion-centric
approach.
“Different Assertions Languages”:-
➢ PSL (Property Specification Language) – based on IBM Sugar
➢ Synopsys OVA (Open Vera Assertions) and OVL (Open Vera)
➢ Assertions in Specman
➢ 0-In (0–In Assertions)
➢ SystemC Verification (SCV)
➢ SVA (System Verilog Assertions)
“System Verilog Assertions”:-
Prior to System Verilog, different assertion languages were used
due to which there was no uniformity in the assertion constructs.
There was a need to natively support assertions in HDL itself due
to the increasing complexity of the verification.
o System Verilog merges benefits from different assertion
languages into one, thus giving the best from all languages.
o Due to native support of assertions in SV, assertions can be
added to the design and testbench directly without needing to
add special interface.
o SVA is easy to learn and implement.
“Immediate Assertions”:-
An immediate assertion is a type of instruction that tells a
simulator how to check the correctness of a design under test
(DUT). It follows the simulation event semantics, which means
it will be evaluated in the event regions based on how assertion
is used. It is written as a procedural statement, and it is executed
like any other statement in a procedural block.
• Immediate assertion as a basic statement that is evaluated for a
single time.
assert(expression)pass_statement[else fail_statement]
“Code Practising”:-
DAY-79
#100DAYSRTL
“Implication Operator”:-
“Code Practising”:-
“Result”:-
“Non-Overlapped Implication”:-
• The non-overlapped implication is denoted by the symbol |=>.
• If there is a match on the antecedent, then the consequent
expression is evaluated in the next clock cycle.
• Below property checks that, if signal “a” is high on a given
positive clock edge, then signal “b” should be high on the next
clock edge.
“Code Practising”:-
“Result”:-
Examples:-
“go to repetition”:-
the go-to repetition operator is used to specify that a signal will
match the number of times specified not necessarily on a
continuous clock cycle
Eg:-
“Assertions Methods”:-
System Verilog has some inbuild methods for the purpose of
assertions
• $rose:-It returns true if the least significant bit of the signal
changed to 1. Otherwise, it returns false
➢ Eg:- Sequence seq_rose checks that the signal “a” transitions
to a value of 1 on every positive edge of the clock. If the
transition does not occur, the assertion will fail
“Code Practising”:-
• $onehot:- checks that only one bit of the expression can be high
on any given clock edge.
• $onehot:-It checks only one bit of the expression can be high
or none of the bits can be high on any given clock edge.
“Conditions to be checked”:-
➢ Reset property:- When rst==0 then count==0;
➢ Up count property:- when udbar=1 then count=count+1;
➢ Down count property:- when udbar=1 then count=count+1;
➢ Load property:- when load==1 then count==load;
➢ 0 to F property:-in case of down counter if count==0; then next
value should be F
➢ F to 0 property:- in case of Up counter if count==F; then next
value should be 0
“Assertions Code”:-
“Some Insights”:-
o RTL Designers wrote the Assertions used to test the
Microarchitecture Design Specification and the internal Chip
level interfaces, illegal combinations.
o But they don't write it within the RTL code instead they wrote
it outside the module as a separate file and then use the keyword
“bind” to map those Assertions within RTL code.
o Sometimes RTL designers use the “assume” keyword as a part
of Assertions to check several design-related features.
Verification Engineers generally put the Assertions within the
“interface” or inside a “monitor” or use a separate file as
“assertions.sv” to increase the observability of the design.
o Verification Engineers wrote the Assertions related to inter-
module interfaces, at full chip level/block level, and used it as a
Checker to verify the design-related features and performance.
DAY-82
#100DAYSRTL
“Introduction”:-
We can generate an infinite number of random scenarios for the
design under test, but we need to stop our verification at some
point in time and consider the design to be verified. Coverage
gives us that metric which can be used to say verification is
complete. This article will be more focused on the concepts of
coverage and thus will be the same for HDLs like System Verilog,
VHDL, etc.
“Coverage in verification”:-
• Coverage is a metric that measures how well the design under
test (DUT) has been verified by the testbench.
• Coverage helps us identify the gaps in the verification process
and ensure that the DUT meets the specifications and
requirements
• Coverage is important because it provides feedback on the
quality and completeness of the verification process.
• Without coverage, it is difficult to know if the testbench has
covered all the features and scenarios of the DUT, or if there are
any missing or redundant tests
“Code Coverage”:-
• Code coverage is a measure of how much of the code in the
DUT has been executed by the testbench.
• It also helps us detect any dead or unreachable code in DUT.
This helps optimize the design to remove any redundant code.
• Code coverage can also help us optimize the verification
process by reducing the number of tests or increasing the
efficiency of the tests.
• With code coverage we can know if some codes have been
executed or not by our stimulus.
• If there are multiple stimuli executing the same code, we can
remove some redundant tests, similarly, we can add new stimuli
if some code is not getting executed.
“Functional Coverage”:-
Functional coverage measures what functionalities/features of
the design have been exercised by the tests. This can be useful in
constrained random verification (CRV) to know what features
have been covered by a set of tests in a regression. Functional
coverage is a user-defined metric that measures how much of the
design specification has been exercised in verification.
“Coverage Model”:-
• The coverage model is defined using the Covergroup construct.
• The covergroup construct is a user-defined type. The type
definition is written once, and multiple instances of that type
can be created in different contexts.
• Similar to a class, once defined, a cover group instance can be
created via the new()operator. A covergroup can be defined as a
module, program, interface, or class.
• Each covergroup specification can include,
• A clocking event that synchronizes the sampling of coverage
points
✓ A set of coverage points
✓ Cross coverage between coverage points
✓ Optional formal arguments
✓ Coverage options
“Bins”:-
• A coverage point can be an integral variable or an integral
expression. Each coverage point is associated with a “bin”. On
each sample clock simulator will increment the associated bin
value.
• The bins will automatically be created or can be explicitly
defined.
“Automatic Bins(Implicit Bins)”:-
• An automatically single bin will be created for each value of the
coverpoint variable range. These are called automatic, or
implicit, bins.
• For an “n” bit integral coverpoint variable, a 2𝑛 number of
automatic bins will get created.
“Illegal Bins”:-
• A set of values or transitions associated with a coverage point
can be marked as illegal by specifying them as illegal_bins.
DAY-84
#100DAYSRTL
“Cross Coverage”:-
• Cross Coverage is specified between the cover points or
variables. Cross coverage is specified using the cross construct.
• Expressions cannot be used directly in a cross; a coverage point
must be explicitly defined first.
• The cross-coverage allows having a cross-product (i.e. cartesian
product) between two or more variables or coverage points
within the same covergroup.
• In simple words, cross-coverage is nothing but a set of cross-
products of variables or coverage points.
“Code Practising”:-
“iff Constructs”:-
• The expression within the iff construct provides feasibility to
exclude the coverpoint in the coverage if an expression is
evaluated as false.
“Code Practising”:-
“bins of”:-
“Transaction”:-
It contains
✓ variables for all ports (DUT) except Global Signals
✓ modifiers for input ports
✓ Constrains for variables
✓ Methods→Printing Values, Copy
“Generator”:-
✓ It performs Randomization for transaction method
✓ It Sends transactions to the driver
✓ It Sense event from Scoreboard and Driver
“Driver”:-
✓ It Receives transactions from the generator
✓ It applies reset to DUT
✓ It applies transactions to DUT with an interface
“Monitor”:-
✓ It Capture DUT response
✓ It Sends a response transaction to the scoreboard
✓ It also controls data to be sent for a specific operation
“Scoreboard”:-
✓ It Receives transactions from the monitor
✓ Store transaction: array, Queue, Associative Array, etc
✓ Compare with expected result
“Environment Class”:-
✓ It holds all classes together
✓ It Schedules different process
✓ It connects Mailbox, Events
“Transaction”:-
✓ It has all the ports of DUT defined with logic
✓ It is dynamic in nature
THANK YOU !