System Verilog Quick View New PDF
System Verilog Quick View New PDF
DATA TYPES:
1.Structural data type:Hardware
Wire or Net 1)drives the values 2) wire default value is z 3)used for continuous assignment
Reg : 1) stores the values 2) reg default value is x unknown 3) 3)used for procedural assignment
8. Enumeration data type – defines set of named values, contains list of names or one/more variables.
Syntax : enum{red,orange,green,blue,yellow}colors;
Enum methods :
first() -> returns the value of the first member of the enumeration
last() -> returns the value of the last member of the enumeration
next() -> returns the value of next member of the enumeration
next(N) -> returns the value of next Nth member of the enumeration
prev() -> returns the value of previous member of the enumeration
prev(N) -> returns the value of previous Nth member of the enumeration
num() -> returns the number of elements in the given enumeration
name() -> returns the string representation of the given enumeration value
9.Class data type: Class is a collection of data and a set of sub routines that operate on that data. Data in a class are referred as class
properties, and its subroutines are called methods. Class is declared using class and endclass keywords.
Syntax : Class name;
Properties(varable declaration);
Methods(functions & tasks);
Endclass
1
SYSTEM VERILOG
1. Fixed size array – array size will be constant throughout the simulation. Default initialized to 0. -Int a[6].
int array[6]; //fixed size compact single dimension array -> int array[6] : integer arrayname[array locations or size of array];
int array[5:0]; //fixed size verbose single dimension array //bit array1[8]; (mention size 8, so can assign 8elements to array1 )
int array[2:0][3:0]; // fixed size multi dimension array //bit array2[ ] = {0,1,0,1}; (if elements are mentioned then size will be
automatically consider as 4 for array2)
2. Packed array – values store in same memory location. Dimensions declare before the object name.
Stored as a continuous set of bits with no unused space, may be used for serial data transfer(or)storage.
Syntax: Bit [2:0] [7:0] array1
3. Unpacked array – Dimensions declared after the object name. Values store in different locations, non-continuous set of bits.
Syntax: Bit [7:0] array1 [2:0]
4. Dynamic array – one dimension of an unpacked array whose size can be set or changed at run time. Space
doesn’t exist until the array is created at run time.
Syntax : bit[7:0] array1[ ]; // datatype arrayname[ ]; ->null declaration, so no need to mention dimensions for dynamic array.
int array2[ ]; Ex : int array3[ ];
Methods: New[] --> allocates the storage. // array3 = new[10]; //will get size of 10
Size () --> returns the current size of dynamic array. // array3 = new[10]; //delete size 10 and create new size 30
Delete() --> empties the array, resulting in a zero-sized array. //array3 = new[30](array3); //complete size is 40 (10+30)
5. Associative array – Allocate memory only when it is used. Used when the size of the collection is unknown it is better option. It
stores entries in sparse(scattered or disorgnized form) matrix.
Syntax : Int array1[*]; *(wildcard entry declaration ) represents unspecified index // datatype arrayname[index type]
bit [31:0] array2[string]; // 32-bit array with string as index
array2[“header”] = 32’h65;
array2[“payload”] = 32’h34;
array2[“tail”] = 32’h25;
Associative Array Methods:
num() --> returns the number of entries in the associative array.
delete(index) --> removes the entry at the specified index. EX: a_array.delete(index).
exists(index) --> returns 1 if an element exists at the specified index else returns 0.
first(var) --> assigns the value of first index to the variable var.
last(var) --> assigns the value of last index to the variable var.
next(var) --> assigns the value of next index to the variable var.
prev(var) --> assigns the value of previous index to the variable var.
6. Array Initialization : 1) Unique array Initialization -> int array[3] = ‘{1,2,3} //Size is 3, So 3elements {1,2,3)are assigned to array
2)Repetitive operator -> int array[3] = ‘ {3{2}}; //so size is 3 all the 3elemets are only 3->{3,3,3} because of repetition
3)default value to array -> int array[3] = ‘ {default :5}; //all 3location values are {5,5,5}
4)Array un-initialization :int array[2]; //will take values as (0 for 2state datatype) and (x for 4state datatype)
7. Queues – It is a variable size, ordered collection of homogenous(same kind) elements. Like dynamic array , queues can grow
and shrink, queues support adding and removing elements anywhere.
Syntax: 1) bit queue1[$]; // queue of bits -> datatype queuename[$], $ represents queue entries
2) Int queue2[$]; //queue of int
3) Byte queue3[$-255]; //queue of byte with maximum size of 256 entries
4) String queue4[$]; //queue of strings
Queue Methods: size() --> returns the number of items in the queue.
insert() --> inserts the given item at the specified index position.
delete() --> deletes the item at the specified index position.
push front() --> inserts the given element at the front of the queue.
pushback() --> inserts the given element at the end of the queue.
pop front() --> removes and returns the first element of the queue.
pop back() --> removes and returns the last element of the queue.
2
SYSTEM VERILOG
a) Array Ordering method - Operate on single dimension arrays or queues, useful for reordering array elements.
reverse() --> reverses all the elements of the array(packed or unpacked)
sort() --> arrange the unpacked array in ascending order
rsort() --> arrange the unpacked array in descending order
shuffle() --> arrange array the elements in zigzag order
b) Array reduction method - Operates on unpacked array to reduce the array to a single value
sum() --> returns the sum of all the array elements
product() --> returns the product of all the array elements
and() --> returns the bit-wise AND ( & ) of all the array elements
or() --> returns the bit-wise OR ( | ) of all the array elements
xor() --> returns the logical XOR ( ^ ) of all the array elements
c) Array locator method - Built-in array locator methods can be classified as, element finder and index finder.
operate on any unpacked arrays and queues, the return type of these methods is a queue.
Array element finder:
find() --> returns all the elements satisfying the given expression
find_first() --> returns the first element satisfying the given expression
find_last() --> returns the last element satisfying the given 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 is unique
Array Index finder :
find_index() --> returns the indexes of all the elements satisfying the given expression
find_first_index() --> returns the index of the first element satisfying the given expression
find_last_index() --> returns the index of the last element satisfying the given expression
unique_index() --> returns the indexes of all elements with unique values or whose expression is unique
d) Array iterator index querying- this method operate on both index and element,
array1.find with ( item == item.index ); // returns the array element whose value is equal to the index value.
array1.find(item) with ( item > item.index); //returns the array element whose value is greater than the index value.
3
SYSTEM VERILOG
1. Blocking assignment – It blocks the execution of next statement until the completion of current
assignment execution. It executes statements in series order.
Ex : initial begin
a = 10; //Value of a is 10
b = 15; //Value of b is 15
a = b; //After Assigning b to a :: Value of a is 15
b = 20; //After Assigning b= 20 :: Value of b is 20
end
3. Unique if - Evaluates all the conditions parallel. Simulator issue a run time error/warning in following conditions:
1. More than one condition is true.
2. No condition is true /false if doesn’t have corresponding else.
Ex1 : int a,b,c; //variable declaration Ex2 : int a,b,c;
initial begin initial begin
a=10; b=20; c=40; a=50; b=20; c=40;
unique if ( a < b ) $display("\t a is less than b"); unique if ( a < b ) $display("\t a is less than b");
else if ( a < c ) $display("\t a is less than c"); else if ( a < c ) $display("\t a is less than c");
else $display("\t a is greater than b and c"); end
end Result :RT Warning: No condition matches in 'unique if' statement
Result : a is less than b
RT Warning: More than one conditions match in 'unique if' statement.
4. Priority if – It evaluates all the conditions in sequential order. Simulator issue a run time error/warning in the following conditions:
1. No condition is true /false if doesn’t have corresponding else.
Ex1 : int a,b,c; //variable declaration Ex2 : int a,b,c;
initial begin initial begin
a=10; b=20; c=40; a=50; b=20; c=40;
priority if ( a < b ) $display("\t a is less than b"); priority if ( a < b ) $display("\t a is less than b");
else if ( a < c ) $display("\t a is less than c"); else if ( a < c ) $display("\t a is less than c");
else $display("\t a is greater than b and c"); end
end Result :RT Warning: No condition matches in 'Priority if' statement
Result : a is less than b
5. do while - It is a flow control statement that allows code to be executed repeatedly based on given condition.
Syntax : do begin Ex1 : int a; // Result1 : Value of a=0,a=1,a=2, a=3, a=4
statement 1 initial begin //statements will execute until condition is false
statement 2 do begin Ex2 : while(a>5); //Result2 : Value of a=0
statement n $display("\tValue of a=%0d",a); end
end a++; end // atleast one time statement will execute,even though
while(condition) while(a<5); if condition is false in do while loop
end
4
SYSTEM VERILOG
6.while loop - It is a control flow statement that allows code to be executed repeatedly based on given condition.
Execution of statements within the loop happens only if the condition is true.
Syntax : while(condition) begin Ex1 : int a; // Result1 : Value of a=0,a=1,a=2, a=3, a=4
statement 1 initial begin //statements will execute until condition is false
statement 2 while(a<5) begin Ex2 : while(a>5) begin //Result2 : Value of a=0
statement n $display("\tValue of a=%0d",a); end
end a++; end // no statements will execute, if condition is false
end in while loop
6. foreach loop - It specifies iteration over the elements of the array. Loop variable is considered based on elements of an array and
no.of loop variable must match the no.of dimensions of the array. Foreach loop iterates through each index starting from index 0.
Syntax : foreach(<variable>[<iterator>]]) begin EX1 : int a[4];
statement1 initial begin
statement2 foreach(a[i]) a[i] = i;//foreach loop deceleration for”single dimensional array”
Statementn foreach(a[i]) $display("\tValue a[%0d]=%0d",i,a[i]);
end end Result : Value a[0]=0,Value a[1]=1,Value a[2]=2,Value a[3]=3.
Ex2 : int a[3][2];
initial begin
foreach(a[i,j]) a[i][j] = i+j; //foreach loop deceleration for “ multidimensional array”
foreach(a[i,j]) $display("\tValue a[%0d][%0d]=%0d",i,j,a[i][j]);
end Result : Value a[0][0]=0,Value a[0][1]=1,Value a[1][0]=1,Value a[1][1]=2,Value a[2][0]=2,Value a[2][1]=3
5
SYSTEM VERILOG
12. continue–execution of continue statement leads to skip the execution of statements followed by continue and jump to next loop.
Ex : initial begin Result : After Continue :: Value of i=0
for(int i=0;i<8;i++) begin After Continue :: Value of i=1
if((i > 2) && (i < 7))begin After Continue :: Value of i=2
continue; end After Continue ::
$display("\t\tAfter Continue\t:: Value of i=%0d",i); After Continue ::
end After Continue ::
end After Continue ::
After Continue :: Value of i=7
13 . event control – Any change in a variable or a net can be detected using the @ event control.
Syntax : always @(*) , always @(posedge clk), always @(negedge clk), always @(posedge clk iff reset == 0)
statement_name :begin
$display("This is a statement_name_bg1");
end : statement_name
end
Statement labels are useful in reporting and debugging so that you have a label associated with a single statement instead of a
filename/line number without having to wrap it in a begin/end block. It also gives your code visibility into the variables declared
inside a for/foreach loop.
Ex : "label: statement" is equivalent to "begin: label statement end : label"
So except in the case where that statement happens to be a begin/end or fork/join, there is no need for the compiler to
insert an extra begin/end.
6
SYSTEM VERILOG
PROCESSES-FORK_JOIN:
1. fork-join – it will start the processes & inside fork-join all statements will execute parallel, wait for the completion of all statements.
2. fork-join any – it will be unblocked after the completion of any of the process.
3. fork-join none – fork block will be non-blocking. Processes inside the fork-join none block will be started at
the same time. Fork block will not wait for the completion of processes inside the fork-join none.
4. wait fork - causes processes to block until the completion of all processes started from fork blocks.
5. disable fork – causes process to kill/terminate all the active processes started from fork blocks.
Ex1 : module fork_join_none;
initial begin
fork
//Process-1
begin
$display($time,"\tProcess-1 Started");
#5;
$display($time,"\tProcess-1 Finished");
end
//Process-2
begin
$display($time,"\tProcess-2 Startedt");
#20;
$display($time,"\tProcess-2 Finished");
end
join_none //join//join_any
wait fork; //waiting for the completion of active fork threads
disable fork; //all the process will terminate
$display($time,"\tOutside Fork-Join_none"
end
endmodule
Ex2 :
initial begin
fork
//Process-1
begin
$display($time,"\tProcess-1 of fork-1 Started");
#5;
$display($time,"\tProcess-1 of fork-1 Finished");
end
//Process-2
begin
sub_process();
end
join_any
disable fork;
$display($time,"\tAfter disable-fork");
end
//Sub-Process
task sub_process;
$display($time,"\tSub-Process Started");
#10;
$display($time,"\tSub-Process Finished");
endtask
Result :
0 Process-1 of fork-1 Started
0 Sub-Process Started
5 Process-1 of fork-1 Finished
5 After disable-fork
7
SYSTEM VERILOG
TASKS:
A task can contain a declaration of parameters , input, output, in out arguments, registers, events and zero or more behavioral
statements.
System Verilog task can be static or automatic: Static task share the same storage space for all task calls. Automatic tasks allocate
unique, stacked storage for each task call.
1)Default direction of argument is input if no direction has been specified for argument values & default arguments type is logic
2)Delays can be mentioned inside task & also multiple statements within task without requiring a begin…end or fork…join blocks
3)A task can pass values by reference, value, names, and position. Returning from task before reaching the end of the task
4)Can declare an automatic variable in a static task, and also can declare a static variable in an automatic task
Syntax : task task_name(arguments) Ex1 : task sum(input int a,b,output int c);
statemts; c = a+b;
#20; endtask
statemts;
endtask
FUNCTIONS:
A Function can contain declarations of range, returned type, parameters, input arguments, registers and events. A function without a
range or return type declaration, returns a one-bit value. Functions cannot contain any time-controlled statements, and they cannot
enable tasks. Functions can return only one value.
System Verilog function can be static or automatic. Static functions share the same storage space for all task calls. Automatic functions
allocate unique, stacked storage for each task call.
1)Default direction of argument is input if no direction has been specified for argument values & default arguments type is logic
2)Delays can be mentioned inside task & also multiple statements within task without requiring a begin…end or fork…join blocks
3)A task can pass values by reference, value, names, and position. Returning from function before reaching the end of the function
4)Can declare an automatic variable in a static task, and also can declare a static variable in an automatic task
Syntax : function function_name(arguments); Ex1 : int x; //function arguments in parentheses
statemts; function int sum(input int a,b);
statemts; sum = a+b;
endfunction endfunction
initial begin
x = sum(10,15); $display("\tValue of x = %0d",x);
end
Ex2 : int x; //function arguments in declarations and mentioning directions
function int sum; Ex3 : int x; //arguments declarations and directions, return value is specified using the return statement.
input int a,b; function int sum;
sum = a+b; input int a,b; Ex4 : //discarding function return value using void datatype
endfunction return a+b; int x;
initial begin endfunction function int sum;
x=sum(10,5); input int a,b;
$display("\tValue of x = %0d",x); return a+b;
end endfunction
Ex5 :int x; //function call as an expression initial begin
function int sum; $display("Calling function with void");
input int a,b; void'(sum(10,5)); Result : Calling function with void , no result
return a+b; end
endfunction //Calling a function without return value assigned to a variable can result in a warning message.
initial begin //void data type is used to discard a function’s return value without any warning message.
x = 10 + sum(10,5);
$display("\tValue of x = %0d",x);
end Result :Value of x = 25
System Verilog provides below methods for passing arguments to functions and tasks,
1.by value
2.by reference
3.by name
4.by position
also functions and tasks can have default argument values.
8
SYSTEM VERILOG
1. Argument pass by value – it works by copying each argument into the sub routine areas. if any changes to arguments with in the
subroutine, those changes will not be visible outside the subroutine.
Ex : int x,y,z; // Variables x and y are passed as an argument in the function call sum,changes to the argument x within the
function int sum(int x,y); function is not visible outside.
x = x+y; //x=20+30 = 50
return x+y;
endfunction
initial begin
x = 20;
y = 30;
z = sum(x,y); //z = sum(50+30) -> 80 //x=x+y value is 50 from function
$display("\tValue of x=%0d,y=%0d,z=%0d", x,y,z);
end Result : x=20, y=30, z=80
2. Argument pass by reference - reference to the original argument is passed to the subroutine. as the argument with in subroutine
is pointing to an original argument, any changes to the argument with in subroutine will be visible outside. To indicate argument pass
by reference, the argument declaration is preceded by keyword ref.
Ex1 : int x,y,z; Ex2 : argument pass by reference with const keyword
function int sum(ref int x,y); function int sum(const ref int x,y);
x = x+y; //x=20+30 = 50 Result : Variable 'x' declared as 'const' cannot be used in this context
return x+y; Source info: x = (x + y); 1error
endfunction //variables x and y are passed as an argument in the function call sum, changes to the argument x within the
initial begin function, is visible outside.
x = 20;
y = 30;
z = sum(x,y); //z = sum(50+30) -> 80 // x=x+y value is 50 from function
$display("\tValue of x=%0d,y=%0d,z=%0d", x,y,z);
end Result : x=50, y=30, z=80
Any modifications to the argument value in pass by reference can be avoided by using const keyword before ref, any attempt in
changing the argument value in subroutine will lead to compilation error(see Ex2 above)
3. default argument value - default value can be specified to the arguments of subroutine. In the subroutine call, arguments with
default value can be omitted from the call. if any value is passed to an argument with default value, then the new value will be
considered.
Ex : int q; // variables x, y and z of the subroutine has a default value of 1,2 and 3 respectively
function int sum(int x=5,y=10,z=20);
return x+y+z;
endfunction
initial begin
q = sum( , ,10); $display("\tValue of q = %0d",q); // value passed only for z, x and y will take the default value.
q = sum(3, ,30); $display("\tValue of q = %0d",q); // values passed for x, z and y will take the default value.
q = sum(1,1); $display("\tValue of q = %0d",q); // values passed for x,y and z will take the default value.
q = sum(); $display("\tValue of q = %0d",q); // value not passed so x,y,z will take the default value.
end Result : Value q=25, Value q=43, Value q=22, Value q=35
4. pass by name - In argument pass by name, arguments can be passed in any order by specifying name of the subroutine argument.
Ex : module argument_passing;
int x,y,z,a;
functio void display(int x=1, y=1, z=1, a=1); Function main points to remember :
$display("\tValue of x=%0d, y=%0d, z=%0d a=%0d", x,y,z,a); 1) default “begin-end” block
Endfunction 2) contains “return” keyword
initial begin 3) default arguments are “inputs”
display(6,7,8,9); //Value of x=6, y=7, z=8 a=9 4) output declaration is possible
display(); //Value of x=1, y=1, z=1 a=1 5) contains “void” as return type
display(.z(10)); //Value of x=1, y=1, z=10 a=1 6) support default arguments to formal arguments
display(,12,.a(25)); //Value of x=1, y=12, z=1 a=25 7) passing arguments by name,value and by reference
end 8) Function cannot have delays , only task has delays
endmodule
9
SYSTEM VERILOG
CLASSES
1)A class is a user defined data type that includes data (class properties), functions and tasks(class methods) that operate on data.
classes allow objects to be dynamically created, deleted, assigned, and accessed via object handles.
Ex : class sv_class; //class declaration has one data property x and two methods set and get.
int x; //class properties
task set(int i); //method-1
x = i;
endtask
function int get(); //method-2
return x;
endfunction
endclass
sv_class pkt; //Class declaration or Class Instance
pkt = new( ); //class properties and methods can be accessed only after creating the object.
sv_class pkt = new(); //this statement will do both declarations of variable and object creation.
3) class constructs – the new function is called as class constructor. On calling the new() allocates memory, returns the address to the
class handle and initialize the variables to default value.
default value – 0 for 2 state variables.
X for 4 state variables.
1)The new operation is defined as a function with no return type
2)Every class has a built-in new method, calling the constructor of class without the explicit definition of the new method will invoke
the default built-in new method
3)Specifying return type to the constructor shall give a compilation error (even specifying void shall give a compilation error)
4)The constructor can be used for initializing the class properties. In case of any initialization required, those can be placed in the
constructor and It is also possible to pass arguments to the constructor, which allows run-time customization of an object.
Ex : class packet; $display("\t write = %0d",write);
bit [31:0] addr; endfunction
bit write; endclass
function new(); //constructor module sv_constructor; Result : addr =16 & write=1
addr = 32'h10; packet pkt;
write = 1; initial begin
Endfunction pkt = new();
function void display(); pkt.display(); end
$display("\t addr = %0d",addr); endmodule
10
SYSTEM VERILOG
4)static class properties – created by using keyword static. Static properties will be created once and all the class objects will access
the same.
static methods - same as static properties, static method can access only static properties of the class and access to the non-static
properties is illegal and lead to compilation error. Note :: static class properties and methods can be used without creating an object
of that type.
5)class assignment – object will be created only after doing new to an class handle. With the assignment both the objects will point to
the same memory. Any changes made with-respect to one packet will reflect on other.
Ex : class packet;
bit [31:0] addr;
bit [31:0] data;
function new();
addr = 32'h10;
data = 32'hFF;
endfunction
function void display();
$display("\t addr = %0d",addr);
$display("\t data = %0h",data);
endfunction
endclass
module class_assignment; //changes made by using pkt_2 will reflect on pkt_1 , changes made by using pkt_1 will reflect on pkt_2
packet pkt_1; // because both shares same memory
packet pkt_2;
initial begin
pkt_1 = new(); Result :
pkt_1.display(); // addr = 16, data =ff
pkt_2 = pkt_1; //assigning pkt_1 to pkt_2
pkt_2.display(); // addr = 16. data =ff
pkt_2.addr = 32'hAB; //changing values with pkt_2 handle
pkt_1.display(); // addr = 171, data =ff
pkt_1.addr = 32'hAF; //changing values with pkt_1 handle
pkt_2.display(); // addr = 175, data =ff
end
endmodule
6)shallow copy - class properties were copied from pkt_1 to pkt_2 this is called as "shallow copy".
Shallow copy allocates the memory, copies the variable values and returns the memory handle. In shallow copy All of the variables are
copied across: integers, strings, instance handles, etc. changes made in pkt1 will not reflect on pkt2 bcz both share different memories.
Note: Objects will not be copied, only their handles will be copied.
Ex : class packet;
int a = 12;
int b = 15;
function void display();
$display("\t a = %0d",a);
$display("\t b = %0d",b);
endfunction
endclass
module shallow;
packet pkt_1;
packet pkt_2;
initial begin pkt_2.a = 30; //changes made by using pkt_2 will reflect on pkt_1 because both pkt_1
pkt_1 = new(); Result : pkt_2.b = 40; and pkt_2 shares different memory
pkt_1.display(); //a=12 , b=15 pkt_1.display(); //a=12 , b=15
pkt_2 = new pkt_1; pkt_2.display(); //a=30 , b=40
pkt_2.display(); //a=12 , b=15 end
endmodule
11
SYSTEM VERILOG
7) deep copy - Users has to write the copy method for deep copy. On calling the copy method, new memory will be allocated new
object is created and all the class properties will be copied to new handle and new handle will be returned.
Ex : class packet; module deep;
int a = 12; packet pkt_1;
int b = 15; packet pkt_2;
function packet copy(); initial begin
copy=new(); pkt_1 = new();
copy.a=this.a; pkt_1.display(); //a=12, b=15
copy.b=this.b; pkt_2 = new();
return(copy); pkt_2.display(); //a=12, b=15
endfunction pkt_1.a = 50; pkt_1.display(); //a=50, b=60
function void display(); pkt_1.a = 60; pkt_2.display(); //a=30, b=40
$display("\t a= %0d",a); pkt_2=pkt_1.copy; end
$display("\t b= %0d",b); pkt_2.display(); //a=50, b=60 endmodule
endfunction pkt_2.a = 30;
endclass pkt_2.b = 40;
7. parameterised class - parameters are like constants local to that particular class. default values can be overridden by passing a new
set of parameters during instantiation. this is called parameter overriding.
Ex : class packet #(parameter int ADDR_WIDTH = 32,DATA_WIDTH = 32);
bit [ADDR_WIDTH-1:0] address;
bit [DATA_WIDTH-1:0] data ;
function new();
address = 10;
data = 20; //packet p1 -> creates pkt handle with default ADDR_WIDTH and DATA_WIDTH values
endfunction This default parameter value can be overridden when the class is instantiated.
endclass //packet #(32,64) pkt; –> creates pkt handle with ADDR_WIDTH = 32 and DATA_WIDTH = 64.
9. classes inheritance - New classes can be created based on existing classes. A derived class by default inherits the properties and
methods of its parent or base class. the derived class may add new properties and methods or modify the inherited properties and
methods.
base class or parent class -> existing class.
derived class or child class -> New class.
Ex : class parent_class;
bit [31:0] addr;
endclass
class child_class extends parent_class;
bit [31:0] data;
endclass
module inheritence;
initial begin
child_class c = new();
c.addr = 10;
c.data = 20;
$display("Value of addr = %0d data = %0d",c.addr,c.data); Result : Value of addr = 10 and data = 20
end
endmodule
10.overriding class members - Base class or parent class properties and methods can be overridden in the child class or extended class.
Defining the class properties and methods with the same name as parent class in the child class will override the class members.
Ex : class parent_class; endfunction //The parent class has the method display().
bit [31:0] addr; endclass //implementing method display() in the child class will override the
function display(); module inheritence; //parent class method
$display("Addr = %0d",addr); initial begin
endfunction child_class c=new(); //c is the handle to the child class, because of override calling c.
endclass c.addr = 10; //display will call display method of the child class, not the parent class
class child_class extends parent_class; c.data = 20;
bit [31:0] data; c.display(); Result : Data = 20
function display(); end
$display("Data = %0d",data); endmodule
12
SYSTEM VERILOG
11.super keyword – used to refer to members of the parent class, by using super keyword parent class method can be accessed from
child class.
Ex : class parent_class; endfunction //The parent class has the method display().
bit [31:0] addr; endclass //implementing method display() in the child class will override the
function display(); module inheritence; //parent class method to over come this calling super.display()
$display("Addr = %0d",addr); initial begin // this display method of the parent class can be accessed.
endfunction child_class c=new(); //c is the handle to the child class, because of override calling c.
endclass c.addr = 10; .
class child_class extends parent_class; c.data = 20;
bit [31:0] data; c.display(); Result : Addr=10 and Data = 20
function display(); end
super.display(); endmodule
$display("Data = %0d",data);
12. Casting - Converting one datatype variable into another datatype variable.(example string to int)
a) Static casting b) Dynamic casting
a) Static casting :
1) System Verilog static casting is not applicable to OOP
2)As the name says ‘Static’, the conversion data type is fixed
3)Static casting will be checked during compilation, so there won’t be run-time checking and error reporting
4)Casting is applicable to value, variable or to an expression
5)A data type can be changed by using a cast ( ‘ ) operation
6)The vale/variable/expression to be cast must be enclosed in parentheses or within concatenation or replication braces
Ex : module casting;
real r_a;
int i_a;
initial begin
r_a = (2.1 * 3.2);
i_a = int'(2.1 * 3.2); //or i_a = int'(r_a); //real to integer conversion
$display("real value is %f",r_a); //Note: the casting is applied to expression here.
$display("int value is %d",i_a); Result : real value is 6.720000
End int value is 7
Endmodule
b) Dynamic casting :
1)Dynamic casting is used to, safely cast a super-class pointer (reference) into a subclass pointer (reference) in a class hierarchy
2)Dynamic casting will checked during run time,an attempt to cast an object to incompatible object will result in run-time error
3)Dynamic casting is done using the $cast(destination, source) method
4)With $cast compatibility of the assignment will not be checked during compile time, it will be checked during run-time
Usage of Dynamic casting :
1)It is always legal to assign a child class variable to a variable of a class higher in the inheritance tree (parent class).
parent_class = child_class; //allowed
2)It is never legal to directly assign a super-class (parent class) variable to a variable of one of its subclasses (child class).
child_class = parent_class; //not-allowed
3)However, it is legal to assign a super-class (parent class) handle to a subclass (child class) variable if the super-class (parent class)
handle refers to an object of the given subclass(child class).
parent_class = child_class ;
child_class = parent_class; //allowed because parent_class is pointing to child_class.
Though parent_class is pointing to child_class, we will get a compilation error saying its not compatible type for the assignment.
This we can over come by make use of $cast method -> $cast(child_class,parent_class);
Ex : class parent_class; module inheritence;
bit [31:0] addr; initial begin
function display(); parent_class p=new(); //in both conditions c=p and c1=p
$display("Addr = %0d",addr); child_class c=new(); //Expression 'p' on rhs is not a class or a compatible class and hence
endfunction child_class c1; // cannot be assigned to class handle on lhs
endclass c.addr = 10; // so make sure lkh and rhs are compatible
class child_class extends parent_class; c.data = 20;
bit [31:0] data; Ex1 : p = c; c.display(); //assigning childclass handle to parentclass handle Result:addr=10 ,data=20
function display(); Ex2 : c = p; c.display(); //assigning parent class handle to child class handle
super.display(); Ex3 : p=c; c1 =p; c1.display(); //type check fails during compile time , lhs & rhs are not compatible
$display("Data = %0d",data); Ex4 : p = c; $cast(c1,p); //with the use of $cast, type chek will occur during runtime
endfunction c1.display(); end
endclass endmodule Result:addr=10 ,data=20
13
SYSTEM VERILOG
13. Data hiding and encapsulation - The technique of hiding the data within the class and making it available only through the methods,
is known as encapsulation. Because it seals the data (and internal methods) safely inside the “capsule” of the class,
where it can be accessed only by trusted users (i.e., by the methods of the class).
Local class members - External access to the class members can be avoided by declaring members as local. Syntax : local integer x;
Any violation could result in compilation error.
Accessing local variable outside the class ( Not allowed ) : The local variable declared inside the class is trying to access from outside
the class by using object handle. As the variable is declared as local, which leads to a compilation error.
Ex1 : class parent_class; Accessing local variable within the class ( Allowed ) : The local variable declared inside
local bit [31:0] tmp_addr; the class is being accessed inside the class. as it is allowed, no compilation error is seen
function new(bit [31:0] r_addr); Ex2 : module encapsulation;
tmp_addr = r_addr + 10; initial begin
Endfunction parent_class p_c = new(5);
function display(); p_c.display();
$display("tmp_addr = %0d",tmp_addr); end
endfunction endmodule Result : Addr = 15
endclass
module encapsulation;
initial begin
parent_class p_c = new(5);
p_c.tmp_addr = 20; //Accessing local variable outside the class
p_c.display();
end //Result : Local member 'tmp_addr' of class 'parent_class'
endmodule is not visible to scope
Protected - In some use cases it is requires to access the class members only by the derived class's, this can be done by prefixing the
class members with protected keyword. Any violation could result in compilation error. Syntax : protected integer x;
Accessing protected variable outside the class ( Not allowed ) : The protected variable declared inside the class is trying to access
from outside the class by using object handle. As the variable is declared as protected, which leads to a compilation error.
Ex1 :class parent_class; Accessing protected variable in the extended class ( allowed ) : The protected variable declared
protected bit [31:0] tmp_addr; inside the class is being accessed inside extended class. as allowed,no compilation error seen.
function new(bit [31:0] r_addr); Ex2 : module encapsulation;
tmp_addr = r_addr + 10; initial begin
endfunction child_class c_c = new(10);
function display(); c_c.incr_addr(); //Accessing protected variable in extended class
$display("tmp_addr = %0d",tmp_addr); c_c.display();
endfunction end
endclass endmodule
class child_class extends parent_class; Result : Addr = 21
function new(bit [31:0] r_addr);
super.new(r_addr);
endfunction
function void incr_addr();
tmp_addr++;
endfunction
endclass
module encapsulation;
initial begin
parent_class p_c = new(5);
child_class c_c = new(10);
p_c.tmp_addr = 10; // variable declared as protected cannot be accessed outside the class
p_c.display();
c_c.incr_addr(); //Accessing protected variable in extended class
c_c.display();
end //Result : Protected member 'tmp_addr' of class 'parent_class' is not visible to scope 'encapsulation'.
endmodule
14
SYSTEM VERILOG
14)Abstract classes and virtual methods - SystemVerilog class declared with the keyword virtual is referred to as an abstract class.
1)An abstract class sets out the prototype for the sub-classes. Syntax : virtual class abc;
2)An abstract class cannot be instantiated, it can only be derived. //Class defination
endclass
3)An abstract class can contain methods for which there are only a prototype and no implementation, just a method declaration.
Instantiating virtual class :In the below example, Creating an object of a virtual class. An abstract class can only be derived,
creating an object of a virtual class leads to a compilation error.
Ex : virtual class packet;//abstract class
bit [31:0] addr;
endclass
module virtual_class;
initial begin
packet p; //Result : virtual_class, "p = new();"
p = new(); Instantiation of the object 'p' can not be done because its type 'packet' is
end an abstract base class.Perhaps there is a derived class that should be used
endmodule
Deriving virtual class : In the below example, An abstract class is derived and written extend the class and creating it.
Ex : virtual class packet; //abstract class
bit [31:0] addr;
endclass
class extended_packet extends packet;
function void display;
$display("Value of addr is %0d", addr);
endfunction
endclass
module virtual_class;
initial begin
extended_packet p;
p = new(); //Result : value of addr is 10
p.addr = 10;
p.display();
end
endmodule
Virtual Methods : SystemVerilog methods declared with the keyword virtual are referred to as virtual methods.
Virtual Functions : A function declared with a virtual keyword before the function keyword is referred to as virtual Function
Virtual Tasks : Task declared with a virtual keyword before the task keyword is referred to as virtual task
Method without virtual keyword :the method inside the base class is declared without a virtual keyword,
on calling method of the base class which is pointing to the extended class will call the base class method.
Ex1 : class base_class; Method with virtual keyword : the method inside the base class is declared with a
function void display; virtual keyword,on calling method of the base class which is pointing to an extended
$display("Inside base_class"); class will call the extended class method.
endfunction Ex2 : class base_class;
endclass virtual function void display;
class extended_class extends base_class; $display("Inside base_class");
function void display; endfunction //continue code from Ex1 form class extended_class
$display("Inside extended class"); endclass // Result : Inside extended_class //on calling method of the base
Endfunction class which is pointing to an extended class will call the extended class method.
endclass
module virtual_class;
initial begin
base_class b_c;
extended_class e_c;
e_c = new();
b_c = e_c; //Result:Inside base_class//calling method of base class which is pointing to extended class will call base class method
b_c.display();
end
endmodule
15
SYSTEM VERILOG
15. scope resolution operator :: - it is used to specify an identifier defined within the scope of a class. The scope resolution operator
uniquely identifies a member of a particular class. Class Resolution operator allows access to static members (class properties and
methods) from outside the class, as well as access to public or protected elements of super classes from within the derived classes.
Ex : class packet;
bit [31:0] addr;
static bit [31:0] id;
function display(bit [31:0] a,b);
$display("Values are %0d %0d",a,b);
endfunction
endclass
module sro_class;
int id=10;
initial begin
packet p; Result : Values are 20 10
p = new();
packet::id = 20; //A static member of the class is accessed outside the class by using class resolution operator ::
p.display(packet::id,id);
end
endmodule
16. classes extern methods - The extern qualifier indicates that the body of the method (its implementation) is to be found outside
the class declaration. Before the method name, class name should be specified with class resolution operator to specify to which class
the method corresponds to. Definition of method can be written outside the body of class.
External function : The function display is declared inside the class with the extern keyword, and the definition of the function is
written outside the class.
Ex : class packet;
bit [31:0] addr;
bit [31:0] data;
extern virtual function void display(); //function declaration - extern indicates out-of-body declaration
endclass
function void packet::display(); //function implementation outside class body
$display("Addr = %0d Data = %0d",addr,data);
endfunction External task : extern virtual task display(); //task declaration - extern indicates out-of-body declaration
module extern_method; task packet::display();
initial begin $display("Addr = %0d Data = %0d",addr,data);
packet p; endtask
p = new(); //same module use for external task //Result : addr=10 data=20
p.addr = 10; Result : addr=10 data=20
p.data = 20;
p.display();
end
endmodule
External function with arguments -> Arguments name mismatch: Change in argument name between method declaration and
method definition will lead to a compilation error.
Ex1 : class packet;
extern virtual function void display(bit [31:0] addr, data );//function declaration - extern indicates out-of-body declaration
endclass
function void packet::display(bit [31:0] addr_t, data_t);//external function is declared with arguments name mismatch
$display("Addr = %0d Data = %0d",addr_t,data_t);
Endfunction Ex2 : function void packet::display(bit [31:0] addr, data); //arguments name match
module extern_method; Result : Addr =20, data= 30
initial begin
packet p;
p = new();
p.display(20,30); // Result for argument name mismatch : External class method definition should match prototype declaration.
end Argument names do not match. The signature of function 'packet::display'
endmodule
16
SYSTEM VERILOG
17. typedef classes - In some cases class variable needs to be declared before the class declaration.in this type of situation typedef is
used to provide a forward declaration of the class. Syntax : typedef class class_name;
Without typedef : Both classes need the handle of each other. As execution will happen in sequential order. Since there is dependency
between both the classes c1 & c2 which leads to a compilation error. To overcome this define typedef class at begging
Ex1 : class c1; //class-1
c2 c; // c2 is instantiated inside c1 ,using class c2 handle before declaring it.
endclass Ex2 : With typedef : typedef class c2; //declare typedef class before class definition
class c2; //class-2 class c1; //class-1(code from here is same as Ex1)
c1 c; // c1 is instantiated inside c2 // Result : Inside typedef_class
endclass
module typedef_class;
initial begin
c1 class1; // Result : token 'c2' should be a valid type. Please declare it virtual if it is an Interface.
c2 class2;
$display("Inside typedef_class");
end
endmodule
RANDOMIZATION AND DISABLING RANDOMIZATION :Random variable will get random value on randomization.
class variables can be declared random using the rand and randc type-modifier keywords.Following types declared as rand and
randc.
singular variables of any integral type
arrays
arrays size
object handle's
1. rand - Variables declared with the rand keyword are standard random variables. Their values are uniformly distributed over their
range. Syntax : rand bit [3:0] addr; -> addr is an 4-bit unsigned integer with a range of 0 to 15. on randomization this variable
shall be assigned any value in the range 0 to 15 with equal probability.
2.randc: random-cyclic - Variables declared with the randc keyword, their values doesn't repeat a random value until every possible
value has been assigned. In order to randomize the object variables, need to call randomize() method.Syntax : randc bit [3:0] addr;
3. disabling random variables - The rand_mode() method can be used to disable the randomization of variable declared with
rand/randc. Syntax:pkt.var.rand_mode(0);//randomization is disabled only for variable by calling obj.variablename.rand_mode(0);
Note: Syntax : pkt.rand_mode(0); //randomization for all the class variables is disabled by calling obj.rand_mode(0);
1.By default rand_mode value for all the random variables will be 1(enable)
2.after setting rand_mode(0) to any random variable it will disable randomization of variables.
4.randomize() -The randomize() method is virtual function that generates random values for all active random variables in the object.
Syntax : object.randomize();
5 Pre_randomize() &post_randomize(): Every class contains built-in pre_randomize() and post_randomize() functions. on calling
randomize(), pre_randomize() and post_randomize() functions will get called before and after the randomize call respectively.
Users can override the pre_randomize() and post_randomize() in any classes.
pre_randomize - function can be used to set pre-conditions before the object randomization.
Post_randomization - function can be used to check perform post-conditions after the object randomization.
Ex : class packet; module rand_methods;
rand bit [7:0] addr; // initial begin
randc bit wr_rd; packet pkt;
bit tmp_wr_rd; pkt = new();
function void pre_randomize(); // function will disable randomization of addr, repeat(4)
if(tmp_wr_rd==1) addr.rand_mode(0); //if previous operation is write. pkt.randomize(); //generates random values
else addr.rand_mode(1); //pkt.addr.rand_mode(0); //randomization is
endfunction disabled for particular variable by calling obj.variablename.rand_mode(0);
function void post_randomize(); //function - store the wr_rd value to tmp_wr_rd
tmp_wr_rd = wr_rd; //and display randomized values of addr and wr_rd //pkt.rand_mode(0); //randomization for all class
$display("POST_RANDOMIZATION:: Addr = %0h,wr_rd = %0h",addr,wr_rd); variables is disabled by calling obj.rand_mode(0);
endfunction end
endclass endmodule
Result : POST_RANDOMIZATION:: Addr = 6e,wr_rd = 1,POST_RANDOMIZATION:: Addr = 6e,wr_rd = 0
POST_RANDOMIZATION:: Addr = 88,wr_rd = 1,POST_RANDOMIZATION:: Addr = 88,wr_rd = 0
17
SYSTEM VERILOG
Constraints:- By writing constraints(control the values getting assigned on randomization) to an random variable, user can get specific
value on randomization. constraints to an random variable shall be written in constraint blocks.
1) Constraint blocks:
a)Constraint blocks are class members like tasks, functions, and variables
b)Constraint blocks will have a unique name within a class
c)Constraint blocks consist of conditions or expressions to limit or control the values for a random variable
d)Constraint blocks are enclosed within curly braces { }
e)Constraint blocks can be defined inside the class or outside the class like extern methods,
f)constraint block defined outside the class is called as extern constraint block
Syntax : constraint <constraint_block_name> { <condition/expression>; Ex : constraint addr_range { addr > 5; }
...
<condition/expression>;}
External constraint blocks - External constraints are Same like external class methods. constraint blocks can be defined outside the
class body, declaration should be with in class body.
A)constraint block is defined inside the class : B)constraint block is declared inside the class and defined outside the class :
class packet; class packet;
rand bit [3:0] addr; rand bit [3:0] addr;
constraint addr_range { addr > 5; } constraint addr_range; //constraint block declaration
endclass endclass
module constr_blocks; constraint packet::addr_range { addr > 5; }//constraint implementation outside class
initial begin module extern_constr;
packet pkt; initial begin
pkt = new(); packet pkt; pkt = new();
repeat(5) begin repeat(10) begin
pkt.randomize(); pkt.randomize();
$display("\taddr = %0d",pkt.addr); $display("\taddr = %0d",pkt.addr);
end Result : addr=14,addr=10,addr=9, end Result : addr=14,addr=10,addr=9,addr=8,addr=9
end addr=8,addr=9 end
endmodule endmodule
2. constraint inheritance - As class members, constraints also will get inherited from parent class to child class. in a child class,
constraint blocks can be overridden by writing constraint block with same name as in parent class.
Ex : Constraint to an addr > 5 of the parent class is overridden with constraint addr < 5 in child class.
class packet; /Parent class or Base class pkt1 = new();
rand bit [3:0] addr; pkt2 = new();
constraint addr_range { addr > 5; } repeat(5) begin
endclass pkt1.randomize();
class packet2 extends packet; //child class or Extended class $display("\tpkt1:: addr = %0d",pkt1.addr);
constraint addr_range { addr < 5; } //overriding constraint of parent class end
endclass repeat(5) begin
module constr_inheretance; pkt2.randomize();
initial begin $display("\tpkt2:: addr = %0d",pkt2.addr);end
packet pkt1; end
packet2 pkt2; endmodule
Result : pkt1:addr=14, pkt1:addr=10, pkt1:addr=9, pkt1:addr=8, pkt1:addr=9
pkt2:addr=0, pkt2:addr=1, pkt2:addr=2, pkt2:addr=0, pkt2:addr=2
3. inside operator - With inside operator, random variables will get values specified within the specific range when we use by inside
operator. values within the inside block can be variable, constant or range.
a) inside block is written with an inside keyword followed by curly braces{} : Syntax : constraint addr_range { addr inside { ... }; }
b) To specify range in inside operator use square braces[ ] : constraint addr_range { addr inside { [5:10]};
c) set of values are specified by ‘comma’ in inside operator : constraint addr_range { addr inside { 1,3,5,7,9}; }
d) it is allowed to mix range and set of values : constraint addr_range { addr inside {1,3,[5:10],12,[13:15]}; }
e) if the value needs to be outside the range, then specify inverse (!) of inside : constraint addr_range { addr !(inside {[5:10]}); }
f) Other random variables can be used in inside block within the[ start_addr :end_addr ] :
Ex : class packet;
rand bit [3:0] addr;
rand bit [3:0] start_addr;
18
SYSTEM VERILOG
4. weighted distribution - With dist operator, some values can be allocated more often to an random
variable.
The := operator assigns the specified weight to the item.
addr dist { 2 := 5, [10:12] := 8 };
addr = 2 , weight 5
The :/ operator assigns the specified weight to the item.
addr dist { 2 :/ 5, [10:12] :/ 8 };
addr = 2 , weight 5
addr = 10, weight 8/3
. implication (->) - The implication operator ( –> ) can be used to declaring conditional relations.
expression -> constraint
if the expression is true, then the constraints must be satisfied.
constraint address_range { (addr_range == "small") -> (addr < 8);}
5. if else - If the expression is true, all of the constraints in the first constraint/constraint-block must be satisfied, otherwise all of the
constraints in the optional else constraint/constraint-block must be satisfied.
6. Iterative constraints – It allow arrayed variables to be constrained using loop variables and indexing expressions.
constraint values { foreach ( addr[i] ) addr[i] inside {4,8,12,16}; }
7. constraint modes - The constraint_mode() method can be used to disable any particular constraint block. By default,
constraint_mode value for all the constraint blocks will be 1.constraint_mode() can be used as follo:
addr_range.constraint_mode(0); //disable addr_range constraint
8. static constraints - A constraint block can be defined as static, by including static keyword in its definition.
static constraint addr_range { addr > 5; }
Any mode change of static constraint will affect in all the objects of same class type.
9. inline constraints - Inline constraints allows to add constraints along with randomize call statement. Constraints defined inside the
class also considered along with the inline constraints.
pkt.randomize() with { addr == 8;};
10. functions in constraints - In some cases constraint can't be expressed in single line, function call can be used to constraint a random
variable.
11. soft constraints - A soft constraint is the constraint on random variable, and it will be true unless contradicted by another
constraint. For any random variable, there should not be any conflict between the constraint declared in parent class and child class
or inline constraint,
19
SYSTEM VERILOG
conflicts in constraints leads to an randomization failure. this kind of problems can be avoided using soft constraints.
12. Bidirectional constraints – System Verilog constraints solved bidirectionally, which means constraints on all random variables will
be solved parallel.
1.$urandom () - The system function $urandom provides a mechanism for generating pseudorandom numbers. The function returns
a new 32-bit random number each time it is called. The number shall be unsigned
variable = $urandom(seed);
The seed is an optional argument that determines the sequence of random numbers generated. The seed can be any integral
expression.
3. $urandom_range() - The $urandom_range() function returns an unsigned integer within a specified range.
The process through which processes communicate/synchronizes each other is known as Inter Process
Communication/synchronization.
1.Semaphore:
Imagine a situation where two processes try to access a shared memory area where one process tries to write to a memory location
when the other process is trying to read. this leads to an unexpected results.
Conceptually, a semaphore is a bucket. When a semaphore is allocated, it contains a fixed number of keys is created.
The process which wants to access the shared resource can first acquire the key/keys, once the process finishes the access to resource,
key/keys shall be put back to the bucket.
If any other process tries to access the same resource, it must wait until a sufficient number of keys is returned to the bucket.
2. mailbox:
20
SYSTEM VERILOG
Mailboxes are created as having either a bounded and unbounded queue size.
A bounded mailbox becomes full when it contains the bounded number of messages. A process that attempts to place a message into
a full mailbox shall be suspended until enough space becomes available in the mailbox queue. Unbounded mailboxes are with unlimited
size.
3. Event
Events are static objects useful for synchronization between the process.
One process will trigger the event, and the other processes can wait for an event to be triggered.
Events are triggered using -> operator or ->> operator
wait for a event to be triggered using @ operator or wait() construct.
System Verilog events act as handles to synchronization queues, thus, they can be passed as arguments to tasks, and they can be
assigned to one another or compared.
1. -> operator - Named events are triggered via the -> operator. Triggering an event unblocks all processes currently waiting on that
event.
2. ->> operator - Nonblocking events are triggered using the ->> operator.
3. @ operator - wait for an event to be triggered is via the event control operator, @. The @ operator blocks the calling process until
the given event is triggered.
NOTE: If the trigger executes first, then the waiting process remains blocked.
4. Wait operator - If the event triggering and waiting for event trigger with @ operator happens at the same time, @ operator may
miss to detect the event trigger.
Where as wait(); construct will detect the event triggering.
wait(event_name.triggered);
5. wait_order() - The wait_order construct is blocks the process until all of the specified events are triggered in the given order (left to
right). event trigger with out of order will not unblocks the process.
Wait_order(a,b,c);
6. Merging events - When one event variable is assigned to another, the two become merged. Thus, executing -> on either event
variable affects processes waiting on either event variable.
4.PROGRAM-BLOCK:
The Program construct provides race-free interaction between the design and the testbench, all elements declared within the program
will get executed in Reactive region.
Non-blocking assignments with in the module are scheduled in the active region, initial blocks within program blocks are scheduled in
the Reactive region.
21
SYSTEM VERILOG
Statements within a program block (scheduled in the Reactive region) that are sensitive to changes in design signals declared in
modules (scheduled in the active region), as active region is scheduled before the reactive region this avoids the race condition
between testbench and design.
Program block,
can be instantiated and ports can be connected same as module.
can contain one or more initial blocks.
cannot contain always blocks, modules, interfaces, or other programs.
In program variables can only be assigned using blocking assignments. Using non-blocking assignments with in the program
shall be an error.
5. INTERFACE:
Interface construct are used to connect the design and testbench.
An interface is a named bundle of wires, aim of the interfaces is to encapsulate communication.
Also specifies the,
directional information, i.e. modports
timing information, i.e. clocking blocks
An interface can have parameters, constants, variables, functions and tasks.
modports and clocking blocks are explained in later chapters.
A simple interface declaration is,
interface interface_name;
...
interface_items
...
endinterface
6. Virtual interface:
A virtual interface is a variable that represents an interface instance.
Syntax:
virtual interface_name instance_name;
example:
virtual mem_intf intf;
Virtual interface must be initialized before using it. i.e., Virtual interface must be connected/pointed to the actual interface.
accessing the uninitialized virtual interface result in a run-time fatal error.
Virtual interfaces can be declared as class properties, which can be initialized procedural or by an argument to new().
Virtual interface variables can be passed as arguments to the tasks, functions, or methods.
All the interface variables/Methods can be accessed via virtual interface handle. i.e virtual_interface.variable
7. mod ports:
Modport groups and specifies the port directions to the wires/signals declared within in the interface.
By specifying the port directions, modport provides access restrictions.
The keyword modport indicates that the directions are declared as inside the module.
22
SYSTEM VERILOG
The Interface can have any number of modports, wire declared in the interface can be grouped in many modports.
wires declared in the modport are accessed as,
modport_name.wire;
8. clocking block:
A clocking block specifies timing and synchronization for group of signals.
The clocking block specifies,
The clock event that provides a synchronization reference for DUT and testbench.
The set of signals that will be sampled and driven by the testbench.
The timing, relative to the clock event, that the testbench uses to drive and sample those signals.
Clocking block can be declared in interface, module or program block.
Clocking event:
The event specification used to synchronize the clocking block, @(posedge clk) is the clocking event.
Clocking signal:
Signals sampled and driven by the clocking block, from_DUT and to_DUT are the clocking signals,
Clocking skew:
Clocking skew specify the moment (w.r.t clock edge) at which input and output clocking signals are to be sampled or driven
respectively. A skew must be a constant expression and can be specified as a parameter.
A skew must be a constant expression and can be specified as a parameter. In case if the skew does not specify a time unit, the current
time unit is used.
1.Boolean expression - The functionality is represented by the combination of multiple logical events. These events could be simple
Boolean expressions.
2. sequence - Boolean expression events that evaluate over a period of time involving single/multiple clock cycles. SVA provides a key
word to represent these events called "sequence."
syntax:
23
SYSTEM VERILOG
sequence name_of_sequence;
……
endsequence
3. property - A number of sequences can be combined logically or sequentially to create more complex sequences. SVA provides a key
word to represent these complex sequential behaviors called "property”.
4. Assert - The property is the one that is verified during a simulation. It has to be asserted to take effect during a simulation. SVA
provides a key word called "assert" to check the property.
2. SVA sequence:
Sequence seq_1 checks that the signal "a" is high on every positive edge of the clock. If signal "a" is not high on any positive clock edge,
the assertion will fail.
sequence seq_1;
@(posedge clk) a==1;
endsequence
2. Sequence Expressions:
By defining arguments in a sequence definition, the same sequence can be re-used for the similar behavior.
For example, we can define a sequence as follows.
sequence seq;
@(posedge clk) a ##2 b;
Endsequence
24
SYSTEM VERILOG
Note :: sequence begins when signal "a" is high on a positive edge of the clock.
property p;
@(posedge clk) seq;
endproperty
a_1 : assert property(p);
In general, it is a good idea to define the clocks in property definitions and keep the sequences independent of the clocks. This will
help increase the re-use of the basic sequence definitions.
A separate property definition is not needed to assert a sequence. the expression to be checked can be
called from the assert statement directly.
4. Forbidding a property:
sequence checks that if signal "a" is high on a given positive edge of the clock, then after 2 clock cycles, signal "b" shall not be high.
The keyword "not" is used to specify that the property should never be true.
sequence seq;
@(posedge clk) a ##2 b;
endsequence
property p;
not seq;
endproperty
a_1: assert property(p);
3.Implication operator:
Implication is equivalent to an if-then structure. The left hand side of the implication is called the "antecedent" and the right hand
side is called the "consequent." The antecedent is the gating condition. If the antecedent succeeds, then the consequent is evaluated.
The implication construct can be used only with property definitions. It cannot be used in sequences.
sequence seq;
@(posedge clk) a ##2 b;
Endsequence
In the above sequence we can observe that, sequence starts on every positive edge of the clock and it looks for "a" to be high on
every positive clock edge. If signal "a" is not high on any given positive clock edge, an error is issued by the checker.
If we want sequence to be checked only after “a” is high, this can achieved by using implication operator.
Overlapped implication
Non-overlapped implication
25
SYSTEM VERILOG
If there is a match on the antecedent, then the consequent expression is evaluated in the same clock cycle.
Below property checks that, if signal "a" is high on a given positive clock edge, then signal "b" should also be high on the same clock
edge.
property p;
@(posedge clk) a |-> b;
endproperty
a: assert property(p);
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.
property p;
@(posedge clk) a |=> b;
endproperty
a: assert property(p);
3. Implication with a fixed delay on the consequent - Below property checks that, if signal "a" is high on a given positive clock edge,
then signal "b" should be high after 2 clock cycles.
property p;
@(posedge clk) a |-> ##2 b;
endproperty
a: assert property(p);
4. Implication with a sequence as an antecedent - Below property checks that, if the sequence seq_1 is true on a given positive edge
of the clock, then starts checking the seq_2 (“d” should be low, 2 clock cycles after seq_1 is true ) .
sequence seq_1;
(a && b) ##1 c;
endsequence
sequence seq_2;
##2 !d;
endsequence
property p;
@(posedge clk) seq_1 |-> seq_2;
endpeoperty
a: assert property(p);
5. Timing windows in SVA checkers - Below property checks that, if signal "a" is high on a given positive clock edge, then within 1 to
4 clock cycles, the signal "b" should be high.
property p;
@(posedge clk) a |-> ##[1:4] b;
endproperty
a: assert property(p);
6. overlapping timing window - Below property checks that, if signal "a" is high on a given positive clock edge, then signal "b" should
be high in the same clock cycle or within 4 clock cycles.
property p;
@(posedge clk) a |-> ##[0:4] b;
endproperty
a: assert property(p);
7. Indefinite timing window - The upper limit of the timing window specified in the right hand side can be defined with a "$" sign
which implies that there is no upper bound for timing. This is called the "eventuality" operator. The checker will keep checking for a
match until the end of simulation
26
SYSTEM VERILOG
Below property checks that, if signal "a" is high on a given positive clock edge, then signal "b" will be high eventually starting from the
next clock cycle.
property p;
@(posedge clk) a |-> ##[1:$] b;
endproperty
a: assert property(p);
4. Repetition operators
property p;
@(posedge clk) a |-> ##1 b ##1 b ##1 b;
endproperty
a: assert property(p);
The above property checks that, if the signal “a” is high on given posedge of clock, then signal “b” should be high for 3 consecutive
clock cycles.
The Consecutive repetition operator is used to specify that a signal or a sequence will match continuously for the number of clocks
specified.
Syntax:
signal [*n] or sequence [*n]
"n" is the number of repetitions.
with repetition operator above sequence can be re-written as,
property p;
@(posedge clk) a |-> ##1 b[*3];
endproperty
a: assert property(p);
1. 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 continuous clock cycles.
Signal [->n]
property p;
@(posedge clk) a |-> ##1 b[->3] ##1 c;
endproperty
a: assert property(p);
the above property checks that, if the signal “a” is high on given posedge of clock, then signal “b” should be high for 3 clock cycles
followed by “c” should be high after ”b” is high for third time.
2. Non-consecutive repetition - This is very similar to "go to" repetition except that it does not require that the last match on the signal
repetition happen in the clock cycle before the end the entire sequence matching.
Signal [=n]
Only expressions are allowed to repeat in "go to" and "non-consecutive" repetitions. Sequences are not allowed.
5. SVA methods:
returns true if the least significant bit of the expression changed to 1. Otherwise, it returns false.
sequence seq_rose;
endsequence
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.
27
SYSTEM VERILOG
2. $fell - $fell( Boolean expression or signal name) returns true if the least significant bit of the expression changed to 0. Otherwise, it
returns false.
sequence seq_fell;
@(posedge clk) $fell(a);
endsequence
Sequence seq_fell checks that the signal "a" transitions to a value of 0 on every positive edge of the
clock. If the transition does not occur, the assertion will fail.
3.$stable - $stable( Boolean expression or signal name) returns true if the value of the expression did not change. Otherwise, it
returns false.
sequence seq_stable;
@(posedge clk) $stable(a);
endsequence
Sequence seq_stable checks that the signal "a" is stable on every positive edge of the clock. If the
there is any transition occur, the assertion will fail.
4. $past - $past(signal_name, number of clock cycles) provides the value of the signal from the previous clock cycle.
Below Property checks that, in the given positive clock edge, if the “b” is high, then 2 cycles before that, a was high.
property p;
endproperty
5.$past construct with clock gating : The $past construct can be used with a
gating signal. on a given clock edge, the a: assert property(p); gating signal has to be true even before
checking for the consequent condition.
Spast (signal_name, number of clock cycles, gating signal)
Below Property checks that, in the given positive clock edge, if the “b” is high, then 2 cycles before that, a was high only if the gating
signal "c' is valid on any given positive edge of the clock.
Property p;
endproperty
a: assert property(p);
1. $onehot(expression) - checks that only one bit of the expression can be high on any given clock edge.
2. $onehot0(expression) - checks only one bit of the expression can be high or none of the bits can be high on any given clock edge.
28
SYSTEM VERILOG
Assert statement a_1 checks that the bit vector "state" is one-hot.
Assert statement a_2 checks that the bit vector "state" is zero one-hot.
Assert statement a_4 checks that the number of ones in the vector "bus" is greater than one.
7. disable iff - In certain design conditions, we don't want to proceed with the check if some condition is true. this can be achieved by
using disable iff.
Below property checks that, if the signal “a” is high on given posedge of clock, then signal “b” should be high for 3 clock cycles
followed by “c” should be high after ”b” is high for third time. During this entire sequence, if reset is detected high at any point, the
checker will stop.
property p;
@(posedge clk)
disable iff (reset) a |-> ##1 b[->3] ##1 c;
endproperty
a: assert property(p);
8. ended - while concatenating the sequences, ending point of the sequence can used as a synchronization point.
sequence seq_1;
(a && b) ##1 c;
endsequence
sequence seq_2;
d ##[4:6] e;
endsequence
property p;
@(posedge clk) seq_1.ended |-> ##2 seq_2.ended;
endpeoperty
a: assert property(p);
Above property checks that, sequence seq_1 and SEQ_2 match with a delay of 2 clock cycle in between them. the end point of the
sequences does the synchronization.
Coverage:
Coverage is used to measure tested and untested portions of the design. Coverage is defined as the percentage of verification
objectives that have been met.
1.Code coverage - Code coverage measures how much of the “design Code” is exercised. This includes, execution of design blocks,
Number of Lines, Conditions, FSM, Toggle and Path.
Simulator tool will automatically extracts the code coverage from the design code.
2. functional coverage - Functional coverage is a user-defined metric that measures how much of the design specification has been
exercised in verification.
Data-oriented Coverage - Checks combinations of data values have occurred. We can get Data-oriented coverage by
writing Coverage groups, coverage points and also by cross coverage.
29
SYSTEM VERILOG
Control-oriented Coverage - Checks whether sequences of behaviors have occurred. We can get assertion coverage by
writing System Verilog Assertions.
Similar to a class, once defined, a covergroup instance can be created via the new()operator. A covergroup can be defined in a
module, program, interface, or class.
1. Automatic/implicit bins – 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, 2n number of automatic bins will get created.
module cov;
logic clk;
logic [7:0] addr;
logic wr_rd;
2. Explicit bins - “bins” keyword is used to declare the bins explicitly to an variable.
Separate bin is created for each value in the given range of variable or a single/multiple bins for the rage of values.
Bins are explicitly declared with in curly braces { } along with the bins keyword followed by bin name and variable value/range,
immediately after the coverpoint identifier.
30
SYSTEM VERILOG
3. Bins for transitions - Transition of coverage point can be covered by specifying the sequence,
value1 => value2
It represents transition of coverage point value from value1 to value2.
sequence can be single value or range,
value1 => value2 => value3 ….
range_list_1 => range_list_2
5. Illegal bins - A set of values or transitions associated with a coverage-point can be marked as illegal by specifying them
as illegal_bins.
3. 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.
bit [3:0] a, b;
covergroup cg @(posedge clk);
c1: coverpoint a;
c2: coverpoint b;
c1Xc2: cross c1,c2;
endgroup : cg
bit [3:0] a, b, c;
covergroup cov @(posedge clk);
BC : coverpoint b+c;
aXb : cross a, BC;
endgroup
The coverage group cov has the same number of cross products as the previous example, but in this case, one of the coverage points
is the expression b+c, which is labelled BC.
4. coverage options
31
SYSTEM VERILOG
Coverage options control the behavior of the covergroup, coverpoint and cross.
1. at_least:
Minimum number of hits for each bin. A bin with a hit count that is
less than number is not considered covered. default value is ‘1’.
2. auto_bin_max:
Maximum number of automatically created bins when no bins are
explicitly defined for a coverpoint. default value is ‘64’.
3. cross_auto_bin_max:
Maximum number of automatically created cross product bins for a
cross. there is no default value, it is unbounded.
parameter
`define
1.parameter - Parameters must be defined within module boundaries using the keyword parameter.
A parameter is a constant that is local to a module that can optionally be redefined on an instance. Parameters are typically used to
specify the width of variables and time delays.
2. Parameter redefinition:
Parameter values are not allowed to modify at runtime but can be modified using the defparam statement and #delay specification
with module instantiation.
‘define Macro:
The `define compiler directive is used to perform global macro substitution and remain active for all files read/compiled after the
macro definition.
it will available until another macro definition changes the value or until the macro is undefined using the `undef compiler directive.
`define WIDTH 8
to avoid redefincation `ifdef can be used,
`ifdef WIDTH
// do nothing (better to use `ifndef)
`else
`define WIDTH 8
`endif
`ifndef WIDTH
`define WIDTH 8
`endif
`ifdef TYPE_1
`define WIDTH 8
`else
32
SYSTEM VERILOG
`define WIDTH 32
`endif
33