factory

The purpose of the UVM factory is to allow an object of one type to be substituted with an object of a derrived type without having to change the structure of the testbench or edit the testbench code.

In order to take advantage of factory, following conventions need to be followed:

1.a component or object must contain following factory registration code:

1.1. an uvm_component_registry wrapper, typedefed to type_id;

1.2. a static function to get the type_id;

1.3 a functin to get the type name;

for example:

class my_component extends uvm_component;

//1.1

typedef uvm_component_registry #(my_component, "my_component") type_id;

//1.2

static function type_id get_type();

  return type_id::get();

endfunction

//1.3

function string get_type_name();

  return "my_component";

endfunction

endclass : my_component

There're four macros to generate the regular pattern:

// for a component

class my_component extends uvm_component;

`uvm_component_utils(my_component)

// for a parameterised componen

class my_param_component #(int ADD_WIDTH=20m int DATA_WIDTH=23) extends uvm_component;

typedef my_param_component #(ADD_WIDTH, DATA_WIDTH) this_t;

`uvm_component_param_utils(this_t)

// for a class derived from an object( uvm_object, uvm_transaction, uvm_sequence_item, uvm_sequence etc)

class my_item extends uvm_sequence_item;

`uvm_object_utils(my_item)

// for a parameterised object class

class my_item #(int ADD_WIDTH=20, int DATA_WIDTH=23) extends uvm_sequence_item;

typedef my_item #(ADD_WIDTH, DATA_WIDTH) this_t;

`uvm_object_param_utils(this_t);

2. set default name in constructor

this allows the factory registered class to be built inside the factory using the defaults and then the class properties are re-assigned to the arguments passed via the create method of the uvm_component_registry wrapper class.

for exampler:

// for component

class my_component extends uvm_component;

function new(string name="my_component", uvm_component parent = null);

  super.new((name,parent);

endfunction

// for an object

class my_item extends uvm_sequence_item;

function new(string name="my_item");

  super.new(name);

endfunction

3. component created in buld_phase, object created as required.

factory override

The UVM factory can be thought of as a lookup table. When "normal" component construction takes place using <type>::type_id::create("<name>",<parent>) approach, what happens is that the type_id is used to pick the factory component wrapper for the class, construct its contents and pass the resultant handle back again. The factory override changes the way in which the lookup happers so that looking up the original type_id results in a different type_id being used and a consequently a handle to a different type of constructed object being returned. This technique relies on polymorphism, the ability to be able to refer to derived types using a base type handle. In practise, an override will only work whn a parent class is overriden by one of its descendents in the class extension hierarchy.

posted on 2017-11-27 16:46  lybinger  阅读(324)  评论(0)    收藏  举报

导航