Hello,
This is my example of how I use uvm_config_db# in my virtual sequence.
I have a configuration class like this:
class l2_config extends uvm_object;
int i_rsp_credit = 12;
`uvm_object_utils_begin( l2_config )
`uvm_field_int ( i_rsp_credit, UVM_DEFAULT + UVM_DEC )
`uvm_object_utils_end
function new ( string name = "l2_config" );
super.new( name );
endfunction : new
endclass: l2_config
And I want to change “i_rsp_credit” during my virtual sequence. I’ve made this in virtual sequence, but it didn’t work:
…
virtual task body();
…
uvm_config_db#(int)::set(uvm_root::get(), “*” ,“i_rsp_credit”, 14);
Can anyone explane what is wrong and is it a good practice to change configuration class in sequnces?
In reply to Danil:
Hi Danil,
unfortunately I do not see all your code and I do not understand why you want to modify the variable i_rsp_credit in the virtual sequence.
It is good practice to pass variables/paramters through the testbench hierarchy. This allows you to retrieve the actual value of a variable in any component of your testbench. Typically it should be set in a corresponding test.
By the way there is no reason to register a configuration object with the factory. This gives you more freedom to implement the configuration class.
Hope this helps.
In reply to chr_sue:
Thank you for reply chr_sue. But if I don’t register a configuration object with the factory I can’t use uvm_config_db#. Am I right?
In reply to Danil:
Hi Danil,
the factory and the configuration database are two different mechanisms for customizing UVM testbenches.
The macro `uvm_component_utils registers a UVM component with the factory.
With uvm_config_db you are making an entry in the configuration data base. This is a way to make data available across the whole testbench hierarchy.
The factory allows you to replace components of the same type in a testbench.
In reply to chr_sue:
Thanks again chr_sue. Now I clearly understand the difference.
Here is my another example. For instance, I have a configuration object:
class my_config extends uvm_object;
int a = 0;
`uvm_object_utils( my_config )
function new ( string name = "my_config" );
super.new( name );
endfunction : new
endclass: my_config
And also I have a driver like this:
class my_driver uvm_driver #(my_item);
my_config cfg;
`uvm_component_utils_begin( my_driver )
`uvm_field_object( cfg , UVM_DEFAULT )
`uvm_component_utils_end
function new (string name = "my_driver", uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase( uvm_phase phase );
super.build_phase( phase );
if( !uvm_config_db#( my_config )::get( this, "", "cfg", cfg ) )
`uvm_error( "NOCONFIG",
{ "Config not set for...", get_full_name() } )
endfunction: build_phase
....
endclass: my_driver
And there is a simple test:
class my_test extends uvm_test;
`uvm_component_utils(my_test)
my_driver driver;
my_config cfg;
virtual function void build_phase( uvm_phase phase );
super.build_phase(phase);
driver = my_driver::type_id::create( "driver", this );
//this slice of code changes "a" value in configuration
cfg = my_config::type_id::create( "cfg", this );
cfg.a = 1;
uvm_config_db#(my_config)::set( uvm_root::get(), "driver*", "cfg" , cfg );
// but if i want to change "a" value like this, it doesn't work
uvm_config_db#(int)::set( uvm_root::get(), "driver.cfg", "a" , 1 );
endfunction
endclass
Could you explain why?
In reply to Danil:
Hi Danil,
it might not work because of the hierachy in the uvm_config_db command.
The first argument in uvm_config_db ist the context. Finally this describes the hierarchy.
There are two useful ways to define this:
-
uvm_config_db#(int)::set( null, ".driver", <string_name>, value);
‘null’ as the first argument means you want to use the full hierarchical path
'.driver’(second argument) means you are pointing to a component named driver in the hierarchy
<string_name> is a simple name under which the value is stored in the config database
-
uvm_config_db#(int)::set( this, “driver”, <string_name>, value);
‘this’ as the first argument indicates you are using a hierarchical path
‘driver’ means you are pointing to a component named driver and instantiated in test.
Remark to class my_config: there is no need to register this with the factory.
Remark to class my_driver: (1) insert extends between my_driver and uvm_driver
(2) don’t use the field macro for the config.
Hope you get it running.
Christoph
In reply to chr_sue:
Thank you chr_sue. I’ll use your advices.