100% found this document useful (3 votes)
147 views

System Verilog Quick View New PDF

System Verilog supports various data types including structural, behavioral, fixed, and user-defined types. It allows multi-dimensional arrays that can be fixed, packed, unpacked, dynamic, or associative. Arrays support initialization, uninitialization, and manipulation methods. Common data types are integers, real numbers, parameters, enums, structures, unions, classes and queues.

Uploaded by

Mani Kumar
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (3 votes)
147 views

System Verilog Quick View New PDF

System Verilog supports various data types including structural, behavioral, fixed, and user-defined types. It allows multi-dimensional arrays that can be fixed, packed, unpacked, dynamic, or associative. Arrays support initialization, uninitialization, and manipulation methods. Common data types are integers, real numbers, parameters, enums, structures, unions, classes and queues.

Uploaded by

Mani Kumar
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

SYSTEM VERILOG

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

2.Behavioural data type:


 Integer – variables hold values range -231 to 231-1 – integer a[0-64] ->4state(0,1,x,z)
 Floating data type : Real – stores 64-bit quantities. – real float(1.43) -> syntax : real g = 1.43; shortreal h = 1.3;
Integer and real both are initialized to zero at the start time of simulation.
 Simulation data types: Syntax : time fix_time=0; realtime real_time=0;
 Time &Realtime– 64-bit quantity, $time(12) &$realtime(12.67) system task to hold simulation time.
- Time not supported for synthesis only used for simulation purpose.
 Parameter – represents constants, can modify at compilation time not at run time.
-can modify with defparam statement or in the module instance statement.
 Fixed variable 4state(0,1,x,z) Logic data type – improved version of reg, can be driven by continuous assignments,
gates and modules . Syntax : logic [3:0] a; // 4states(0,1,x,z)
3.Fixed variable 2state(0,1) datatypes :
Two state data types improve performance and memory usage over four state type.
 Bit – single bit – unsigned. bit b; signed : 2^(n-1) to( 2^(n-1)-1)
 Int – 32 bit integer – signed. int c; 8bit signed : (2^8) = -128 to 127 -> byte b =0;
 Byte – 8bit – signed byte d; Unsigned : 0 to 2^(n-1)
 Short int – 16 bit – signed shortint e; 8bit unsigned : 0 to 255 -> bit[7:0] b = 8’haf;
 Long int – 64 bit – signed longint f; Ex : longint a = 0;(signed) Ex:bit [63:0] a= 64’b0010…;(unsigned)
4. Void data type – represents non existing data. Syntax : void ‘(function_call( ));
5. String data type – it represents variable size, it dynamically allocated array of bytes. -> Syntax: string i = ”system verilog”.
6. Event – used to trigger, changes the value in variable.
event declaration examples,
event e1;
event e2;
event done;
7. User defined datatype – user can define a new type using typedef.
Syntax : typedef enum{red,orange,green,blue,yellow}colors;

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

10. Structure: Collection of different datatypes with separate memory locations


Syntax : 1) struct {bit[15:0] data; integer addr;}memory; // collection of different datatypes
memory m1,m2; //separate memory creation for m1&m2
2) typedef struct {bit[15:0] data; integer addr;}memory;
memory m1,m2;

1
SYSTEM VERILOG

11. Union: Collection of different datatypes with shared memory locations


Syntax : 1) union {bit[15:0] data; integer add; bit a; enum{b,c,d}alphabet;}memory; // collection of different datatypes
memory m1,m2; //shared memory creation for m1&m2
2)typedef union {bit[15:0] data; integer addr;}memory;
memory m1,m2;
ARRAYS: Array is collection of variables of same data type.
//$display("size of array : %0d", $size(arrayname));
//$display("value of specific element in array:%0d",arrayname[element location]);
//$display("value of all elements in array : %0p", arrayname);

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

8 Array Manipulation Methods:

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.

9) Repetitive array Operations using loops:


Array repetition can be done by using below loops
a)for loop : b) foreach loop : c) repeat loop :
module tb; module tb; module tb;
int arr[10]; //0-9 int arr[10]; //0-9 int arr[10];///0-9
int i =0; int i =0; int i =0;
initial begin initial begin initial begin
for(i= 0; i< 10; i++) begin foreach(arr[j]) begin //0---9 repeat(10) begin
arr[i] = i; arr[j] = j; //arr[j] = 5; arr[i] = i;
end end i++; end
$display("arr : %0p", arr); $display("arr : %0p", arr); $display("arr : %0p",arr);
end end end
endmodule endmodule endmodule
Result - arr : 0,1,2,3,4,5,6,7,8,9 (in all 3 loop conditions)
Array Copy Method : Array compare method :
Ex : module tb; Ex : module tb;
int array1[5]; int array1[5] = ‘{1,2,3,4,5}; //’{1,2,3,4,5}
int array2[5]; int array2[5] = ‘{1,2,3,4,5}; //’{1,2,8,4,5)
initial begin int status;
for(int i= 0; i< 5; i++) begin initial begin
array1[I] = 5*i; //0,5,10,15,20 status = (array1 == array2);
end $display("status : %0d", status);
array2 = array1; //copy elements from array1 to array2 end
$display("arrar1 : %0p", array1); endmodule
$display("arrar2 : %0p", array2); Result : status : 1 (if equal) or status : 0(if not equal)
end Result : array 1 : 0,5,10,15,20 //status = (array1 != array2);
endmodule array 2 : 0,5,10,15,20 Result : status : 1 (if not equal) 0r status : 1 (if equal)

3
SYSTEM VERILOG

PROCEDURAL STATEMENTS AND CONTROL FLOW:

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

2. Non-blocking assignment - statements executes in parallel.


Ex1 : 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 10 at initial execution
b <= 20; //After Assigning b= 20 :: Value of b is 15 at initial execution
end
Result : End of Simulation :: Value of a is 15
End of Simulation :: Value of b is 20
Ex2 : int a,b;
int x,y; Result:
initial begin //Value of x is 0
a = 10; //Value of y is 0
b = 15; //End of Simulation :: Value of x is 25
x <= a + b; //End of Simulation :: Value of y is 25
y <= a + b + x;
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

8. for loop – Enhanced for loop


1. declaration of loop variable within the for loop.
2. one or more initial declaration or assignment within the for loop.
3. one or more step assignment within the for loop.
Syntax :for(initialization; condition; modifier) begin Ex1 : initial begin //declaration of a loop variable within the for loop.
statement1 for(int i=0;i<5;i++)
statement2 $display("\t Value i=%0d",i);
Statementn end Result : Value i=0,Value i=1,Value i=2,Value i=3,Value i=4
end
Ex2 :initial begin //declaration and initialization of 2variables i,j in for loop
for ( int j=0,i=4;j<8;j++) begin Ex3 : initial begin //use of j++ and i– within the for loop.
if(j==i) for( int j=0,i=7;j<8;j++,i--) begin
$display("\tValue j=%0d equal to Value i=%0d",j,i); $display("\tValue j=%0d Value i=%0d",j,i);
end Result : Value j=4 equals to Value of i=4 end
end Result : Value j=0 Value of i=7
Value j=1 Value of i=6
Value j=2 Value of i=5
Value j=3 Value of i=4
Value j=4 Value of i=3
Value j=5 Value of i=2
Value j=6 Value of i=1
Value j=7 Value of i=0
9. repeat loop - It will execute the statements within the loop for loop variable number of times.
Ex : int a;
initial begin
repeat(4) begin //repeat for 4loops
$display("\tValue a=%0d",a);
a++; end
end Result :Value a=0,Value a=1,Value a=2,Value a=3.
10. forever loop – It executes the statements inside the loop forever
Ex :int a;
initial begin
forever begin
$display("\tValue a=%0d",a); Result : Value a=0,Value a=1,Value a=2,Value a=3.
a++; $finish at simulation time 20
#5; end
end
initial begin
#20 $finish; //$finish simulation ends at #20 time
end

5
SYSTEM VERILOG

11. break – execution of break statement leads to end of the loop.


Ex : int i;
initial begin
i = 8;
while(i!=0) begin
$display("\tValue of i=%0d",i); Result : Value i=8,Value i=7,Value i=6,Value i=5,Value i=4
if(i == 4) begin
break;end //execution will break when value i=4
i--; end
end

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)

14 .Named Blocks & Statement Blocks :


Syntax : initial begin
begin : block_name
$display("This is a block_name_bg1");
end : block_name

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.

15 . Disable Blocks & Disable statements : used to disable blocks or statements.


Ex : initial
begin : break_block
i=0;
forever begin
if(i==a)
disable break_block;
#10 i=i+1;
end
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 AND FUNCTIONS:


Tasks and functions provide a means of splitting code into small parts.

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.

2)this keyword - used to refer to class properties.


this keyword - shall only be used within non-static class methods
this keyword - refers to the object handle in which it is invoked
Ex : class packet;
bit [31:0] addr;
bit write;
function new(bit [31:0] addr,data,bit write,string pkt_type); //constructor
this.addr = addr; //addr =addr; //Result :addr = 0 //if addr=addr and write= write then values will not be assigned
this.write = write; //write = write; write = 0 properly.
endfunction
function void display(); //method to display class prperties
$display("\t addr = %0h",addr);
$display("\t write = %0h",write);
endfunction
endclass
module sv_constructor; Result : addr = 10
packet pkt; write = 1
initial begin
pkt = new(32'h10,1);
pkt.display();
end
endmodule

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

rand bit [3:0] end_addr;


constraint addr_1_range { addr inside {[start_addr:end_addr]}; } //addr will get random values with in range of startaddr &endaddr
//constraint addr_1_range { !(addr inside {[start_addr:end_addr]}); } //addr will get the random value outside the range start_addr
endclass and end_addr. this is done by using negation or invert operator (!)
module constr_insideoperator;
initial begin Result : start_addr = 12,end_addr = 15
packet pkt; addr =13 //output within range of start_addr & end_arrd
pkt = new(); Result : start_addr = 12,end_addr = 15
repeat(3) begin addr =9 //output outside the range of start_addr & end_arrd
$display("\tsrt_addr=%0d,end_addr=%0d",pkt.start_addr,pkt.end_addr);
$display("\taddr = %0d",pkt.addr);
end
end
endmodule

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.

constraint end_addr_c { end_addr == e_addr(start_addr); }

function bit [3:0] e_addr(bit [3:0] s_addr);

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,

for example, constraining a < 10 in parent class and

19
SYSTEM VERILOG

constraining a > 10 in child class or inline constraint.

conflicts in constraints leads to an randomization failure. this kind of problems can be avoided using soft constraints.

constraint c_name { soft variable { condition }; }

12. Bidirectional constraints – System Verilog constraints solved bidirectionally, which means constraints on all random variables will
be solved parallel.

RANDOM SYSTEM FUNCTIONS

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.

2. $random() - $random() is same as $urandom() but it generates signed numbers.

3. $urandom_range() - The $urandom_range() function returns an unsigned integer within a specified range.

$urandom_range( int unsigned maxval, int unsigned minval = 0 );


addr1 = $urandom_range(30,20);

SYNCHRONIZATION AND COMMUNIACTION MECHANISAMS

The process through which processes communicate/synchronizes each other is known as Inter Process
Communication/synchronization.

1.Semaphore:

semaphores are used for shared resources asses control.

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.

creating a semaphore is:


semaphore semaphore_name;
Semaphore is a built-in class that provides the following methods:
 new() - Create a semaphore with a specified number of keys - the default number of keys is ‘0’
 get() - Obtain one or more keys from the bucket - The default number of keys is 1.
 put() - Return one or more keys into the bucket - The default number of keys is 1.
 try_get() - Try to obtain one or more keys without blocking - The default number of keys is 1.

2. mailbox:

A mailbox is a communication mechanism that allows messages to be exchanged between processes.


The process which wants to talk to another process posts the message to mailbox , which stores the messages temporarily in a system
defined memory object, to pass it to the desired process.

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.

There are two types of mailboxes,


1. Generic Mailbox (type-less mailbox)
The default mailbox is type-less, that is, a single mailbox can send and receive any type of data.
mailbox mailbox_name;

2. Parameterized mailbox (mailbox with particular type)


mailbox is used to transfer a particular type of data.
mailbox#(type) mailbox_name;

Mailbox is a built-in class that provides the following methods:


Below Methods are applicable for both Generic and Parameterized mailboxes
new(); - Create a mailbox
put(); - Place a message in a mailbox
try_put(); - Try to place a message in a mailbox without blocking
get(); or peek(); - Retrieve a message from a mailbox
try_get(); or try_peek(); - Try to retrieve a message from a mailbox without blocking
num(); - Returns the number of messages in the mailbox

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.

The syntax for the program block is,


program test (input clk, input [7:0] addr, output [7:0] wdata);
...
endprogram

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

 An interface can be instantiated hierarchically like a module, with or without ports.


interface_name inst_name;
 Interface can have parameters, constants, variables, functions and tasks.
Advantages of interface over the traditional connection,
 allows number of signals to be grouped together and represented as a single port, single port handle is passed instead of
multiple signal/ports.
 interface declaration is made once and the handle is passed across the modules/components.
 addition and deletion of signals is easy.

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.

9. Input and output skews:


Input (or inout) signals are sampled at the designated clock event. If an input skew is specified then the signal is sampled at skew time
units before the clock event. Similarly, output (or inout) signals are driven skew simulation time units after the corresponding clock
event.

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.

10. Clocking block events:


The clocking event of a clocking block is available directly by using the clocking block name, regardless of the actual clocking event used
to declare the clocking block.
The clocking event of the cb clocking block can be used to wait for that particular event:
@( cb );
The above statement is equivalent to @(posedge clk).

11. cycle delay:##


The ## operator can be used to delay execution by a specified number of clocking events, or clock cycles.

SYSTEM VERILOG ASSERTIONS

1.Building blocks of SVA:

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.

The steps involved in the creation of a SVA checker,

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

1. Sequence with logical relationship:


Below sequence seq_2 checks that on every positive edge of the clock, either signal "a" or signal "b" is high. If both the signals are
low, the assertion will fail.
sequence seq_2;
@(posedge clk) a || b;
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_lib (a, b)


a || b ;
endsequence

3. sequence with timing relationship:


In SVA, clock cycle delays are represented by a "##" sign. For example, ##2 means 2 clock cycles.
For the signal "a" being high on a given positive edge of the clock. If signal "a" is not high, then the sequence fails. If signal "a" is high
on any given positive edge of clock, then signal "b" should be high 2 clock cycles after that. If signal "b" is not asserted after 2 clock
cycles, the assertion fails.

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.

A clock can be specified in a sequence, in a property or even in an assert statement.


clock defined in the sequence definition:

Clock defined in the property definition:


sequence seq;
a ##2 b;
endsequence

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.

There are 2 types of implication:

 Overlapped implication
 Non-overlapped implication

25
SYSTEM VERILOG

1.Overlapped implication - Overlapped implication is denoted by the symbol |->.

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);

2. Non-overlapped implication - 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.
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:

1. $rose - $rose(Boolean expression or signal name)

returns true if the least significant bit of the expression changed to 1. Otherwise, it returns false.

sequence seq_rose;

@(posedge clk) $rose(a);

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;

@(posedge clk) b |-> ($past(a,2) == 1);

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;

@(posedge clk) b |-> ($past(a,2,c) == 1);

endproperty

a: assert property(p);

6. Built-in system functions:

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.

3. $isunknown(expression) - checks if any bit of the expression is X or Z.

4. $countones(expression) - counts the number of bits that are high in a vector.

a_1: assert property( @(posedge clk) $onehot(state) );

a_2: assert property( @(posedge clk) $onehot0(state) );

a_3: assert property( @(posedge clk) $isunknown(bus) ) ;

a_4: assert property( @(posedge clk) $countones(bus)> 1 );

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_3 checks if any bit of the vector "bus" is X or Z.

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.

This is expressed by attaching the keyword "ended" to a sequence name.

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.

SYSTEM VERILOG COVERAGE

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.

There are two types of coverage metrics.


 Code Coverage
 Functional Coverage

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.

There are two types of functional coverage,

 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.

Defining the coverage model:


Coverage model is defined using 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 covergroup instance can be created via the new()operator. A covergroup can be defined in 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
Defining coverage points:
A covergroup can contain one or more coverage points. A coverage point can be an integral variable or an integral expression. Each
coverage point is associated with “bin”. On each sample clock simulator will increment the associated bin value.

The bins will automatically created or can be explicitly defined.

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;

covergroup cg @(posedge clk);


c1: coverpoint addr;
c2: coverpoint wr_rd;
endgroup : cg
cg cover_inst = new();
...
endmodule

Below are the bins, will get created automatically,


for addr: c1.auto[0] c1.auto[1] c1.auto[2] … c1.auto[255]
for wr_rd: c2.auto[0]

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.

covergroup cg @(posedge clk);


c1: coverpoint addr { bins b1 = {0,2,7};
bins b2[3] = {11:20};
bins b3 = {[30:40],[50:60],77};
bins b4[] = {[79:99],[110:130],140};
bins b5[] = {160,170,180};
bins b6 = {200:$};
bins b7 = default;}
c2: coverpoint wr_rd {bins wrd};
endgroup : cg

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

4. Ignore bins - A covergroup cg @(posedge clk); set of values or


transitions c1: coverpoint addr{ bins b1 = (10=>20=>30); associated with a
coverage-point bins b2[] = (40=>50),(80=>90=>100=>120); can be explicitly
excluded from bins b3 = (1,5 => 6, 7);} coverage by
covergroup cg @(posedge clk);
specifying them c2: coverpoint wr_rd; as ignore_bins.
c1: coverpoint addr{ ignore_bins b1 = {6,60,66};
endgroup : cg
ignore_bins b2 = (30=>20=>10); }
endgroup : cg
bins b1 = (10=>20=>30); // transition from 10->20->30
bins b2[] = (40=>50),(80=>90=>100=>120); // b2[0] = 40->50 and b2[1] = 80->90->100->120
bins b3 = (1,5 => 6, 7);} // b3 = 1=>6 or 1=>7 or 5=>6 or 5=>7

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.

covergroup cg @(posedge clk);


c1: coverpoint addr{ illegal_bins b1 = {7,70,77};
ignore_bins b2 = (7=>70=>77);}
endgroup : cg

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.

Cross coverage by cover_point name:

bit [3:0] a, b;
covergroup cg @(posedge clk);
c1: coverpoint a;
c2: coverpoint b;
c1Xc2: cross c1,c2;
endgroup : cg

Cross coverage by variable name:


bit [3:0] a, b;
covergroup cov @(posedge clk);
aXb : cross a, b;
endgroup
In the above example, each coverage point has 16 bins, namely auto[0]...auto[15]. The cross of a and b (labelled aXb), therefore, has
256 cross products, and each cross product is a bin of aXb.

Cross coverage between variable and expression:

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.

coverage options can be used as below,

covergroup cg @(posedge clk);


c1: coverpoint addr { option.auto_bin_max = 128;}
c2: coverpoint wr_rd { option.atleast = 2;}
c1Xc2: cross c1, c2 { option.cross_auto_bin_max = 128;}
SYSTEM endgroup : cg VERILOG PARAMETERS AND ‘define

There are two ways to define constants:

 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 can be used as if..else

`ifdef TYPE_1
`define WIDTH 8
`else

32
SYSTEM VERILOG

`define WIDTH 32
`endif

33

You might also like