0% found this document useful (0 votes)
60 views

GO2UVM Debug 2016

UVM Debug Go2UVM

Uploaded by

svenka3
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)
60 views

GO2UVM Debug 2016

UVM Debug Go2UVM

Uploaded by

svenka3
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/ 8

by Srinivasan Venkataramanan and Ajeetha Kumari, VerifWorks

cryptic and do not point to the actual source code, rather


Universal Verification Methodology (UVM) is the industry somewhere from the base classes, making the debug
standard verification methodology for Verification using difficult. We have captured a series of such common
SystemVerilog (SV). UVM provides means of doing issues and error messages into a collateral form that we
verification in a well-defined and structured way. It is call “UVM Vault”. As part of our QVP engagement with
a culmination of well-known ideas, thoughts and best Mentor Graphics, we are integrating this UVM Vault to
practices. Questa® in the near future.

Given the major adoption of UVM across the globe and Specifically, we will highlight a few hand-picked features in
across the industry, advanced users are looking for tips the UVM factory and provide tips and tricks around them.
and tricks to improve their productivity. UVM does define It is expected that the readers are conversant with the
a structured framework for building complex testbenches. UVM framework to appreciate the tips presented below.
It is built on strong OOP principles and design patterns
using underlying SystemVerilog language features. This
strong OOP nature presents certain challenges to the UVM provides a convenient way to control which
end users. Recall that many Design-Verification (DV) objects get manufactured at run time via the well-known
engineers come from hardware, electronics backgrounds Factory Design pattern. Wikipedia defines factory
and not heavy Software backgrounds. Hence at times it pattern as:
gets tricky for users to debug UVM based testbenches
In class-based programming, the factory method pattern
when things do not work as expected.
is a creational pattern that uses factory methods to deal
In this article the authors share their long experience of with the problem of creating objects without having to
assisting customers with run time debug of common UVM specify the exact class of the object that will be created.
issues and potential solutions to them. During our various This is done by creating objects by calling a factory
training and consulting engagements using UVM we have method rather than by calling a constructor.
seen DV engineers struggling to debug relatively simple
In UVM to use factory, there are three important steps:
UVM issues. It will be unfair to blame the
users as many a times, the error 1. Registration – all classes shall be registered
messages are with a global factory singleton table
2. Use class::type_id::create() instead of new()
3. Use set_type_override functions

Steps 1 & 2 above are to be done while a


verification environment is being created by
the developers. Once such a good framework
is ready, verification engineers and VIP users
can use step 3 above to tweak the behavior of
underlying components and transactions. Below is
a sample log with a transaction named s2p_xactn.

41
Figure 1: Sample log with s2p_xactn

Now a simple factory override with a derived transaction


(possibly with additional constraints) can be set as shown in
Figure 2 below:

Figure 4: Related transactions

Now if two overrides are specified for the same s2p_xactn


(assume that’s the transaction on which driver, sequencer
etc. are parameterized), code snippet in Figure 5 shows a
Figure 2: Simple factory override
way to “replace” the first override with the second.

A sample run with Questa shows a log as shown below


in Figure 3.

Figure 3: Debug tip for factory override

TIP: Look at the “Type” column in standard UVM print Figure 5: Pseudo-code to replace existing override
(uvm_object::sprint) to see if your override indeed worked!
If not, no need of waveforms to debug, go back to your This is a handy trick to run a test with a few 100 transactions
UVM code! first with one type and then replace with another derived
type and run another few 100s within the same test!

There are cases when multiple overrides are set on the TIP: Look for UVM log ID “TPREGR” as shown below
same object. There are use cases to “ignore” such to ensure your replacement is guaranteed!
overrides and then other situations where-in it is desired
to “replace”. UVM’s factory override mechanism supports
both requirements. Consider a transaction model derived as
shown in Figure 4, there are two similar error transactions
derived from a base s2p_xactn.
Figure 6: Built-in debug hook in UVM
to display factory replacement

42
Often in a IP to sub-system reuse scenarios the
subsystem engineer is not fully aware of IP level sequence
functionality. It is possible that a factory override was
already set by the IP level sequence. Imagine a scenario
Figure 9: Built-in debug hook in UVM to display
where-in a sub-system verification engineer wants to
factory override behavior
“query” the IP sequence to see if an override exists, if not,
set a new override.
Sometimes the user wants to “undo” an override – i.e.,
a base class has been overridden to be replaced with a
derived class. A little later, with-in the same simulation one
wants to remove/undo the override and revert back to base
class. This makes sense only for transactions/sequence
items as the override plays a role only when the create()
gets called AFTER the override setting.

Another scenario when “undo” operation is desired is when


a IP is being reused at the next level and the integrator
wants to nullify the override set by the IP.
Figure 7: Reuse scenario – verification plan as flowchart
An intuitive way to do this would be to override with
Though SystemVerilog and UVM do not have a full-fledged the “same” class when desired. Consider an example
“reflection API” to “query” such arbitrary questions on the of pseudo-code below:
database, UVM factory does support this use case via a
“ignore” option to the factory override method. Refer to
Figure 8 that shows a similar override as in the previous
example, but setting the “replace” argument to 0.

Figure 10: Undo an override

While the above code will work fine with the latest UVM 1.2
release, in case of UVM 1.1d (which is more prevalent at
many customer designs as of today), the above code will
lead to an error as shown below in Figure 11.
Figure 8: Pseudo-code to query and add a new override

This is very useful for the reuse scenarios as described


above for sub-system integrators.
Figure 11: Questa® simulation log
TIP: Look for UVM log ID “TPREGD” as shown to for factory undo in UVM 1.1d
ensure your replacement is conditional (if no previous
override, then do it!).

43
A work-around for achieving the same in UVM 1.1d version A code snippet of internal implementation of UVM factory
could be to derive a dummy, new class from the base class is shown in Figure 13 below.
and use it. The new class that is derived should contain no
extra code and is intended to just fool the compiler to treat
it as a derived type, but functionally same as the base type.
Figure 12 shows a possible s2p_undo_xactn UML diagram
to explain this.

Figure 13: Built-in debug hook in UVM factory

When things do not work as expected, the user can add the
following code snippet inside a test:

Figure 12: Deriving an extra, dummy transaction


to implement factory UNDO in UVM 1.1d
Figure 14: User code to display factory contents
at run time
TIP: Factory undo works out-of-the-box in UVM 1.2
TIP: Factory undo requires a small workaround in UVM 1.1d A sample print from Questa® simulation with the above
debug code is shown below in Figure 15. Note that we used
all_types (0) to see only relevant information.
Given that UVM supports global and instance based
overrides (with instance name being a string, computed
at run time), it is possible for the users to get it wrong the
first time – i.e., user expects an override to occur, but it
did not occur. A less popular API in the factory (and not
so highly recommended to use) uses names to specify
the original and override objects. Since all SystemVerilog
strings are computed at run time and typically users tend
to use “regexp” on these string names, there are definite
Figure 15: Questa sample log for factory debug
possibilities to get these paths, names wrong. Good thing
however is UVM factory already has auditing capabilities TIP: Use uvm_factory::print(.all_types(0)) – it is built
to help in such cases. There exists a print routine in to show the overrides alone.
uvm_factory that can display things like:

• All the registered classes


• All the overrides seen so far
(at the time of calling print routine)
• Specific instance where the overrides shall take place

44
passed to the name argument the same as the handle
In UVM components are built hierarchically and hooked name. There are cases such as AXI fabric environments
up at the top level. The hook-up happens through 2 key where-in the same agent is instantiated many times using
fields – name and parent. Every UVM component in user a dynamic array. Hence the handle name is an array
code implements new() as shown below in Figure 16. variable, where-as the name argument must be created to
be unique for each element in that array. While
doing this, care must be taken to:

• Keep each object’s name to be unique


• Keep sensible names – will see why below.

Figure 16: Typical constructor in a UVM component For simplicity, let’s consider a case where-in we
change the name to be different than the handle. Figure
For the first-timer the above code looks a bit strange, but 18 shows an AXI fabric UVM setup. The environment is
since the base class (uvm_component to be precise) instantiated with a handle named axi_fabric_env_0.
requires these 2 arguments, it becomes important to
stick to this style (though technically speaking there are
other crude ways with default values, etc.). The parent
argument in the component’s constructor is expected to
be connected to the “testbench” parent component (and
not necessarily a standard OOP parent class). A typical
hierarchy/topology of a UVM testbench looks as shown
in Figure 17. The standard UVM print_topology prints in
a tree format as shown below and every “indentation”
level indicates a layer in the testbench. For instance,
driver is indented inside agent. It indicates that driver’s
parent argument is connected to the agent object.

Figure 18: Using different name for the object


than the handle in UVM

In the build_phase the environment is constructed


using factory’s create() – but for experimentation sake
the name has been changed to CRAZY_ENV.

This directly impacts the hierarchical name of this


component and all underneath (as the path has a different
name). Fast-forward, consider a test writer setting an
Figure 17: Typical testbench topology in UVM instance based factory override for the sequence item
within this env-agent-sequencer. Refer to Figure 19 with
The other argument name is a string value that represents an attempt to override via instance specific API.
the name of the object in the given hierarchy. In UVM, all
object names must be unique at a given level of hierarchy.
In general, it is recommended to keep the value that is

45
automation brings productivity to the
teams. Debugging UVM issues can
become tricky and painful if users are not
fully aware of many of the built-in debug
hooks in the base class library of UVM.
In this article the authors shared some
Figure 19: Instance specific override for AXI transaction
of the time tested tips with respect to UVM factory. All the
While the above code shall compile, run, it will not produce tips mentioned are tool and vendor independent and comes
the intended overrides! The reason being that the name for free with UVM. Readers are encouraged to see the
of the environment with the handle axi_fabric_env_0 has references section to learn more such tips and tricks.
been set to CRAZY_ENV during the build phase (Refer to
Figure 18).

Figure 20 shows the correct way to get the instance specific • Accellera UVM standard: http://accellera.org/activities/
override working in this case. Please note that this is an working-groups/uvm/
experimental example to demonstrate the impact of name • DVCon US 2016 UVM tutorial, available on request
argument in UVM and the authors do NOT recommend this via http://www.verifnews.org
unless it is really necessary.

Figure 20: Using correct name in the instance path


for a factory override

TIP: In case of instance specific overrides,


the “instance path” is important and recall that it uses
the “name” of the object than the name of the handle!
TIP: Keep the name simple and straight forward
and match it to the handle name as much as possible
TIP: Use get_full_name in case the instance path
is not clear.

UVM is a very powerful methodology. Since it is well


structured, generation of standard UVM framework as
a starting point is quite common practice. Such simple

46
Editor: Tom Fitzpatrick
Program Manager: Rebecca Granquist

Wilsonville Worldwide Headquarters


8005 SW Boeckman Rd.
Wilsonville, OR 97070-7777
Phone: 503-685-7000

To subscribe visit:
www.mentor.com/horizons

To view our blog visit:


VERIFICATIONHORIZONSBLOG.COM

You might also like