class A_config extends uvm_object;
bit enable_some_function;
endclass
class A extends uvm_component;
A_config a_cfg;
.
virtual task configure_phase(uvm_phase phase);
if(a_cfg.enable_some_function)
some_function();
endtask
virtual function void some_function();
$display("To be redefined in the extended class");
endfunction: some_function
.
endclass: A
class B_config extends A_config;
bit enable_someother_function;
endclass: B_config
//This is a component
class B extends A;
B_config b_cfg;
.
virtual task post_configure_phase(uvm_phase phase);
if(b_cfg.enable_someother_function)
some_other_function();
endtask
function void some_function();
$display("Has been redefined!");
endfuncion
function void some_other_function();
$display("Some other function in Class B!");
endfuncion
.
endclass: B
Now in the environment class I have created component of type B and object of type B_config. Now I can do a uvm_config_db#(B_config)::set(this, “class_b_handle”, “b_cfg”, b_cfg) and do a uvm_config_db::get in the class B’s build_phase.
Since B_config class inherits all properties and methods of A_config, the B_config class has the property enable_some_function.
What would be the ideal place to assign the derived class B_config handle to the base class A_config handle? Is it in the constructor of the uvm_component class B like so?
You can’t assign b_cfg to a_cfg because they are not type compatible. When you create b_cfg and assign it to the handle in B, you should create a_cfg with the appropriate values and assign that handle at the same time. Since B has both a_cfg and b_cfg, you don’t need to assign super.a_cfg.
Why do you say that b_cfg and a_cfg are not type compatible? B_config extends from A_config and it should be legal to upcast extended class object to the base class. Right?
You are suggesting to create a_cfg in addition to b_cfg. My question is B_congig object already has all the properties of A_config and I would simply like to use these properties from the B_config object instead of creating a separate object go type A_config. Does that make sense? May be I didnt get what you said.
The problem am seeing is because I try to do uvm_config_db set/get of the config object. And uvm_config_db set uses the class type as a parameter. Can I do a set like below in the env,
And, do uvm_config_db::get in the build phase of class B and A? When I do a get in class B, the call to get will be parameterized with type B_config. But the get in Class A will have A_config as the parameter. But I want to do one uvm_config_db::set and have uvm_config_db::get calls in the classes A and B. Hopefully that makes sense.
Here is a more complete code of what am trying to do. When I execute this I get a null object access error. What needs attention in the below code is the uvm_config_db::set and uvm_config_db::get.
Here is a link to EDA playground with the code to execute.
// Code your testbench here
// or browse Examples
module top;
class A_config extends uvm_object;
bit enable_some_function;
`uvm_object_utils(A_config)
function new(string name = "");
super.new(name);
endfunction
endclass: A_config
class B_config extends A_config;
bit enable_someother_function;
`uvm_object_utils(B_config)
function new(string name = "");
super.new(name);
endfunction
endclass: B_config
class A extends uvm_component;
A_config a_cfg;
`uvm_component_utils(A)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
virtual function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
if(!uvm_config_db#(A_config)::get(this, "", "a_cfg", a_cfg))
`uvm_fatal("class A", "Couldnt get the config object!")
endfunction
virtual task configure_phase(uvm_phase phase);
if(a_cfg.enable_some_function)
some_function();
endtask
virtual function void some_function();
$display("To be redefined in the extended class");
endfunction: some_function
endclass: A
class B extends A;
B_config b_cfg;
`uvm_component_utils(B)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
virtual function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
if(!uvm_config_db#(B_config)::get(this, "", "b_cfg", b_cfg))
`uvm_fatal("class B", "Couldnt get the config object!")
endfunction
virtual task post_configure_phase(uvm_phase phase);
if(b_cfg.enable_someother_function)
some_other_function();
endtask
function void some_function();
$display("Has been redefined!");
endfunction
function void some_other_function();
$display("Some other function in Class B!");
endfunction
endclass: B
class env extends uvm_component;
B b_h;
B_config b_cfg;
`uvm_component_utils(env)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
b_cfg = B_config::type_id::create("b_cfg");
b_h = B::type_id::create("b_h", this);
uvm_config_db#(B_config)::set(this, "b_h", "b_cfg", b_cfg);
endfunction
endclass: env
initial begin
env e;
e = env::type_id::create("e", null);
run_test();
end
endmodule
In the connect_phase of the class B, may be I can use $cast to assign the super class handle to subclass handle, since a_cfg has B_config object by doing uvm_config_db::get() in class A.