Overriding a parameter

I need to override the parameter value of a parameterized uvm_component. Is this possible at all? I’ve tried several ways and failed in all of them. I can’t pass a variable/config field to the parameter while creating the component.
eg: A#(xyz)::type_id::create - This won’t work as I need to declare the type of A with the parameter.
I’m almost certain that the answer will be a NO, but just wanted someone to confirm this:
Can we do this for class A which has an integer parameter. I’m getting an FCTTYP error with this.

A#(4)::type_id::set_type_override(A#(5)::get_type())

Any help with this is appreciated. Thanks!

When you are using parameterized components and objects, make sure that you use the corresponding `uvm_*_param_utils macros and not the normal ones:


class my_param_component#(int WIDTH=32) extends uvm_component;

  `uvm_component_param_utils(my_param_component#(WIDTH))
.
.
.

In reply to cgales:

I did that. The issue I’m having is that I don’t want to hardcode the value of the parameter at the time of the object creation. Instead, I want it to be something like a config bit.
eg: I’m trying to do this:

 obj_A = class_A#(xyz_cfg.width)::type_id::create();

You can’t override a class parameter (or any parameter in SystemVerilog for that matter) with a dynamic variable. It must be another parameter, a literal constant, or some expression containing only these.

There are a few ways to achieve something close to what you are looking for if you can elaborate all the possible values of values that could be selected. (i.e. xyz_cfg.width could be 8,16,32,64)

You can create an associative array of proxy classes indexed by the elaborated values, then select the element you want to override with

class class_A #(int WIDTH) extends common_base;
...
endclass
uvm_object_wrapper class_A_proxies[int] = '{
                 5:class_A#(5)::get_type(),
                 8:class_A#(8)::get_type(),
                 16:class_A#(16)::get_type()
            }
...
commmon_base::type_id::set_type_override(class_A_proxies[xyz_cfg.width]);

See my popular DVcon paper for more details about parameters, constants, proxies and why you need a common_base class.

Another mechanism is to use a string lookup as described in another blog post of mine.

In reply to dave_59:

Thanks for the pointers, Dave. Is it possible to change the value of the parameter in an extended class and then override the class using a plusarg?
eg:

class A;
   parameter int WIDTH = 8;
endclass

class A1 extends A;
    parameter int WIDTH = 16;
endclass

run the test with +uvm_set_type_override=A,A1

In reply to itsmyturn:

Extending a class with another parameter does not override the parameter inside the base class, it just adds another parameter.

What you can do is

class A extends uvm_object;
`uvm_object_utils(A)
// put anything that is not dependent on the WIDTH in this class
endclass
class B #(int width) extends A;
// no factory registration
endclass
class B16 extends B#(16);
`uvm_object_utils(B16)
endclass

run test with +uvm_set_type_override=A,B16

In reply to dave_59:

Thanks a lot, Dave. Do we need 3 layers here? Can’t we just override A with B#(16)?

In reply to itsmyturn:

You can use 2 layers if you use the A::type_id::set_type_override(B#(16)) method, or if you use one of the mechanisms I showed above. You can only use the +uvm_set_type_override plusarg method with 2 layers if there is a string name associated with a class type you want to override. The UVM macros don’t register strings names for parameterized classes, but you can do that yourself explicitly.

Don’t you need a tick in the uvm macro calls? Also, it appears your post is missing eol’s.

Fixed. Thanks. That was a formatting problem when we migrated the forums to a new platform.