White Paper
June 2014
Hierarchal Testbench Configuration
Using uvm_config_db
Authors
Hannes Nurminen
Professional
Services, Synopsys
Satya Durga Ravi
Professional
Services, Synopsys
Abstract
SoC designs have become extremely complex as more and more IP blocks are integrated into them. This
increases the verification challenge manifold in terms of configuration and data handling, as well as architecting
and maintaining a large verification environment. Hence it has become very important to create a robust and
reusable testbench using a proven methodology that does not just facilitate but also improves the efficiency in
verifying different configurations of the device under test (DUT).
Accellera Systems Initiative’s Universal Verification Methodology (UVM), a stable and widely used methodology
for architecting testbenches for verification of complex designs helps mitigate these verification challenges
to create a scalable, robust and reusable test environment. UVM provides a vast set of macro, policy and
base classes that help facilitate the creation of these testbenches, including an easy way to pass objects and
variables across testbench hierarchy.
For engineers who are new to verification methodologies or are in the process of adopting UVM, this paper
focuses on the UVM configuration mechanism “uvm _ cong _ db, which helps in passing different class
properties across hierarchy testbench components. Through the use of examples, the usage, techniques, and
limitations of uvm _ cong _ db are explained.
Introduction
To address the needs of today’s verification architecture, a hierarchical setup of components is necessary to
easily move or share configurations and other parameters across different testbench components. To enable
this, UVM provides the infrastructure to maintain a database of objects and variables that can be populated
and accessed using strings. This is achieved using the UVM syntax uvm _ cong _ db.
Using uvm _ cong _ db, objects can share the handle to their data members with other objects. Other
testbench components can get access to the object without knowing where it exists in the hierarchy. Its
almost like making some class variables global or public. Any testbench component can place handles and
get handles to objects. In the database, handles are identified by assigned ‘type’ and ‘name’.
Primarily there are two uvm _ cong _ db functions, set( ) and g et(). Any verification component using
set() gives others access to the object it has created and controls which components have visibility to the
object it has shared. The object can be shared globally or made available to one or more specific testbench
components. Verification components using get() check if there is a shared handle matching the used
parameters. The g et() function defines the object type, the name and hierarchical path to the object
searched for.
How to Use It – Different Syntax and Operation
Explicit set() and get() call functions are how you interact with the uvm _ cong _ db. The uvm _
cong _ db class functions are static, so they must be called using the “::” operator.
Hierarchal Testbench Configuration Using uvm_config_db 2
Figure 1: set() and get() function syntax
cntxt” and “inst _ name” are used to specify the storage location or address of the object handle. When used
properly these parameters define the hierarchical path to the object data.
eld _ name” is the name for the object. It does not have to match the object’s actual name in the source code.
Objects using set() and get() must use exactly the same name, otherwise the receiving party (get()) will fail to
find the object from
uvm _ cong _ db.
value” is the actual object handle shared through the uvm _ cong _ db. Multiple recipients accessing an
object via get(), will access the same object.
<type>” is used as a parameter for the uvm _ cong _ db class to identify the object from the uvm _
cong _ db. “<type>” which may be either an integral or string, is the class name of the “value. The exception
is with enumerated type variables which must use int otherwise the set() won’t work as expected.
Figure 2: config_db for enum type
The set() specifies the “address” (cntxt & inst _ name) where the object handle is stored to control the
recipient(s) of the object. The g et() has the same flexibility, and can freely select from where the information is to
be fetched. In practice g et() can be used to fetch an object destined to any component in the hierarchy. Typically
for set() and g et(), this is used in the “cntxt” field to specify the current instance/scope. set() uses
inst _ name” to address the object to the appropriate sub-block in the hierarchy. g et() often uses empty (“”)
inst _ name, since it typically is getting the objects destined for itself.
Figure 3: set() and get() typical use
uvm _ cong _ db has two additional functions e x ist s() and wait _ modied(). e xists() verifies that the
defined variable is found in the uvm _ cong _ db. The wait _ modied() function blocks execution until the
defined variable is accessed with the set() call.
Figure 4: exists() and wait_modified() typical use
2 uvm_config_db#(<type>)::set(uvm_component cntxt,
3 string inst _name,
4 string field_name,
5 <type> value)
6
7 uvm_config_db#(<type>)::get(uvm_component cntxt,
8 string inst _name,
9 string field_name,
10 ref value)
13 typedef enum {single,incr,w rap4,i ncr4,wrap8,i ncr8,w rap16,incr16}h burst_t
14 hburst _t hburst;
15 uvm_config_db#(int)::set(this,“a”,“ hburst”,incr);
5 uvm_config_db#(int)::set(this,“ my _subblock_a”,“ max_cycles”,max_cycles)
6 uvm_config_db#(int)::get(this,“ ”, “max _cycles”,max _cycles)
2 uvm_config_db#(int)::exists(t his,“ my _subblock_a”,“ max_cycles”)
3 uvm_config_db#(int):: wait _modified(t his,“ my _subblock_a”,“ max_cycles”)
Hierarchal Testbench Configuration Using uvm_config_db 3
Automatic Configuration
UVM also offers build-time configuration of uvm _ co mponent (and extended) classes utilizing uvm _ cong _
db. In automatic configuration, it is sufcient to call set( ) from an upper layer in the hierarchy and the g et() will
automatically execute at build time without requiring an explicit call. Automatic configuration utilizes the uvm _
cong _ db feature “under the hood” to pass the configuration values from higher level testbench components in
the hierarchy to its lower level components.
For automatic configuration to work there are two important requirements:
The variable or object must have the appropriate FLAG in uvm _ eld _ * macros
s u p er() must be called in build _ phase()
3 class agents extends uvm _ agent;
4 int i4;
5 `uvm _ component _ utils _ begin (agent)
6 `uvm _ eld _ int (i4, UVM _ ALL _ ON)
7 `uvm _ component _ utils _ end
8
9 virtual function void build _ phase(uvm _ phase p h a s e);
10 super.build _ phase(p h a s e);
11
12 endfunction
13
14 endclass
Once the component properties have the uvm _ eld _ * declaration(s) in place with the appropriate FLAG(s),
the macro provides the set _ * _ local functionality and super.build _ phase() calls the apply _
cong _ settings() method under the hood. The apply _ cong _ settings() method searches for all
appropriate config settings matching this component’s instance and for each match, the appropriate set _ * _
local method is called using the matching uvm _ cong _ db setting’s “eld _ name” and “value”.
The super.build _ phase() method may be replaced with the apply _ cong _ settings() method
however it is recommended to use the super.build _ phase() method.
15 class agent extends uvm _ agent;
16 int i4;
17 uvm _ component _ utils _ begin(agent)
18 `uvm _ eld _ int (i4, UVM _ ALL _ ON)
19uvm _ component _ utiles _ end
20 virtual function void build _ phase(uvm _ phase p h a s e);
21 apply _ cong _ settings(1); //No super.build _ phase(phase)
22
23 endfunction
24
25 endclass
The implicit get() method call will not work in the following instances:
Missing uvm _ eld _ * macro
FLAG is set to UVM _ READONLY
Missing super.build _ phase() or apply _ cong _ settings() in build _ phase()
Below are log messages generated during the simulation phase because of an explicit apply _ cong _
sett i n gs() function call:
UVM _ INFO @ 0: env.name _ agent _ 1 [CFGAPL] applying conguration settings
UVM _ INFO @ 0: env.name _ agent _ 1 [CFGAPL] applying conguration to eld i4
To set the value for “i4” of the above agent, env would have the build _ phase() below:
3 function void build _ phase (uvm _ phase p h a s e);
4 agent _ 1 = agent::type _ id::create( n a m e _ a g e n t _ 1”, this);
5 uvm _ component _ db#(int):: set(this,name _ agent _ 1, “i4”, 1111);
6 endfunction
Hierarchal Testbench Configuration Using uvm_config_db 4
During the build phase of the simulation the agent object’s “i4” variable would get value 1111. It is important to note
that automatic configuration happens only at build phase.
Command Line
Compilation and simulation time are the major contributors to verification overhead. The ability to change the
configuration or parameters without being forced to recompile is critical. The UVM class
uvm _ cmdline _
processor provides a mechanism to capture the command line argument and pass to verification components
the testcase name, verbosity, configuration and other attributes.
Configuration overriding can only be done from the command line for integer and string using the following:
+uvm _ set _ cong _ int=<comp>,<led>,<value>
+uvm _ set _ cong _ string=<comp>,<eld>,<value>
There is no way to override the object from the command line, because uvm _ object cannot be passed to
the simulation.
When using the command line argument to set the configuration, make sure that the “<type>” used in
uvm _ cong _ db set() and get() functions is uvm_bitstream_t for integer and the “<type>” for
string is as shown below:
2 class env extends uvm _ env;
3 int a;
4 string color;
5 …
6 …
7 function new(string name, uvm _ component parent);
8 su p er.new(name, parent);
9 endfunction
10
11 virtual function void build _ phase(uvm _ phase parent);
12 super.build _ phase ( p h a s e );
13 if(!uvm _ cong _ db #(uvm_bitstream_t):: get(this, “, “a, a))
14 `uvm _ fatal(“GET _ NOTSUCC”, “Get is not successful for a ….);
15 if(!uvm _ cong _ db #(string):: get(this, “”, “color”, color))
16 `uvm _ fatal(“GET _ NOTSUCC”, “Get is not successful for color.”);
17 `uvm _ info( G E T _ V A L U E ”, $psprintf (“The value of a = %d and color =
%s”,a,color),UVM _ LOW);
18 endfunction
19
20
21 endclass
22
23 class test extends uvm _ test;
24 int a = 2;
25 string color =”blue”;
26 env env _ i;
27
28
29 virtual function void build _ phase(uvm _ phase p h a s e);
30 super.build _ phase ( p h a s e );
31 env _ i = env:type _ id::create( e n v _ i”, this);
32 uvm _ cong _ db#( uvm_bitstream_t):: set(this, “env _ i, “a, a);
33 uvm _ cong _ db#(string):: set(this, “env _ i, “color”, color);
34 endfunction
35
36 endclass
The command line argument for the example above is:
<simulation command> +UVM _ TESTNAME=test +uvm _ set _ cong _ int=uvm _ test _
top.env _ i, a, 6 +uvm _ set _ cong _ string=uvm _ test _ top.env _ i, color, red
Hierarchal Testbench Configuration Using uvm_config_db 5
The log message generated during simulation is:
UVM _ INFO @ 0: reporter [UVM _ CMDLINE _ PROC] Applying cong setting from the
command line: +uvm _ set _ cong _ int=uvm _ test _ top.env _ i, a, 6
UVM _ INFO @ 0: reporter [UVM _ CMDLINE _ PROC] Applying cong setting from the
command line: +uvm _ set _ cong _ string=uvm _test_top.env_i, color, red
Cross-Hierarchical Access
The set() and get() parameters “cntxt”,inst _ name” and “eld _ name” make it possible to use a
number of different paths to the same object. “cntxt” uses actual object hierarchy whereas “inst _ name” and
eld _ name” uses the hierarchy path with names given to the objects in create()/new() method. It is good
practice to create the objects with the same name as the object name.
When referencing down in hierarchy, it should be enough to use this in “cntxt” and then provide the path and/
or names in “inst _ name”.Field _ name” should be used just for the name of the object. When referencing
upwards in hierarchy, utilize the uvm _ root::get() function to get access to the hierarchy root, and then
reference down from there using “inst _ name” parameter.
Figure 5 below clarifies and provides examples how objects can be referenced in uvm _ cong _ db.
Figure 5: Options for using “cntxt” and “inst_name” parameters in set() and get()
uvm _ cong _ db does not actually limit how path field name is shared between “cntxt”,inst _ name” and
eld _ name. UVM combines all three of these parameters into one “key” that is used to access the database.
This feature makes it possible to reference the same object in multiple different ways using the 3 metacharacters
*,+,?. The table below determines the significance of each metacharacter:
Character Meaning
* 0 or more characters
+ 1 or more characters
? Exactly 1 character
test a
agent_1
agent_2
env
test a
agent_1
agent_2
test a
agent_1
agent_2
env
test a
agent_1
agent_2
env
test a
agent_1
agent_2
envenv
To one object To multiple objectsTo everyone Upwards from one objectsHorizontaly from objects
Hierarchal Testbench Configuration Using uvm_config_db 6
The illustration below shows using these metacharacters for the same object in uvm _ cong _ db.
Figure 6: Different path notations to the one and same object
Where To Use Usage and Its Benefits
Passing Configuration
uvm _ cong _ db is used often to configure agents of the testbench and to pass access to signal interfaces.
Agent is a class encapsulating sequencer, driver and monitor. Agent usually takes care of generating and receiving
data for an interface. The configuration variables or virtual interface are set at agent from top-level and later the
agent is responsible for passing the virtual interface or configuration to other sub-components rather than passing
it from top-level as shown in the figure below. Agents are often reused either as VIP blocks or across projects.
This means that the receiver (get) of the information dictates “type” and “eld _ name, and source of the
information (set) must use proper parameters when setting data into uvm _ cong _ db. This is also part of the
beauty of uvm _ cong _ db: agents can be created without knowing where the parameters or signal interfaces
are coming from, from where in the testbench hierarchy the agent object exists, what name it has, or how many
instances there are in parallel.
Figure 7: Passing configuration to agent and sub-components
Passing Virtual Interface
Passing the virtual interface across the verification component is the most common requirement when creating the
reusable verification environment. The preferred approach of doing this in UVM is to push the virtual interface into the
configuration database from top-level. This is because top-level module is not uvm _ component hence the context
is “null” and the instance is the absolute hierarchal path of the component where the virtual interface is assigned.
The absolute hierarchal instance of the component starts with “uvm_test_top.” Because the environment is
usually instantiated by test and agent, it can extract the virtual interface from the configuration database as shown
in the example on the next page
this “env.name_agen+” “i _of_env”
this “env.name_agent_?” “i _of_env”
this “env.*“i _of_env”
uv
m_config_db#(<type>)::set( <cntx> , <inst_name> , <field _name> , <object>);
uv
m_config_db#(<type>)::set( <cntx> , <inst_name> , <field _name> , <object>);
cfg
test_a
agent_1
env
cfg
cfg
cfg
cfgcfg
monitor
sequncr
driver
set
set
set
set
test_a
agent_1
env
set
set
set
set
cfg
cfg
cfg
cfg
monitor
sequncr
driver
Hierarchal Testbench Configuration Using uvm_config_db 7
2 module t b _ t o p();
3 svt _ axi _ if vif();
4 …
5 …
6 initial begin
7 uvm _ cong _ db #(virtual s v t _ a x i _ i f )::set(null, “uvm _ test _ top.env.m _
agent _ 0”, “vif, vif);
8 end
9 endmodule
10
11 class axi _ agent extends uvm _ agent;
12 virtual svt _ axi _ if vif();
13
14
15 virtual function _ void build _ phase(uvm _ phase p h a s e);
16 super.build _ phase( p h a s e );
17
18 if(!uvm _ cong _ db#(virtual s v t _ a x i _ i f ):: get(this,”,v i f ”, v i f ))
19 `uvm _ fatal(AXI _ AGENT:NOVIF”, “The virtual interface get is not successful);
20 uvm _ cong _ db#(virtual s v t _ a x i _ i f ):: set(this, “driver”,vif,vif);
21 uvm _ cong _ db#(virtual s v t _ a x i _ i f ):: set(this,m o n it o r ”,” v i f ”,v i f );
22 endfunction
23 endclass
(
&
(
(
Object Z
uvm_event my _event _too;
uvm_config _db#(uvm _event)::get(this, “”, “my_event”, my _event _too);
Object A
uvm_event my _event;
my _event = new(“my_event”);
uvm_config _db#(uvm _event)::set(this, “agent*”, “my_event”, my _event);
Object X
uvm_event my _event;
uvm_config _db#(uvm _event)::get(this, “”, “my_event”, my _event);
Object Y
uvm_event my _event _also;
uvm_config _db#(uvm _event)::get(this, “”, “my_event”, my _event _also);
event
Event Synchronization
uvm _ cong _ db is used to make the object available for others, it does not create new copies of the object.
Figure 8 below shows how event-object created by Object A is also made available to Objects X, Y and Z through
the uvm _ cong _ db. When Object A chooses to use trigger() for the event object, others can detect
it because they have access to exactly the same object. This demonstrates how the same object “event” is
referenced from four different objects with three different instance names.
Figure 8: uvm_config_db shares handles to existing object
Some attention needs to be paid that set() is called before g et()for a specific item, otherwise get() will
fail. Values passed through uvm _ cong _ db before run _ p hase() need to take into account that
build _ phase()constructs objects from top to bottom. This is often the desired order, since settings and
configurations are usually set from higher levels to lower levels via agents. During the simulation, use of set()
and g et() need to be synchronized/timed by the normal testbench operation or by using events to create a
synchronization mechanism.
Limitations
uvm _ cong _ db can be used anywhere in the hierarchy. The first parameter of set() and g et() functions,
cntxt, however needs to be of type class uvm _ component (or extended from that). “cntxt” parameter
is often given value utilizing class member this. So if s et() or g et() functions are used outside uvm _
component extended object, “cntxt” parameter can be given value using uvm _ root::get(), or just
value “null”.
Hierarchal Testbench Configuration Using uvm_config_db 8
Figure 9: set() and get() functions need “cntxt” parameter of type uvm_component or null
One common usage of uvm _ cong _ db outside uvm _ components, is delivering values from hdl _ top to
the testbench, including access to interfaces instantiated on hdl _ top. Though hdl _ top is not extended from
any UVM class, uvm _ cong _ db can still be utilized and communication with the UVM part of the testbench
is possible.
If set() or get() function is used with “cntxt” parameter not pointing to object of uvm _ component extended
classes, there will be a compile error as shown below.
Figure 10: Example error messages when trying to use “this” for non-uvm_component in set/get
Problems, Errors and Debug
Even though operation and use of set() and g et() functions with uvm _ cong _ db are logical and quite
simple, uvm _ cong _ db related debugging is often needed. Some errors may stop the compile or simulation
making them easy to find, as opposed to a coding error that simulates without error even though the g et()
function was receiving incorrect objects. Some common types of errors are:
Compile time errors
Parameter type does not match provided T value
Trying to use this-pointer from class not extended from uvm _ component
Simulation time errors
g et() does not find what was set using s et() due to misspelling of “inst _ name” or “eld value
null object access attributed to get() used before set()
25 Error-[S V-IUOT] Illegal us of this
26 test.sv, 9
27 ‘this’ can only be used in a class method.
28
29 Error-[ICTTFC] Incompatible complex type usage
30 test.svh, 281
31 Incompatible complex type usage in task or function call.
32 The following expression is incompatible with the formal parameter of the
33 function. The type of the actual is ‘class
34 my _pkg:: bus_slave’, while the type of the formal is ‘class
35 uvm_pkg::uvm _component. Expression: this
36 Source info: uvm_pkg_uvm_config _db_2116934237::get(this, “\000”,
37 this.get _full_name(), my _agent)
uvm_sequencer
uvm_driver uvm_scoreboard uvm_monitor
uvm_agent
uvm_env uvm_test
uvm_component
uvm_report_object
uvm_object
uvm_void
uvm_transaction
uvm_sequence
uvm_sequence_base
uvm_sequence_item
Hierarchal Testbench Configuration Using uvm_config_db 9
Synopsys’ VCS Discovery Visualization Environment (DVE) has built-in support for UVM debug. Using the GUI, it is
possible to get list of “Set calls without Get” and “Get calls without Set. These lists help to find and detect errors
in the testbench. Figure 11 below shows the DVE UVM debug dialog window.
Figure 11: Synopys’ VCS DVE UVM debug dialog window
The UVM command line option +UVM _ CONFIG _ DB _ TR ACE makes all set() and get() calls visible in the
simulation log. However doing this makes the log file too verbose and difcult to interpret. For this reason tracing
is typically turned on only when finding a specific uvm _ cong _ db problem. Below is an example of log
messages printed out when set() and g et() functions are executed.
39 UVM _ INFO /global/apps4/vcs _ 2012.09-3/etc/uvm-1.1/base/uvm _ resource db.svh(129) @ 0:
40 reporter [CFGDB/SET]
41 Conguration ‘uvm _ test _ top.env.name _ agent _ 1.i _ of _ env’ (type int)
42 set by uvm _ test _ top.env.name _ agent _ 1 = (int) 1
43
44 UVM _ INFO /global/apps4/vcs _ 2012.09-3/etc/uvm-1.1/base/uvm _ resource _ db.svh(129) @ 0;
45 reporter [CFGDB/GET]
46 Conguration ‘uvm _ test _ top.env.name _ agent _ 1.i _ of _ env’ (type int)
47 read by uvm _ test _ top.env.name _ agent _ 1 = (int) 1
Sometimes it may help just to print out the name of the object. UVM object has functions get _ n a m e() and
get _ full _ na m e(). By using these, it can be verified manually that names used in the source code and
named objects at runtime match. Below is an example of how to print the object’s name.
4 9 $ d i s p l a y ( t h i s . g e t _ n a m e = % 0 s , t h i s _ g e t _ f u l l _ n a m e = % 0 s , t h i s . g e t _ n a m e ( ) ,
this.get _ full _ name());
Conclusion
When using UVM you can’t avoid uvm _ cong _ db. So it’s better to get a solid understanding about what the
set() and g et() functions of the uvm _ cong _ db do and how you can use them more efficiently in building
your testbench. Below are some dos and don’ts found to be useful when using UVM.
Do’s:
For simplicity and to avoid confusion, use the “eld name” as the variable name
Investigate an upshot warning/error on an unsuccessful get() method call
Set the configuration variable needed across the verification component in the agent’s test environment
to enable the agent to later set its sub-components
Hierarchal Testbench Configuration Using uvm_config_db 10
Don’ts:
Avoid using the uvm _ cong _ db mechanism excessively as it may cause
performance issues
Avoid using the automatic configuration or implicit get() method call
Apart from the above recommendations, it is recommended to use a UVM-aware GUI-based debugging tool such
as Synopsys’ VCS Discovery Visualization Environment (DVE). As part of Synopsys Professional Services we have
used these concepts across multiple customer engagements to successfully deploy UVM. For more information
on these services, see www.synopsys.com/services.
Appendix
Below is a sample UVM environment showcasing the examples presented earlier. set() and get() functions
utilize only integers (int) though classes and interfaces that would normally be used.
1 // Usage
2 // vcs –R –sverilog –ntb _ opts uvm-1.1 –debug _ all +vcs+vcdpluson
-1 sim.log
3 // –q example.sv +UVM _ TESTNAME=test _ a
4 import u v m _ p k g::*;
5
6 module dut;
7 int dut _ int = 10;
8 initial uvm _ cong _ db#(int)::s e t(uvm _ root::get(),
9 *”,
10 “from _ dut”,
11 dut _ int
1 2 );
13 endmodule
14
15 module top;
16 initial r u n _ t e s t();
17 dut i _ dut();
18 endmodule
19
20 class agent extends uvm _ component;
21
int i1 _ agent, i2 _ agent, i3 _ agent; // to receive values from uvm _ cong _ db
22 int i4; // to use automatic conguration
23 uvm _ event new _ values; // to signal new step in test (env->agent)
24 `uvm _ component _ utils _ begin (agent)
25 `uvm _ eld _ int(i4, UVM _ ALL _ ON)
26 `uvm _ component _ utils _ end
27 function new (string name, uvm _ component parent);
28 su p er.new(name, parent);
29 endfunction
30 function void build _ phase (uvm _ phase p h a s e);
31 super.build _ phase( p h a s e);
32 uvm _ cong _ db#( u v m _ e v e n t ):: get(this, “, “new _ values”, new _ values);
33 if (new _ values == null)
34 `uvm _ fatal(get _ name(),
35 “new _ values must be set in uvm _ cong _ db”
36 );
37 $display(“ Agent \%0s\” got Automatic conguration: i4=%0d”,
38 get _ name(),
39 i4
40 );
41 endfunction
42 task run _ phase (uvm _ phase p h a s e);
43 while (1)
44 begin
45 uvm _ cong _ db#(int)::get(this,
46 ”,
47 “i _ of _ env”,
48 i1 _ agent
49 );
Hierarchal Testbench Configuration Using uvm_config_db 11
50 uvm _ cong _ db#(int)::get(uvm _ root::get(),
51 “uvm _ test _ top.env.name _ agent _ 1,
52 “i _ of _ env”,
53 i2 _ agent
5 4 );
55
$display(Agent \%0s\” got: %0d (and stole %0d from agent1),
56 get _ name(),
57 i1 _ agent,
58 i2 _ agent
59 );
60 uvm _ cong _ db#(int)::get(this, “, “from _ dut, i3 _ agent);
61 $display(“ Agent \%0s\” got %0d from DUT”,
62 get _ name(),
63 i3 _ agent
6 4 );
65 new _ values.wait _ trigger();
66
67 end
68 endtask
69 endclass
70
71 class env extends uvm _ env;
72 `uvm _ component _ utils(env)
73 agent agent _ 1, agent _ 2, agent _ 3;
74 int i1 _ env=1, i2 _ env=2, i3 _ env=3,
75 i4 _ env=4, i5 _ env=5, i6 _ env=6,
76 i7 _ env=7, i8 _ env=8;
77 uvm _ event new _ values;
78 function new(string name, uvm _ com ponent parent);
79 s u p er.new(name, parent);
80 endfunction
81 function void build _ phase (uvm _ phase p h a s e);
82 agent _ 1 = agent::type _ id::create(name _ agent _ 1, this);
83 agent _ 2 = agent::type _ id::create(na me _ agent _ 2, this);
84 agent _ 3 = agent::type _ id::create(“na me _ agent _ 3, this);
85 set _ cong _ int(“name _ agent _ 1, “i4, 1111);
86 set _ cong _ int(“name _ agent _ 2”, “i4”, 2222);
87 set _ cong _ int(“name _ agent _ 3”, “i4”, 3333);
88 new _ values = new(“new _ values);
89 //Share event through uvm _ cong _ db with agents
90 uvm _ cong _ db#(uvm _ event)::s e t(this,
91 name _ agent _ *”,
92 “new _ values”,
93 new _ values
9 4 );
95 endfunction
96 task run _ phase (uvm _ phase p h a s e);
97 phase.raise _ objections(this);
98 //uvm _ cong: share data with one specic object
99 $display(“ --- 1, 2, 3 to every agent separately --- “);
100 uvm _ cong _ db#(int)::s e t(agent _ 1,
101 ”,
102 i _ of _ env”,
103 i1 _ env
10 4 );
105 uvm _ cong _ db#(int)::s e t(this,
106 n a m e _ a g e n t _ 2 ”,
107 “i _ of _ env”,
108 i2 _ env
109 );
110 uvm _ cong _ db#(int)::s e t(uvm _ root::get(),
111 “uvm _ test _ top.env.name _ agent _ 3,
112 “i _ of _ env”,
113 i3 _ env
1 14 );
115 // uvm _ cong _ db: share data with multiple objects using regexp
06/14.AP.CS3989.
Synopsys, Inc.
700 East Middlefield Road
Mountain View, CA 94043
www.synopsys.com
©2014 Synopsys, Inc. All rights reserved. Synopsys is a trademark of Synopsys, Inc. in the United States and other countries. A list of Synopsys trademarks is
available at http://www.synopsys.com/copyright.html . All other names mentioned herein are trademarks or registered trademarks of their respective owners.
116 new _ values.trigger(); #1;
117 $display(“ --- 4 to every agent, regexp name _ agent _ ? --- “ );
118 uvm _ cong _ db#(int)::s e t(this,
119 n a m e _ a g e n t _ ?”,
120 “i _ of _ env”,
121 i4 _ env
1 2 2 );
123 new _ values.trigger(); #1;
124 $display(“ --- 5 to every agent, regexp name _ agent* --- “ );
125 uvm _ cong _ db#(int)::s e t(this,
126 “name _ agent _ *,
127 “i _ of _ env”,
128 i5 _ env
1 29 );
130 new _ values.trigger(); #1;
131 $display(“ --- 6 to every agent, regexp *agent* --- “);
132 uvm _ cong _ db#(int)::s e t(uvm _ root::get(),
13 3 *a g e nt*”,
134 “i _ of _ env,
135 i6 _ env
1 36 );
137 // uvm _ cong _ db: share data with everyone
138 new _ values.trigger(); #1;
139 $display(“ --- 7 to everyone, regexp *--- “ );
140 uvm _ cong _ db#(int)::s e t(uvm _ root::get(),
141 *”,
142 “i _ of _ env,
143 i7 _ env
144 );
145 new _ values.trigger(); #1;
146 $display(“ --- 8 to everyone, regexp *--- “);
147 uvm _ cong _ db#(i n t )::s e t(null,
148 *”,
149 “i _ of _ env”,
150 i8 _ env
151 );
152 new _ values.trigger();
153 phase.drop _ objection(this);
154 endtask
155 endclass
156
157 class test _ a extends uvm _ test;
158 `uvm _ component _ utils (test _ a)
159 env env;
160 function new (string n a m e = t e s t _ a”, uvm _ component parent=null);
161 su p er.new (name, parent);
162 env = new( e n v ”, this);
163 endfunction
164 function void end _ of _ elaboration();
165 print();
166 endfunction
167 task run _ phase(uvm _ phase p h a s e);
168 #1000; global _ stop _ request();
169 endtask
170 endclass
References
1
Accellera Systems Initiative Universal Verification Methodology (UVM) 1.1 User’s Guide, May 18, 2011
2
Accellera Systems Initiative Universal Verification Methodology (UVM) 1.1 Class Reference Manual, June 2011