System Verilog Quick View 4pages
System Verilog Quick View 4pages
DATA TYPES: 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
1.Structural data type:Hardware
memory m1,m2; //shared memory creation for m1&m2
Wire or Net 1)drives the values 2) wire default value is z 3)used for continuous assignment
2)typedef union {bit[15:0] data; integer addr;}memory;
Reg : 1) stores the values 2) reg default value is x unknown 3) 3)used for procedural assignment
memory m1,m2;
ARRAYS: Array is collection of variables of same data type.
2.Behavioural data type:
//$display("size of array : %0d", $size(arrayname));
Integer – variables hold values range -231 to 231-1 – integer a[0-64] ->4state(0,1,x,z)
//$display("value of specific element in array:%0d",arrayname[element location]);
Floating data type : Real – stores 64-bit quantities. – real float(1.43) -> syntax : real g = 1.43; shortreal h = 1.3; //$display("value of all elements in array : %0p", arrayname);
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; 1. Fixed size array – array size will be constant throughout the simulation. Default initialized to 0. -Int a[6].
Time &Realtime– 64-bit quantity, $time(12) &$realtime(12.67) system task to hold simulation time. int array[6]; //fixed size compact single dimension array -> int array[6] : integer arrayname[array locations or size of array];
- Time not supported for synthesis only used for simulation purpose. int array[5:0]; //fixed size verbose single dimension array //bit array1[8]; (mention size 8, so can assign 8elements to array1 )
Parameter – represents constants, can modify at compilation time not at run time. 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
-can modify with defparam statement or in the module instance statement. automatically consider as 4 for array2)
Fixed variable 4state(0,1,x,z) Logic data type – improved version of reg, can be driven by continuous assignments, 2. Packed array – values store in same memory location. Dimensions declare before the object name.
gates and modules . Syntax : logic [3:0] a; // 4states(0,1,x,z) Stored as a continuous set of bits with no unused space, may be used for serial data transfer(or)storage.
3.Fixed variable 2state(0,1) datatypes : Syntax: Bit [2:0] [7:0] array1
Two state data types improve performance and memory usage over four state type. 3. Unpacked array – Dimensions declared after the object name. Values store in different locations, non-continuous set of bits.
Bit – single bit – unsigned. bit b; signed : 2^(n-1) to( 2^(n-1)-1) Syntax: Bit [7:0] array1 [2:0]
Int – 32 bit integer – signed. int c; 8bit signed : (2^8) = -128 to 127 -> byte b =0; 4. Dynamic array – one dimension of an unpacked array whose size can be set or changed at run time. Space
Byte – 8bit – signed byte d; Unsigned : 0 to 2^(n-1) doesn’t exist until the array is created at run time.
Short int – 16 bit – signed shortint e; 8bit unsigned : 0 to 255 -> bit[7:0] b = 8’haf; Syntax : bit[7:0] array1[ ]; // datatype arrayname[ ]; ->null declaration, so no need to mention dimensions for dynamic array.
Long int – 64 bit – signed longint f; Ex : longint a = 0;(signed) Ex:bit [63:0] a= 64’b0010…;(unsigned) int array2[ ]; Ex : int array3[ ];
4. Void data type – represents non existing data. Syntax : void ‘(function_call( )); Methods: New[] --> allocates the storage. // array3 = new[10]; //will get size of 10
5. String data type – it represents variable size, it dynamically allocated array of bytes. -> Syntax: string i = ”system verilog”. Size () --> returns the current size of dynamic array. // array3 = new[10]; //delete size 10 and create new size 30
6. Event – used to trigger, changes the value in variable. Delete() --> empties the array, resulting in a zero-sized array. //array3 = new[30](array3); //complete size is 40 (10+30)
event declaration examples, 5. Associative array – Allocate memory only when it is used. Used when the size of the collection is unknown it is better option. It
event e1; stores entries in sparse(scattered or disorgnized form) matrix.
event e2; Syntax : Int array1[*]; *(wildcard entry declaration ) represents unspecified index // datatype arrayname[index type]
event done; bit [31:0] array2[string]; // 32-bit array with string as index
7. User defined datatype – user can define a new type using typedef. array2[“header”] = 32’h65;
Syntax : typedef enum{red,orange,green,blue,yellow}colors; array2[“payload”] = 32’h34;
array2[“tail”] = 32’h25;
8. Enumeration data type – defines set of named values, contains list of names or one/more variables. Associative Array Methods:
Syntax : enum{red,orange,green,blue,yellow}colors; num() --> returns the number of entries in the associative array.
Enum methods : delete(index) --> removes the entry at the specified index. EX: a_array.delete(index).
first() -> returns the value of the first member of the enumeration exists(index) --> returns 1 if an element exists at the specified index else returns 0.
last() -> returns the value of the last member of the enumeration first(var) --> assigns the value of first index to the variable var.
next() -> returns the value of next member of the enumeration last(var) --> assigns the value of last index to the variable var.
next(var) --> assigns the value of next index to the variable var.
next(N) -> returns the value of next Nth member of the enumeration
prev(var) --> assigns the value of previous index to the variable var.
prev() -> returns the value of previous member of the enumeration
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
prev(N) -> returns the value of previous Nth member of the enumeration 2)Repetitive operator -> int array[3] = ‘ {3{2}}; //so size is 3 all the 3elemets are only 3->{3,3,3} because of repetition
num() -> returns the number of elements in the given enumeration 3)default value to array -> int array[3] = ‘ {default :5}; //all 3location values are {5,5,5}
name() -> returns the string representation of the given enumeration value 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
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 and shrink, queues support adding and removing elements anywhere.
properties, and its subroutines are called methods. Class is declared using class and endclass keywords. Syntax: 1) bit queue1[$]; // queue of bits -> datatype queuename[$], $ represents queue entries
Syntax : Class name; 2) Int queue2[$]; //queue of int
Properties(varable declaration); 3) Byte queue3[$-255]; //queue of byte with maximum size of 256 entries
Methods(functions & tasks); 4) String queue4[$]; //queue of strings
Endclass Queue Methods: size() --> returns the number of items in the queue.
insert() --> inserts the given item at the specified index position.
10. Structure: Collection of different datatypes with separate memory locations delete() --> deletes the item at the specified index position.
Syntax : 1) struct {bit[15:0] data; integer addr;}memory; // collection of different datatypes push front() --> inserts the given element at the front of the queue.
memory m1,m2; //separate memory creation for m1&m2 pushback() --> inserts the given element at the end of the queue.
2) typedef struct {bit[15:0] data; integer addr;}memory; pop front() --> removes and returns the first element of the queue.
pop back() --> removes and returns the last element of the queue.
memory m1,m2;
1 2
d) Array iterator index querying- this method operate on both index and element, 3. Unique if - Evaluates all the conditions parallel. Simulator issue a run time error/warning in following conditions:
array1.find with ( item == item.index ); // returns the array element whose value is equal to the index value. 1. More than one condition is true.
array1.find(item) with ( item > item.index); //returns the array element whose value is greater than the index value. 2. No condition is true /false if doesn’t have corresponding else.
Ex1 : int a,b,c; //variable declaration Ex2 : int a,b,c;
9) Repetitive array Operations using loops: initial begin initial begin
Array repetition can be done by using below loops a=10; b=20; c=40; a=50; b=20; c=40;
a)for loop : b) foreach loop : c) repeat loop : unique if ( a < b ) $display("\t a is less than b"); unique if ( a < b ) $display("\t a is less than b");
module tb; module tb; module tb; else if ( a < c ) $display("\t a is less than c"); else if ( a < c ) $display("\t a is less than c");
int arr[10]; //0-9 int arr[10]; //0-9 int arr[10];///0-9 else $display("\t a is greater than b and c"); end
int i =0; int i =0; int i =0; end Result :RT Warning: No condition matches in 'unique if' statement
initial begin initial begin initial begin Result : a is less than b
for(i= 0; i< 10; i++) begin foreach(arr[j]) begin //0---9 repeat(10) begin
RT Warning: More than one conditions match in 'unique if' statement.
arr[i] = i; arr[j] = j; //arr[j] = 5; arr[i] = i;
end end i++; end 4. Priority if – It evaluates all the conditions in sequential order. Simulator issue a run time error/warning in the following conditions:
$display("arr : %0p", arr); $display("arr : %0p", arr); $display("arr : %0p",arr); 1. No condition is true /false if doesn’t have corresponding else.
end end end Ex1 : int a,b,c; //variable declaration Ex2 : int a,b,c;
endmodule endmodule endmodule initial begin initial begin
Result - arr : 0,1,2,3,4,5,6,7,8,9 (in all 3 loop conditions) a=10; b=20; c=40; a=50; b=20; c=40;
Array Copy Method : Array compare method : priority if ( a < b ) $display("\t a is less than b"); priority if ( a < b ) $display("\t a is less than b");
Ex : module tb; Ex : module tb; else if ( a < c ) $display("\t a is less than c"); else if ( a < c ) $display("\t a is less than c");
int array1[5]; int array1[5] = ‘{1,2,3,4,5}; //’{1,2,3,4,5} else $display("\t a is greater than b and c"); end
int array2[5]; int array2[5] = ‘{1,2,3,4,5}; //’{1,2,8,4,5) end Result :RT Warning: No condition matches in 'Priority if' statement
initial begin int status; Result : a is less than b
for(int i= 0; i< 5; i++) begin initial begin
array1[I] = 5*i; //0,5,10,15,20 status = (array1 == array2); 5. do while - It is a flow control statement that allows code to be executed repeatedly based on given condition.
end $display("status : %0d", status); Syntax : do begin Ex1 : int a; // Result1 : Value of a=0,a=1,a=2, a=3, a=4
array2 = array1; //copy elements from array1 to array2 end statement 1 initial begin //statements will execute until condition is false
$display("arrar1 : %0p", array1); endmodule statement 2 do begin Ex2 : while(a>5); //Result2 : Value of a=0
$display("arrar2 : %0p", array2); Result : status : 1 (if equal) or status : 0(if not equal) statement n $display("\tValue of a=%0d",a); end
end Result : array 1 : 0,5,10,15,20 //status = (array1 != array2); end a++; end // atleast one time statement will execute,even though
endmodule array 2 : 0,5,10,15,20 Result : status : 1 (if not equal) 0r status : 1 (if equal) while(condition) while(a<5); if condition is false in do while loop
end
3 4
SYSTEM VERILOG 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 11. break – execution of break statement leads to end of the loop.
statement 1 initial begin //statements will execute until condition is false Ex : int i;
statement 2 while(a<5) begin Ex2 : while(a>5) begin //Result2 : Value of a=0 initial begin
statement n $display("\tValue of a=%0d",a); end i = 8;
end a++; end // no statements will execute, if condition is false while(i!=0) begin
end in while loop $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
6. foreach loop - It specifies iteration over the elements of the array. Loop variable is considered based on elements of an array and break;end //execution will break when value i=4
no.of loop variable must match the no.of dimensions of the array. Foreach loop iterates through each index starting from index 0. i--; end
Syntax : foreach(<variable>[<iterator>]]) begin EX1 : int a[4]; end
statement1 initial begin
statement2 foreach(a[i]) a[i] = i;//foreach loop deceleration for”single dimensional array” 12. continue–execution of continue statement leads to skip the execution of statements followed by continue and jump to next loop.
Statementn foreach(a[i]) $display("\tValue a[%0d]=%0d",i,a[i]); Ex : initial begin Result : After Continue :: Value of i=0
end end Result : Value a[0]=0,Value a[1]=1,Value a[2]=2,Value a[3]=3. for(int i=0;i<8;i++) begin After Continue :: Value of i=1
Ex2 : int a[3][2]; if((i > 2) && (i < 7))begin After Continue :: Value of i=2
initial begin continue; end After Continue ::
foreach(a[i,j]) a[i][j] = i+j; //foreach loop deceleration for “ multidimensional array” $display("\t\tAfter Continue\t:: Value of i=%0d",i); After Continue ::
foreach(a[i,j]) $display("\tValue a[%0d][%0d]=%0d",i,j,a[i][j]); end After Continue ::
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 end After Continue ::
After Continue :: Value of i=7
8. for loop – Enhanced for loop
1. declaration of loop variable within the for loop. 13 . event control – Any change in a variable or a net can be detected using the @ event control.
2. one or more initial declaration or assignment within the for loop. Syntax : always @(*) , always @(posedge clk), always @(negedge clk), always @(posedge clk iff reset == 0)
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. 14 .Named Blocks & Statement Blocks :
statement1 for(int i=0;i<5;i++) Syntax : initial begin
statement2 $display("\t Value i=%0d",i); begin : block_name
Statementn end Result : Value i=0,Value i=1,Value i=2,Value i=3,Value i=4 $display("This is a block_name_bg1");
end end : block_name
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. statement_name :begin
if(j==i) for( int j=0,i=7;j<8;j++,i--) begin $display("This is a statement_name_bg1");
$display("\tValue j=%0d equal to Value i=%0d",j,i); $display("\tValue j=%0d Value i=%0d",j,i); end : statement_name
end Result : Value j=4 equals to Value of i=4 end end
end Result : Value j=0 Value of i=7 Statement labels are useful in reporting and debugging so that you have a label associated with a single statement instead of a
Value j=1 Value of i=6 filename/line number without having to wrap it in a begin/end block. It also gives your code visibility into the variables declared
Value j=2 Value of i=5 inside a for/foreach loop.
Value j=3 Value of i=4 Ex : "label: statement" is equivalent to "begin: label statement end : label"
Value j=4 Value of i=3 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
Value j=5 Value of i=2 insert an extra begin/end.
Value j=6 Value of i=1
Value j=7 Value of i=0 15 . Disable Blocks & Disable statements : used to disable blocks or statements.
9. repeat loop - It will execute the statements within the loop for loop variable number of times. Ex : initial
Ex : int a; begin : break_block
initial begin i=0;
repeat(4) begin //repeat for 4loops forever begin
$display("\tValue a=%0d",a); if(i==a)
a++; end disable break_block;
end Result :Value a=0,Value a=1,Value a=2,Value a=3. #10 i=i+1;
10. forever loop – It executes the statements inside the loop forever end
Ex :int a; end
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 6
7 8
SYSTEM VERILOG 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 CLASSES
subroutine, those changes will not be visible outside the subroutine. 1)A class is a user defined data type that includes data (class properties), functions and tasks(class methods) that operate on data.
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 classes allow objects to be dynamically created, deleted, assigned, and accessed via object handles.
function int sum(int x,y); function is not visible outside. Ex : class sv_class; //class declaration has one data property x and two methods set and get.
x = x+y; //x=20+30 = 50 int x; //class properties
return x+y; task set(int i); //method-1
endfunction
x = i;
initial begin
x = 20; endtask
y = 30; function int get(); //method-2
z = sum(x,y); //z = sum(50+30) -> 80 //x=x+y value is 50 from function return x;
$display("\tValue of x=%0d,y=%0d,z=%0d", x,y,z); endfunction
end Result : x=20, y=30, z=80 endclass
sv_class pkt; //Class declaration or Class Instance
2. Argument pass by reference - reference to the original argument is passed to the subroutine. as the argument with in subroutine pkt = new( ); //class properties and methods can be accessed only after creating the object.
is pointing to an original argument, any changes to the argument with in subroutine will be visible outside. To indicate argument pass sv_class pkt = new(); //this statement will do both declarations of variable and object creation.
by reference, the argument declaration is preceded by keyword ref.
Ex1 : int x,y,z; Ex2 : argument pass by reference with const keyword 2)this keyword - used to refer to class properties.
function int sum(ref int x,y); function int sum(const ref int x,y); this keyword - shall only be used within non-static class methods
this keyword - refers to the object handle in which it is invoked
x = x+y; //x=20+30 = 50 Result : Variable 'x' declared as 'const' cannot be used in this context
Ex : class packet;
return x+y; Source info: x = (x + y); 1error
bit [31:0] addr;
endfunction //variables x and y are passed as an argument in the function call sum, changes to the argument x within the bit write;
initial begin function, is visible outside. function new(bit [31:0] addr,data,bit write,string pkt_type); //constructor
x = 20; this.addr = addr; //addr =addr; //Result :addr = 0 //if addr=addr and write= write then values will not be assigned
y = 30; this.write = write; //write = write; write = 0 properly.
z = sum(x,y); //z = sum(50+30) -> 80 // x=x+y value is 50 from function endfunction
$display("\tValue of x=%0d,y=%0d,z=%0d", x,y,z); function void display(); //method to display class prperties
end Result : x=50, y=30, z=80 $display("\t addr = %0h",addr);
Any modifications to the argument value in pass by reference can be avoided by using const keyword before ref, any attempt in $display("\t write = %0h",write);
changing the argument value in subroutine will lead to compilation error(see Ex2 above) endfunction
endclass
3. default argument value - default value can be specified to the arguments of subroutine. In the subroutine call, arguments with module sv_constructor; Result : addr = 10
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 packet pkt; write = 1
considered. initial begin
Ex : int q; // variables x, y and z of the subroutine has a default value of 1,2 and 3 respectively pkt = new(32'h10,1);
function int sum(int x=5,y=10,z=20); pkt.display();
return x+y+z; end
endmodule
endfunction
initial begin
3) class constructs – the new function is called as class constructor. On calling the new() allocates memory, returns the address to the
q = sum( , ,10); $display("\tValue of q = %0d",q); // value passed only for z, x and y will take the default value. class handle and initialize the variables to default value.
q = sum(3, ,30); $display("\tValue of q = %0d",q); // values passed for x, z and y will take the default value. default value – 0 for 2 state variables.
q = sum(1,1); $display("\tValue of q = %0d",q); // values passed for x,y and z will take the default value. X for 4 state variables.
q = sum(); $display("\tValue of q = %0d",q); // value not passed so x,y,z will take the default value. 1)The new operation is defined as a function with no return type
end Result : Value q=25, Value q=43, Value q=22, Value q=35 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. pass by name - In argument pass by name, arguments can be passed in any order by specifying name of the subroutine argument.
4)The constructor can be used for initializing the class properties. In case of any initialization required, those can be placed in the
Ex : module argument_passing;
constructor and It is also possible to pass arguments to the constructor, which allows run-time customization of an object.
int x,y,z,a;
Ex : class packet; $display("\t write = %0d",write);
functio void display(int x=1, y=1, z=1, a=1); Function main points to remember :
bit [31:0] addr; endfunction
$display("\tValue of x=%0d, y=%0d, z=%0d a=%0d", x,y,z,a); 1) default “begin-end” block
bit write; endclass
Endfunction 2) contains “return” keyword
function new(); //constructor module sv_constructor; Result : addr =16 & write=1
initial begin 3) default arguments are “inputs”
addr = 32'h10; packet pkt;
display(6,7,8,9); //Value of x=6, y=7, z=8 a=9 4) output declaration is possible
write = 1; initial begin
display(); //Value of x=1, y=1, z=1 a=1 5) contains “void” as return type
Endfunction pkt = new();
display(.z(10)); //Value of x=1, y=1, z=10 a=1 6) support default arguments to formal arguments
function void display(); pkt.display(); end
display(,12,.a(25)); //Value of x=1, y=12, z=1 a=25 7) passing arguments by name,value and by reference
$display("\t addr = %0d",addr); endmodule
end 8) Function cannot have delays , only task has delays
endmodule
9 10
4)static class properties – created by using keyword static. Static properties will be created once and all the class objects will access 7) deep copy - Users has to write the copy method for deep copy. On calling the copy method, new memory will be allocated new
the same. 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;
static methods - same as static properties, static method can access only static properties of the class and access to the non-static int a = 12; packet pkt_1;
properties is illegal and lead to compilation error. Note :: static class properties and methods can be used without creating an object int b = 15; packet pkt_2;
of that type. function packet copy(); initial begin
copy=new(); pkt_1 = new();
copy.a=this.a; pkt_1.display(); //a=12, b=15
5)class assignment – object will be created only after doing new to an class handle. With the assignment both the objects will point to copy.b=this.b; pkt_2 = new();
the same memory. Any changes made with-respect to one packet will reflect on other. return(copy); pkt_2.display(); //a=12, b=15
Ex : class packet; endfunction pkt_1.a = 50; pkt_1.display(); //a=50, b=60
bit [31:0] addr; function void display(); pkt_1.a = 60; pkt_2.display(); //a=30, b=40
bit [31:0] data; $display("\t a= %0d",a); pkt_2=pkt_1.copy; end
function new(); $display("\t b= %0d",b); pkt_2.display(); //a=50, b=60 endmodule
addr = 32'h10; endfunction pkt_2.a = 30;
data = 32'hFF; endclass pkt_2.b = 40;
endfunction
function void display(); 7. parameterised class - parameters are like constants local to that particular class. default values can be overridden by passing a new
$display("\t addr = %0d",addr); set of parameters during instantiation. this is called parameter overriding.
$display("\t data = %0h",data); Ex : class packet #(parameter int ADDR_WIDTH = 32,DATA_WIDTH = 32);
endfunction bit [ADDR_WIDTH-1:0] address;
endclass bit [DATA_WIDTH-1:0] data ;
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 function new();
address = 10;
packet pkt_1; // because both shares same memory
data = 20; //packet p1 -> creates pkt handle with default ADDR_WIDTH and DATA_WIDTH values
packet pkt_2; endfunction This default parameter value can be overridden when the class is instantiated.
initial begin endclass //packet #(32,64) pkt; –> creates pkt handle with ADDR_WIDTH = 32 and DATA_WIDTH = 64.
pkt_1 = new(); Result :
pkt_1.display(); // addr = 16, data =ff 9. classes inheritance - New classes can be created based on existing classes. A derived class by default inherits the properties and
pkt_2 = pkt_1; //assigning pkt_1 to pkt_2 methods of its parent or base class. the derived class may add new properties and methods or modify the inherited properties and
pkt_2.display(); // addr = 16. data =ff methods.
pkt_2.addr = 32'hAB; //changing values with pkt_2 handle base class or parent class -> existing class.
pkt_1.display(); // addr = 171, data =ff derived class or child class -> New class.
pkt_1.addr = 32'hAF; //changing values with pkt_1 handle Ex : class parent_class;
pkt_2.display(); // addr = 175, data =ff bit [31:0] addr;
end endclass
endmodule class child_class extends parent_class;
bit [31:0] data;
endclass
6)shallow copy - class properties were copied from pkt_1 to pkt_2 this is called as "shallow copy".
module inheritence;
Shallow copy allocates the memory, copies the variable values and returns the memory handle. In shallow copy All of the variables are
initial begin
copied across: integers, strings, instance handles, etc. changes made in pkt1 will not reflect on pkt2 bcz both share different memories. child_class c = new();
Note: Objects will not be copied, only their handles will be copied. c.addr = 10;
Ex : class packet; c.data = 20;
int a = 12; $display("Value of addr = %0d data = %0d",c.addr,c.data); Result : Value of addr = 10 and data = 20
int b = 15; end
function void display(); endmodule
$display("\t a = %0d",a);
$display("\t b = %0d",b); 10.overriding class members - Base class or parent class properties and methods can be overridden in the child class or extended class.
endfunction Defining the class properties and methods with the same name as parent class in the child class will override the class members.
endclass 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
module shallow;
function display(); module inheritence; //parent class method
packet pkt_1;
$display("Addr = %0d",addr); initial begin
packet pkt_2; endfunction child_class c=new(); //c is the handle to the child class, because of override calling c.
initial begin pkt_2.a = 30; //changes made by using pkt_2 will reflect on pkt_1 because both pkt_1 endclass c.addr = 10; //display will call display method of the child class, not the parent class
pkt_1 = new(); Result : pkt_2.b = 40; and pkt_2 shares different memory class child_class extends parent_class; c.data = 20;
pkt_1.display(); //a=12 , b=15 pkt_1.display(); //a=12 , b=15 bit [31:0] data; c.display(); Result : Data = 20
pkt_2 = new pkt_1; pkt_2.display(); //a=30 , b=40 function display(); end
pkt_2.display(); //a=12 , b=15 end $display("Data = %0d",data); endmodule
endmodule
11 12
SYSTEM VERILOG 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. 13. Data hiding and encapsulation - The technique of hiding the data within the class and making it available only through the methods,
Ex : class parent_class; endfunction //The parent class has the method display(). is known as encapsulation. Because it seals the data (and internal methods) safely inside the “capsule” of the class,
bit [31:0] addr; endclass //implementing method display() in the child class will override the where it can be accessed only by trusted users (i.e., by the methods of the class).
function display(); module inheritence; //parent class method to over come this calling super.display() Local class members - External access to the class members can be avoided by declaring members as local. Syntax : local integer x;
$display("Addr = %0d",addr); initial begin // this display method of the parent class can be accessed. Any violation could result in compilation error.
endfunction child_class c=new(); //c is the handle to the child class, because of override calling c. Accessing local variable outside the class ( Not allowed ) : The local variable declared inside the class is trying to access from outside
endclass c.addr = 10; . the class by using object handle. As the variable is declared as local, which leads to a compilation error.
class child_class extends parent_class; c.data = 20; Ex1 : class parent_class; Accessing local variable within the class ( Allowed ) : The local variable declared inside
bit [31:0] data; c.display(); Result : Addr=10 and Data = 20 local bit [31:0] tmp_addr; the class is being accessed inside the class. as it is allowed, no compilation error is seen
function display(); end function new(bit [31:0] r_addr); Ex2 : module encapsulation;
super.display(); endmodule tmp_addr = r_addr + 10; initial begin
$display("Data = %0d",data);
Endfunction parent_class p_c = new(5);
function display(); p_c.display();
12. Casting - Converting one datatype variable into another datatype variable.(example string to int)
$display("tmp_addr = %0d",tmp_addr); end
a) Static casting b) Dynamic casting
endfunction endmodule Result : Addr = 15
a) Static casting :
endclass
1) System Verilog static casting is not applicable to OOP
module encapsulation;
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 initial begin
4)Casting is applicable to value, variable or to an expression parent_class p_c = new(5);
5)A data type can be changed by using a cast ( ‘ ) operation p_c.tmp_addr = 20; //Accessing local variable outside the class
6)The vale/variable/expression to be cast must be enclosed in parentheses or within concatenation or replication braces p_c.display();
Ex : module casting; end //Result : Local member 'tmp_addr' of class 'parent_class'
real r_a; endmodule is not visible to scope
int i_a;
initial begin 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
r_a = (2.1 * 3.2); class members with protected keyword. Any violation could result in compilation error. Syntax : protected integer x;
i_a = int'(2.1 * 3.2); //or i_a = int'(r_a); //real to integer conversion Accessing protected variable outside the class ( Not allowed ) : The protected variable declared inside the class is trying to access
$display("real value is %f",r_a); //Note: the casting is applied to expression here. from outside the class by using object handle. As the variable is declared as protected, which leads to a compilation error.
$display("int value is %d",i_a); Result : real value is 6.720000
Ex1 :class parent_class; Accessing protected variable in the extended class ( allowed ) : The protected variable declared
End int value is 7
protected bit [31:0] tmp_addr; inside the class is being accessed inside extended class. as allowed,no compilation error seen.
Endmodule
function new(bit [31:0] r_addr); Ex2 : module encapsulation;
b) Dynamic casting : tmp_addr = r_addr + 10; initial begin
1)Dynamic casting is used to, safely cast a super-class pointer (reference) into a subclass pointer (reference) in a class hierarchy endfunction child_class c_c = new(10);
2)Dynamic casting will checked during run time,an attempt to cast an object to incompatible object will result in run-time error function display(); c_c.incr_addr(); //Accessing protected variable in extended class
3)Dynamic casting is done using the $cast(destination, source) method $display("tmp_addr = %0d",tmp_addr); c_c.display();
4)With $cast compatibility of the assignment will not be checked during compile time, it will be checked during run-time endfunction end
Usage of Dynamic casting : endclass endmodule
1)It is always legal to assign a child class variable to a variable of a class higher in the inheritance tree (parent class). class child_class extends parent_class; Result : Addr = 21
parent_class = child_class; //allowed function new(bit [31:0] r_addr);
2)It is never legal to directly assign a super-class (parent class) variable to a variable of one of its subclasses (child class). super.new(r_addr);
child_class = parent_class; //not-allowed
endfunction
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)
function void incr_addr();
handle refers to an object of the given subclass(child class).
parent_class = child_class ; tmp_addr++;
child_class = parent_class; //allowed because parent_class is pointing to child_class. endfunction
Though parent_class is pointing to child_class, we will get a compilation error saying its not compatible type for the assignment. endclass
This we can over come by make use of $cast method -> $cast(child_class,parent_class); module encapsulation;
Ex : class parent_class; module inheritence; initial begin
bit [31:0] addr; initial begin parent_class p_c = new(5);
function display(); parent_class p=new(); //in both conditions c=p and c1=p child_class c_c = new(10);
$display("Addr = %0d",addr); child_class c=new(); //Expression 'p' on rhs is not a class or a compatible class and hence p_c.tmp_addr = 10; // variable declared as protected cannot be accessed outside the class
endfunction child_class c1; // cannot be assigned to class handle on lhs p_c.display();
endclass c.addr = 10; // so make sure lkh and rhs are compatible c_c.incr_addr(); //Accessing protected variable in extended class
class child_class extends parent_class; c.data = 20; c_c.display();
bit [31:0] data; Ex1 : p = c; c.display(); //assigning childclass handle to parentclass handle Result:addr=10 ,data=20
end //Result : Protected member 'tmp_addr' of class 'parent_class' is not visible to scope 'encapsulation'.
function display(); Ex2 : c = p; c.display(); //assigning parent class handle to child class handle
endmodule
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 14
14)Abstract classes and virtual methods - SystemVerilog class declared with the keyword virtual is referred to as an abstract class. 15. scope resolution operator :: - it is used to specify an identifier defined within the scope of a class. The scope resolution operator
1)An abstract class sets out the prototype for the sub-classes. Syntax : virtual class abc; uniquely identifies a member of a particular class. Class Resolution operator allows access to static members (class properties and
2)An abstract class cannot be instantiated, it can only be derived. //Class defination methods) from outside the class, as well as access to public or protected elements of super classes from within the derived classes.
endclass Ex : class packet;
3)An abstract class can contain methods for which there are only a prototype and no implementation, just a method declaration. bit [31:0] addr;
Instantiating virtual class :In the below example, Creating an object of a virtual class. An abstract class can only be derived, static bit [31:0] id;
creating an object of a virtual class leads to a compilation error. function display(bit [31:0] a,b);
Ex : virtual class packet;//abstract class $display("Values are %0d %0d",a,b);
bit [31:0] addr; endfunction
endclass endclass
module virtual_class; module sro_class;
initial begin int id=10;
packet p; //Result : virtual_class, "p = new();" initial begin
p = new(); Instantiation of the object 'p' can not be done because its type 'packet' is packet p; Result : Values are 20 10
end an abstract base class.Perhaps there is a derived class that should be used p = new();
endmodule packet::id = 20; //A static member of the class is accessed outside the class by using class resolution operator ::
Deriving virtual class : In the below example, An abstract class is derived and written extend the class and creating it. p.display(packet::id,id);
Ex : virtual class packet; //abstract class end
bit [31:0] addr; endmodule
endclass
class extended_packet extends packet; 16. classes extern methods - The extern qualifier indicates that the body of the method (its implementation) is to be found outside
function void display; the class declaration. Before the method name, class name should be specified with class resolution operator to specify to which class
$display("Value of addr is %0d", addr); the method corresponds to. Definition of method can be written outside the body of class.
endfunction External function : The function display is declared inside the class with the extern keyword, and the definition of the function is
endclass written outside the class.
module virtual_class; Ex : class packet;
initial begin bit [31:0] addr;
extended_packet p; bit [31:0] data;
p = new(); //Result : value of addr is 10 extern virtual function void display(); //function declaration - extern indicates out-of-body declaration
p.addr = 10; endclass
p.display(); function void packet::display(); //function implementation outside class body
end $display("Addr = %0d Data = %0d",addr,data);
endmodule endfunction External task : extern virtual task display(); //task declaration - extern indicates out-of-body declaration
Virtual Methods : SystemVerilog methods declared with the keyword virtual are referred to as virtual methods. module extern_method; task packet::display();
Virtual Functions : A function declared with a virtual keyword before the function keyword is referred to as virtual Function initial begin $display("Addr = %0d Data = %0d",addr,data);
Virtual Tasks : Task declared with a virtual keyword before the task keyword is referred to as virtual task packet p; endtask
Method without virtual keyword :the method inside the base class is declared without a virtual keyword, p = new(); //same module use for external task //Result : addr=10 data=20
on calling method of the base class which is pointing to the extended class will call the base class method. p.addr = 10; Result : addr=10 data=20
Ex1 : class base_class; Method with virtual keyword : the method inside the base class is declared with a p.data = 20;
function void display; virtual keyword,on calling method of the base class which is pointing to an extended p.display();
$display("Inside base_class"); class will call the extended class method. end
endfunction Ex2 : class base_class; endmodule
endclass virtual function void display; External function with arguments -> Arguments name mismatch: Change in argument name between method declaration and
class extended_class extends base_class; $display("Inside base_class"); method definition will lead to a compilation error.
function void display; endfunction //continue code from Ex1 form class extended_class Ex1 : class packet;
$display("Inside extended class"); endclass // Result : Inside extended_class //on calling method of the base extern virtual function void display(bit [31:0] addr, data );//function declaration - extern indicates out-of-body declaration
Endfunction class which is pointing to an extended class will call the extended class method. endclass
endclass function void packet::display(bit [31:0] addr_t, data_t);//external function is declared with arguments name mismatch
module virtual_class; $display("Addr = %0d Data = %0d",addr_t,data_t);
initial begin Endfunction Ex2 : function void packet::display(bit [31:0] addr, data); //arguments name match
base_class b_c; module extern_method; Result : Addr =20, data= 30
extended_class e_c; initial begin
e_c = new(); packet p;
b_c = e_c; //Result:Inside base_class//calling method of base class which is pointing to extended class will call base class method p = new();
b_c.display(); p.display(20,30); // Result for argument name mismatch : External class method definition should match prototype declaration.
end end Argument names do not match. The signature of function 'packet::display'
endmodule endmodule
15 16
SYSTEM VERILOG 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; Constraints:- By writing constraints(control the values getting assigned on randomization) to an random variable, user can get specific
Without typedef : Both classes need the handle of each other. As execution will happen in sequential order. Since there is dependency value on randomization. constraints to an random variable shall be written in constraint blocks.
between both the classes c1 & c2 which leads to a compilation error. To overcome this define typedef class at begging 1) Constraint blocks:
Ex1 : class c1; //class-1 a)Constraint blocks are class members like tasks, functions, and variables
c2 c; // c2 is instantiated inside c1 ,using class c2 handle before declaring it. b)Constraint blocks will have a unique name within a class
endclass Ex2 : With typedef : typedef class c2; //declare typedef class before class definition c)Constraint blocks consist of conditions or expressions to limit or control the values for a random variable
class c2; //class-2 class c1; //class-1(code from here is same as Ex1) d)Constraint blocks are enclosed within curly braces { }
e)Constraint blocks can be defined inside the class or outside the class like extern methods,
c1 c; // c1 is instantiated inside c2 // Result : Inside typedef_class
f)constraint block defined outside the class is called as extern constraint block
endclass
Syntax : constraint <constraint_block_name> { <condition/expression>; Ex : constraint addr_range { addr > 5; }
module typedef_class; ...
initial begin <condition/expression>;}
c1 class1; // Result : token 'c2' should be a valid type. Please declare it virtual if it is an Interface. External constraint blocks - External constraints are Same like external class methods. constraint blocks can be defined outside the
c2 class2; class body, declaration should be with in class body.
$display("Inside typedef_class"); A)constraint block is defined inside the class : B)constraint block is declared inside the class and defined outside the class :
end class packet; class packet;
endmodule rand bit [3:0] addr; rand bit [3:0] addr;
constraint addr_range { addr > 5; } constraint addr_range; //constraint block declaration
RANDOMIZATION AND DISABLING RANDOMIZATION :Random variable will get random value on randomization. endclass endclass
class variables can be declared random using the rand and randc type-modifier keywords.Following types declared as rand and module constr_blocks; constraint packet::addr_range { addr > 5; }//constraint implementation outside class
randc. initial begin module extern_constr;
singular variables of any integral type packet pkt; initial begin
arrays pkt = new(); packet pkt; pkt = new();
arrays size
repeat(5) begin repeat(10) begin
object handle's
pkt.randomize(); pkt.randomize();
1. rand - Variables declared with the rand keyword are standard random variables. Their values are uniformly distributed over their
$display("\taddr = %0d",pkt.addr); $display("\taddr = %0d",pkt.addr);
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. end Result : addr=14,addr=10,addr=9, end Result : addr=14,addr=10,addr=9,addr=8,addr=9
2.randc: random-cyclic - Variables declared with the randc keyword, their values doesn't repeat a random value until every possible end addr=8,addr=9 end
value has been assigned. In order to randomize the object variables, need to call randomize() method.Syntax : randc bit [3:0] addr; endmodule endmodule
3. disabling random variables - The rand_mode() method can be used to disable the randomization of variable declared with 2. constraint inheritance - As class members, constraints also will get inherited from parent class to child class. in a child class,
rand/randc. Syntax:pkt.var.rand_mode(0);//randomization is disabled only for variable by calling obj.variablename.rand_mode(0); constraint blocks can be overridden by writing constraint block with same name as in parent class.
Note: Syntax : pkt.rand_mode(0); //randomization for all the class variables is disabled by calling obj.rand_mode(0); Ex : Constraint to an addr > 5 of the parent class is overridden with constraint addr < 5 in child class.
1.By default rand_mode value for all the random variables will be 1(enable) class packet; /Parent class or Base class pkt1 = new();
2.after setting rand_mode(0) to any random variable it will disable randomization of variables. rand bit [3:0] addr; pkt2 = new();
constraint addr_range { addr > 5; } repeat(5) begin
4.randomize() -The randomize() method is virtual function that generates random values for all active random variables in the object.
endclass pkt1.randomize();
Syntax : object.randomize();
class packet2 extends packet; //child class or Extended class $display("\tpkt1:: addr = %0d",pkt1.addr);
5 Pre_randomize() &post_randomize(): Every class contains built-in pre_randomize() and post_randomize() functions. on calling
constraint addr_range { addr < 5; } //overriding constraint of parent class end
randomize(), pre_randomize() and post_randomize() functions will get called before and after the randomize call respectively.
endclass repeat(5) begin
Users can override the pre_randomize() and post_randomize() in any classes.
module constr_inheretance; pkt2.randomize();
pre_randomize - function can be used to set pre-conditions before the object randomization.
initial begin $display("\tpkt2:: addr = %0d",pkt2.addr);end
Post_randomization - function can be used to check perform post-conditions after the object randomization.
packet pkt1; end
Ex : class packet; module rand_methods;
rand bit [7:0] addr; // initial begin packet2 pkt2; endmodule
randc bit wr_rd; packet pkt; Result : pkt1:addr=14, pkt1:addr=10, pkt1:addr=9, pkt1:addr=8, pkt1:addr=9
bit tmp_wr_rd; pkt = new(); pkt2:addr=0, pkt2:addr=1, pkt2:addr=2, pkt2:addr=0, pkt2:addr=2
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 3. inside operator - With inside operator, random variables will get values specified within the specific range when we use by inside
else addr.rand_mode(1); //pkt.addr.rand_mode(0); //randomization is operator. values within the inside block can be variable, constant or range.
endfunction disabled for particular variable by calling obj.variablename.rand_mode(0); a) inside block is written with an inside keyword followed by curly braces{} : Syntax : constraint addr_range { addr inside { ... }; }
function void post_randomize(); //function - store the wr_rd value to tmp_wr_rd 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}; }
tmp_wr_rd = wr_rd; //and display randomized values of addr and wr_rd //pkt.rand_mode(0); //randomization for all class
d) it is allowed to mix range and set of values : constraint addr_range { addr inside {1,3,[5:10],12,[13:15]}; }
$display("POST_RANDOMIZATION:: Addr = %0h,wr_rd = %0h",addr,wr_rd); variables is disabled by calling obj.rand_mode(0);
e) if the value needs to be outside the range, then specify inverse (!) of inside : constraint addr_range { addr !(inside {[5:10]}); }
endfunction end f) Other random variables can be used in inside block within the[ start_addr :end_addr ] :
endclass endmodule Ex : class packet;
Result : POST_RANDOMIZATION:: Addr = 6e,wr_rd = 1,POST_RANDOMIZATION:: Addr = 6e,wr_rd = 0 rand bit [3:0] addr;
POST_RANDOMIZATION:: Addr = 88,wr_rd = 1,POST_RANDOMIZATION:: Addr = 88,wr_rd = 0 rand bit [3:0] start_addr;
17 18
rand bit [3:0] end_addr; constraining a > 10 in child class or inline constraint.
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 conflicts in constraints leads to an randomization failure. this kind of problems can be avoided using soft constraints.
endclass and end_addr. this is done by using negation or invert operator (!)
module constr_insideoperator; constraint c_name { soft variable { condition }; }
initial begin Result : start_addr = 12,end_addr = 15 12. Bidirectional constraints – System Verilog constraints solved bidirectionally, which means constraints on all random variables will
packet pkt; addr =13 //output within range of start_addr & end_arrd
be solved parallel.
pkt = new(); Result : start_addr = 12,end_addr = 15
repeat(3) begin addr =9 //output outside the range of start_addr & end_arrd RANDOM SYSTEM FUNCTIONS
$display("\tsrt_addr=%0d,end_addr=%0d",pkt.start_addr,pkt.end_addr);
$display("\taddr = %0d",pkt.addr); 1.$urandom () - The system function $urandom provides a mechanism for generating pseudorandom numbers. The function returns
end a new 32-bit random number each time it is called. The number shall be unsigned
end
endmodule variable = $urandom(seed);
The seed is an optional argument that determines the sequence of random numbers generated. The seed can be any integral
expression.
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. 2. $random() - $random() is same as $urandom() but it generates signed numbers.
addr dist { 2 := 5, [10:12] := 8 };
3. $urandom_range() - The $urandom_range() function returns an unsigned integer within a specified range.
addr = 2 , weight 5
The :/ operator assigns the specified weight to the item. $urandom_range( int unsigned maxval, int unsigned minval = 0 );
addr dist { 2 :/ 5, [10:12] :/ 8 }; addr1 = $urandom_range(30,20);
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);} SYNCHRONIZATION AND COMMUNIACTION MECHANISAMS
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. The process through which processes communicate/synchronizes each other is known as Inter Process
Communication/synchronization.
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}; } 1.Semaphore:
7. constraint modes - The constraint_mode() method can be used to disable any particular constraint block. By default, semaphores are used for shared resources asses control.
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 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.
8. static constraints - A constraint block can be defined as static, by including static keyword in its definition. Conceptually, a semaphore is a bucket. When a semaphore is allocated, it contains a fixed number of keys is created.
static constraint addr_range { addr > 5; }
Any mode change of static constraint will affect in all the objects of same class type. 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.
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. creating a semaphore is:
pkt.randomize() with { addr == 8;}; semaphore semaphore_name;
Semaphore is a built-in class that provides the following methods:
10. functions in constraints - In some cases constraint can't be expressed in single line, function call can be used to constraint a random new() - Create a semaphore with a specified number of keys - the default number of keys is ‘0’
variable. 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.
constraint end_addr_c { end_addr == e_addr(start_addr); } try_get() - Try to obtain one or more keys without blocking - The default number of keys is 1.
19 20
SYSTEM VERILOG SYSTEM VERILOG
Mailboxes are created as having either a bounded and unbounded queue size. 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
A bounded mailbox becomes full when it contains the bounded number of messages. A process that attempts to place a message into between testbench and design.
a full mailbox shall be suspended until enough space becomes available in the mailbox queue. Unbounded mailboxes are with unlimited
size. The syntax for the program block is,
program test (input clk, input [7:0] addr, output [7:0] wdata);
There are two types of mailboxes, ...
1. Generic Mailbox (type-less mailbox) endprogram
The default mailbox is type-less, that is, a single mailbox can send and receive any type of data.
mailbox mailbox_name; Program block,
can be instantiated and ports can be connected same as module.
2. Parameterized mailbox (mailbox with particular type) can contain one or more initial blocks.
mailbox is used to transfer a particular type of data. cannot contain always blocks, modules, interfaces, or other programs.
mailbox#(type) mailbox_name; In program variables can only be assigned using blocking assignments. Using non-blocking assignments with in the program
shall be an error.
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 5. INTERFACE:
put(); - Place a message in a mailbox Interface construct are used to connect the design and testbench.
try_put(); - Try to place a message in a mailbox without blocking An interface is a named bundle of wires, aim of the interfaces is to encapsulate communication.
get(); or peek(); - Retrieve a message from a mailbox Also specifies the,
try_get(); or try_peek(); - Try to retrieve a message from a mailbox without blocking directional information, i.e. modports
num(); - Returns the number of messages in the mailbox timing information, i.e. clocking blocks
An interface can have parameters, constants, variables, functions and tasks.
3. Event modports and clocking blocks are explained in later chapters.
Events are static objects useful for synchronization between the process. A simple interface declaration is,
One process will trigger the event, and the other processes can wait for an event to be triggered. interface interface_name;
Events are triggered using -> operator or ->> operator ...
wait for a event to be triggered using @ operator or wait() construct. interface_items
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. endinterface
1. -> operator - Named events are triggered via the -> operator. Triggering an event unblocks all processes currently waiting on that An interface can be instantiated hierarchically like a module, with or without ports.
event. interface_name inst_name;
Interface can have parameters, constants, variables, functions and tasks.
2. ->> operator - Nonblocking events are triggered using the ->> operator. 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
3. @ operator - wait for an event to be triggered is via the event control operator, @. The @ operator blocks the calling process until multiple signal/ports.
the given event is triggered. interface declaration is made once and the handle is passed across the modules/components.
addition and deletion of signals is easy.
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 6. Virtual interface:
miss to detect the event trigger.
Where as wait(); construct will detect the event triggering. A virtual interface is a variable that represents an interface instance.
wait(event_name.triggered); Syntax:
virtual interface_name instance_name;
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 example:
right). event trigger with out of order will not unblocks the process. virtual mem_intf intf;
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 Virtual interface must be initialized before using it. i.e., Virtual interface must be connected/pointed to the actual interface.
variable affects processes waiting on either event variable. 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.
4.PROGRAM-BLOCK:
All the interface variables/Methods can be accessed via virtual interface handle. i.e virtual_interface.variable
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. 7. mod ports:
Modport groups and specifies the port directions to the wires/signals declared within in the interface.
Non-blocking assignments with in the module are scheduled in the active region, initial blocks within program blocks are scheduled in By specifying the port directions, modport provides access restrictions.
the Reactive region. The keyword modport indicates that the directions are declared as inside the module.
21 22
The Interface can have any number of modports, wire declared in the interface can be grouped in many modports. sequence name_of_sequence;
wires declared in the modport are accessed as, ……
modport_name.wire; endsequence
3. property - A number of sequences can be combined logically or sequentially to create more complex sequences. SVA provides a key
8. clocking block: word to represent these complex sequential behaviors called "property”.
A clocking block specifies timing and synchronization for group of signals.
The clocking block specifies, 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
The clock event that provides a synchronization reference for DUT and testbench. provides a key word called "assert" to check the property.
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.
The steps involved in the creation of a SVA checker,
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.
sequence seq_1;
@(posedge clk) a==1;
endsequence
2. sequence - Boolean expression events that evaluate over a period of time involving single/multiple clock cycles. SVA provides a key sequence seq;
word to represent these events called "sequence." @(posedge clk) a ##2 b;
Endsequence
syntax:
23 24
SYSTEM VERILOG SYSTEM VERILOG
If there is a match on the antecedent, then the consequent expression is evaluated in the same clock cycle.
Below property checks that, if signal "a" is high on a given positive clock edge, then signal "b" should also be high on the same clock
edge.
property p;
@(posedge clk) a |-> b;
endproperty
a: assert property(p);
In general, it is a good idea to define the clocks in property definitions and keep the sequences independent of the clocks. This will 4. Implication with a sequence as an antecedent - Below property checks that, if the sequence seq_1 is true on a given positive edge
help increase the re-use of the basic sequence definitions. of the clock, then starts checking the seq_2 (“d” should be low, 2 clock cycles after seq_1 is true ) .
A separate property definition is not needed to assert a sequence. the expression to be checked can be
called from the assert statement directly. sequence seq_1;
(a && b) ##1 c;
4. Forbidding a property: endsequence
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_2;
sequence seq; ##2 !d;
@(posedge clk) a ##2 b; endsequence
endsequence
property p;
property p; @(posedge clk) seq_1 |-> seq_2;
not seq; endpeoperty
endproperty a: assert property(p);
a_1: 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
3.Implication operator: 4 clock cycles, the signal "b" should be high.
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. property p;
The implication construct can be used only with property definitions. It cannot be used in sequences. @(posedge clk) a |-> ##[1:4] b;
endproperty
sequence seq; a: assert property(p);
@(posedge clk) a ##2 b; 6. overlapping timing window - Below property checks that, if signal "a" is high on a given positive clock edge, then signal "b" should
Endsequence be high in the same clock cycle or within 4 clock cycles.
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 property p;
every positive clock edge. If signal "a" is not high on any given positive clock edge, an error is issued by the checker. @(posedge clk) a |-> ##[0:4] b;
If we want sequence to be checked only after “a” is high, this can achieved by using implication operator. endproperty
a: assert property(p);
There are 2 types of implication:
7. Indefinite timing window - The upper limit of the timing window specified in the right hand side can be defined with a "$" sign
Overlapped implication 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
Non-overlapped implication
25 26
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 2. $fell - $fell( Boolean expression or signal name) returns true if the least significant bit of the expression changed to 0. Otherwise, it
next clock cycle. returns false.
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 a: assert property(p);
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. 6. Built-in system functions:
1. $onehot(expression) - checks that only one bit of the expression can be high on any given clock edge.
5. SVA methods:
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.
1. $rose - $rose(Boolean expression or signal name)
3. $isunknown(expression) - checks if any bit of the expression is X or Z.
returns true if the least significant bit of the expression changed to 1. Otherwise, it returns false.
4. $countones(expression) - counts the number of bits that are high in a vector.
sequence seq_rose;
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 a_3: assert property( @(posedge clk) $isunknown(bus) ) ;
occur, the assertion will fail.
a_4: assert property( @(posedge clk) $countones(bus)> 1 );
27 28
SYSTEM VERILOG SYSTEM VERILOG
Assert statement a_1 checks that the bit vector "state" is one-hot. Control-oriented Coverage - Checks whether sequences of behaviors have occurred. We can get assertion coverage by
writing System Verilog Assertions.
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. Defining the coverage model:
Coverage model is defined using Covergroup construct.
Assert statement a_4 checks that the number of ones in the vector "bus" is greater than one. 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.
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. 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.
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 Each covergroup specification can include,
checker will stop. A clocking event that synchronizes the sampling of coverage points
A set of coverage points
property p;
Cross coverage between coverage points
@(posedge clk)
Optional formal arguments
disable iff (reset) a |-> ##1 b[->3] ##1 c;
Coverage options
endproperty
a: assert property(p); 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
8. ended - while concatenating the sequences, ending point of the sequence can used as a synchronization point. coverage point is associated with “bin”. On each sample clock simulator will increment the associated bin value.
This is expressed by attaching the keyword "ended" to a sequence name. The bins will automatically created or can be explicitly defined.
sequence seq_1; 1. Automatic/implicit bins – Automatically single bin will be created for each value of the coverpoint variable range. These are called
(a && b) ##1 c; automatic, or implicit, bins.
endsequence For an “n” bit integral coverpoint variable, 2n number of automatic bins will get created.
sequence seq_2;
d ##[4:6] e; module cov;
endsequence logic clk;
logic [7:0] addr;
property p; logic wr_rd;
@(posedge clk) seq_1.ended |-> ##2 seq_2.ended;
endpeoperty covergroup cg @(posedge clk);
a: assert property(p); c1: coverpoint addr;
c2: coverpoint wr_rd;
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 endgroup : cg
sequences does the synchronization. cg cover_inst = new();
...
SYSTEM VERILOG COVERAGE endmodule
There are two types of coverage metrics. 2. Explicit bins - “bins” keyword is used to declare the bins explicitly to an variable.
Code Coverage Separate bin is created for each value in the given range of variable or a single/multiple bins for the rage of values.
Functional Coverage 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.
1.Code coverage - Code coverage measures how much of the “design Code” is exercised. This includes, execution of design blocks, covergroup cg @(posedge clk);
Number of Lines, Conditions, FSM, Toggle and Path. c1: coverpoint addr { bins b1 = {0,2,7};
bins b2[3] = {11:20};
Simulator tool will automatically extracts the code coverage from the design code. bins b3 = {[30:40],[50:60],77};
bins b4[] = {[79:99],[110:130],140};
2. functional coverage - Functional coverage is a user-defined metric that measures how much of the design specification has been bins b5[] = {160,170,180};
exercised in verification. bins b6 = {200:$};
bins b7 = default;}
There are two types of functional coverage, c2: coverpoint wr_rd {bins wrd};
endgroup : cg
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 30
3. Bins for transitions - Transition of coverage point can be covered by specifying the sequence, Coverage options control the behavior of the covergroup, coverpoint and cross.
value1 => value2
It represents transition of coverage point value from value1 to value2. 1. at_least:
sequence can be single value or range, Minimum number of hits for each bin. A bin with a hit count that is
value1 => value2 => value3 …. less than number is not considered covered. default value is ‘1’.
range_list_1 => range_list_2
2. auto_bin_max:
4. Ignore bins - A covergroup cg @(posedge clk); set of values or Maximum number of automatically created bins when no bins are
transitions c1: coverpoint addr{ bins b1 = (10=>20=>30); associated with a explicitly defined for a coverpoint. default value is ‘64’.
coverage-point bins b2[] = (40=>50),(80=>90=>100=>120); can be explicitly
excluded from bins b3 = (1,5 => 6, 7);} coverage by 3. cross_auto_bin_max:
covergroup cg @(posedge clk);
specifying them c2: coverpoint wr_rd; as ignore_bins. Maximum number of automatically created cross product bins for a
c1: coverpoint addr{ ignore_bins b1 = {6,60,66};
endgroup : cg cross. there is no default value, it is unbounded.
ignore_bins b2 = (30=>20=>10); }
endgroup : cg
bins b1 = (10=>20=>30); // transition from 10->20->30 coverage options can be used as below,
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
covergroup cg @(posedge clk);
c1: coverpoint addr { option.auto_bin_max = 128;}
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. c2: coverpoint wr_rd { option.atleast = 2;}
c1Xc2: cross c1, c2 { option.cross_auto_bin_max = 128;}
SYSTEM endgroup : cg VERILOG PARAMETERS AND ‘define
covergroup cg @(posedge clk);
c1: coverpoint addr{ illegal_bins b1 = {7,70,77};
ignore_bins b2 = (7=>70=>77);} There are two ways to define constants:
endgroup : cg
parameter
`define
3. cross coverage
Cross Coverage is specified between the cover points or variables. Cross coverage is specified using the cross construct.
1.parameter - Parameters must be defined within module boundaries using the keyword parameter.
Expressions cannot be used directly in a cross; a coverage point must be explicitly defined first.
A parameter is a constant that is local to a module that can optionally be redefined on an instance. Parameters are typically used to
Cross coverage by cover_point name:
specify the width of variables and time delays.
bit [3:0] a, b;
2. Parameter redefinition:
covergroup cg @(posedge clk);
Parameter values are not allowed to modify at runtime but can be modified using the defparam statement and #delay specification
c1: coverpoint a;
with module instantiation.
c2: coverpoint b;
c1Xc2: cross c1,c2;
endgroup : cg
‘define Macro:
Cross coverage by variable name:
The `define compiler directive is used to perform global macro substitution and remain active for all files read/compiled after the
bit [3:0] a, b; macro definition.
covergroup cov @(posedge clk); it will available until another macro definition changes the value or until the macro is undefined using the `undef compiler directive.
aXb : cross a, b;
endgroup `define WIDTH 8
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 to avoid redefincation `ifdef can be used,
256 cross products, and each cross product is a bin of aXb.
`ifdef WIDTH
Cross coverage between variable and expression: // do nothing (better to use `ifndef)
`else
bit [3:0] a, b, c; `define WIDTH 8
covergroup cov @(posedge clk); `endif
BC : coverpoint b+c;
aXb : cross a, BC; `ifndef WIDTH
endgroup `define WIDTH 8
`endif
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. `ifdef can be used as if..else
`ifdef TYPE_1
4. coverage options `define WIDTH 8
`else
31 32
SYSTEM VERILOG
`define WIDTH 32
`endif
33