UVM Parameterized classes

Hello everyone, is it a good practice to use parameterized UVM classes? I know i can define them as defines/macros in another file and use in all classes, but what if I want to have two drivers with different parameters? I do not think I will be able to create them. So, I need to have a parameterized driver class. Is there easier way to implement it when there are a lot of parameters? Because it is not easy to add a new parameter when all classes are parameterized and it looks messy.

Rahmat Rustam,

Hope it is fine I will correct the term, parameterized classes are a System-Verilog language construct, which is being used in many UVM base classes.
You don’t need to import the uvm_pkg (import uvm_pkg::*;), in order to receive this capability.

We had once parameterized classes (ref-model, scoreboards,…) with MANY parameters, the way we chose to handle it was with config-class (extends from uvm_object) which is passed as one of the parameterized class parameters, rather than using defines/macros (not a big fan of this approach).
This concept is similar to the way we encapsulate many configuration knobs in one cfg_obj of a verification agent, which is being passed trough uvm_config_db.

Things you need to keep in mind: “Each class parameterization creates a new type”.

Rahmat MichaelP,

Yes, thank you for the clarification.

I understand the idea but let say I have the parameters passed to cfg_obj in the test file and then I pass this object to environment, agents by using uvm_config_db. Then I get it in the driver class and want to create a signal
logic [DWIDTH - 1: 0] data;. How can I access parameter DWIDTH from the cfg_obj. Like writing cfg_obj.DWIDTH? is it possible?
Lets say: class my_config_class#(parameter DWIDTH = 32)…

No need in using the uvm_config_db passing this “parameters config-class” which holds the parameters… did some other hack.

class abc_params_cfg extends uvm_object;
    localparm  ADDR_W = 64;
    localparm  DATA_W = 64;
    localparm  ID_W  = 8;
    //define more parameters...
    
    function new (string name = "abc_params_cfg");
        super.new(name);
    endfunction
endclass


// Next the abc_params_cfg class will be defined as one of the parametrized parameters! 

class abc_ref_model#(type PARAMS_CFG = abc_params_cfg) extends uvm_component;
    localparm ADDR_W = PARAMS_CFG::ADDR_W;
    localparm DATA_W  = PARAMS_CFG::DATA_W;
    localparm ID_W  = PARAMS_CFG::ID_W;
    // define more parameters... 

    `uvm_component_params_utils_begin(abc_ref_model#(PARAMS_CFG))
    `uvm_component_utils_end
endclass

class abc_env extends uvm_component;
    `uvm_component_utils(abc_env)

     abc_cfg    cfg;
     
     abc_ref_model#(abc_params_cfg)      abc_rm;

    
endclass

Few notes:

  1. The abc_params_cfg encapsulates all the parameters you would like to pass to your parametrized class (similar to the cfg object which is commonly being set/get to/from uvm_config_db), but without really setting/getting it to/from uvm_config_db and without using the macro/defines syntax!
  2. You can have multiple parameter config classes, as you wish. Just pass the correct one you wish to the specific instance of the parametrized class.
  3. The abc_params_cfg is passed as one of the type parameters to the parametrized class, and its parameters are being assigned to elaboration-time constant localparam.

Let me know if it worked out.

1 Like

It worked!! This is a good approach. Thanks a lot.

You are welcome