0% found this document useful (0 votes)
48 views184 pages

SystemVerilog Veriflcation

The document presents an overview of System Verilog for verification, detailing its features, verification basics, and the importance of design verification. It highlights the differences between verification and testing, the types of verification, and the advantages of using System Verilog, particularly in writing complex testbenches. Additionally, it covers object-oriented programming concepts, data types, and various array structures in System Verilog.

Uploaded by

Abhishek Kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
48 views184 pages

SystemVerilog Veriflcation

The document presents an overview of System Verilog for verification, detailing its features, verification basics, and the importance of design verification. It highlights the differences between verification and testing, the types of verification, and the advantages of using System Verilog, particularly in writing complex testbenches. Additionally, it covers object-oriented programming concepts, data types, and various array structures in System Verilog.

Uploaded by

Abhishek Kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 184

System Verilog for Verification

Presented by,
Dr. Amit M Joshi,
Assistant Professor,
Department of Electronics & Communication,
MNIT-Jaipur
Outline

❑ Verification Basics
❑ Features of System Verilog
❑ Arrays of System Verilog
❑ Basic of Test Bench
❑ Assertion
❑ Coverage
Basics of Verifications
What is Verification ?
• Verification is a process used to demonstrate the functional
correctness of a design.

• Commonly used verification process in our lives are :

􀂙 Balancing monthly bank statement

􀂙 Tasting of food dish


• Testbench” usually refers to the code used to create a pre-
determined input sequence to a design, then optionally observe the
response.
What is Design Verification?

❖ To verify the correctness of your design


(Find as many design bugs as possible)

Design Flow

Functional Design Design Physical


Specification Creation RTL Implementation Gate
Gate Implementation GDSII
Where are the Bugs?
• Functional specification
– English/Algorithms
→ Timing diagrams, system or behavior-level
descriptions
• Design creation
– Inconsistent with spec
– RTL coding error (typo, X, logical error)
– Assumption on the environment
• Design/Physical implementation
– Synthesis tools
– Manual optimization
What is Design Verification?

To verify the correctness of your design


(Find as many design bugs as possible)

Design Flow

Functional Design Design Physical


Specification Creation RTL Implementation Gate
Gate Implementation GDSII
Verification vs. Testing
Design Design Design Chip
Specification Creation Implementation Manufacture

High-level spec RTL design Synthesis/P&R ICs

Verification Testing

• Object → design • Object → chip


• Methodologies • Methodologies
➢ Simulation ➢ ATPG
➢ Emulation ➢ Fault Simulation
➢ Formal techniques ➢ Scan / BIST
Types of Verification
1. Functional (Would be discussing)
u Consider functional correctness only
u Usually doesn’t consider timing (i.e. 0-delay model)
u Sequential circuit (i.e. multi-cycles)
2. Timing
u Reg-to-reg timing constraints
u Clock domain checking
3. Physical
u Layout vs. Schematics (LVS)
u Design Rule Checking (DRC)
u Signal integrity
How do you verify/debug your
design?
A “Typical” Verification Practice
• Defining spec --- Chief architect or manager (or sometimes designer)
– Verified by proof-reading
– Write a behavior model and verify by simulation
• RTL coding
– Designer writes the testbench for his blocks
– Verification engineer creates the verification environment (tool
integration, scripts, etc)
– Designer/Verification engineer runs the RTL simulation
– Designer fixes the bugs
– (maybe) Designer/Verification engineer
writes more test benches
Yes, most people verify their designs
by simulation and debug by
looking at the waveforms
Verify by Simulation

0
1
0
1
1
0 Circuit 11000011
1 -
1 01100011
0 diff ?
0 expected
1 result
Any Problem? Whose Problem?
“My biggest problem about design
verification is that the time is never
enough. I can only do my best to run
more simulation, but I don’t know
whether it is sufficient.”
--- Broadcom designer (similar comments from
many others)

“It is very hard to write the testbenches


and assertions for the design, since I
am not a designer. Ask the designer
to do it more? No way!!”
--- Sun Microsystems verification engineer (similar
comments from many others)

What are
Gap between designers and
the problems?
verification engineers
– (For designers) I thought
I have fixed all the
bugs…
– (For verification
engineers) Find ways to
understand the design
better
• Verification methodologies
are not optimal
– Need to learn more
alternatives
Verfication usually takes up
to 70% of resource during
the design flow
Let’s do some math
• Suppose a circuit has 100
registers (this is considered tiny
in modern design)
100
– Total number of states = 2 =
30 24
10 = 10 M
– Requires (in the worse case) at
24
least 10 M cycles to exhaust
all the possible states
– Let alone the input
combinations
– Running simulation (million
cycles per second) can only
cover a very small portion of
state space
What is System Verilog?
What is SystemVerilog?

❖ SystemVerilog is a hardware description and Verification


language(HDVL)
❖ SystemVerilog is an extensive set of enhancements to IEEE
1364 Verilog-2001 standards
❖ It has features inherited from Verilog HDL,VHDL,C,C++
❖ It supports all features of verilog plus add on features
❖ It’s a super verilog
❖ Unified design, modeling, verification
❖ Latest IEEE standard 1800-2012
What is Verification ?

Complete validation of design functionality


❖ Make sure design is bug free by verifying it in all
aspects ; all possible scenarios

module half_adder(s,co,a,b);
output s,co;
Will this work??
input a,b;
xor1 u1(s,a,b);
nand1 u2 (co,a,b);
How to make sure design is
endmodule bug free??
How To Verify ?

A B S CO

B
Why System Verilog for Verification ?
➢ Verilog was initially used for writing testbench.
➢ But, writing complex testbenches is much more of a programming task
than describing hardware. No need to synthesize testbench.

➢ Fact: UVM is replacing SV based verification in industry.


➢ Still, UVM = Structured SV. Knowing SV based verification helps
understanding UVM based verification, else UVM feels like set of magic
macros.
UVM = Universal Verification Methodology
Why SystemVerilog ?
Why SystemVerilog?

Constrained Randomization Easy c model integration

OOP support New data types ie,logic


System Verilog
Assertions Coverage support

Narrow gap b/w design & verification engineer


OOP Concepts
What is OOP?

classes encapsulation

OOP

polymorphism inheritance
What is OOP?

❑ OOP is object oriented programming


❑ Classes form the base of OOP programming
❑ Encapsulation - OOP binds data & function together
❑ Inheritance –extend the functionality of existing objects
❑ Polymorphism – wait until runtime to bind data with
functions
What is OOP?

❑ OOP breaks a testbench into blocks that work together to


accomplish the verification goal
❑ Why OOP

• Highly abstract system level modelling


• Classes are intended for verification
• Classes are easily reused and extended
• Data security
• Classes are dynamic in nature
• Easy debugging, one class at a time
Why not C++

Why system
Verilog?

Why Not C++?


Why not C++

C++ System Verilog

❑ No relation to ❑ Superset of Verilog


verilog
❑ RTL/Verification language
❑ Interface is required
❑ Assertion language
to interact with Verilog
❑ Constraint language
❑ Code coverage language
Inheritance

❑ Inheritance is to reuse the existing code


❑ Inheritance allows to add new

• Data members(properties)
• New Methods

❑ Inheritance is to share code between classes


Inheritance

❑Advantages

• Common code can be grouped into one class


• No need to modify the existing classes
• Add new features to existing class by means of
new derived classes
• Easy debug & easy to maintain the code base
Relaxed data type rules
Verilog System Verilog

❑ Strict about usage of wire ❑ Logic data type can be used so


& reg data type no need to worry about reg & wire
❑ Variable types are 4 state ❑ 2 state data type added – 0, 1
– 0,1,X,Z state
❑ Memories are dynamic in
nature
SystemVerilog Concepts
System Verilog Concepts
Data types :
reg r; // 4-state Verilog-2001
Bit subs logic w; // 4-valued logic, see below
allowed bit b; // 2-state bit 0 or 1
integer i; // 4-state, 32-bits, signed Verilog-2001
byte b8; // 8 bit signed integer
int i; // 2-state, 32-bit signed integer
shortint s;// 2-state, 16-bit signed integer
longint l; // 2-state, 64-bit signed integer

Explicit 2-state variables allow compiler


optimizations to improve performance

logic is has single driver (procedural assignments or a


continuous assignment), can replace reg and single driver wire.
(Equivalent to “std_ulogic” in VHDL)
System Verilog Concepts
Data types :

Logic :

❖ Logic is replaced reg of verilog


❖ Reg keywords gets confused with flipflop
❖ Logic can be net or reg depending on usage
❖ Logic is 4 state type : 0,1 X, Z
Logic
➢ logic replaces reg of Verilog
➢ reg keyword gets confused with flipflop
➢ logic can be net or reg depending on usage

Logic – 4 state data type


Equivalent 2 – State
4 – State value Represents
value
logic zero or a false
0 0
condition
logic one or a true
1 1
condition
unknown logic value
X 0
(don’t care)
high-impedance state
Z 0
(open connection)
System Verilog Data Types

Variable
Integer

Real

Void

Class

String

Event
User-
Defined
Enumeratio
n
Variable – a data storage element

Variable Integer State Size Sign Default


Integer value Value
Real shortint 2 16 bits signed ‘0
Void int 2 32 bits signed ‘0
longint 2 64 bits signed ‘0
Class
byte 2 8 bits signed ‘0
String
bit 2 user-defined unsigned ‘0
Event vector
User-
Defined
logic 4 user-defined unsigned ‘X
Enumeratio vector
n
reg 4 user-defined unsigned ‘X
vector
integer 4 32 bits signed ‘X
time 4 64 bits unsigned ‘X
Variable – a data storage element

Variable Real type C-type Size Sign Default


Integer (floating Value
Real point)
Void real double 64 bits signed 0.0
shortreal float 32 bits signed 0.0
Class
$realtime
String

Event $realtime vs $time – Depends on


timescale
User-
Defined
Enumeratio
n
Variable – a data storage element

Variable ➢ synchronization of, two or more concurrently


Integer
active processes.
Real

Void

Class

String event a; // declaration


Event → a; // event triggerred
User-
Defined @(a); // waiting for occurrence of the event
Enumeratio trigger
n
Variable – a data storage element

Variable Typedef
Integer
typedef data_type type_identifier ;
Real

Void

Class
Ex.
String
typedef int animal;
Event
User- animal lion, tiger;
Defined
Enumeratio
n
Variable – a data storage element

Variable ➢ a set of integral named constants


Integer
enum {red, yellow, green} ← red = 0, yellow = 1, green
Real light1; =2
Void enum integer {IDLE, XX='x, S1='b01,
Class S2='b10} state, next;
← IDLE = 0, others
String having values
Event
User- enum {bronze=3, silver, gold} ← silver = 4, gold = 5
Defined medal;
Enumerati
on ←c=8
enum {a=3, b=7, c} alphabet;
Array of System Verilog

✓ Arrays
✓ Dynamic Array
✓ Associative Array
✓ Queue
Arrays
Packed Arrays : Unpacked Array :
➢Treated as single vector
➢byte, shortint, int, longint, ➢size after variable name
integer, time ➢logic b1 [7:0]
byte c2; ➢int a1 [7:0]
integer a1; // 2D array - packed int;
➢bit signed [7:0] c2;//size unpacked byte
before variable
logic signed [31:0] a1;
Memory : Array Literals:
int a [3:0]; → a = ‘{4{3}} =
logic [7:0] mem [0:255] ‘{3,3,3,3}
mem[5] = 0;
data = mem[addr] int b [0:1] [0:2] → b =
‘{‘{1,2,3},’{3{4}}}
1 2 3
4 4 4
Fixed Size Arrays
Declaring fixed-size arrays
• int lo_hi[0:15]; // 16 ints [0]..[15]
• int c_style[16]; // 16 ints [0]..[15]
Multi Dimensional
• int array2 [0:7][0:3]; // Verbose declaration
• int array3 [8][4]; // Compact declaration
• array2[7][3] = 1; // Set last array element
Packed and Unpacked Arrays
Queue…
❑ Data storage array [$]
• Variable size array with automatic sizing
• Searching, sorting and insertion methods
• A queue is a variable-size, ordered collection of
homogeneous elements.
• Each element in a queue is identified by an ordinal
number that represents its position within the queue, with
0 representing the first, and $ representing the last.
• A queue is analogous to a one-dimensional unpacked
array that grows and shrinks automatically.
Examples of Queue

• variable-size, ordered collection of homogeneous elements.


byte q1 [$] ; // queue of bytes, $ represents last.
string q2 [$] = {“hello”} ; // queue of strings initialized to “hello”
int q3 [$] = {3,2,7} ; // initialized queue of integers
Queue

Method Description

size() Returns number of items in queue

insert() Inserts given item at specific index

delete() Deletes item at specific index

pop_front() Removes and returns the first element of queue

pop_back() Removes and returns the last element of queue

push_front() Inserts element at front of queue

push_back() Inserts element at last of queue


Queue Operators

Following operators are used in working with queues

•0 : Used to access first element of queue


•$ : Used to access last element of queue
•{} : Used along with first and last operator to add/delete elements
Queue Methods
SystemVerilog provides following methods to work with queues
integer queue[$] = { 0, 1, 2, 3, 4 };
insert()
The insert() method inserts the given item at the specified index position.
queue.insert(4,8);
delete()
The delete() method deletes the item at the specified index position.
pop_front()
The pop_front() method removes and returns the first element of the queue.
i = queue.pop_front();
pop_back()
The pop_back() method removes and returns the last element of the queue.
push_front()
The push_front() method inserts the given element at the front of the queue.
push_back()
The push_back() method inserts the given element at the end of the queue.
size()
The size() method returns the number of items in the queue. If the queue is empty,
it returns 0.
Dynamic Array
A dynamic array is one dimension of an unpacked array whose
size can be set or changed at runtime. The space for a dynamic
array doesn t exist until the array is explicitly created at runtime.

SystemVerilog provides set of function to work with dynamic


arrays.

new[] : This operator is used to set or change the size of the


array.
size(): This method returns the current size of the array.
delete() : This method clears all the elements yielding an
empty array (zero size).
Dynamic Array
➢ Unpacked array, whose size can be set/change at runtime.
➢ declared by [] Ex. - int a [];
Method Description
new[]() Set/Change size of array, default value of array members = 0
set → int a [] = new [4]; //a size 4 → int a [] = new [4]
(b); //copy b to a
change → int a [] = new [8] (a); //copy old a to new a,
increase size to 8
size() Returns current size of dynamic array
→ int j = addr.size();
→ addr = new[ addr.size() * 4 ] (addr); // quadruple addr array

delete() Empties an array


int ab = new [4];
ab.delete(); // ab having size = 0
Dynamic Array
Associative Array
➢ Dynamic array - good with contiguous data collection, whose size
changes dynamically

➢ But when size of collection is unknown / Data space is sparse –Use


Associative Array

➢ Index can be of any data type, say string.

data_type array_name [index_type]

Ex. int abc [string];

integer def [*]; //unspecified index, can be anything

➢ Associative arrays do not have any storage allocated until it is used.


Associative Array
Method Description

num(), size() Returns number of entries in associative array

delete() Removes entry at specific index

exists() Checks whether element exists at specific index

first() Returns the value of first index

last() Returns the value of last index

next() Returns the smallest index whose value is greater than given
index
prev() Returns the largest index whose value is lesser than given
index
Interface

❑ bundling of port signals


• provide an abstract encapsulation of communication
between blocks
• Directional information (modports)
• Timing (clocking blocks)
• Functionality (routines,assertions)

device1 interface device2


Interfaces
Interfaces – Characteristics
• Brings abstraction-level enhancements to ports and internals

• Interface may contain any legal System Verilog code except


module definitions and/or instances.
– tasks, functions, initial/always blocks, parameters, etc.

• Bus timing, pipelining, etc. may be captured in an interface.

• Interfaces are defined once and used widely, so it simplifies


design.

• Interfaces are synthesizable.


Interface

Interface:An example

Interface bus_a (input clock);


logic [7:0] address;
logic [31:0] data ;
bit valid ;
bit rd_wr ;
Endinterface: bus_a
• Different users of interface need different views
– Master/Slave
– Monitor/driver

• Modport construct allows you to group signals and specify


directions

ModPorts
Modports
❑ An interface can have multiple viewpoints
• Master/Slave, Transmitter/Receiver
❑ These can be specified using modports

All signal names


Interface bus_b (input clock);
in a modport must
be declared in the
logic [7:0] addr,data;
interface
logic [1:0] mode ;
bit ready ;
modport master (input ready,output addr,data,mode) ;
modport slave (input addr,data,mode,output ready) ;
endinterface: bus_b
Mod port example
Clocking Block

❑ Specify synchronization characteristics of the


design
❑ Offer a clean way to drive and sample signals
❑ Features
• Clock specification
• Input skew,output skew
• Cycle delay (##)
Clocking Block

▪ Can be declared inside interface,module or program


▪ Used to specify timing of synchronous signals with respect to
clock
▪Mainly used in test benches and inside interfaces
▪It ensures that all signals are driven or sampled with same clock
delays
▪Interfaces can contain multiple clocking blocks (1 per clock)
Clocking Block
Module M1(ck, enin, din, enout, dout);
input ck,enin;
input [31:0] din ;
output enout ;
output [31:0] dout ;
Signals will be sampled
clocking sd @(posedge ck); 2ns before posedge ck
input #2ns ein,din ;
output #3ns enout, dout;
endclocking:sd Signals will be driven
3ns after posedge ck
reg [7:0] sab ;
initial begin
sab = sd.din[7:0];
end
endmodule:M1
Inter Process Communication
❑ High-level and easy-to-use synchronization and communication

mechanism are essential to control the kinds of interactions that


occur between dynamic processes
System Verilog provides following to help inter process
communication
❖Mailbox
❖Semaphore
❖Events
Mail Box

❑A mailbox is a mechanism to exchange messages between


processes.
❑ Data can be sent to a mailbox by one process and retrieved by
another.
❑Mailbox can be used a FIFO if required. Data can be any valid
system Verilog data types, including class data types.
METHODS OF USING MAIL BOX
• Mailbox is a built-in class that provides the following methods:
– Create a mailbox: new()
– Place a message in a mailbox: put()
– Try to place a message in a mailbox without
blocking: try_put()
– Retrieve a message from a mailbox: get() or peek()
– Try to retrieve a message from a mailbox without
blocking: try_get() or try_peek()
– Retrieve the number of messages in the mailbox: num()
Mail Box

SystemVerilog provides following methods for working with


mailbox.
❖ Mailbox allocation : new()
❖ Put data : put()
❖Try to place a message in a mailbox without blocking: try_put()
❖Get data : get() or peek()
❖Try to retrieve a message from a mailbox without blocking:
try_get() or try_peek()
❖Retrieve the number of messages in the mailbox: num()
Semaphore
❑ Used for Synchronization
• Variable number of keys can be put and removed
• controlled access to a shared object
• think of two people wanting to drive the same car – the key
is a semaphore
• Semaphore is used for lock/unlock of a common resource.
If resource is in unlock state the resource can be used, if it is
in lock state, then it can not be used.
Semaphore

❑ Semaphore in SystemVerilog supports


following methods for above operations.

Semaphore allocation : new()


Using semaphore keys : get()
Returing semaphore keys : put()
Try to obtain one or more keys without
blocking: try_get()
Randomization
Randomization

❑Why Randomization ?

• Random generation of stimulus


• Random setting of parameters
• Hard-to-reach corner cases can be reached
Randomization

Shift from directed to random

Directed Random

❑ Detect the expected bugs ❑ Detects unexpected bugs (corner


cases)
❑ Time consuming
❑ Tremendously reduce the efforts
Randomization

❑ Constrained Randomization
❑ Improves the result
❑ Speed-up the bug finding process
❑ More interesting cases can be achieved within the
constrained boundary
System Verilog Concepts
Fork/join
Initial
Begin
Clk =0;
fork
#5
Fork
#5 a = 0;
#10 b = 0;
join Join
Clk= 1;
end
System Verilog Concepts
Fork/join
Initial
Begin
Clk =0;
fork
#5
Fork
#5 a = 0;
#10 b = 0;
Clk becomes 1
join Join
at t=15
Clk= 1;
end
System Verilog Concepts
Fork/join_any
Initial
Begin
Clk =0;
fork
#5
Fork
#5 a = 0;
#10 b = 0;

Join_any Join_any
Clk= 1;
end
System Verilog Concepts
Fork/join_any
Initial
Begin
Clk =0;
fork
#5
Fork
#5 a = 0;
#10 b = 0;
Clk becomes 1
Join_any Join_any
at t=10
Clk= 1;
end
System Verilog Concepts
Fork/join_none
Initial
Begin
Clk =0;
fork
#5
Fork
#5 a = 0;
#10 b = 0;
Join_none
Join_none
Clk= 1;
end
System Verilog Concepts
Fork/join_none
Initial
Begin
Clk =0;
fork
#5
Fork
#5 a = 0;
#10 b = 0;
Clk becomes 1
Join_none
Join_none at t=5
Clk= 1;
end
Verification Targeted Capabilities
Verification environment

Checks Testbench
Verification
correctness Environment
Creates
stimulus
Identifies
Executes Test Self Check transactions
transactions

Transactor Checker Observes


Supplies data data
to the DUT from DUT
Driver Assertions Monitor

DUT
Assertions
Assertion

❑ Used primarily to validate the behaviour of a design


❑ An assertion is a statement about a designs intended behaviour
❑ In-line assertions are best added by design engineers
❑ Interface assertions are best added by verification engineers
❑ An assertion’s sole purpose is to ensure consistency between
the designer’s intention and design implementation
❑ It increases the bug detection possibility during RTL design
phase
Assertion
There are two kinds of assertions:
❑ concurrent
❑ Immediate

❖ Immediate assertions follow simulation event semantics for their


execution and are executed like a statement in a procedural block.

❖ Concurrent assertions are based on clock semantics and use


sampled values of variables.
Immediate Assertion

❑ procedural statements and are mainly used in simulation


❑ An assertion is basically a statement that something must be
true, similar to the if statement.

❑ If outcomes 0,x,z then simulator generates an error message

❑ Failure of assertion has severity associated with it. It cane be


$error, $warning or $fatal error.
A simple immediate assertion is shown below,
The always block executes if either signal "a" or signal "b" changes.
Concurrent Assertion
❑ Concurrent assertions describe behavior that spans over time.
❑ Unlike immediate assertions, the evaluation model is based
on a clock such that a concurrent assertion is evaluated only at
the occurrence of a clock tick.
❑ The behaviour of a design may be specified using statements
similar to these:
"The Read and Write signals should never be asserted together."

❑ asserts that the expression Read && Write is never true at any
point during simulation.
Concurrent Assertion

❑ "A Request should be followed by an Acknowledge occurring


no more than two clocks after the Request is asserted."

❑|-> is the implication operator, so this assertion checks that


whenever Req is asserted Ack should be asserted in next or next
to next clock cycle.
❑ There are two forms of implication: overlapped using
operator |->, and non-overlapped using operator |=>. after the
Request is asserted."
Properties and Sequences
❑ Example with property

❑ Example with Sequence


Different Operator with Sequences
❑ The ## operator delays execution by the specified number of
clocking events, or clock cycles

❑ The * operator is used to specify a consecutive repetition


of the left-hand side operand.
Different Operator with Sequences
❑ The $ operator can be used to extend a time window to a
finite, but unbounded range.

❑ The [-> or goto repetition operator specifies a non-


consecutive sequence.

❑ The [= or non-consecutive repetition operator is similar


to goto repetition, but the expression (b in this example)
need not be true in the clock cycle before c is true
Random Constraints
Simplest randomness
❖ $urandom system tasks
❖ $urandom() is SV, thread stable, deterministic
❖ $urandom returns unsigned 32-bit integers
❖ Constraints are built onto the Class system
❖ Random variables use special modifier:
❖rand –random variable
❖randc –random cyclic variable
❖ Object is randomized by calling randomize( )method
❖Automatically available for classes with random variables.
Constraints
❖ Set of Boolean algebraic expressions
❖ Example:
❖ constraint a_le_b { a <= b; }
❖ constraint c_eq_10 {c == 10;}
❖ constraint b_in_range { b >= 2 && b <= 8; }
❖ constraint all_gt_0 {a > 0; b > 0; c > 0;}
Conflicting constraints
• What happens when you impose constraints that conflict
in some way?
• Example:
– constraint x_gt_y { x > y; }
– constraint y_gt_z { y > z; }
– constraint z_gt_x { z > x; }
– …
– if ( x_inst.randomize() == 0 ) // Solver error
– begin
– …
– end
Coverage
Covergroup

❑ Captures results from a random simulation


❑ Encapsulates the coverage specification
• bins
• transitions

Covergroup check @(posedge top.valid );


coverpoint global;
coverpoint top.test;
endgroup:check
………………
check chk = new();
Coverage Features

• Coverage of variables and expressions


• Cross coverage
• Automatic and user-defined coverage bins
-- Values, transitions, or cross products
• Filtering conditions at multiple levels
• Flexible coverage sampling
-- Events, Sequences, Procedural
Cover Groups
❑ The covergroup construct encapsulates the specification of a coverage model.
❑Each cover group specification can include the following components:
▪ clocking event that synchronizes the sampling of coverage points
▪ A set of coverage points
▪ Cross coverage between coverage points
▪ Optional formal arguments
▪ Coverage options
Cover group is defined between key words covergroup & endgroup.
A Covergroup Instance can be created using the new() operator.

covergroup cg;
...
...
...
endgroup

cg cg_inst = new;
Cover points
❑ A covergroup can contain one or more coverage points. A
coverage point can be an integral variable or an integral expression.
A coverage point creates a hierarchical scope, and can be optionally
labeled. If the label is specified then it designates the name of the
coverage point.

program main;
bit [0:2] y;
bit [0:2] values[$]= '{3,5,6};
covergroup cg;
cover_point_y : coverpoint y;
endgroup
cg cg_inst = new();
initial
foreach(values[i])
begin
y = values[i];
cg_inst.sample();
end
endprogram
Cover points

❑ Results
VARIABLE : cover_point_y
Expected : 8
Covered : 3
Percent: 37.50.
Bins
COVERAGE BINS

❖ A coverage-point bin associates a name and a count with a set of


values or a sequence of value transitions.
❖ If the bin designates a set of values, the count is incremented
every time the coverage point matches one of the values in the
set.
❖ If the bin designates a sequence of value transitions, the count is
incremented every time the coverage point matches the entire
sequence of value transitions.
Bins can be created implicitly or explicitly.
Bins
Implicit Bins
While define cover point, if you do not specify any bins, then
Implicit bins are created. The number of bins creating can be
controlled by auto_bin_max parameter.

Example for non enum cover point


program main;
bit [0:2] y;
bit [0:2] values[$]= '{3,5,6};
covergroup cg;
cover_point_y : coverpoint y
{ option.auto_bin_max = 4 ; }
endgroup
cg cg_inst = new();
initial
foreach(values[i])
begin
y = values[i];
cg_inst.sample();
end
endprogram
Bins
In the above example, the auto_bin_max is declared as 4. So, the total possible values are
divided in 4 parts and each part correspoits to one bin. The total possible values for variable
"y" are 8. They are divided in to 4 groups.
Bin[0] for 0 and 1
Bin[1] for 2 and 3
Bin[2] for 4 and 5
Bin[3] for 6 and 7
Varible Y is assigned values 3,5 and 6. Values 3,5 and 6 belongs to bins bin[1],bin[2] and
bin[3] respectively. Bin[0] is not covered.
Coverage report:
--------------------
VARIABLE : cover_point_y
Expected : 4
Covered : 3
Percent: 75.00
Uncovered bins
------------------
auto[0:1]
Covered bins
------------------
auto[2:3]
auto[4:5]
EXPLICIT BIN CREATION
Explicit bin creation is recommended method. Not all values are interesting or
relevant in a cover point, so when the user knows the exact values he is going to
cover, he can use explicit bins. You can also name the bins.
program main;
bit [0:2] y;
bit [0:2] values[$]= '{3,5,6};
covergroup cg;
cover_point_y : coverpoint y {
bins a = {0,1};
bins b = {2,3};
bins c = {4,5};
bins d = {6,7};
}
endgroup
cg cg_inst = new();
initial
foreach(values[i])
begin
y = values[i];
cg_inst.sample();
end
endprogram
EXPLICIT BIN CREATION

In the above example, bins are created explicitly. The bins are named a,b,c and d.

Coverage report:
-------------------
VARIABLE : cover_point_y
Expected : 4
Covered : 3
Percent: 75.00

Uncovered bins
--------------------
a

Covered bins
--------------------
b
c
d
Array Of Bins

To create a separate bin for each value (an array of bins) the square brackets, [], must follow
the bin name.

program main;
bit [0:2] y;
bit [0:2] values[$]= '{3,5,6};
covergroup cg;
cover_point_y : coverpoint y {
bins a[] = {[0:7]};
}
endgroup

cg cg_inst = new();
initial
foreach(values[i])
begin
y = values[i];
cg_inst.sample();
end

endprogram
Array Of Bins

In the above example, bin a is array of 8 bins and each bin associates to one number between
0 to 7.

Coverage report:
--------------------
VARIABLE : cover_point_y
Expected : 8
Covered : 3
Percent: 37.50

Uncovered bins
-------------------
a_0
a_1
a_2
a_4
a_7

Covered bins
-------------------
a_3
a_5
a_6
To create a fixed number of bins for a set of values, a number can be specified inside the
square brackets.

program main;
bit [0:3] y;
bit [0:2] values[$]= '{3,5,6};

covergroup cg;
cover_point_y : coverpoint y {
bins a[4] = {[0:7]};
}
endgroup

cg cg_inst = new();
initial
foreach(values[i])
begin
y = values[i];
cg_inst.sample();
end

endprogram
In the above example, variable y is 4 bit width vector. Total possible values for this vector
are 16.
But in the cover point bins, we have giving the interested range as 0 to 7. So the coverage
report is calculated over the range 0 to 7 only. In this example, we have shown the number
bins to be fixed to size 4.

Coverage report:
--------------------
VARIABLE : cover_point_y
Expected : 4
Covered : 3
Percent: 75.00

Uncovered bins
-------------------
a[0:1]

Covered bins
------------------
a[2:3]
a[4:5]
a[6:7]
Cover points
A coverage point can be an integral variable or an integral Expression.
SystemVerilog allows specifying the cover points in various ways.

1)Using XMR
Example:
Cover_xmr : coverpoint top.DUT.Submodule.bus_address;
2)Part select
Example:
Cover_part: coverpoint bus_address[31:2];
3)Expression
Example:
Cocver_exp: coverpoint (a*b);
4)Function return value
Example:
Cover_fun: coverpoint funcation_call();
5)Ref variable
Example:
covergroup (ref int r_v) cg;
cover_ref: coverpoint r_v;
endgroup
Cover filter
The expression within the iff construct specifies an optional condition that
disables coverage for that cover point. If the guard expression evaluates to false at
a sampling point, the coverage point is ignored.

For example:

covergroup cg;
coverpoint cp_varib iff(!reset); // filter condition
endgroup

In the preceding example, cover point varible "cp_varib" is covered only if the
value reset is low.
COVERAGE BINS
Default Bins
The default specification defines a bin that is associated with none of the defined value bins.
The default bin catches the values of the coverage point that do not lie within any of the
defined bins. However, the coverage calculation for a coverage point shall not take into
account the coverage captured by the default bin.

program main;
bit [0:3] y;
bit [0:2] values[$]= '{3,5,6};
covergroup cg;
cover_point_y : coverpoint y {
bins a[2] = {[0:4]};
bins d = default;
}
endgroup
cg cg_inst = new();
initial
foreach(values[i])
begin
y = values[i];
cg_inst.sample();
end
endprogram
Default Bin
In the above example, we have specified only 2 bins to cover values from 0 to 4. Rest of
values are covered in default bin which is not using in calculating the coverage percentage.

Coverage report:
--------------------
VARIABLE : cover_point_y
Expected : 2
Covered : 1
Percent: 50.00

Uncovered bins
------------------
a[0:1]

Covered bins
----------------
a[2:4]

Default bin
-----------------
d
TRANSITION BINS

Transitional functional point bin is used to examine the legal


transitions of a value. SystemVerilog allows to specifies one or more
sets of ordered value transitions of the coverage point.

Type of Transitions:

Single Value Transition


Sequence Of Transitions
Set Of Transitions
Consecutive Repetitions
Range Of Repetition
Goto Repetition
Non Consecutive Repetition
Single Value Transition

Single value transition is specified as:


value1 => value2
program main;
bit [0:3] y;
bit [0:2] values[$]= '{3,5,6};
covergroup cg;
cover_point_y : coverpoint y {
bins tran_34 = (3=>4);
bins tran_56 = (5=>6);
}
endgroup
cg cg_inst = new();
initial
foreach(values[i])
begin
y = values[i];
cg_inst.sample();
end
endprogram
In the above example, 2 bins are created for covering the transition
of point "y" from 3 to 4 and other for 5 to 6. The variable y is given
the values and only the transition 5 to 6 is occurring.

Coverage report:
--------------------
VARIABLE : cover_point_y
Expected : 2
Covered : 1
Percent: 50.00

Uncovered bins
------------------
tran_34

Covered bins
----------------
tran_56
Sequence Of Transitions
A sequence of transitions is represented as:
value1 => value3 => value4 => value5
In this case, value1 is followed by value3, followed by value4 and followed by
value5. A sequence can be of any arbitrary length.
program main;
bit [0:3] y;
bit [0:2] values[$]= '{3,5,6};
covergroup cg;
cover_point_y : coverpoint y {
bins tran_345 = (3=>4>=5);
bins tran_356 = (3=>5=>6);
}
endgroup
cg cg_inst = new();
initial
foreach(values[i])
begin
y = values[i];
cg_inst.sample();
end
endprogram
In the above example, 2 bins re created for covering the transition of
point "y" from 3 to 4 to 5 and other for 3 to 5 to 6. The variable y is
given the values and only the transition 3 to 5 to 6 is occurring.

Coverage report:
--------------------
VARIABLE : cover_point_y
Expected : 2
Covered : 1
Percent: 50.00

Uncovered bins
------------------
tran_345

Covered bins
-----------------
tran_356
Set Of Transitions
A set of transitions can be specified as:
range_list1 => range_list2
program main;
bit [0:3] y;
bit [0:2] values[$]= '{3,5,6};
covergroup cg;
cover_point_y : coverpoint y {
bins trans[] = (3,4=>5,6);
}
endgroup
cg cg_inst = new();
initial
foreach(values[i])
begin
y = values[i];
cg_inst.sample();
end
endprogram
In the above example, bin trans creates 4 bin for covering
3=>5,4=>5,3=>6 and 4=>6.

Coverage report:
--------------------
VARIABLE : cover_point_y
Expected : 4
Covered : 1
Percent: 25.00

Uncovered bins
------------------
tran_34_to_56:3->6
tran_34_to_56:4->5
tran_34_to_56:4->6

Covered bins
----------------
tran_34_to_56:3->5
Consecutive Repetitions

Consecutive repetitions of transitions are specified using


trans_item [* repeat_range ]

Here, trans_item is repeated for repeat_range times. For


example,
3 [* 5]
is the same as
3=>3=>3=>3=>3
program main;
bit [0:3] y;
bit [0:2] values[$]= '{3,3,3,4,4};
covergroup cg;
cover_point_y : coverpoint y {
bins trans_3 = (3[*5]);
bins trans_4 = (4[*2]);
}
endgroup

cg cg_inst = new();
initial
foreach(values[i])
begin
y = values[i];
cg_inst.sample();
end
endprogram
Coverage report:
--------------------
VARIABLE : cover_point_y
Expected : 2
Covered : 1
Percent: 50.00

Uncovered bins
------------------
trans_3

Covered bins
----------------
trans_4
Range Of Repetition

An example of a range of repetition is:


3 [* 3:5]
is the same as
3=>3=>3, 3=>3=>3=>3, 3=>3=>3=>3=>3
program main;
bit [0:3] y;
bit [0:2] values[$]= '{4,5,3,3,3,3,6,7};

covergroup cg;
cover_point_y : coverpoint y {
bins trans_3[] = (3[*3:5]);
}
endgroup
cg cg_inst = new();
initial
foreach(values[i])
begin
y = values[i];
cg_inst.sample();
end
endprogram
In the above example, only the sequence 3=>3=>3=>3 is generated. Other
expected sequences 3=>3=>3 and 3=>3=>3=>3=>3 are not generated.
Coverage report:
--------------------
VARIABLE : cover_point_y
Expected : 3
Covered : 1
Percent: 33.33

Uncovered bins
------------------
tran_3:3[*3]
tran_3:3[*5]

Covered bins
----------------
tran_3:3[*4]
Goto Repetition
The goto repetition is specified using: trans_item [-> repeat_range]. The
required number of occurrences of a particular value is specified by the
repeat_range. Any number of sample points can occur before the first
occurrence of the specified value and any number of sample points can
occur between each occurrence of the specified value. The transition
following the goto repetition must immediately follow the last occurrence
of the repetition.
For example:
3 [-> 3]
is the same as
...=>3...=>3...=>3
where the dots (...) represent any transition that does not contain the value
3.
A goto repetition followed by an additional value is represented as
follows:
1 => 3 [ -> 3] => 5
is the same as
1...=>3...=>3...=>3 =>5
program main;
bit [0:3] y;
bit [0:2] values[$]= '{1,6,3,6,3,6,3,5};
covergroup cg;
cover_point_y : coverpoint y {
bins trans_3 = (1=>3[->3]=>5); }
endgroup
cg cg_inst = new();
initial
foreach(values[i])
begin
y = values[i];
cg_inst.sample();
end endprogram

Coverage report:
--------------------
VARIABLE : cover_point_y
Expected : 1
Covered : 1
Percent: 100.00
Coverage report:
--------------------
VARIABLE : cover_point_y
Expected : 1
Covered : 1
Percent: 100.00
Non Consecutive Repetition

The nonconsecutive repetition is specified using: trans_item [= repeat_range].


The required number of occurrences of a particular value is specified by the
repeat_range. Any number of sample points can occur before the first
occurrence of the specified value and any number of sample points can occur
between each occurrence of the specified value. The transition following the
nonconsecutive repetition may occur after any number of sample points so long
as the repetition value does not occur again.
For example:
3 [= 2]
is same as ...=>3...=>3

A nonconsecutive repetition followed by an additional value is represented as


follows:
1 => 3 [=2] => 5
is the same as
1...=>3...=>3...=>5
program main;
bit [0:3] y;
bit [0:2] values[$]= '{1,6,3,6,3,6,5};
covergroup cg;
cover_point_y : coverpoint y {
bins trans_3 = (1=>3[=2]=>5); }
endgroup
cg cg_inst = new();
initial
foreach(values[i])
begin
y = values[i];
cg_inst.sample();
end
endprogram

Coverage report:
--------------------
VARIABLE : cover_point_y
Expected : 1
Covered : 1
Percent: 100.00
WILDCARD BINS

By default, a value or transition bin definition can specify 4-state


values.
When a bin definition includes an X or Z, it indicates that the bin
count should only be incremented when the sampled value has an X
or Z in the same bit positions.
The wildcard bins definition causes all X, Z, or ? to be treated as
wildcards for 0 or 1 (similar to the ==? operator).
For example:

wildcard bins g12_16 = { 4'b11?? };

The count of bin g12_16 is incremented when the sampled variable is


between 12 and 16:

1100 1101 1110 1111


program main;
reg [0:3] y;
reg [0:3] values[$]= '{ 4'b1100,4'b1101,4'b1110,4'b1111};
covergroup cg;
cover_point_y : coverpoint y {
wildcard bins g12_15 = { 4'b11?? } ; }
endgroup
cg cg_inst = new();
initial
foreach(values[i])
begin
y = values[i];
cg_inst.sample();
end
endprogram
Coverage report:
VARIABLE : cover_point_y
Expected : 1
Covered : 1
Percent: 100.00
Covered bin
g12_15 Number of times g12_15 hit : 4
Coverage report:
VARIABLE : cover_point_y
Expected : 1
Covered : 1
Percent: 100.00
Covered bin
g12_15 Number of times g12_15 hit : 4
Similarly, transition bins can define wildcard bins.
For example:

wildcard bins T0_3 = (2'b0x => 2'b1x);

The count of transition bin T0_3 is incremented for the following


transitions (as if by (0,1=>2,3)):

00 => 10 , 00 => 11, 01 => 10 , 01 => 11


program main;
reg [0:1] y;
reg [0:1] values[$]= '{ 2'b00,2'b01,2'b10,2'b11};

covergroup cg;
cover_point_y : coverpoint y {
wildcard bins trans = (2'b0X => 2'b1X );
}

endgroup
Coverage report:
--------------------
VARIABLE : cover_point_y
Expected : 1
Covered : 1
Percent: 100.00

Covered bin
---------------
trans
Number of times trans hit : 1 (01 => 10)
IGNORE BINS

A set of values or transitions associated with a coverage-point can


be explicitly excluded from coverage by specifying them as
ignore_bins.

program main;
bit [0:2] y;
bit [0:2] values[$]= '{1,6,3,7,3,4,3,5};

covergroup cg;
cover_point_y : coverpoint y {
ignore_bins ig = {1,2,3,4,5};
}

endgroup
Coverage report:
--------------------
VARIABLE : cover_point_y
Expected : 3
Covered : 2
Percent: 66.66
Uncovered bins
------------------
auto[0]

Excluded/Illegal bins
-------------------------
ig
auto[1]
auto[2]
auto[3]
auto[4]
auto[5]
Covered bins
----------------
auto[6]
auto[7]
ILLEGAL BINS

A set of values or transitions associated with a coverage-point can be


marked as illegal by specifying them as illegal_bins. All values or
transitions associated with illegal bins are excluded from coverage. If
an illegal value or transition occurs, a runtime error is issued.

program main;
bit [0:2] y;
bit [0:2] values[$]= '{1,6,3,7,3,4,3,5};

covergroup cg;
cover_point_y : coverpoint y {
illegal_bins ib = {7};
}
endgroup
Result:
------------
** ERROR **
Illegal state bin ib of coverpoint cover_point_y in
covergroup cg got hit with value 0x7
CROSS COVERAGE

Cross allows keeping track of information which is received


simultaneous on more than one cover point. Cross coverage is
specified using the cross construct.
program main;
bit [0:1] y;
bit [0:1] y_values[$]= '{1,3};

bit [0:1] z;
bit [0:1] z_values[$]= '{1,2};

covergroup cg;
cover_point_y : coverpoint y ;
cover_point_z : coverpoint z ;
cross_yz : cross cover_point_y,cover_point_z
;
endgroup
cg cg_inst = new();
initial
foreach(y_values[i])
begin
y = y_values[i];
z = z_values[i];
cg_inst.sample();
end

endprogram
In the above program, y has can have 4 values 0,1,2 and 3 and
similarly z can have 4 values 0,1,2 and 3. The cross product of the y
and z will be 16 values
(00),(01),(02),(03),(10),(11)........(yz)......(32)(33) .
Only combinations (11) and (32) are generated.

Cross coverage report: cover points are not shown.

Covered bins
-----------------
cover_point_y cover_point_z
auto[3] auto[2]
auto[1] auto[1]
Example:
module test();
logic [2:0] addr;
logic [1:0] cmd;
reg ce;
covergroup address_cov () @ (posedge ce);
ADDRESS : coverpoint addr {
bins addr0 = {0};
bins addr1 = {1};
bins addr2 = {2};
bins addr3 = {3};
} CMD :
coverpoint cmd {
bins READ = {0};
bins WRITE = {1};
bins IDLE = {2};
};
CRS_ADDR_CMD : cross ADDRESS, CMD;
endgroup
address_cov my_cov = new();
initial begin
ce <= 0;
$monitor("ce %b addr 8'h%x cmd %x",ce,addr,cmd);
repeat (10)
begin ce <= 1;
addr <= $urandom_range(0,5);
cmd <= $urandom_range(0,2);
#10;
ce <= 0;
#10;
end
end
endmodule
ce 1 addr 8'h2 cmd 2
ce 0 addr 8'h2 cmd 2
ce 1 addr 8'h1 cmd 0
ce 0 addr 8'h1 cmd 0
ce 1 addr 8'h1 cmd 2
ce 0 addr 8'h1 cmd 2
ce 1 addr 8'h4 cmd 0
ce 0 addr 8'h4 cmd 0
ce 1 addr 8'h0 cmd 2
ce 0 addr 8'h0 cmd 2
ce 1 addr 8'h5 cmd 2
ce 0 addr 8'h5 cmd 2
ce 1 addr 8'h2 cmd 2
ce 0 addr 8'h2 cmd 2
ce 1 addr 8'h5 cmd 0
ce 0 addr 8'h5 cmd 0
ce 1 addr 8'h2 cmd 2
ce 0 addr 8'h2 cmd 2
ce 1 addr 8'h4 cmd 2
ce 0 addr 8'h4 cmd 2
User-Defined Cross Bins
User-defined bins for cross coverage are defined using bin select expressions.
Consider the following example code:

int A,B;
coverpoint A { a[] ={[0:27]};}
coverpoint B { b[] = {[0:27]};}
cross_A_B cross a,b;

You need selected range cross between A,B


like i need cross between a[2]...a[5] & b[3]...b[6],
a[6]...a[8] & b[7]...b[10],
a[9]...a[15] & b[11]...b[15],
a[16]...a[27] & b[16]..b[27];

cross A_B a,b {


bins r1 = binsof(a) intersect {[2:5]} && binsof(b) intersect {[3:6]};
bins r2 = binsof(a) intersect {[6:8]} && binsof(b) intersect {[7:10]};
bins r3 = binsof(a) intersect {[9:15]} && binsof(b) intersect {[11:15]};
bins r4 = binsof(a) intersect {[16:27]} && binsof(b) intersect {[16:27]};
}
User-Defined Cross Bins
User-defined bins for cross coverage are defined using bin select expressions.
Consider the following example code:

int A,B;
coverpoint A { a[] ={[0:27]};}
coverpoint B { b[] = {[0:27]};}
cross_A_B cross a,b;

Instead of
coverpoint A { a[] ={[0:27]};}
coverpoint B { b[] = {[0:27]};}
Do write:
coverpoint A { bins a1 = {[2:5]};
bins a2 = {[2:8]};
bins a3 = {[9:15]};
bins a4 = {[16:27]};
} coverpoint B
{ bins b1 = {[3:6]};
bins b2 = {[7:10]};
bins b3 = {[11:15]};
bins b4 = {[16:27]}; }
SYSTEM TASKS

SystemVerilog provides the following system tasks and functions to help manage
coverage data collection.

$set_coverage_db_name ( name ) :
Sets the filename of the coverage database into which coverage information is saved at
the end of a simulation run.

$load_coverage_db ( name ) :
Load from the given filename the cumulative coverage information for all coverage
group types.

$get_coverage ( ) :
Returns as a real number in the range 0 to 100 the overall coverage of all coverage
group types.
SYSTEM TASKS

There are tasks and functions that are used to generate input
and output during simulation. Their names begin with a
dollar sign ($). The synthesis tools parse and ignore system
functions, and hence can be included even in synthesizable
models

$display, $strobe, $monitor

Difference among three?


SYSTEM TASKS

$display and $strobe display once every time they are


executed, whereas $monitor displays every time one of its
parameters changes.

$strobe:
$strobe displays the parameters at the very end of the current
simulation time unit.

$display
when it is executed it will be displayed

$monitor
$monitor displays every time one of its parameters changes
$time, $stime, $realtime
These return the current simulation time as a 64-bit integer, a 32-
bit integer, and a real number, respectively.

$reset, $stop, $finish


$reset resets the simulation back to time 0; $stop halts the
simulator and puts it in interactive mode where the user can enter
commands; $finish exits the simulator back to the operating
system.
References
Websources:
1. www.systemverilog.org
2. www.asic-world.com/systemverilog/index.html
3. http://svug.org/

Books :
1. Writing Testbenches using SystemVerilog
- Janick Bergeron
2. Verification Methodology Manual
- Janick Bergeron
3. SystemVerilog For Verification
- Chris Spear
183
Thank you

You might also like