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:
- 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!
- 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.
- 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.
It worked!! This is a good approach. Thanks a lot.
You are welcome