The factory pattern is an well known object-oriented design pattern. The factory method design pattern defining a separate method for creating the objects. , whose subclasses can then override to specify the derived type of object that will be created.

Using this method, objects are constructed dynamically based on the specification type of the object. User can alter the behavior of the pre-build code without modifying the code. From the testcase, user from environment or testcase can replace any object which is at any hierarchy level with the user defined object.

For example: In your environment, you have a driver component. You would like the extend the driver component for error injection scenario. After defining the extended driver class with error injection, how will you replace the base driver component which is deep in the hierarchy of your environment ? Using hierarchical path, you could replace the driver object with the extended driver. This could not be easy if there are many driver objects. Then you should also take care of its connections with the other components of testbenchs like scoreboard etc.

One more example: In your Ethernet verification environment, you have different drivers to support different interfaces for 10mbps,100mps and 1G. Now you want to reuse the same environment for 10G verification. Inside somewhere deep in the hierarchy, while building the components, as a driver components ,your current environment can only select 10mmps/100mps/1G drivers using configuration settings. How to add one more driver to the current drivers list of drivers so that from the testcase you could configure the environment to work for 10G.

Using the uvm fatroy, it is very easy to solve the above two requirements. Only classs extended from uvm_object and uvm_component are supported for this.

There are three basic steps to be followed for using uvm factory.

1) Registration
2) Construction
3) Overriding

The factory makes it is possible to override the type of uvm component /object or instance of a uvm component/object in2 ways. They are based on uvm component/object type or uvm compoenent/object name.


While defining a class , its type has to be registered with the uvm factory. To do this job easier, uvm has predefined macros.

`uvm_component_param_utils(class_type_name #(params))
`uvm_object_param_utils(class_type_name #(params))

For uvm_*_param_utils are used for parameterized classes and other two macros for non-parameterized class. Registration is required for name-based overriding , it is not required for type-based overriding.

EXAMPLE: Example of above macros

class packet extends uvm_object;

class packet #(type T=int, int mode=0) extends uvm_object;
`uvm_object_param_utils(packet #(T,mode))

class driver extends uvm_component;

class monitor #(type T=int, int mode=0) extends uvm_component;


To construct a uvm based component or uvm based objects, static method create() should be used. This function constructs the appropriate object based on the overrides and constructs the object and returns it. So while constructing the uvm based components or uvm based objects , do not use new() constructor.

Syntax :

static function T create(string name,
uvm_component parent,
string context = " ")

The Create() function returns an instance of the component type, T, represented by this proxy, subject to any factory overrides based on the context provided by the parents full name. The context argument, if supplied, supersedes the parents context. The new instance will have the given leaf name and parent.

class_type object_name;

object_name = clss_type::type_id::creat("object_name",this);

For uvm_object based classes, doesnt need the parent handle as second argument.


If required, user could override the registered classes or objects. User can override based of name string or class-type.

There are 4 methods defined for overriding:

function void set_inst_override_by_type
(uvm_object_wrapper original_type,
uvm_object_wrapper override_type,
string full_inst_path )

The above method is used to override the object instances of "original_type" with "override_type" . "override_type" is extended from"original_type".

function void set_inst_override_by_name
(string original_type_name,
string override_type_name,
string full_inst_path )

Original_type_name and override_type_name are the class names which are registered in the factory. All the instances of objects with name "Original_type_name" will be overriden with objects of name "override_type_name" using set_inst_override_by_name() method.

function void set_type_override_by_type
(uvm_object_wrapper original_type,
uvm_object_wrapper override_type,
bit replace = 1 )

Using the above method, request to create an object of original_type can be overriden with override_type.

function void set_type_override_by_name
(string original_type_name,
string override_type_name,
bit replace = 1)

Using the above method, request to create an object of original_type_name can be overriden with override_type_name.

When multiple overrides are done , then using the argument "replace" , we can control whether to override the previous override or not. If argument "replace" is 1, then previous overrides will be replaced otherwise, previous overrides will remain.

print() method, prints the state of the uvm_factory, registered types, instance overrides, and type overrides.

Now we will see a complete example. This example is based on the environment build in topic UVM TESTBENCH . Refer to that section for more information about this example.

Lets look at the 3 steps which I discussed above using the example defined in UVM TESTBENCH

1) Registration

In all the class, you can see the macro `uvm_component_utils(type_name)

2) Construction

In file agant.sv file, monitor and driver are constructed using create() method.

mon = monitor::type_id::create("mon",this);
drv = driver::type_id::create("drv",this);

3)In this example, a one testcase is already developed in topic UVM_TESTBENCH. There are no over rides in this test case.

Topology of this test environment is shown below.

In this example, there is one driver class and one monitor class. In this testcase , By extending driver class , we will define driver_2 class and by extending monitor class, we will define monitor_2 class.

From the testcase , Using set_type_override_by_type, we will override driver with driver_2 and Using set_type_override_by_name, we will override monitor with monitor_2.

To know about the overrides which are done, call factory.print() method of factory class.

class driver_2 extends driver;


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


class monitor_2 extends monitor;


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


class test_factory extends uvm_test;

env t_env;

function new (string name="test1", uvm_component parent=null);
super.new (name, parent);

t_env = new("t_env",this);
endfunction : new

function void end_of_elaboration();
uvm_report_info(get_full_name(),"End_of_elaboration", UVM_LOW);
endfunction : end_of_elaboration

task run ();
endtask : run


(S)Download the example:

Browse the code in uvm_factory.tar

(S) Command to simulate

Command to run the example with the testcase which is defined above:
VCS Users : make vcs
Questa Users: make questa

Method factory.print() displayed all the overrides as shown below in the log file.

#### Factory Configuration (*)

No instance overrides are registered with this factory

Type Overrides:

  Requested Type  Override Type
  --------------  -------------
  driver          driver_2
  monitor         monitor_2

In the below text printed by print_topology() method ,we can see overridden driver and monitor.

Name                     Type                Size                Value
uvm_test_top             test_factory        -          uvm_test_top@2
  t_env                  env                 -                 t_env@4
    ag1                  agent               -                   ag1@6
      drv                driver_2            -                  drv@12
        rsp_port         uvm_analysis_port   -             rsp_port@16
        sqr_pull_port    uvm_seq_item_pull_+ -        sqr_pull_port@14
      mon                monitor_2           -                  mon@10
    ag2                  agent               -                   ag2@8
      drv                driver_2            -                  drv@20
        rsp_port         uvm_analysis_port   -             rsp_port@24
        sqr_pull_port    uvm_seq_item_pull_+ -        sqr_pull_port@22
      mon                monitor_2           -                  mon@18

In the below text printed by print_topology() method ,with testcase test1 which does note have overrides.

Command to run this example with test1 is
VCS Users : make vcs
Questa Users: make questa

Name                     Type                Size                Value
uvm_test_top             test1               -          uvm_test_top@2
  t_env                  env                 -                 t_env@4
    ag1                  agent               -                   ag1@6
      drv                driver              -                  drv@12
        rsp_port         uvm_analysis_port   -             rsp_port@16
        sqr_pull_port    uvm_seq_item_pull_+ -        sqr_pull_port@14
      mon                monitor             -                  mon@10
    ag2                  agent               -                   ag2@8
      drv                driver              -                  drv@20
        rsp_port         uvm_analysis_port   -             rsp_port@24
        sqr_pull_port    uvm_seq_item_pull_+ -        sqr_pull_port@22
      mon                monitor             -                  mon@18

Uvm Testbench
Uvm Reporting
Uvm Transaction
Uvm Configuration
Uvm Factory
Uvm Sequence 1
Uvm Sequence 2
Uvm Sequence 3
Uvm Sequence 4
Uvm Sequence 5
Uvm Sequence 6
Uvm Tlm 1
Uvm Tlm 2
Uvm Callback

Report a Bug or Comment on This section - Your input is what keeps Testbench.in improving with time!




copyright 2007-2017 :: all rights reserved www.testbench.in::Disclaimer