UVM JDI Ebook

Download as pdf or txt
Download as pdf or txt
You are on page 1of 103
At a glance
Powered by AI
The key takeaways are about unleashing UVM adoption globally through free availability of learning material and increasing UVM adoption across the globe.

The purpose of this book is to help engineers get started with UVM and provide a simple verification example to understand UVM concepts.

Some of the topics covered in the book include introduction to UVM, getting started with UVM, simple verification model example, simulation results etc.

UnleashingUVM – Just Do It!

Congratulations on your personalized copy of the book:

UnleashingUVM – Just Do It!

About this e-book copy

This copy of the electronic edition of the


book, “UnleashingUVM – Just Do It!” is
provided to you for your use only and is
electronically marked with your identification.
You may not distribute this copy to others;
instead, please refer them to download their own
free copy at:

www.verifnews.org/UnleashingUVM/JDI

Unauthorized reproduction or distribution


is strictly prohibited. Reproductions may not be
shared or transmitted in any form or by any
means, electronic or mechanical, without the
express written consent of the publisher.

For more information about this book as


well as any addenda or errata published
subsequent to this edition, please refer to the
2
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

UnleashingUVM website:

www.verifnews.org/UnleashingUVM/JDI

Copyright

Copyright © 2018 by Ajeetha Kumari, Srinivasan


Venkataramanan.

All rights reserved. No part of this work covered


by the copyright herein may be reproduced,
transmitted, stored, or used in any form or by any
means graphic, electronic, or mechanical,
including but not limited to photocopying,
recording, scanning, taping, digitizing, web
distribution, information networks, or
information storage and retrieval systems, except
as permitted under Section 107 or 108 of the 1976
US Copyright Act, without the prior written
permission of the publisher. Published jointly by
VerifNews.org, VerifWorks & CVC.

Although the authors and publisher have made


every effort to ensure the accuracy and
completeness of information contained in this
3
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

book, we assume no responsibility for errors,


inaccuracies, omissions, or any inconsistency
herein.

4
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

Acknowledgements

We would like to thank our customers,


partners, colleagues and friends who engaged
with us over the years and induced the motivation
to create this book. We specially thank Ben
Cohen for reviewing our book and providing
valuable feedback.

We would like to thank our families for


what we are today. Without our parents and our
families’ blessings we couldn’t have been here.

We acknowledge the valuable time of our


sons Anirudh and Adruth & our family for
having scarified their personal time that they have
missed while their parents were busy writing
these books over the years. We also would like to
dedicate this book to our father/in-law and role
model Sri. Venkataramanan Krishnamurthy.
His memories and blessings are our sole
inspiration to take up challenges and cross them
successfully.
5
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

Table of Contents

Prologue ..................................................................... 9
The humble beginning ................................................ 9
Early day of SystemVerilog & CVC ............................... 9
The “Becoming of DV power-house” ......................... 10
Recognition of CVC .................................................... 11
UnleashingUVM book – the big picture ..................... 12
About this book – Just Do It ...................................... 13
1. Introduction ....................................................... 14
2. Why UVM? ........................................................ 15
3. Lets’ get started ................................................. 17
4. Simple DFF Verification Model ........................... 24
4.1. DFF description ................................................... 24
4.2. RTL model for DFF ............................................... 25
4.3. Verifying DFF functionality .................................. 25
4.4. Role of SystemVerilog interface in UVM ............. 26
4.5. SystemVerilog interface for DFF .......................... 27
4.6. Adding modport, clocking block .......................... 27
4.7. Using SystemVerilog Assertions .......................... 28
5. Using Go2UVM test to verify DFF ....................... 30
5.1. Using a base test go2uvm_base_test .................. 30
5.2. Using `G2U_TEST_BEGIN macro .......................... 32
5.3. Using UVM config-db to retrieve interface .......... 33
5.4. Applying reset to the design ............................... 34
5.5. Separation of Concerns –UVM way ..................... 37
6
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

5.6. Main phase of DFF test ....................................... 38


5.7. First, complete UVM test .................................... 39
5.8. Putting it all together – top module .................... 41
5.9. Clock generation in Go2UVM .............................. 41
5.10. Connecting DUT & Test via virtual interface ..... 42
5.11. Summary, next steps ........................................ 44
6. UVM - Conceptual view ..................................... 44
7. Using classes to model testbench components and
transactions .............................................................. 47
8. Verification of a FIFO – UVM .............................. 49
8.1. DUT .................................................................... 49
8.2. Modeling transactions ........................................ 50
8.3. Building a driver model in UVM .......................... 55
8.4. Building a sequencer model in UVM ................... 65
8.5. Building Hierarchical components in UVM .......... 66
8.6. UVM Agent ......................................................... 68
8.6.1. Creating a FIFO Agent ....................................... 69
8.6.2. Using create() instead of new() in UVM ............ 71
8.6.3. Building components under agent .................... 75
8.6.4. Connecting components inside agent ............... 76
8.7. UVM Environment .............................................. 78
8.7.1. Hierarchical build_phase in UVM ..................... 80
8.8. UVM Sequence ................................................... 81
8.8.1. UVM “DO Macros” ........................................... 82
8.8.2. UVM sequence body() ...................................... 84
8.8.3. `uvm_do_with macro ....................................... 85
8.9. Writing Tests in UVM .......................................... 86
8.9.1. Using uvm_test base class ................................ 87
8.9.2. Creating a base_test in UVM ............................ 88
8.9.3. Creating user tests in UVM ............................... 90
8.10. Top, DUT connections in UVM .......................... 92
7
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

8.10.1. DUT hook-up ................................................. 93


8.10.2. Using config_db::set in UVM ......................... 94
8.10.3. Using run_test() in UVM ................................ 95
8.11. File Structure and Compilation ......................... 97
8.11.1. Using generic Makefile for UVM .................... 99
8.12. Simulation Results ......................................... 100
9. Epilogue .............................................................. 102
9.1. UVM journey so far ........................................... 102
9.2. Apercu of upcoming UnleashingUVM series ...... 103

8
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

Prologue
The humble beginning

It all started with a young, woman engineer


out of the prestigious Indian Institute of
Technology – Madras/Chennai (IIT-M) back in
2000 deciding to start her own company instead
of joining a regular employment at any of the
Multi-National Companies (MNCs) based out of
India. Starting with independent consulting she
matured to envision her own start-up around
2004. Thus, born was Contemporary Verification
Consultants (CVC), a name that sounds very
familiar to every semiconductor design house in
India and many abroad as well. Fast forward to
2018, CVC has grown to be a global leader in
VLSI Design-Verification (DV) training.

CVC provided training in emerging DV


technologies back in those days including
Verilog, VHDL, CFV, PSL etc.

Early day of SystemVerilog & CVC

When SystemVerilog standard was


released, Ajeetha could see the potential impact it
9
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

can have on the lives of many DV engineers.


Hence, CVC started consulting and training
around the industry’s most widely adopted
Hardware Design & Verification Language
(HDVL). CVC pioneered advanced Design-
Verification through consulting, books, papers,
blogs and more. At this stage, it is imperative to
acknowledge the guidance, coaching and moral
support we received from Ben Cohen, industry
veteran and author of several books on VHDL,
Verilog, PSL, SVA, VMM and more. CVC has
been working with Ben Cohen over last decade
and disseminated knowledge on PSL, SVA,
VMM etc. through DVCon USA 2010 tutorial,
and multiple DVCon papers across the globe,
books, blogs and countless technical support on
various online forums such as Verification Guild,
Verification Academy, EDAboard etc.

The “Becoming of DV power-house”

Just around 2009, Srini joined CVC and


both started unleashing the wave of
SystemVerilog language and methodologies
across the globe. Having co-authored book on
VMM (precursor to UVM), CVC was all set to
drive UVM development and evangelization right
10
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

from its inception. As a pioneer and strategist,


Srini insisted in registering a trademark to protect
CVC’s investments over the years and the result
of it is UnleashingUVM!

UnleashingUVM is a registered Trademark


of CVC Pvt. Ltd. and is an official stamp of
CVC’s authority over this field as recognized by
the Government of India.

Recognition of CVC

Accellera, the standards organization that


develops standards such as SystemVerilog, UVM,
UPF, PSS etc. recognized the efforts of CVC Pvt.
Ltd. and awarded “The outstanding contribution
award in recognition of driving adoption of
Accellera standards in the Indian Ecosystem” to
Ajeetha Kumari, CVC Pvt. Ltd

Around 2016, CVC spun off a new venture


named VerifWorks to develop a suite of
productivity tools and deploy them at customer
sites through dedicated set of consultants. Having
deployed UVM at various design houses, our
team quickly realized the challenges faced by
11
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

users in developing UVM based testbenches and


also the ramp up needed and difficulties in
adopting UVM for first-timers. Go2UVM is an
open-source attempt to solve these two key
missing aspects of UVM.

UnleashingUVM book – the big picture

Having trained more than 10,000 working


professionals across the globe, CVC truly
understands the psychology of tech-savvy
engineers and their way of learning by
experience. With several books available on
similar topics with page counts of 200-400, it is
becoming rather boring for the engineers to read
it all-in-one. Also with UVM becoming the most
adopted methodology, it has gained users with
varying levels of expertise in UVM. So, it is very
tricky to get one book that serves all UVM users.
Also, learning should be fun, so why not make it
more like an irresistible novel (Think of your
favorite children comics for a motivation if you
will – a la Geronimo Stilton).

With UnleashingUVM – we don’t release


just “a book”, instead it is a series of them each
addressing a targeted set of engineers using
12
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

UVM. We begin with “Just Do It” – intended for


those who just want to get going instead of
reading voluminous pages of theory behind
UVM. Not to say that theory is unimportant, in-
fact our upcoming books will address the “whys”
and “hows” of UVM.

About this book – Just Do It

As the title says, it is for those who just


want to get started with UVM – no frills attached.
It is intended for the first-time UVM users,
budding engineers, students to get started with
UVM without much hype.

To keep the page-count low and for a fun-


filled reading experience, this book assumes a fair
amount of exposure to SystemVerilog syntax and
a basic exposure to modern-day Verification.

To serve the goals of this book, many-a-times


this book does not delve deep into why certain
choices are made in the UVM – such as usage of
create () instead of new() just as an example. Rest
assured that in the series of UnleashingUVM
books, these topics will be addressed in the near
future.
13
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

1. Introduction

The UVM (Universal Verification


Methodology) was introduced in December 2009,
by a technical subcommittee of Accellera. UVM
uses Open Verification Methodology as its
foundation. Accellera released version UVM 1.0
EA on May 17, 2010. UVM Class Library
provides the building blocks needed to quickly
develop well-constructed and reusable
verification components and test environments. It
uses SystemVerilog as its implementation
language. Recently, a SystemC version of UVM
has also been developed. All major simulation
vendors (Synopsys, Cadence, Mentor, Aldec etc.)
support UVM today, which was not the case with
other verification methodologies. Today, more
and more logic is being integrated into a single
chip, thus its verification is a very challenging
task. More than 70% of the time is spent on the
verification of the chip. Hence it is necessary to
have a common verification methodology that
provides a framework to construct robust and
reusable verification environment. UVM
provides that framework through a Base Class
Library (BCL).

14
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

Fig 1.0: UVM Version and Timeline

2. Why UVM?

In Verilog or VHDL, a testbench consists of


a hierarchy of modules containing testbench code
that are connected to the design-under-test
(DUT). The modules contain stimulus and
response checking code that is loaded into
simulator memory along with the DUT at the
beginning of the simulation and is present for the
entire duration of the simulation. Therefore, the
classic Verilog testbench wrapped around a DUT
consists of what are known as static objects.
15
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

SystemVerilog builds on top of Verilog by adding


abstract language constructs targeted at helping
the verification process. One of the key additions
to the language was the class. SystemVerilog
classes allow Object Orientated Programming
(OOP) techniques to be applied to testbenches.
The UVM itself is a library of base classes that
facilitates the creation of structured testbenches
using code that is open source and can be run on
any SystemVerilog IEEE 1800 simulator. The
UVM Base Class Library (BCL) provides the
building blocks needed to quickly develop well-
constructed and reusable verification components
and test environments in SystemVerilog.

UVM is the first truly open, interoperable,


and proven verification reuse methodology.
Fundamentally, UVM recommends a layered
approach for building verification environments.
Object-oriented programming concepts are key to
contemporary UVM. OO techniques allow
verification components to be specialized to the
needs of a specific testbench or test without
modifying their source code. It also enables well-
structured communication between those
components. In UVM, the class is used as a

16
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

container to represent components, transactions,


sequences, tests, and configurations.

Fig 2.0: UVM Basic base classes

3. Lets’ get started

Fig 3.0: Ubiquitous Example

17
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

Hello World! – The ubiquitous example in


any programming language is – Hello World! –
So here it is in Verilog, SystemVerilog, UVM and
Go2UVM.

$display (“Hello World!”);

Now, in a typical simulation world we need


little more context such as:
• Who printed this message?
• When (at what simulation time) was it
issued?

This can be done in Verilog as shown below:

$display (“%m %0t Hello World with time and


hierarchy!”, $time);

Sample output from the above code is


shown below:

hw_test.test 10.00 ns:


Hello World with time and hierarchy!

18
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

Next question would be, which file and line-


number issued the above message?

In a typical simulation setup, several source


files issue such messages and are usually spread
across several directories/folders.

Question: how do we locate (quickly) the file


and line number that issued the above message?
If you are a UNIX geek, you start thinking of your
friendly find .. grep.

Thanks to SystemVerilog, it can save


several minutes for you! It adds 2 macros to
extract file and line-number.
• `__FILE__
• `__LINE__

So, the above code can be further improved


as below:

$display (“%m %0t [%s | %0d]


Hello World with FILE & LINE”,
$time, `__FILE__, `__LINE__);

19
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

Sample output from the above code is


shown below:

hw_test.test 20.00 ns:


[UnleashingUVM/go2uvm/hw_test.sv | 55]
Hello World with FILE & LINE

Now, that’s handful amount of code to type


– though the benefits are aplenty. Guaranteed, not
every engineer would do that for sure in every
print statement! So how do we enforce it?
Welcome to UVM!

`uvm_info (“UVM”, “Hello World from UVM”,


UVM_MEDIUM)

Sample output:

UnleashingUVM_Code/go2uvm/hw_test.sv
(57) @ 30.00 ns: reporter [UVM] Hello World
from UVM

20
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

Now, that’s very useful indeed! UVM is


useful, isn’t it? Hold on – what are those extra
arguments to that “powerful” `uvm_info macro?
Can I not get it simpler, yet with all bells-and-
whistles of UVM?

Here you go – Presenting to you Go2UVM J

`g2u_display (“Hello World from Go2UVM!”)

Sample output:

UnleashingUVM_Code/go2uvm/hw_test.sv
(57) @ 30.00 ns:: reporter [Go2UVM]
Hello World from Go2UVM

Now, compare Verilog and Go2UVM:

$display (“Hello World!”);

21
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

`g2u_display (“Hello World!”)

That’s not too much to type, and you get all


benefits of UVM!

In typical print statements, fields of a


transaction such as addr, data are printed as well.
A Verilog code snippet for this is shown below:

$display (“%m %0t Register name: %s addr:


0x%0h data: 0x%0h”,$time, reg_name, reg_addr,
reg_wdata);

UVM provides a macro and using


$sformatf, the same intent can be achieved as
shown below:

`uvm_info (“ID”, $sformatf


(“Register name: %s addr: 0x%0h data: 0x%0h”,
reg_name, reg_addr, reg_wdata),
UVM_MEDIUM)

22
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

With Go2UVM, it is simpler:

`g2u_printf ((“Register name: %s addr: 0x


%0h data: 0x%0h”, reg_name, reg_addr,
reg_wdata))

Sample output:

UnleashingUVM_Code/go2uvm/hw_test.sv
(57) @ 30.00 ns: reporter [Go2UVM] Register
name: CTRL_REG addr:0x84ef2187 data:
0x1e996664

Please note the extra braces () – that’s a must


with this macro!

23
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

4. Simple DFF Verification Model

Now that we got started with UVM and


Go2UVM, let’s take first step in hardware design
verification world – and what’s a better example
than a simple D-Flip Flop that every electronics
engineer in the world knows all about!

4.1. DFF description

A typical block diagram for a DFF looks as


shown below:

Fig 4.0: DFF- Block Diagram

24
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

4.2. RTL model for DFF

A simple RTL model for a DFF is shown


below:

module g2u_dff_rtl (input clk, rst_n, d, output q);


always_ff @ (posedge clk,
negedge rst_n) begin: dff
if (! rst_n) begin: rst_dff
q <= 1'b0;
end: rst_dff
else begin: d_to_q
q <= d;
end: d_to_q
end: dff
endmodule: g2u_dff_rtl

4.3. Verifying DFF functionality

Let’s build a small test for this DFF in UVM.


At the outset, UVM will be an overkill for DFF
verification. Simple elements such as DFF do not
really need so much verification at logic level.
However, we will use the DFF as an example to
get started with UVM and then move on to a more
complex design.
25
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

4.4. Role of SystemVerilog interface in UVM

The first step in building a UVM testbench


for a given design is to create a SystemVerilog
interface to enable the class based UVM
framework to connect to a module based RTL.

A DUT typically carries with it a set of


requirement documents and a set of interfaces.
SystemVerilog provides a useful construct, the
interface to abstract the communication across
several modules. Some designers use the
SystemVerilog interface definition in the RTL
design. Others restrict the design to the Verilog
style with individual port signals, instead of
grouping the signals with SystemVerilog
interfaces. If an interface is not defined by the
design team, it is necessary for the verification
engineer to define such an interface model as this
facilitates the connections to the verification
environment defined in classes through the use of
virtual interfaces.

26
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

4.5. SystemVerilog interface for DFF

A simple interface for DFF is shown below.


Global signals such as clock and reset are usually
passed as inputs to the interface. This facilitates a
centralized clock and reset generation and control
in larger designs.

interface g2u_dff_if (input clk, rst_n);

logic d, q;

endinterface: g2u_dff_if

4.6. Adding modport, clocking block

Inside a SystemVerilog interface all local


signals are treated like inout-s with no direction
sense. With modport and clocking blocks, the
appropriate directions for these signals can be
captured for design and testbench respectively.
For this simple DFF, modport and clocking block
code is shown below:

27
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

interface g2u_dff_if (input clk, rst_n);

logic d, q;

default clocking cb @ (posedge clk);


output d;
input q;
endclocking: cb

modport dut_mp (input clk, rst_n, d, output q);

endinterface: g2u_dff_if

4.7. Using SystemVerilog Assertions

An interface typically has assertions


associated with the operation of the signals of the
interface. Interface assertions relate to the
properties or timing relationships of those signals.
For this simple DFF two typical assertions
required are:
• After reset, output shall be 0
• When reset is de-asserted, value of Q shall
follow D after a clock cycle
A complete SystemVerilog interface with
modport, clocking block and a set of assertions is
shown below for DFF.
28
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

interface g2u_dff_if (input clk, rst_n);


logic d, q;

default clocking cb @ (posedge clk);


output d;
input q;
endclocking: cb

modport dut_mp (input clk, rst_n, d, output q);

a_rst_val_chk: assert property (! rst_n |=> q == 0)


else begin: fail_rst_ab
`uvm_error (“a_rst_val_chk”,
“DFF Q is not 0 after reset”)
`G2U_ABV_TURN_OFF(a_rst_val_chk)
end: fail_rst_ab

a_normal_val_chk: assert property


(disable iff !(rst_n)
$change(d) |=> q == $past(d))

else begin: fail_norm_ab


`uvm_error (“a_normal_val_chk”,
$sformatf (“DFF Q: 0x%0h does not follow D:
0x%0h”,
q, $sampled($past(d)) ) )
`G2U_ABV_TURN_OFF(a_normal_val_chk)
end: fail_ab

endinterface: g2u_dff_if

29
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

5. Using Go2UVM test to verify DFF

Developing a full-fledged UVM for a simple


design like DFF will be an overkill. This is so
because UVM is meant for large designs with
multiple interfaces and complex protocols. UVM
is a structured approach to build a reusable
testbench. However, it is highly unlikely to have
a requirement to “reuse” a DFF verification
environment. Hence it makes sense to leverage on
few features of UVM to get started and then build
on more features.

5.1. Using a base test go2uvm_base_test

In UVM based simulation, the entry point is a


test. UVM BCL (Base Class Library) provides a
base class named uvm_test that shall be extended
by users to add stimulus. Given the layered
structure of UVM, it usually requires more code
to hook-up various components hierarchically.
Go2UVM provides a base class
go2uvm_base_test to ease simple test
development. From an OOP perspective, it is
derived from uvm_test and a UML representation
is shown below:

30
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

31
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

5.2.Using `G2U_TEST_BEGIN macro

User test shall be extended from this


go2uvm_base_test. It is done using a macro
`G2U_TEST_BEGIN(<name>).

import uvm_pkg::*;

`include "vw_go2uvm_macros.svh"

// Import Go2UVM Package


import vw_go2uvm_pkg::*;

// Use the base class provided by the


vw_go2uvm_pkg

`G2U_TEST_BEGIN(dff_test)

So, what does this macro do? It extends a


new class from the go2uvm_base_test class and
implements the mandatory constructor (i.e.
function new()) and key UVM macros.

32
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

5.3. Using UVM config-db to retrieve interface

SystemVerilog provides a key construct


named virtual interface to connect class based
testbench to module based design. UVM provides
a base class named uvm_config_db that helps in
connecting this virtual interface. With Go2UVM
a handy macro `G2U_GET_VIF is provided to
make the typical use cases of Config-DB easier.
This macro shall be called inside a function or a
task. In a full UVM flow this connection between
testbench and design shall be done in a pre-
defined phase named connect_phase(). To get
started, the DFF example will simply call this
macro inside a reset() task instead.

33
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

import uvm_pkg::*;
`include "vw_go2uvm_macros.svh"

// Import Go2UVM Package


import vw_go2uvm_pkg::*;

// Use the base class provided by the


vw_go2uvm_pkg
`G2U_TEST_BEGIN(dff_test)

task reset;
// Connect to a design interface
`G2U_GET_VIF(g2u_dff_if)

// .. Reset logic
endtask: reset

5.4. Applying reset to the design

In a typical hardware design two key phases


exist – one during reset and the other during main
data phase. UVM captures this via reset_phase()
and main_phase(). Given the phasing is an
advanced UVM topic, Go2UVM hides some of
the complexity using wrapper methods named
reset() and main().

34
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

A typical reset() implementation for DFF


looks as shown below. In this example, the design
has an active low reset named rst_n that is driven
to 0 for a few cycles and then de-asserted by
driving it to 1. In the code below, vif is the name
of DFF SystemVerilog virtual interface. A
clocking block named cb is used to drive inputs
to the DUT.

35
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

import uvm_pkg::*;
`include "vw_go2uvm_macros.svh"

// Import Go2UVM Package


import vw_go2uvm_pkg::*;

// Use the base class provided by the


vw_go2uvm_pkg
`G2U_TEST_BEGIN(dff_test)

task reset;
// Connect to a design interface
`G2U_GET_VIF(g2u_dff_if)

`g2u_display ("Start of reset")


this.vif.cb.rst_n <= 1'b0;
repeat (5) @ (this.vif.cb);
this.vif.cb.rst_n <= 1'b1;
repeat (1) @ (this.vif.cb);
`g2u_display ("End of reset")
endtask: reset

36
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

5.5. Separation of Concerns –UVM way

UVM strongly advocates a popular design


principle - “Separation of Concerns”. In general
software engineering terms, “Separation of
Concerns” is a design principle for separating a
computer program into distinct sections, such that
each section addresses a separate concern. A
concern is a set of information that affects the
code of a computer program. (Ref. Wikipedia). In
DV (Design Verification) context, this refers to
separating the stimulus, checking and other
concerns to individual components.

The code for reset() shown above only


contains the stimulus part of the test. Recall that
the interface declaration already has a set of
assertions to verify the functionality/behavior of
the DUT. In simple designs a comprehensive set
of assertions is usually the easiest way to
implement this checking. In more complex
designs a scoreboard shall also be developed in
UVM along with assertions.

37
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

5.6. Main phase of DFF test

The next key phase in a UVM test is the


main_phase(). As mentioned earlier, Go2UVM
has a simplified task named main() that is coded
as shown below.

task main ();


byte unsigned rnd_del;
bit inp_val;

`g2u_display ("Start of main")

for (int i =0; i < 50; i++) begin: send_stimuli


inp_val = (i%2);
`g2u_printf (("Transaction ID: %0d Driving:
'b%0b", i, inp_val))
this.vif.cb.d <= inp_val;
rnd_del = $urandom();
repeat (rnd_del) @ (this.vif.cb);
end: send_stimuli

`g2u_display ("End of main")

endtask: main

`G2U_TEST_END

38
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

As noted earlier, this code contains only the


stimulus – i.e. driving the d pin of the DFF at
random internals. Checking for correctness of the
DUT is handled by assertions inside the interface.

5.7. First, complete UVM test

The complete code for this DFF test is shown


below.

39
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

import uvm_pkg::*;
`include "vw_go2uvm_macros.svh"
// Import Go2UVM Package
import vw_go2uvm_pkg::*;
// Use the base class provided by vw_go2uvm_pkg
`G2U_TEST_BEGIN(dff_test)
task reset;
// Connect to a design interface
`G2U_GET_VIF(g2u_dff_if)
`g2u_display ("Start of reset")
this.vif.cb.rst_n <= 1'b0;
repeat (5) @ (this.vif.cb);
this.vif.cb.rst_n <= 1'b1;
repeat (1) @ (this.vif.cb);
`g2u_display ("End of reset")
endtask: reset
task main ();
byte unsigned rnd_del;
bit inp_val;
`g2u_display ("Start of main")
for (int i=0; i < 50; i++) begin: send_stimuli
inp_val = (i%2);
`g2u_printf (("Transaction ID: %0d Driving:
'b%0b", i, inp_val))
this.vif.cb.d <= inp_val;
rnd_del = $urandom();
repeat (rnd_del) @ (this.vif.cb);
end: send_stimuli
`g2u_display ("End of main")
endtask: main
`G2U_TEST_END
40
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

5.8. Putting it all together – top module

With a test written for the DUT, it needs to be


hooked up to the DUT. The below code shows
how this is achieved in a typical UVM setup. The
interface and test files are included.

5.9. Clock generation in Go2UVM


Clock generation is a key aspect in verifying
large designs. Go2UVM has a handy module
named g2u_clk_gen that can generate clock of a
chosen frequency. In this example, a clock of
100MHz is generated.

`include "g2u_dff_if.sv"
`include "g2u_dff_test.sv"

module go2uvm_dff;
parameter DFF_FREQ = 100;

// Simple clock generator


bit clk;

g2u_clk_gen # (. FREQUENCY_MHZ
(DFF_FREQ)) cgen (. clk(clk));

41
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

5.10. Connecting DUT & Test via virtual


interface

A SystemVerilog interface is intended to


hook-up class based tests to a module based
design. At the top module, the interface is
instantiated and connected to both design and
testbench. Connecting to the design is shown
below considering that the design is a Verilog
RTL module that does not use an interface for its
ports. For the testbench side UVM provides a
Config-DB mechanism as briefed earlier. The top
module is responsible to connect the underlying
testbench’s virtual interface to an actual
interface. This is done through
uvm_config_db::set() API as shown below. A call
to built-in run_test() is necessary to kick-start the
UVM.

42
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

`include "g2u_dff_if.sv"
`include "g2u_dff_test.sv"
module go2uvm_dff;
parameter DFF_FREQ = 100;
// Simple clock generator
bit clk ;
g2u_clk_gen #(.FREQUENCY_MHZ
(DFF_FREQ)) cgen (.clk(clk));
// Interface instance
g2u_dff_if g2u_dff_if_0 (.*);
// DUT instance
g2u_dff_rtl u_g2u_dff_rtl (
.clk(g2u_dff_if_0.clk),
.rst_n(g2u_dff_if_0.rst_n),
.d(g2u_dff_if_0.d),
.q(g2u_dff_if_0.q)
);
initial begin : go2uvm_test
// Connect virtual interface to physical interface
uvm_config_db#(g2u_dff_if)::set (null,
“uvm_test_top”, “vif”, g2u_dff_if_0)
// Kick start standard UVM phasing
run_test ();
end : go2uvm_test
endmodule : go2uvm_dff

43
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

5.11. Summary, next steps

Voila! With few simple steps, a UVM test for


DFF is now created. This step-by-step approach
demonstrates that UVM can be adopted very fast
using Go2UVM with very minimal know-how on
the UVM internals.

In the next sections, a more modular UVM


framework with various key UVM components
shall be developed for a First-In-First-Out (FIFO)
design.

6. UVM - Conceptual view

• Component – A structural building block,


conceptually equivalent to a Verilog
module, but customizable to various tests
on need basis.
• Transaction – A bundle of data items,
which may be distributed over time and
space in the system, and which form a
communication abstraction such as a
handshake, bus cycle, or data packet
• Sequence – An ordered collection of
transactions or of other sequences
44
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

• Phase – The execution is subdivided into


various predefined phases that permit
components to agree on when to build
components, connect ports, run simulation,
and so forth
• Factory – A function call that returns a
component, transaction, or sequence, the
type of which may be overridden from a
test
• Port and export – Connection points for
transaction-level communication between
components
• Test – The top-level component, which
drives the entire simulation
• Configuration – An object associated with
a component which may be set or
randomized by a test. It is used to configure
the components as the component
hierarchy is built
• Sequencer – A component that arbitrates
sequences and sends transactions
generated by those sequences downstream
to another sequencer or to a driver
• Driver – A component that receives
transactions from a sequencer and that
drives the signal-level interface of the
Design Under Test (DUT)
45
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

• Monitor – A component that senses the


signal-level interface of the DUT and then
sends transactions to the verification
environment
• Subscriber – A component typically used
for collecting functional coverage
information using SystemVerilog
covergroups within that component
• Checking – Functional correctness of the
DUT can be checked using either
procedural code within a component or
SystemVerilog assertions within an
interface.

Fig 6.1 Visualizing data flow in UVM


environment
46
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

7. Using classes to model testbench


components and transactions

Verilog has only the module construct as


containers. SystemVerilog extends that capability
to allow object-oriented modeling using the class
construct as containers. It brings many of JAVA’s
capabilities to the Verilog world. It is best to use
SystemVerilog classes to declare all testbench
related components and transactions.

The rationale behind this guideline is as


follows: by definition a transaction has a limited
lifetime - from the time it gets generated to the
time it is consumed by the DUT, checked for
correctness etc. The number of such transactions
in a system is variable - this would logically mean
that a dynamic memory allocation of such
transactions is a must have to make optimal use
of simulation. By definition, constructs such as
plain Verilog modules and SystemVerilog
interfaces etc. are “static” in nature - they exist
throughout the simulation and hence are not
suited for modeling dynamic transactions.

47
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

Another key reason to consider using


SystemVerilog classes to model components and
transactions is the ability to easily derive and
extend them to create variations of transactions
and to mimic real-life data streams such as
Ethernet Packets. An Ethernet packet, as defined
by the standard, has several layers (such as L2,
L3, L4 etc.), and each layer encapsulates another
one. With a conventional “Hardware Design
Language”, one is limited to use only a simple
modeling style that does not lend to good,
maintainable and reusable code. The Software
domain has been handling such complexity in the
past with great success with Object-Oriented
(OO) programming style. SystemVerilog brings
in that OO style to Hardware Verification via the
class data type.

48
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

8. Verification of a FIFO – UVM



8.1. DUT

The design under test (DUT) is a synchronous


first-in first-out (FIFO) model. Figure 8.1.1
describes the block diagram of FIFO model.

clk push_err_on_full

rst_n pop_err_on_empty

push full

pop FIFO empty

data_in data_out

Fig 8.1.1 FIFO Block Diagram

As described in a previous section, the first


step in building a UVM testbench for a given
DUT is to build a SystemVerilog interface.
Figure 8.1.2 demonstrates the FIFO interface.

49
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

interface fifo_if (input logic clk,


input logic reset_n);
import fifo_pkg::*; clocking driver_cb @
logic push; (posedge clk);
logic pop; input empty, full,
data_out, error;
logic full; output data_in,
logic empty; push, pop;
endclocking: driver_cb
logic error;
logic [DATA_WIDTH-1:0]
data_in;
logic [DATA_WIDTH-1:0]
data_out;
endinterface : fifo_if

Figure 8.1.2 FIFO Interface

8.2. Modeling transactions

The basic idea of a Transaction-Based


Verification (TBV) methodology, such as UVM,
is to separate the transaction from the component.
While there are few varying definitions of these
terms, here is a simple definition we follow in this
book. A transaction is basically “what needs to
be done” and a component models “how to do it”.

50
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

Examples of a transaction are:

1. Instruction.
This represents the high-level tasks
to be executed, such as a READ, WRITE,
NO-OP, LOAD, etc.
2. Data.
This represents information such as
address, data, number of cycles, etc.
3. Parameters.
This can represent a mode,
a size, etc.

The fields and attributes of a data item are


derived from the data item’s specification. For
example, the Ethernet protocol specification
defines valid values and attributes for an Ethernet
data packet. In a typical test, many data items are
generated and sent to the DUT. By intelligently
randomizing data item fields using
SystemVerilog constraints, you can create a large
number of meaningful tests and maximize
coverage.

51
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

In a TBV methodology, a transaction


defines the basic data model of the system,
establishes a common currency for the system.
The individual properties/members of a
transaction may need to be randomized to
support a Constrained Random Verification
(CRV) on top of TBV.

UVM defines a base class named


uvm_sequence_item to model transactions. It is
used as the fundamental layer for all transaction
descriptors and data models. A simple example of
a FIFO transaction model using
uvm_sequence_item is shown below.

class fifo_xactn extends uvm_sequence_item;


endclass : fifo_xactn

One of the advantages of using


uvm_sequence_item as base class for transaction
models, is that it has important built-in utility
methods. These important methods remove many
coding requirements that existed in Verilog
testbenches.

52
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

There are two ways to implement important


transaction methods - first is to use UVM field
macros and the second is to manually implement
the built-in virtual methods. We recommend
using field macros.

class fifo_xactn extends uvm_sequence_item;

rand bit [FIFO_WIDTH-1:0] data_in;


bit [FIFO_WIDTH-1:0] data_out;
rand fifo_op_t kind;
rand bit [3:0] num_rst_cycles;
time xactn_time;

`uvm_object_utils_begin(fifo_xactn)

`uvm_field_int (data, UVM_ALL_ON)


`uvm_field_int (idle_cycles, UVM_ALL_ON)
`uvm_field_enum (fifo_scen_t, kind,
UVM_ALL_ON)

`uvm_object_utils_end

endclass : fifo_xactn

53
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

These field macros implement several utility


functions, some of the important ones are shown
in the table below.

Method name Description

print(), sprint() Used to print fields of the


transaction. Macros can
implement these
convert2string() User definable routine –
not implemented by the
field macros
copy(), clone() Copies (recursively) all
fields to a target object
compare() Compares each field
(Options available to skip
few fields)
pack(), unpack() Converts transactions to
bit-stream and vice-versa

record() Records transaction to a


debug database (dump file)

54
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

The standard transaction methods are zero-


time functions that should be defined in a
transaction class and should always include user
methods. One function that is important to define
is the print() function, just because many users
expect it to be available. If the design includes
serial-to-parallel or parallel-to-serial activities
that are very common among network packet-
based designs, additional functions that will be
included in the standard transaction methods list,
should include: pack() and unpack(). One more
standard transaction function is the record()
function that is somewhat tool specific and used
to help debug transient transaction objects.

8.3. Building a driver model in UVM

In UVM, a component is a generic name, and


there are several kinds of component such as
driver, sequencer, monitor, scoreboard etc. A
direct equivalent of a typical UVM component is
what’s conventionally known as BFM (Bus
Functional Model) at the lower level. On the
driver side, a BFM takes a transaction as input
and sends it to the DUT according to the
underlying protocol.
55
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

Fig 8.3 TBV Driver

A driver is an active entity that models the


logic that drives the DUT. A typical driver
repeatedly receives a data item and drives it to the
DUT by sampling and driving the DUT signals.
For example, a driver controls the read/write
signal, address bus, and data bus for a number of
clocks cycles to perform a write transfer. The
driver’s role is to drive data items to the bus
following the interface protocol. The driver
obtains data items from an adjacent component
(called sequencer in UVM) for execution. The
UVM Class Library provides pull model and push
model with base classes uvm_driver and
uvm_push_driver, from which all driver classes

56
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

should be extended, either directly or indirectly.


In this book, we will use pull model.

UVM provides a base class named


uvm_driver which is derived from
uvm_component. Figure 8.3.1 UML diagram
shows the IS-A relationship model of
uvm_driver.

Fig 8.3.1 UML Structure of driver


UVM uses parameterized classes to create
templates for users to derive from. In case of
uvm_driver, there are two parameters viz.
• REQ
• RSP
57
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

Inside the UVM BCL, the following code


implements the above UML diagram.

class uvm_driver # (
type REQ = uvm_sequence_item,
type RSP = REQ) extends uvm_component;

User driver is extended from this base class


uvm_driver along with a matching transaction
item (derived from uvm_sequence_item).

class fifo_driver extends uvm_driver #(fifo_xactn);


endclass: fifo_driver

As class objects are dynamic in nature,


communication to a DUT requires a
handle/pointer because the DUT is a static model.
SystemVerilog provides virtual interface for this
purpose. Declaring a virtual interface for FIFO
driver is shown below:

58
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

class fifo_driver extends uvm_driver #


(fifo_xactn);

virtual fifo_if vif;

endclass: fifo_driver

UVM components use a handy macro to


keep them factory compatible. It is called
component utility macro. A typical use of this
macro is shown below:

`uvm_component_utils_begin (fifo_driver)
`uvm_component_utils_end

The constructor of uvm_component is used


to hook-up components hierarchically. Hence a
standard prototype is used throughout the UVM
for all components. Below code snippet shows the
standard constructor for any UVM component.

function new (string name, uvm_component parent);


super.new(.name (name),. parent (parent));
endfunction : new

59
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

UVM uses Transaction Level Modelling


connections to hook-up multiple components
hierarchically. The driver has a TLM port through
which it communicates with the sequencer. The
base class uvm_driver declares a TLM port as
shown below:

class uvm_driver # (
type REQ = uvm_sequence_item,
type RSP = REQ) extends uvm_component;

uvm_seq_item_pull_port #(REQ, RSP)


seq_item_port;

The base class uvm_component has a set of


pre-defined methods (called “phases” in UVM)
that captures a generic flow of events for any
simulation. These are all declared as virtual
methods. Derived components may override one
or more of these phases as per the component’s
functionality.

60
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

TLM port shown above, seq_item_port is


used inside the main_phase to request for
sequence-items/transactions from a sequencer.

The driver class is responsible for


extracting (or getting) the transaction from the
TLM port, and parsing the transaction into the
wire-level activity used by the DUT. Code
snippet below represents the consumption of
transactions from the sequence_item_port (pull
model).

task fifo_driver::main_phase (uvm_phase phase);

`g2u_display ("Driver Starting...”)

forever
begin
this.seq_item_port.get_next_item(item);
this.send_to_dut(item);
this.seq_item_port.item_done();
end

endtask: main_phase

61
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

In UVM driver is meant to be a free


running component forked off as an independent
thread. Typically, a forever loop is used inside
main_phase() to achieve this. Motivation is to let
higher layer component such as a test control how
many items to send to the DUT in a given run. A
driver simply fetches continuously and sends
each item to the DUT as per the interface
protocol.

In case of our FIFO model, below code


shows a typical send_to_dut() implementation.

task fifo_driver::send_to_dut (fifo_xactn item);

`g2u_printf (("Driver sending item: %s...\n”,


item.sprint))

case (item.kind)
PUSH: this.push_op (.data_in (item.data_in));
POP : this.pop_op ();
endcase

endtask: send_to_dut

62
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

The driver may also need to sample some


DUT signals to control the timing, response etc.
Protocol or “how to drive an item to DUT” is
design dependent. A sample implementation of
the push_op() task to drive the virtual interface
from the transaction is shown below.

task fifo_driver::push_op
(input[DATA_WIDTH-1:0]data_in);

@(this.vif.fifo_cb);
this.vif.fifo_cb.push <=1'b1;
this.vif.fifo_cb.pop <=1'b0;
this.vif.fifo_cb.data_in <=data_in;
@(this.vif.fifo_cb);
this.vif.fifo_cb.push <=1'b0;

endtask: push_op

A similar task needs to be implemented for


pop_op() task and is omitted here for brevity.
Complete FIFO driver code is shown below
(excluding the detailed push/pop operations).

63
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

class fifo_driver extends uvm_driver #(fifo_xactn);


virtual fifo_if vif;
`uvm_component_utils_begin(fifo_driver)
`uvm_component_utils_end

function new (string name,


uvm_component parent);
super.new(name,parent);
endfunction : new

virtual task reset_phase (uvm_phase phase);


phase.raise_objection (this);
`g2u_display("Reset phase is running”,
UVM_HIGH)
this.vif.rst_n <= 1’b0;
repeat (10) (this.vif.cb);
this.vif.rst_n <= 1’b1;
phase.drop_objection(this);
endtask : reset_phase

virtual task main_phase (uvm_phase phase);


`g2u_display(("Main phase is running ….”,
UVM_HIGH))
forever begin
seq_item_port.get_next_item (this.req);
this.send_to_dut(this.req)
seq_item_port_item_done ();
end
endtask : main_phase
endclass : fifo_driver

64
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

8.4. Building a sequencer model in UVM

UVM sequencer is an abstract model of an


arbiter that arbitrates and chooses the next
sequence item to be sent to the connected driver.
By default, a sequencer behaves similar to a
simple round robin arbiter. However, various
arbitration schemes are available for advanced
use cases.

For a simple sequencer, all the code is in the


UVM BCL (Base Class Library), so a mere
instantiation with specific transaction type is
sufficient.

class fifo_sequencer extends uvm_sequencer #


(fifo_xactn);

`uvm_component_utils_begin(fifo_sequencer)
`uvm_component_utils_end

function new (string name,


uvm_component parent);
super.new(name, parent);
endfunction : new

65
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

8.5. Building Hierarchical components in UVM

UVM testbenches are built using classes


derived from the uvm_component base class. The
testbench hierarchy is determined by a series of
'has-a' class relationships. In OOP, “HAS-A”
relationship is commonly used. A simple example
explaining this has-a relationship is shown in
Figure 8.5.1

Figure 8.5.1 – OOP IS-A & HAS-A


relationships
66
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

In UVM based testbenches, one component


contains one or more components (also known as
composition). The top-level class in an UVM
testbench is usually known as the test class and
this class is responsible for configuring the
testbench, initiating the construction process by
building the next level down in the hierarchy and
by initiating the stimulus by starting the main
sequence. For a given verification environment,
the testbench hierarchy below the test class is
reasonably consistent. The UVM testbench
architecture is modular to facilitate the reuse of
groups of verification components either in
different projects (horizontal reuse) or at a higher
level of integration in the same project (vertical
reuse). There are two main collective component
types used to enable reuse - the uvm_env (short
for environment) and the uvm_agent.

67
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

8.6. UVM Agent

One of the primary motivations to use UVM is


reusability. The term reusability is an overloaded
one with different meanings to different
stakeholders. To keep the reuse aspect of UVM
intact, UVM recommends grouping relevant
components per-design-interface under an agent.
Sequencers, drivers, and monitors can be
reused independently, but this requires the
environment integrator to learn the names, roles,
configuration, and hookup of each of these
entities. To reduce the amount of work and
knowledge required by the test writer, UVM
recommends that environment developers create
a more abstract container called an agent. Agents
can emulate and verify DUT devices. They
encapsulate a driver, sequencer, and monitor.
Verification environments can contain more than
one agent. Some agents (for example, master or
transmit agents) initiate transactions to the DUT,
while other agents (slave or receive agents) react
to transaction requests. Agents should be
configurable so that they can be either active or
passive. Active agents emulate devices and drive
transactions according to test directives. Passive
agents only monitor DUT activity.
68
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

8.6.1. Creating a FIFO Agent

Using base class named uvm_agent, a derived


class for FIFO can be created as shown below.

class fifo_agent extends uvm_agent;


endclass: fifo_agent

Once this skeleton code is ready, we can


add various components that belong to this agent.
The driver and sequencer components shown
earlier shall be instantiated inside this agent.

69
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

class fifo_agent extends uvm_agent;

fifo_sequencer fifo_sqr_0;

fifo_driver fifo_drv_0;

`uvm_component_utils_begin(fifo_agent)
`uvm_field_enum (uvm_active_passive_enum,
is_active, UVM_ALL_ON)

`uvm_component_utils_end

function new (string name,


uvm_component parent);
super.new (name, parent);
endfunction: new

extern virtual function void


build_phase (uvm_phase phase);

extern virtual function void


connect_phase (uvm_phase phase);

endclass: fifo_agent

70
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

For now, this agent has only driver and


sequencer, other components such as monitor,
subscriber etc. can be added later. The two
functions (phases) declared as extern are part of
UVM phasing. Phases are “special” methods
(functions/tasks) that get automatically invoked
in a pre-defined order by the BCL.

8.6.2. Using create() instead of new() in


UVM

As SystemVerilog classes are dynamic,


handles need to be constructed to point to objects.
SystemVerilog uses constructor to achieve this
via the new() function. Hence to construct a UVM
driver one could do:

71
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

class fifo_agent extends uvm_agent;

fifo_driver fifo_drv_0;

`uvm_component_utils_begin(fifo_agent)
`uvm_field_enum(uvm_active_passive_enum,
is_active, UVM_ALL_ON)

`uvm_component_utils_end

function new (string name,


uvm_component parent);
super.new (name, parent);

// Bad coding style, just for illustration purpose


this.fifo_drv_0 = new (.name(“fifo_drv_0”,
.parent (this));
endfunction: new

endclass: fifo_agent

72
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

In UVM all components (and transactions)


are thought of as reusable elements. By reuse we
mean that in future a user of this code may want
to extend any component and add/modify
methods and their behaviors. To keep this
flexibility in a standard OOP paradigm requires a
design pattern named “factory”. We will delve
deeper into this factory later in this series of
books, but a quick note is to use a “proxy” method
for construction instead of the SystemVerilog
standard constructor – new. UVM provides
create() method and it has similar signature as
that of UVM component’s constructor. As a
proxy routine, the create() internally calls the
new() with same arguments.

73
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

class fifo_agent extends uvm_agent;

fifo_driver fifo_drv_0;

`uvm_component_utils_begin(fifo_agent)
`uvm_field_enum(uvm_active_passive_enum,
is_active, UVM_ALL_ON)

`uvm_component_utils_end

function new (string name,


uvm_component parent);
super.new (name, parent);

// This shall be moved to build_phase later

this.fifo_drv_0 = fifo_driver::type_id::create
(.name(“fifo_drv_0”,
.parent(this));
endfunction : new
endclass : fifo_agent

74
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

8.6.3. Building components under agent

In UVM, components are constructed in a


dedicated phase called build_phase. This is done
in a top-down fashion by UVM BCL internally
and provides a way for higher layers to determine
the configurations for lower layer components. A
typical build_phase code for FIFO agent is shown
below.

function void fifo_agent::build_phase


(uvm_phase phase);

super.build_phase(phase);

this.fifo_sqr_0 =
fifo_sequencer::type_id::create (“fifo_sqr_0”,
this);

this.fifo_drv_0 =
fifo_driver::type_id::create (“fifo_drv_0”, this);

endfunction : build_phase

75
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

8.6.4. Connecting components inside


agent

Next step is to connect the driver and


sequencer. Imagine a situation wherein the driver
and sequencer are not paired/connected – the
below picture subtly captures the result!

However, UVM provides built-in utilities


and has built-in checks to ensure that users do not
end-up with such scenarios. Through a
customized TLM port called
uvm_seq_item_pull_port UVM enforces that it is
connected to an equivalent
uvm_seq_item_pull_export. The TLM port has a
76
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

built-in method named “connect” to connect a


producer and consumer. Pseudo-code doing this
connection is shown below:

tlm_port.connect(tlm_export);

UVM uses a separate phase/method named


connect_phase() to hook-up components. On the
driver’s input is a TLM port that gets fed by a
sequencer. Driver’s output shall be connected to
the DUT via virtual interface. UVM
recommends that the agent obtains a handle to the
virtual interface and provide to all its constituent
components such as driver, monitor.

For our FIFO agent, connect_phase is


shown below:

77
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

function void fifo_agent::connect_phase (uvm_phase


phase);
super.connect_phase(phase);
this.fifo_drv_0.seq_item_port.connect
(this.fifo_sqr_0.seq_item_export);

this.fifo_drv_0.vif = this.vif;
endfunction : connect_phase

8.7. UVM Environment

The environment (env) is the top-level


container of the verification components. It
contains one or more agents, as well as other
components such as scoreboards. The
environment contains configuration properties
that enable you to customize the topology and
behavior and make it reusable. For example,
active agents can be changed into passive agents
when the verification environment is reused in
system verification. An environment class can
also be used as sub-environment in another
environment.

78
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

In UVM, a base class named uvm_env is


available. uvm_env is extended from
uvm_component and is used to create and connect
the different agents.

class fifo_env extends uvm_env;


fifo_agent agent_0;

`uvm_component_utils_begin (fifo_env)
`uvm_component_utils_end

extern function new


(string name, uvm_component parent);

extern virtual function void build_phase


(uvm_phase phase);

endclass: fifo_env

79
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

8.7.1. Hierarchical build_phase in UVM

As a layered methodology, UVM promotes


building components hierarchically. In the agent
section earlier, components such as driver,
sequencer were constructed inside agent’s
build_phase(). Since agent is instantiated inside
uvm_env, the build_phase() of env is used to
construct (using factory) the agent(s).

function void fifo_env::build_phase (uvm_phase


phase);
super.build_phase(phase);

fifo_agent_0 = fifo_agent::type_id::create(
.name(“fifo_agent_0”),
.parent(this));

endfunction : build_phase

Note: Agent’s is_active shall be set to


UVM_ACTIVE/UVM_PASSIVE via
config_DB. For brevity, that part of the code is
not shown above.

80
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

With environment in place, it is time to start


sending traffic to the DUT. UVM provides a
structured way to create complex stimulus
through sequences and tests. Next chapters shall
address these key topics.

8.8. UVM Sequence

Given the complexity and reuse requirements


of modern day designs, UVM recommends to
model stimulus around a set of sequences. A
UVM sequences is simply a series of
sequence_item objects invoked in some order.

UVM provides a base class uvm_sequence,


user sequences shall extend this base class. FIFO
random sequence is shown below.

81
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

class fifo_rand_seq extends uvm_sequence


#(fifo_xactn);

`uvm_object_utils(fifo_rand_seq)

function new(string name = "fifo_rand_seq");


super.new(name);
endfunction : new

extern virtual task body();

endclass : fifo_rand_seq

The main value of a UVM sequence (over


sequence_item) is the body() task. It is a place-
holder to capture a specific test-plan item from a
typical verification plan and typically invokes
multiple sequence_item-s.

8.8.1. UVM “DO Macros”

To promote reuse and handle common


coding guidelines, UVM provides handy macros
to be used inside a UVM sequence. These are

82
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

often referred to as “do macros”. There are two


important macros to begin with as shown below:

`uvm_do
`uvm_do_with

A typical set of steps to send a


sequene_item to a sequencer is shown below:
• Create an object of sequence_item using
factory
• Indicate the connected sequencer about the
availability of a new sequence_item
• Wait for a grant from the sequencer (Recall
that UVM sequencer is an arbiter)
• Once granted, randomize the transaction as
per class constraints and any additional in-
line constraints from the user
• Ensure that the randomization passed, else
issue a note/warning to the user
• Send the sequence_item that just got
granted and randomized to the driver via
sequencer
• Wait for the item_done() indication from
the driver

83
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

All the above steps can be achieved using a


simple `uvm_do call as shown below:

task fifo_seq::body();
`uvm_do(req)
endtask : body

The above sequence is the simplest


sequence that can be written in UVM. At the
simplest level a sequence is same as a
sequence_item (or transaction loosely speaking)
that was introduced in chapter 6.

8.8.2. UVM sequence body()

Bulk of the stimulus in a typical UVM


setup is implemented inside
uvm_sequence::body() task. Typically, a looping
structure is used as shown below:

84
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

task fifo_rand_seq::body();
for (int i=0; i < 10; i++)
begin: send_10_items
`uvm_do(req)
end: send_10_items
endtask : body

With a simple structure as above, UVM


enables users to throw a lot of traffic at the DUT
with ease. Recall the discussion on “Separation of
Concerns” earlier – with driver, sequencer, agent,
env and sequence, this technique is well adopted
by UVM.

8.8.3. `uvm_do_with macro

Often users want to be able to add


additional constraints during randomization.
UVM provides `uvm_do_with macro to handle
this requirement.

For the FIFO DUT, creating a series of


PUSH followed by series of POP is a desired
sequence. Below code snippet shows how this can
be achieved using `uvm_do_with macro.

85
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

task fifo_push_pop_seq::body();
for (int i=0; i < 10; i++) begin: do_10_push
`uvm_do_with (req, {kind == PUSH;})
end: do_10_push

for (int i=0; i < 10; i++) begin: do_10_pop


`uvm_do_with (req, {kind == POP;})
end: do_10_pop
endtask: body

8.9. Writing Tests in UVM

In UVM, a test is the entry point into a


simulation run. All activities start from a test.
A test can be seen as the top container for the
whole simulation. At times one can also have
just a test and nothing below for simple
runs/scenarios.

In a typical UVM setup, uvm_test


instantiates the env (and hence the agent-
driver-sequencer all hierarchically). Figure
below shows the test and all components
beneath in a typical UVM setup.

86
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

8.9.1. Using uvm_test base class

UVM BCL provides a base class named


uvm_test. User tests shall extend from this
base class. In a typical UVM based flow there
will be several tests implementing the test
plan.

The way UVM is architected, a single


simulation run is triggered by a single UVM
test. UVM does not allow more than one test
to be run in a single simulation run (also
known as “cascaded tests”). Choice of which
87
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

test to run can be done via command-line


argument:

vsim tb_top +UVM_TESTNAME=fifo_test

8.9.2. Creating a base_test in UVM

Next step is to create a set of tests to send


some traffic to the DUT via the
env.agent.sequencer. Since all tests for a given
DUT share the same environment, the
construction, hook-up of various testbench
components can be leveraged from a base test.

SystemVerilog provides abstract classes


through a keyword virtual class. An abstract class
is ideal for a base_test as it does not run any
sequences, instead used as a base for many tests
and performs actions that are common to
all/majority of the tests. Following code snippet
shows a base test for FIFO.

88
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

virtual class fifo_base_test extends uvm_test;

function new (string name,


uvm_component parent);
super.new(name, parent);
endfunction : new

fifo_env fifo_env_0;

extern virtual function void


build_phase (uvm_phase phase);

endclass: fifo_base_test

In case of FIFO DUT, the env class created


earlier is common for all tests. This env needs to
be instantiated, constructed. Going by the
convention of hierarchical build_phase(), this is
done inside base_test::build_phase() as shown
below.

89
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

function void fifo_base_test::build_phase


(uvm_phase phase);

super.build_phase(phase);

this.fifo_env_0 = fifo_env::type_id::create
(.name(“fifo_env_0”, .parent(this));

endfunction : build_phase

8.9.3. Creating user tests in UVM

A real test (a la “concrete class”) shall


extend the fifo_base_test developed in previous
section and start a sequence on sequencer.

Using standard OOP principle, a user test


shall extend from the base_test and implement
only what is specific to that test. In UVM, a
dedicated phase named main_phase() is used to
capture test specific activities.

Following code shows a test for FIFO


extended from the base test created in previous
section.

90
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

class fifo_push_pop_test extends fifo_base_test;


`uvm_component_utils_begin (fifo_push_pop_test)
`uvm_component_utils_end

fifo_push_pop_seq fifo_seq_0;

function new (string name, uvm_component


parent);
super.new(name, parent);
endfunction: new

extern virtual task main_phase (uvm_phase phase);


endclass : fifo_push_pop_test

In UVM the terms test and sequence are


often used interchangeably to refer to the actual
stimulus to be sent to the DUT in a given test.
Recall the uvm_sequence developed in previous
chapters – its body() task contains the actual
scenarios being tested in a given test. That
sequence can be started on FIFO sequencer inside
a user test. This is done in the test::main_phase()
as shown below.

91
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

task fifo_push_pop_test::main_phase
(uvm_phase phase);

phase.raise_objection(this);
this.fifo_seq_0 = fifo_seq::type_id::create
(.name(“fifo_seq_0”));

`g2u_display(“Starting a SEQ on FIFO SQR”)

this.fifo_seq_0.start
(this.fifo_env_0.fifo_agent_0.fifo_sqr_0);

`g2u_display(“Finished a SEQ on FIFO SQR”)

phase.drop_objection(this);
endtask : main_phase

8.10. Top, DUT connections in UVM

As with regular Verilog based flow, the DUT


and the testbench needs to be connected, clocks
need to be generated etc. The below code snippet
shows how this is done for FIFO DUT.

92
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

module tb_top ();


`include "fifo_include.svh"
`include "fifo_rand_test.sv"

logic clk;

// Instantiate DUT interface


fifo_if fifo_if_0 ((.clk (clk) );

g2u_clk_gen #(.FREQUENCY_MHZ(100))
.clk(clk));

8.10.1. DUT hook-up

In this FIFO example, DUT has Verilog ANSI


styled port list. It needs to be connected to
SystemVerilog interface. This hook-up is shown
below.

93
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

module tb_top ();


// Other code

// DUT instance
fifo fifo_0 (
.clk(fifo_if_0.clk),
.data_in(fifo_if_0.data_in),
.pop(fifo_if_0.pop),
.push(fifo_if_0.push),
.rst_n(fifo_if_0.rst_n),
.data_out(fifo_if_0.data_out),
.empty(fifo_if_0.empty),
.full(fifo_if_0.full),
.pop_err_on_empty
(fifo_if_0.pop_err_on_empty),
.push_err_on_full
(fifo_if_0.push_err_on_full)
);

8.10.2. Using config_db::set in UVM

As described earlier, SystemVerilog class


uses virtual interface to connect TB to DUT. This
connection is done via a built-in feature named
uvm_config_db. At the top module level, this

94
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

config-DB is used to set the correct interface to


the appropriate agent within the env.

This is shown below for FIFO.

module tb_top ();


`include "fifo_include.svh"
`include "fifo_rand_test.sv"

// Instantiate DUT interface


fifo_if fifo_if_0 ((.clk (clk) );

initial begin
uvm_config_db#(virtual fifo_if)::set(
.cntxt(null),
.inst_name
("uvm_test_top.fifo_env_0.fifo_agent_0"),
.field_name("vif"),
.value(fifo_if_0));
end

8.10.3. Using run_test() in UVM

To start a UVM testbench, a built-in task


named run_test() has to be called from the static
part of the testbench. It is usually called from
within an initial block in the top level module of
95
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

the testbench. Calling run_test () constructs the


UVM test component and then initiates the UVM
phasing. Below code snippet shows the
run_test() call for FIFO.

module tb_top ();


`include "fifo_include.svh"
`include "fifo_rand_test.sv"

// Instantiate DUT interface


fifo_if fifo_if_0 ((.clk (clk) );

initial begin
uvm_config_db#(virtual fifo_if)::set(
.cntxt(null),

.inst_name("uvm_test_top.fifo_env_0.fifo_agent_0"
),
.field_name("vif"),
.value(fifo_if_0));

run_test();
end

96
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

8.11. File Structure and Compilation


Table 8.11.1 demonstrates the file
Structure and the purpose of each file.

File Purpose
fifo_agent.svh Creates the
components and
establishing the
connections between
them.
fifo_agent.sv Body of agent
fifo_base_test.sv Base Test – common
for all tests, contains
the env instantiation
fifo_driver.svh Sending item to DUT
through interface
fifo_driver.sv Body of driver
fifo_env.svh Creates agent and
deciding the type
(active/passive)
fifo_env.sv Body of env
fifo_if.sv Defines the FIFO
interface
97
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

fifo_include.svh Include file per-UVC


fifo_pkg.sv Top level package for
a given UVC. Defines
types and parameters
fifo_push_pop_seq.sv Push-Pop SEQ
fifo_push_pop_test.sv Push-Pop Test
fifo_seq_lib.sv SEQ library – includes
all sequences
fifo_sequencer.svh Choosing the next item
and sending to the
driver
fifo_sequencer.sv Body of sequencer
fifo_sva_if.sv Assertion property
models
fifo_sva_bind.sv SVA bind
fifo_tb_dut_top.sv Represents the top
level and instantiates
the RTL. Sets the
interface to relevant
agents. Calls run_test()
to initiate the start of
UVM phases.
fifo_xactn.svh Defines the transaction
class with the
constraints
fifo_xactn.sv Body of transaction

98
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

8.11.1. Using generic Makefile for


UVM

Given the widespread usage of UVM,


many first timers to UVM find it hard to
remember all relevant options to their favorite
simulator to get going with UVM. Go2UVM
provides a generic Makefile.

All DUT & TB files are specified in a


simple text file named “flist”. This file contains
names (and paths as necessary) of all the design
and Testbench files. The rest of the magic is
handled by the Makefile. Below is a table of
supported tools and target names in Makefile. In
this table CLI stands for “Command Line
Interface” (or batch mode) and GUI – Graphical
User Interface.

99
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

A typical use with Riviera-Pro looks as follows:


make cvc4_gui TOP=my_chip_uvm_tb_top
TEST=my_uvm_test

8.12. Simulation Results

All simulations were performed with Aldec


Rivera-PRO © simulator. The code base has been
tested on multiple simulators and targets for each
has been added in the Makefile.

A typical use with Riviera-Pro looks as


follows:
make cvc4_gui TOP=my_chip_uvm_tb_top
TEST=my_uvm_test

Figure below shows typical output from a


UVM simulation (print_topology being shown).

100
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

Figure 8.10.2 shows waveform from


Aldec’s Riviera-Pro tool for our FIFO with Push
Error (Push on FULL).

101
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

Waveform for Pop-On-Empty error


scenario is shown below.


9. Epilogue

9.1. UVM journey so far

The “U” in UVM stands for “Universal”


and availability of learning material will go a long
way in making that very term true! It is imperative
that the global leaders in deploying UVM take the
next logical step to increase the adoption of UVM
across the globe.

This book is just the beginning of such


unleashing wave. Especially given the free
availability of this book, the authors sincerely
102
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute
UnleashingUVM – Just Do It!

believe that more engineers will adopt UVM. We


also hope our readers look forward to the
upcoming books in this series.

At the time of releasing this book, some


parts of India are recovering from torrential
floods. Through this book, we make an earnest
attempt to raise funds for Kodagu Flood relief.
Kindly visit the KodaguConnect page to donate:

www.verifnews.org/UnleashingUVM/JDI
9.2. Apercu of upcoming UnleashingUVM
series

As mentioned earlier in this book, JDI (Just-


Do-It), is just the beginning of UnleashingUVM
series. The authors are working closely with
industry leaders in bringing a series of interesting
titles under this umbrella. Some of them will deal
with selected topics in UVM while others present
methodologies for specific verification problems
solved using UVM. So please stay tuned for
more!

Thank you for reading!

103
© VerifWorks & CVC Private Limited, Bangalore, India.
verifnews.org/UnleashingUVM/JDI
Registered Copy Do not distribute

You might also like