System Verilog Classes

Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 105

SYSTEM VERILOG

CONTENTS
• Introduction

• Data Types

• ARRAYS
• TASKS & FUNCTIONS
• OOPS

• Class
• Object
• Inheritance
• Polymorphism
• $Cast
• ABSTRACTION (OR) VIRTUAL CLASS

• CONSTRUCTOR - NEW() KEYWORD


• SUPER KEYWORD

• SUPER.NEW() KEYWORD

• THIS KEYWORD

• EXTERN KEYWORD

• SHALLOW COPY

• DEEP COPY

• MAILBOX
• SEMAPHORE

• RANDOMIZATION

• rand & randc

• CONSTRAINTS

• Distribution Constraints

• Inline Constraints

• Conditional Constraints

• Soft Constraints

• THREADS (FORK_JOIN , FORK_JOIN_ANY,


FORK_JOIN_NONE)

• SEMAPHORE
• MODPORTS

• CLOCKING BLOCKS , PROGRAM BLOCKS

• INPUT AND OUTPUT SKEW

• INTERFACE and VIRTUAL INTERFACE

• CODE COVERAGE

• FUNCTIONAL COVEARGE

• TB ARCHITECTURE

• ASSERTIONS (or) CHECKERS


Introduction

Advantages of SV over Verilog

• A language which supports all the verification methodologies


• New data types added
• New features in task & function and also new events in stratified event queues.
• Oops concepts (class, inheritance, polymorphism)
• Constraints based Randomization
• Assertions
• Coverage
DATA TYPES
DATA TYPES IN SYSTEM VERILOG

• System verilog has two major categories of data types:


• Variables and Nets
Variables
• It stores a value from one assignment to the next.
• It retain the values until the next assignments
Nets
• Signals declared as nets do not store a value.
2-State and 4-State Data types:-
In System Verilog, there are following data types:
• 2-State data type (0,1)
• 4-State data type(0,1,X,Z)

2-state data type:-


2-state data type can have values as 0 or 1. Below are the 2-state
datatypes.
bit 0,1 1-bit unsigned
byte (0-7) 8-bit Signed
Short_int (0-15) 16-bit Signed
int (0-31) 32-bit Signed

Long_int (0-63) 64-bit Signed


4-State data type:-

• 4-state data type can have values out of 0,1, X,


• Z. Below are the 4-state datatypes.

logic 1-bit

Integer 32-bit

Time 64-bit
Strings

• Variable length –it grows automatically


• Memory is dynamically allocated

Logic
• Logic –functionality similar to reg
• It is synthesizable and it can be used to define both combinational and sequential
logics
• Logic data types are 4- state data types
•It can be used anywhere i.e input, inout, output ports
System Verilog:
• Default value = x module counter(count, flag, clk, rst);
• Verilog:
module counter(count, flag, clk, rst); output logic [3:0] count;
output logic flag; // excluding logic will also insert a wire by
output reg [3:0] count; default
output flag; // by default it will be wire input clk, rst;
input clk, rst;
//assign flag = (count == 10) ? 1'b1 : 1'b0;

assign flag = count == 10 ? 1'b1 : 1'b0; always @ (posedge clk)


begin
if (rst || flag == 1'b1)
always @ (posedge clk) count <= count + 1'b1; // count will be reg
begin flag = 1’b1 – if (count = 15)
end
if (rst || flag == 1'b1)
count <= count + 1'b1; endmodule
end

endmodule
Enum Datatype:- (list of values)
• An Enumerated data type defines a set of named values.
Example 1: enum { red, green, blue, yellow, white }

• The actual values are defaulted to integers starting at 0 and then increase.
• So in this example by default variable will get the default value of 0,1,2,3,4.

Example 2: enum { red=0, green, blue=4, yellow, white=10 }

• Here I have set red=0, blue=4, white=10.


• A name without a value is automatically assigned an increment of the value of the previous
name.
• So green and yellow automatically assigned to the increment value of 1,5.
• NOTE:-If an automatically incremented value is assigned elsewhere in the same enumeration, this
shall be a syntax error.
Code of Enum:
module enums;
enum{red=0,green=1,yellow=2,blue=3,pink=4}clr;
initial
begin
clr = 2; // yellow
clr=clr.first();
$display("display the first clr=%0s",clr);
clr=clr.last();
$display("display the last clr=%0s",clr); clr=clr.next();// we can also
give like clr = clr.next(3);
$display("display the next clr=%0s",clr);
clr=clr.prev(); // we can also give like clr = clr.prev(3);
$display("display the prev clr=%0s",clr);
end endmodule
Typedef Data Type:-
• Typedef allows users to create their own names for type definition that they will use
frequently in their code.
• Typedefs can be very convenient when building up complicated array definitions.
• By using typedef we can define any data type.
• By using typedef we can declare outside of the module , with the help of handle we
can
access inside the module.
• Syntax of typedef:
• typedef enum {red, blue, green} clr; //
• typedef bit [4:0] var; // var is a data type of size 5 bit – default value = 0
• typedef sturct { bit [15:0] opcode; reg [34:0] address;} str_name; // str_name is a
datatype – struct datatype
Code of Typedef:
typedef enum{red=0,green=1,yellow=2,blue=3,pink=4}colours;
module sv;
colours clr;
initial begin
clr=clr.first();
$display("display the first clr=%0s",clr);
clr=clr.last();
$display("display the last clr=%0s",clr);
clr=clr.next();
$display("display the next clr=%0s",clr);
clr=clr.prev();
$display("display the prev clr=%0s",clr);
end
endmodule
Struct
•Collection of data types
•It is synthesizable
Struct {
bit [15:0 ] opcode;
logic [23:0] address;
} str_name;

Str_name.opcode = 1 or str_name = {5, 200};

Str_name i1;
i1.opcode = 3; or i1 = {3, 100};
Struct Data Types:- static
• Collection of variables of different data types.
• It is fixed data type.
• Memory allocations can be done at compilation time.
Sample code of Struct:
module sv;
struct packed{ int addr;
bit data;
byte arun; }pkt;
initial
begin
pkt='{1,2,3};
$display("pkt=%0d",pkt);
$display("addr=%0d,data=%0d,arun=%0d",pkt.addr,pkt.data,pkt.arun);
end
endmodule
DATA SIGNED/U SIZE STATE COMPATIBILITY SYNTAX
TYPES NSIGNED (IN
BITS)

reg Unsigned 1 4 SV/V Reg <variable_name>;


wire Unsigned 1 4 SV/V Wire <variable_name>;
logic Unsigned 1 4 SV Logic <variable_name>;
integer Signed 32 4 SV/V Integer <variable_name>;
real Signed 64 4 SV/V real <variable_name>;
realtime Unsigned 64 4 SV/V realtime <variable_name>;
time Unsigned 64 4 SV/V time <variable_name>;
int Signed 32 2 SV Int <variable_name>;
bit Unsigned 1 2 SV bit <variable_name>;
byte signed 8 2 SV byte <variable_name>;
shortint Signed 16 2 SV shortint <variable_name>;
longint Signed 64 2 SV longint <variable_name>;
Type Conversion
System Verilog provide the feasibility of assigning on one data type to other by using
casting there are two methods in casting.
1. Static casting
2. Dynamic casting
Static casting : (No checking of values)
The static cast operation converts between two types with no checking of values.
You specify the destination type, an apostrophe, and the expression to be converted.
Example:
int I;
real r;
I = int’(10.0 – 0.1) ; // 9.9 = 9
r = real’(42); // 42.0
Dynamic casting :
The dynamic cast, $cast allows you to check for out of bound values.
Example :
$cast(dest_var, source_exp)
$cast(I, 10 – 0.1)
Dynamic casting has error handling mechanism
Example:
enum {a, b, c, d} val;
val = ‘5; // static casting – will not give error
$cast(val,5); // Dynamic casting – will give error saying “value is out of bound”
Mainly used in UVM inside the uvm_sequence, uvm_sequencer
ARRAYS
SYSTEM VERILOG - ARRAYS
ARRAYS:
An array is collection of variables of same type, and accessed using
the
same name plus one or more indices.

Types of Arrays :
• Fixed Size Arrays
• Packed and Un-packed Arrays
• Dynamic Array
• Associative Array
• Queues
• String
In system Verilog we have following type arrays:-

• Fixed Size Array:


In fixed size array, array size will be constant throughout the simulation, Once the
array is declared no need to create it. By default, the array will be initialized with value
‘0’.
• Single dimensional array
Syntax : int array1 [6];
int array2 [5:0];
• Multidimensional array are also known as an array of
arrays.

Two dimensional array


Syntax : int arr [5][3]; // int arr [4:0][2:0];
This array has total 2*3=6 elements.

Three dimensional array:


Syntax : int array1 [2:0][3:0];
Packed and Unpacked Arrays: How to access:
Array:
Packed array:- Initial begin
• Packed arrays can be of single bit data types like reg, logic, bit. Array1 [2] = 8’b 0101_1010;
Array1 [2][7] = 1’b1;
• Dimensions declared before the data identifier name. end
Syntax: logic[15:0] arr;
• Packed arrays are fixed sized , single or multidimensional array.
• Packed array is guaranteed to be represented as a contiguous set of bits.
• Syntax : bit [2:0][7:0] array1;
• The below example shows storing packed array as a contiguous set of
bits.
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
Unpacked
Array:-
• Unpacked arrays can be of any data type.
• Unpacked arrays shall be declared by specifying the element ranges after the
identifier
name.
• An unpacked array may or may not be so presented as a contiguous set of bits.
• Syntax : bit [7:0] array2[2:0];

• Below diagram shows storing unpacked array as a non-contiguous set of bits.

7 6 5 4 3 2 1 0
7 6 5 4 3 2 1 0
7 6 5 4 3 2 1 0
Dynamic
Array :
• A dynamic array is unpacked array whose size can be set or changed at runtime.
• During the runtime we can increase size and decrease the size.
• Dynamic array can be represented as [ ];
• Syntax : int array_1 []; bit [5:0] array_2 [];
• Array creation : array_1 = new [16Gb]; // 15:0 – Gb
• Methods : size() // it will print how many locations are
present - 10
delete()

Array_1[0] = 32’h1234_5678;
Array_1[0][16] = 1’b1;
Sample code for Dynamic
array:
module sv;
int array_1[];
initial
begin
$display("display the size of the array_1=%0d",array_1.size()); array_1=new[10];
$display("display the size of the array_1=%0d",array_1.size());
array_1=new[50](array_1); // See what is this operation means – resizing
$display("display the size of the array_1=%0d",array_1.size());
array_1.delete();
$display("display the size of the array_1=%0d",array_1.size());
end
endmodule
Associative Array:-

• Associative array has non-continuous elements.


• Associative array can be represented as [*] , * indicates index values.
• Index values can be either integers(1,2,3) or strings(a,b,c).
• For large memory storing we are using associative array.
• Associative arrays allocate the storage only when it is used, unless like in the dynamic array
we need to allocate memory before using it.
• When the size of a collection is unknown or the data space is sparse, an associative array is
a
better option.
Syntax:
int array_1[*] //associative array of integer (unspecified index).
Associative array methods are:-

• num(),
• first(var),
• last(var),
• next(var),
• perv(var),
• delete(index),
• exists(index)
code of Associative array
using(int):
module assoc; int $display("display the first index array_1=%0d",index,array_1[index]);

array_1[int]; int array_1.last(index);


index; initial $display("display the last index array_1=%0d",index,array_1[index]);
begin array_1.prev(index);
$display("numbe $display("display the prev index array_1=%0d",index,array_1[index]);
r of entries
array_1.next(index);
array_1=
%0d",array_1.n $display("display the next index array_1=%0d",index,array_1[index]);
um());
if(array_1.exists(2))
array_1[1]=500;
$display("index 2 is exists in array_1");
array_1[2]=700;
else
array_1[3]=300;
array_1[4]=200; $display("index 2 is not exists in array_1");

array_1[5]=900; if (array_1.exists(7))

array_1[6]=1000; $display("index 7 is exists in


array_1");
$display("number of entries array_1=%0d",array_1.num());
else
foreach(array_1[i])
$display("index 7 is not exists in
$display("number of entries array_1[%0s]=%0d",i,array_1[i]); array_1");
array_1.first(index);
end
code of Associative array
using(string):
module assoc; array_1.first(index);
int array_1[*]; $display("display the first index array_1=%0d",index,array_1[index]);
int index; array_1.last(index);
initial $display("display the last index array_1=%0d",index,array_1[index]);
begin array_1.prev(index);
$display("number of entries array_1=%0d",array_1.num()); $display("display the prev index array_1=%0d",index,array_1[index]);
array_1["A"]=500; if(array_1.exists(2))
array_1["B"]=700; $display("index 2 is exists in array_1");
array_1["C"]=300; else
array_1["D"]=200; $display("index 2 is not exists in array_1");
array_1["C"]=900; if(array_1.exists(7))
array_1["E"]=1000; $display("index 7 is exists in array_1");
$display("number of else
entries array_1=
$display("index 7 is not exists in array_1");
%0d",array_1.num(
)); end
foreach(array_1[i]) endmodule
$display("number of
Queues:-
• Queues can be represented as $.
• In queue 0 represents the first, and $ representing the last entries.
• Queue supports adding and removing elements anywhere.
• Queue has flexible memory.
• Queue has variable sizing.
• Queue has 2 types:
Bounded ---- If size is
mentioned. Unbounded ---- If size is
not mentioned.
• Syntax:
• example:-
• int queue_1 [$];
• int queue_1[$]; //queue of bits (Unbounded queue)
• byte queue2[$:255]; //queue of byte (bounded queue with 256
entries)
Queue Methods:-

• size()
• insert(1,5)
• delete()
• push_front()
• push_back()
• pop_front()
• pop_back()
module sv;
int queue_1[$]; code of queue:
queue_1.pop_back();
initial
$display("size of the queue(pop_back) is
begin queue_1=%0d",queue_1.size());
$display("size of the queue is queue_1=%0d",queue_1.size());
queue_1= {1,2,3,4,5,7,8,10};
queue_1.insert(1,766);
foreach(queue_1[i]) $display("size of the queue(insert) is
queue_1=%0d",queue_1.size());
$display("size of the queue(size) is
queue_1[%0d]=%0d",i,queue_1[i]);
foreach(queue_1[i])
queue_1.push_front(100); $display("size of the
$display("size of the queue(push_front) is queue(size after all
queue_1=%0d",queue_1.size()); methods)
queue_1.push_back(200); is queue_1[%0d]=
%0d",i,queue_1[i]);
$display("size of the queue(push_back) is
queue_1=%0d",queue_1.size());
queue_1.pop_front(); queue_1.delete();
$display("size of the queue(pop_front) is $display("size of the
queue_1=%0d",queue_1.size()); queue(delete) is
queue_1=%0d",queue_1.size());
STRING :
• String is a group of characters.
• String should be with in the double
quotes(“”).
• We can put & get characters in the string.
Syntax:
String s1 = “SemiConducTors”;
• String Methods:
tolower()
toupper()
putc()
getc()
substr()
len()
STRING code:

module sv; $display("display the s2=%0s",s2.toupper());


string s1="semiconductors"; $display("display the s1=%0s",s1.getc(5));
string s2="samsung"; $display("display the s2=%0s",s2.getc(6));
initial $display("display the s1=%0d",s1.len());
begin $display("display the s2=%0d",s2.len());
$display("display s1.putc(1,"A");
the s1=%0s",s1); $display("display the s1=%0s",s1);
$display("display end
the s2=%0s",s2);
endmodul
$display("display
the s2= e
%0s",s1.tolower())
;
$display("display
SYSTEM VERILOG THERADS
Fork-join

•It will start all the process/statements in parallel and waits for the completion of the
processes/statements.
•Any delay specified inside the block is relative to the time at which the fork join block
has entered.

Fork-join-any
The parent process blocks until any one of the processes wait by this fork completes.

Fork-join-none
The parent process will not block further process.
Initial Example : Fork_join
fork - join module sv;
Begin
Initial
Clk =0; begin fork begin
fork
#5; #10 $display($time,"i am cat");
end
Fork begin
#5 a = 0; // t = 10 #20 $display($time,"i am fat");
end begin
#10 b = 0; // t = 15
#30 $display($time,"i am dog"); end
Join Clk becomes 1 join
join at t=15 #40 $display($time,"i am rat");
Clk= 1;
end
end endmodule
fork – join_any Initial
Example : Fork join_any
Begin module sv; initial begin
fork begin
Clk =0; #10 $display($time,"i am cat"); end
fork #5 begin
#20 $display($time,"i am fat");
Fork end
#5 a = 0; begin
#30 $display($time,"i am dog");
#10 b = 0; end
Join_any join_any
Clk becomes 1 #40 $display($time,"i am rat");
Join_any Clk= 1; at t=10 end
endmodule
#2 $finish;
end
Initial
Begin
fork – join_none
Clk =0;
Example : Fork Join_none
#5 module sv;
initial begin fork begin
Fork T= 5, a = 0
fork #10 $display($time,"i am cat");
a = 0; T= 15, b = 0 end
begin
#10 b = 0; #20 $display($time,"i am fat");
Join_none end
Clk becomes 1 begin
#2 Clk= 1; at t=7 #30 $display($time,"i am dog");
T= 12, c = 0
#5 C = 0; end
Join_none join_none
#6 b = 1; #40 $display($time,"i am rat");
end
disable fork;
endmodule
end
INTERFACE
INTERFACE

• Bundle of Interconnects.
• Provide an abstract encapsulation of communication between blocks
• Signal directions can be given in below two formats
• Directional information (modports)
• Timing (clocking blocks)

Example:
device1 interface device2 interface bus_a (input clock);
logic [7:0] address;
interface

logic [31:0] data ;


bit valid ;
interface device3
bit rd_wr ;
endinterface: bus_a
MODPORT

• Generally interface will have all the signals defined and the DUT_wrapper
directions are specified in the modport. Addr, data,
• A modport can include all the signals or only some signals. mode
Design_1 Design_2
• modport des_1 (input ready, output addr, data, mode);
ready
• modport des_1 (input ready, output addr, data);

module DUT_wrapper(……);
Example:
input clk;
Interface bus_b (input clock);
bus_b bus (clk); //interface
logic [7:0] addr, data;
Design_1 d1 (bus.des_1);
logic [1:0] mode ;
Design_2 d2 (bus.des_2); // instantiating
bit ready ;
specific
modport des_1 (input ready, output addr, data, mode);
modport
modport des_2 (input addr, data, mode, output ready);
….
endinterface: bus_b
endmodule
CLOCKING BLOCK
• Specify synchronization characteristics of the design
• Offer a clean way to drive and sample signals Interface M1(clk, enin, din, enout, dout);
input clk,enin;
• Features
input [31:0] din ;
• Clock specification output enout ;
• Input skew,output skew output [31:0] dout ;
• Cycle delay (##)
clocking sd @(posedge clk); Signals will be
• Can be declared inside interface,module or program
sampled 2ns
input #2ns ein,din;
before posedge
output #3ns enout, dout; clk
endclocking:sd

reg [7:0] sab ;


initial begin
sab = sd.din[7:0];
Signals will be
end driven 3ns after
endinterface:M1 posedge clk
Input and Output Skew:
• Input skew: TB samples DUT outputs before the clock
edge
• Output skew: TB drives the DUT inputs at the clock edge.
New features in Task & Function
module argument_passing;
No begin end required int x,y,z;
Return can be used in task
//function to add two integer numbers.
Function return values can have a “void return type” function int sum(ref int a, b);
a = a + b;
Functions can have any number of inputs, outputs and
return a + b;
inouts including none endfunction
Return can be used in both function & task
initial begin
Variable passing – pass by value, pass by reference x = 20;
y = 30;
z = sum(x, y);
Example: $display("\tvalue of x = %0d",x); // 50
Function void sum (input x, y, output out); $display("\tvalue of y = %0d",y); // 30
$display("\tvalue of z = %0d",z); // 50
out = x + y; end
Endfunction Endmodule

Sum(in1, in2, sumation);// in1


OOP’s – Object
Oriented programing
OOPS – Object oriented programming

classes

OOP

polymorphism inheritance
Class

• The class definition describes all the properties, behavior, and identity of objects present within that class. It is the central
point of OOP and that contains data and codes with behavior.

Class Properties: variables


declaration Methods: functions/tasks
syntax:
class my_class;
statement 1;
Assigning a variable for
… accessing the class
endclass properties/methods
handle
my_class handle; New constructor create a
memory location to the class
object
and returns the address. This is
handle = new(); address is assigned to the
handle
inheritance

Inheritance is an OOP concept that allows the user to create classes that are built upon existing classes.
The new class will be with new properties and methods along with having access to all the properties and
methods of the original class.
Child can access the parent properties/methods, but parent cannot access the child properties/methods.

//module
//base class module inheritence;
class parent_class; initial begin
bit [31:0] addr; child_class c = new();
endclass c.addr = 10;// accessing the parent property
from child object
//child class c.data = 20;
class child_class extends parent_class;
bit [31:0] data; $display("Value of addr = %0d data =
endclass %0d",c.addr,c.data); // addr = 10, data = 20
end
endmodule
polymorphism
Polymorphism means many forms. Polymorphism in SystemVerilog provides an ability to an object to take on
many forms.
Method handle of super-class can be made to refer to the subclass method, this allows polymorphism or
different forms of the same method.

// module
// base class module class_polymorphism;
class base_class; initial begin
function void display(); //declare and create extended class
$display("Inside base class"); ext_class_1 c_1 = new();
endfunction //base class handle
endclass base_class b_c;
//assigning extended class to base class
// extended class 1 b_c = c_1;
class ext_class_1 extends base_class; //accessing extended class methods using base class
function void display(); handle
$display("Inside extended class 1"); b_c.display();
endfunction end
Endclass endmodule
Imp keywords
The “this” keyword is used to unambiguously refer to
class properties or methods of the current instance. • The “super” keyword is used in a
derived class to refer to the members of
class packet;
//class properties the parent class.
bit [31:0] data; // GLOBAL
//constructor class parent_class;
module inheritence;
function new(bit [31:0] data); // constructor fun bit [31:0] addr;
initial begin
this.data = data; // LOCAL TO FUN function display();
child_class c=new();
endfunction $display("Addr = %0d",addr);
c.addr = 10;
//method to display class properties endfunction
c.data = 20;
function void display(); endclass
module sv_const; c.display(); // will
bit [31:0] data;
packet execute both the display
this.data = data; class child_class extends parent_class;
functions
$display("\t data = %0h",this.data); pkt;//handle bit [31:0] data;
initial begin end
endfunction function display();
pkt = new(10);// endmodule
endclass super.display(); // call parent display
obj $display("Data = %0d",data);
pkt.data = 14; endfunction
pkt.display(); endclass
end
$cast:
In polymorphism we are assigning parent = child but there is no possibility to assign child=parent,
but by using $cast we can perform child = parent, which will be legal in this case.

class parent; module polymorphism;

virtual function void display(); initial


begin
$display ("i am in parent ");
endfunction parent p = new();
endclass child c = new();
child c_1;
p=c;
class child extends parent;
$cast (c_1,p);
function void
c_1.display()
display();
; end
super.display();
endmodule
$display("i am in child");
endfunction
Abstract Class:

• A class is called abstract class if virtual keyword is used before a class.


• An abstract class cannot be instantiated, it can only be derived and can be used in
module inside initial begin block.
• Without deriving if we use abstract class directly in to module initial begin block, it
will give compilation error.

• Syntax :
virtual class parent;
Code of Abstract
class:
virtual class parent;
function void display();
$display("Iam in parent");
endfunction
endclass

class child extends parent;


endclass
module sv;
parent p;
child c;
initial
begin
c=new();
c.display();
end
endmodule
Shallow Copy:
• Only properties parent class are copied , but not object of subclass.
• Shallow copy creates a separate memory only for the properties of the class but not the subclass
object.
example endfunction
//-- class --- //method to display class properties
class address_range; function void display();
bit [31:0] start_address; $display("---------------------------------------------------------");
bit [31:0] end_address ; $display("\t addr = %0h",addr);
function new(); start_address = 10; $display("\t data = %0h",data);
end_address = 50; $display("\t start_address = %0d",ar.start_address);
endfunction $display("\t end_address = %0d",ar.end_address);
endclass $display("---------------------------------------------------------");
endfunction
//-- class --- endclass
class packet;
//class properties
bit [31:0] addr;
bit [31:0] data;
address_range ar; //class handle

//constructor
function new();
addr = 32'h10;
data = 32'hFF;
ar = new(); //creating object
// -- module ---
module class_assignment;
packet pkt_1;
packet pkt_2;

initial begin
pkt_1 = new(); //creating pkt_1 object
$display("\t**** calling pkt_1 display ****");
pkt_1.display();

pkt_2 = new pkt_1; //creating pkt_2 object and copying pkt_1 to pkt_2
$display("\t**** calling pkt_2 display ****");
pkt_2.display();

//changing values with pkt_2 handle


pkt_2.addr = 32'h68;
pkt_2.ar.start_address = 60;
pkt_2.ar.end_address = 80;
$display("\t**** calling pkt_1 display after changing pkt_2 properties ****");

//changes made to pkt_2.ar properties reflected on pkt_1.ar, so only handle of the object
get copied, this is called shallow copy
pkt_1.display();
$display("\t**** calling pkt_2 display after changing pkt_2 properties ****");
pkt_2.display(); //
end
endmodule
Deep Copy:
• Both Data & Objects of parent class are
copied.
• .copy() method is used to perform deep_copy.
pt1=new();
class simple; pt2=new();
int a,b; pt2=pt1.copy();
function simple copy(); $display("a=
%d,b=
copy=new(); %d",pt1.a,pt1.b)
copy.a=2; ;
copy.b=4; $display("a=
endfunction %d,b=
endclass %d",pt2.a,pt2.b)
;
module main();
pt1.a=5;
simple pt1,pt2; pt1.b=7;
initial begin $display("a=
%d,b=
%d",pt1.a,pt1.b)
RANDOMIZATION
Randomization:
• System Verilog randomization provides a built-in method randomize. The randomize() method
generates random values for all the active random variables of an object.
• Variables declared with the rand keyword will get random values on the object.randomize()
method call.
• 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() functions.
• If we declare a rand method i.e., rand & randc we need to use .randomize() method also.
class test;
rand bit [31:0] addr;
bit [127:0] data;
enclass

module TB;
bit success;
test t_h = new;
initial begin
#10;
success = t_h.randomize;
end
function void pre_randomize();
$dispaly(addr)
data = addr * 2;
endfunction

function void post_randomize()


$display(addr);
data = 0;
endfunction
endmodule
rand and randc

• rand : In the declared list of values , when we use rand keyword , it can
repeat values at any point of time.
• randc: random cyclic it means values are not repeated until one cycle
completes.
• Value will repeated only after all the possible values have been assigned at
least once.
randc bit [1:0] val; // 2'b00 - 01 - 10 - 11
repeat(10)
t_h.randomize - 00 - 01 - 11 - 00 - 01 - 11 - 11

rand
00 - 01 - 11 - 00 - 01 - 11 - 11

randc
00 - 11 - 01 - 10 - 01 - 11 - 10 - 00 - 10 - 11
Code of Randomization:
class parent;
rand bit[7:0] a;
endclass
module sv;
parent p;
initial
begin
p=new();
repeat(10)
begin
p.rando
mize();
$display("a
=%0d",p.a);
end
end
CONSTRAINTS
Constraints
• Constraints are declared with in the class.
• In class after randomization only, constraints are possible.
• Constraints are limited to particular value.
• Control the values getting assigned on randomization, this can be achieved by writing
constraints.

Syntax :
constraint <constraint_name> { variable condition;}
Ex:
constraint sname{a==5;}

constraint sname{a%5==0;}
constraint sname_1{a%3==0;}
• constraint_modes:
• Constraint_mode(1) --- It will enable the constraint. By default
constraints are enabled
• Constraint_mode(0) --- It will disable the constraint.

• rand_modes:
• rand_mode(1) ----- It will enable the randomization. By default
randomization is enable
• rand_mode(0) ----- It will disable the randomization.
Types of Constraints:
• Inline constraint
• Inside constraint
• Distributional constraint
• Conditional constraints
• Solve before constraint
• Soft constraint
Inline example:
class packet;
rand bit [3:0] addr;
rand bit [3:0] data;

constraint data_range { data > 0; data < 10; }


endclass

module inline_constr;
initial begin
packet pkt;
pkt = new();
repeat(2)
begin
If(pkt.rando
mize()
with
{ addr ==
8; data ==
• inline constraints: used to introduce an additional constraint represented as
randomize() with;

• Inside Operator:
• During randomization , it might require to randomize the variable with in range of values.
the
• Values with in the inside block can be variable, constant or range.
Syntax:
constraint addr {data inside {1,3,[5:10],12,[13:15]};}
constraint data_range { data inside {[1:9]}; }
constraint data_range { data > 0; data < 10; length == size**2; size == 2;}

In the above example 1,3 are set of values and [13:15] represents range.
Inside operator:
class packet;
rand bit [3:0] addr; rand bit [3:0] wr; rand
bit [3:0] rd;
extern constraint addr_1_range {addr inside {[wr:rd]}; } // We can add values also with in the
range.
Endclass

module constr_inside;
initial begin packet pkt; pkt = new();
repeat(3) begin
pkt.randomize();
$display("wr = %0d,rd =
%0d",pkt.wr,pkt.rd);
$display("addr = %0d",pkt.addr); end
end
endmodule
Extern constraints :
class packet;
rand bit [3:0] addr;
rand bit [3:0] wr;
rand bit [3:0] rd;
extern constraint addr_1_range {} // We can add values also with in the range.
endclass

constraint packet::addr_1_range {addr inside {[wr:rd]}; }

module constr_inside;
initial begin packet pkt; pkt = new();
repeat(3) begin
pkt.randomize();
$display("wr = %0d,rd =
%0d",pkt.wr,pkt.rd);
$display("addr = %0d",pkt.addr); end
end
endmodule
Distribution constraints:
• Controls the values on randomization.
• Repetition of the same value on randomization can be controlled by weighted
distribution.
• There are 2 types of operators in distribution constraints.
1) := for each declared range, assigns weight to every value.
Syntax: [101:200] := 200
In the above example from 101 , 102, …,200 … each value gets a weight
of
200.
Constraint c1 {a.dist { [101:200] := 0};}
2) :/ assigns weight to whole
value. Syntax: [101:123]:/ 20
-------
// 20/23 = 0.86 => 1
In the above example each item
Conditional Constraint:
• The implication operator can be used to declaring conditional relations
between two variables.
Syntax:
Constraint identifier {expression ->{constraint_set};}

Constraint const {a>1 -> {b inside {[1:10]};};}


If else : if else block allows conditional executions of constraints. If the
expression is true, all the constraints in the first constraint/constraint-block must be
satisfied, otherwise all the constraints in the optional else constraint/constraint-
block must be satisfied.
Syntax:
{if (exp) {constraint_set {else constraint_set}};}
Example:
constraint address_range { if(addr == "true")
data < 8;
else
data > 8;
}
Soft Constraint:
• To override the constraint we use the soft keyword, any conflict between
class
constraint leads to a randomization failure, from this it is clear that it is not
possible to override the class constraint by inline constraint.

class packet; repeat(4) begin


rand bit [3:0] data; pkt.randomize() with { data < 6;};
$display("data = %0d",pkt.data);
constraint addr_range {soft data > 6; }
end
constraint addr_range_2 {data > 2; }
end
endclass
endmodule
module soft_constr;
initial begin Data = 3, 4, 5, 6
packet pkt; Data = 10 ,11, 12,124
pkt = new();
Solve before constraints:
• solve before constraints are used to force the constraint block to specify
the
order of constraint solving.
module inline;
Example:
initial
begin
class packet;
packet pkt;
rand bit; pkt = new();
rand bit [3:0]b; repeat(10)
constraint ab {solve a
pkt.randomi
before b;}
ze();
constraint a_b {(a $display(“v
==1) -> (b==0);} alue of a =
endclass %0d, b =
%0d”,
pkt.a , pkt.b);
Unique Constraint:
• Unique values to set of variables or unique elements to an array can be generated by using
Unique
Constraint.

Syntax: module sv;


class packet; packet pkt;
rand bit [31:0] array[10]; initial begin
constraint array_c {unique {array}; pkt = new();
foreach(array[i]) array[i] < 10;} pkt.randomiz
function display(); e();
$display("array = %p",array); pkt.display()
endfunction ; end
endclass endmodule
Scope resolution(::)
• This is used to randomize the variables that are not declared with rand key word.

Example:

module sv;
bit [3:0] a, b, c;
bit success;
initial begin
Success = std::randomize(a, b) with {a > 10; b > 10;};
$display(“a = %d, b = %d, c = %d, success = %d”, a, b, c, success);
end
endmodule
Keypoints of Constraints:
• Constraints are declared with in the class.
• Constraints are possible only after randomization.
• Constraint overriding is possible only by declaring the same name in another constraint
also.
• Syntax: constraint c1 {a == 10;}
constraint c1 { a == 20;}
• Constraint Conflict:
Syntax constraint c1 {a >10 ;}
: constraint c2 {a <10 ;}
In the above example , as we have declared the same variable name , randomization
cannot choose what constraint has to be randomized. So in this case constraint conflict
occurs.
MAILBOX
MAILBOX
:• A mailbox is a Inter Process communication mechanism between two components (i.e.,
generator
& driver) , (monitor & Scoreboard) in system Verilog.

• In generator we are using put() method , to place some data and using get() method we can
retrieve the data in driver.

• Mailbox has 2 types depends up on type:


• Generic mailbox (all data types)
• Parameterized mailbox (particular data type)
Mailbox has 2 types depends on size:
• Bounded mailbox (size is mentioned)
• Unbounded mailbox (size is not mentioned)
There are 2 methods of mailbox:
• put();, get(); , peek() Blocking methods
• tryput(), tryget(); , Non_blocking methods
trypeek();
Syntax:

mailbox # (transaction) gen2drv; // handle


Gen2drv = new(); // object – of unbounded – no limitation for the no
of transactions
Gen2drv = new(16); // object – of bounded –only 16 transactions can
be done – inside the mail box we can have only 16 transactions

Ex:
Mailbox #(interface intf) gen2drv;
SEMAPHORE
Semaphore:
• Semaphore is a System Verilog built-in class, used for access control to shared resources,
and for basic synchronization and mutual exclusion purpose.
• A semaphore is like a bucket with number of keys.
• By using semaphore we can put the keys and get the keys to access any files.

Semaphore methods:
• Semaphore is a built-in class that provides the following methods,
• new(); Create a semaphore with a specified number of keys.
• get(); Obtain one or more keys from the bucket.
• put(); Return one or more keys into the bucket.
• try_get(); Try to obtain one or more keys without
blocking.
• try_put(); To return one or more keys without blocking.
Semaphore code:

module semaphore_ex;
task automatic semaphore_ex::display();
semaphore sema; //handle
sema.get(4); //getting '4' keys from
Extern task automatic display();
sema
initial
$display($time,"Current Simulation Time");
begin sema=new(4); // object - key = 4
fork
#20;
display();
sema.put(4) //putting '4' keys to sema
display();
; endtask
join end
endmodule
STRATIFIED EVENT QUEUE
Detailed:
Stratified event scheduler:
Virtual Interface:
• An interface is a named as group of signals.
• Virtual Interface is Bi-directional.
• In interface we are declaring input , output signals by using logic data type.
• Virtual Interface is dynamic in nature, we can change virtual interface during the run_time.
• Virtual Interface contains Modports & Clocking blocks.
• Virtual interface point outs the physical interface which is present in the sv_library or
uvm_library.
• An interface can have parameters, constants, variables, functions, and tasks.
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
Code Coverage :
• Code coverage measures how much of the “design Code” is covered.

•The simulator tool will automatically extract the code coverage from the design code.

Types of Code Coverage :


1. Line Coverage

2. Statement Coverage

3. Toggle /Transition Coverage

4. FSM Coverage

5. Branch / Conditional Coverage

6. Block / Expression Coverage

7. Path Coverage
1. Line Coverage : Conveys the number of lines covered in the
design.
Syntax: input a ;

output b;

2. Statement Coverage :
Conveys the number of
statements covered.
Syntax: y = a+b;

x = b+c;

3. Toggle / Transition
Coverage : It covers
the toggle
i.e., 0-1 or 1-0
conditions.
Functional
coverage :
• Functional coverage is a user-defined metric that measures how much of the
design specifications or how many features have been covered in verification of
the design.
• Functional coverage is user-defines implemented at environment side.

• In the functional coverage we have covergroups

coverpoints,

bins ,

cross coverage.
Cover group:
covergroup cg @(posedge clk)
c1 : coverpoint addr disable iff (rst == 1){
Bins = {[100 : 200]};
bins[5] = {[300 : 500]};
} illegal bin = {[201:299]};
c2 : coverpoint data {
bins [ ] = {[10:50]};
bins [2] = {[60:90]};
}
c1 *c2 : cross c1,c2;
endgroup
• Once covergroup is created we need to create a handle for that.
Syntax: cg cg_inst;
• Once covergroup is instantiated we need to assign memory
for that.
Syntax: cg_inst = new();
• Once memory is assigned we need to sample the covergroup.
• cg_inst.sample ();
Defining cover
• 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 be created or can be explicitly defined.

Automatic Bins or Implicit Bins:


• An automatically single bin will be created for each value of the coverpoint variable range. These are
called
automatic, or implicit, bins.

• For an “n” bit integral coverpoint variable, a 2^n number of automatic bins will get created.

• Syntax : 1) bins [ ] = {[0:10]}; // Here 11 bins are created for 11 values.

2) bins [5] = {[0:10]} ;// 5 bins are created for 11 values.


Explicit bins :
• “bins” keyword is used to declare the bins explicitly to a variable.

• A separate bin is created for each value in the given range of variable or a single/multiple bins

for the range of values.

• Bins are explicitly declared within curly braces { } along with the bins keyword followed by

bin name and variable value/range, immediately after the coverpoint identifier.

• Syntax : c1: coverpoint addr { bins b1 = {0,2,7};}


Transition bins

• The 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

Syntax: c1: coverpoint addr { bins b1 = (10=>20=>30);}


illegal and ignore bins:

Ignore bins: Ignore bins are excluded from the coverage if you declare , the bin as ignore it will
give

the fatal error. It is not included in the coverage , but simulator will give the coverage list which are

ignored.

Syntax : - c1: coverpoint addr{ ignore_bins b1= {5 , 10 , 15};}

illegal bins: illegal_bins are not added in the coverage , it is excluded from the coverage , if we

declare illegal bin , simulator throws the run time error.

Syntax: - c1:coverpoint addr{ illegal_bins b1={7,70,77};}


Coverage options
at_least :

auto_bin_max :

cross_auto_bin_max :

eg

covergroup cg
@(posedge clk);

c1: coverpoint addr


{ option.auto_bin_ma
x = 128;}

c2: coverpoint wr_rd


{ option.atleast = 2;}

c1Xc2: cross c1, c2 { option.cross_auto_bin_max = 128;}


Important Topics of Coverage:
Scenario 1:
When Code Coverage is 90% & Functional coverage is 100% ?
• When code is covered till 90% remaining 10% is not covered due to missing of some blocks,
statements, toggle conditions , lines or FSM states etc.,

Scenario 2:
When Functional Coverage is 90% & Code Coverage is 100%?
• When code is Covered 100% ,but if functional coverage is less compared to code coverage
because of some features are missing, even though if we cover all features we cannot
expect 100% coverage.

Scenario 3:
Refinement File : When Functional Coverage is 98% , remaining 2% can be achieved by refinement file.
Refinement File can be collected from RTL designer.
Assertions / Checkers:
• Assertion is a property , that the design should operate and which is always
true.
• These are used to monitor the internal signals.
• To check the proper assertion quality, stimulus must be driven.

There are 2 types


1) Immediate of assertions
Assertions : in System Verilog:
• Immediate Assertions can be written only inside procedural block and will be only inside
active procedural block.
• Error message occurs when assertions fails.
2) Concurrent Assertions :
• By using Concurrent assertions we can express complex designs also very
simple.
• Can be used in procedural block , module, interface .
• Can be used with both static and Dynamic verification.
Built –in functions of
Assertions :
• $rose( ) : useful for edge triggered properties.
• Syntax: $rose (expr) : Change in transition of a signal and it must be 1.

• $fell( ) : Change in transition of a signal and it must be 0.


• Syntax : $fell (expr)

• $past( ): Returns the value of A from a previous evaluation cycle.


• Syntax : $past (A , N)

• $stable( ) : Checks for the previous cycle.

• $countones( ) : Returns the number of 1’s in an expression , any value other than one will be
ignored.
• Syntax : $countones (expr)

• $isunknown( ) : Returns a boolean true if any bit in expression is x or z.


• Syntax: $isunknown (expr)

You might also like