Jump to content

About the config class usage


Recommended Posts

Hi,

Recently, i would like to gather all the config parameters for each OVC component into only one class, and name it as config class, and use this class to configure our OVC behaviours. So I am wondering whether UVM have recommoned config class usage example, and I am also puzzled with the following 2 questions:

1. how to choose the base class of our config class, to use uvm_object or to use uvm_component?

2. why uvm not recommend us to explicit call xx.build() task?

BR

MIKE

Link to comment
Share on other sites

Mike,

This is exactly what we recommended in the OVM. Use only config objects, not ints or strings. Use uvm_object as the base for your config class; components have much more overhead associated with them.

You should not call xx.build() directly because the scheduler inside the UVM kernel will do that for you at the appropriate time.

Dave Rich

Link to comment
Share on other sites

1. but in fact, if we would like to use set_config_* to config our defined config class, then how to deal with it? As we know, set_config_* method can not config uvm_object extended sub_class, do you have any suggestion about this?

2. If we choose uvm_object as the base class, and if we want to configure multi extended config classes in our TB by wildcard just like set_config_*, how to achieve this?

3. could you provide some offical example about how to use config class in OVM/UVM? Thanks a lot!

Link to comment
Share on other sites

The new uvm_config_db#() does not depend on the configuration being in a uvm_component. As long as the full_path_name + instance name + option name match (using regexp) in both the set() and get(), it'll work. So you can configure anything.

The other advantage of uvm_config_db#() is that it is strongly typed. You won't configure a component with the wrong configuration object. And because it uses a parameter for the type, the configuration class need not be based on any class -- although basing it on uvm_object is a good idea.

Link to comment
Share on other sites

You are really asking about two different things:

1) How to pass configuration information down the hierarchy

2) How to set the configuration values in that configuration object

What Dave (and I) recommend is that you create the configuration object instance, initialize as required (or randomize it) then pass it (the entire object) down via uvm_config_db#()

What you seem to be asking is to have a configuration object instantiated in the component that you can set via the uvm_config_db#(). That requires a) that field automation macros be used, B) that it be a uvm_component instantiated in the component hierarchy and c) that super.build_phase() or apply_config_settings() be called in the component's build_phase(). See http://www.uvmworld.org/forums/showthread.php?155-help-on-UVM_READONLY for a related discussion.

Link to comment
Share on other sites

Yes, the second one you mentioned above is just what we did. But I agree with you, the first one is better. What I concern is that, in the first way, if we want to change a parameter value of uvm_object based config class in test case level before pass it down to the desired component, is there any better way to achieve this?Just use assign('=')?

Link to comment
Share on other sites

What better and simpler way is there than a simple "=" operation?? :-)

The beauty of the uvm_config_db#() (and the underlying uvm_resource_db#()) is that anyone can retrieve anything (with the appropriate look-up names of course) so you "set" a default configuration object in yoru envionrment, "get" the configuration object in the test and modify it (by reference), then "get" the modified configuration object in the VIP.

Link to comment
Share on other sites

Fine, great thanks, I will try this way, thanks. here is my plan, please correct me, if I made mistake:

1. Define config obj:

class xxx_configure_obj extends uvm_object;

rand bit endian;

...

endclass

2. In VIP

class xxx_env extends uvm_env;

xxx_cofigure_obj xxx_obj;

endclass

3. in TB env:

class TB_env extends uvm_env;

xxx_configure_obj myobj1;

xxx_env myenv;

virtual function void build_phase(uvm_phase phase);

super.build_phase(phase);

myobj1 = new();//with default settings

//create myenv component

uvm_config_db#(uvm_object)::set(this, "myenv", "xxx_obj" ,myobj1);

...

endfunction

endclass

4. in Test case

class testcase extends uvm_test;

TB_env TB_env_inst;

xxx_configure_obj test_obj;

virtual function void build_phase(uvm_phase phase);

super.build_phase(phase);

uvm_config_db#(uvm_object)::get(this, "TB_env_inst", "myobj1" ,test_obj);

test_obj.endian = 0; // modified some items

uvm_config_db#(uvm_object)::set(this, "TB_env_inst", "myobj1" ,test_obj);

...

//create TB_env_inst

endfunction

...

endclass

Link to comment
Share on other sites

1. Use uvm_config_db#(xxx_configure_obj) to make it strongly-typed

2. Use the factory to instantiate xxx_obj in TB_env

3. build_phase() is top-down. You are therefore attempting to get() the config object in the test before the environment (which creates it) is built. You need to either 1) new+set() from the test which will override the default one created and set in the environment or 2) get+modify in a subsequent phase.

4. No need to set() after a get() as you are modifying the object by reference.

Link to comment
Share on other sites

3. build_phase() is top-down. You are therefore attempting to get() the config object in the test before the environment (which creates it) is built. You need to either 1) new+set() from the test which will override the default one created and set in the environment or 2) get+modify in a subsequent phase.

I understand 1, 2 and 4. But not very clear about item 3, "get+modify in a subsequent phase", do you mean the modified config obj can not pass to the VIP within the build phase()? And where to get, where to modify, what's the subsequent phase(connect or end_of_elaboration_phase)? Thanks for your help

Link to comment
Share on other sites

The best way to do this is to have the VIP check if it already has a configuration object by calling get() and, if not, allocate a default one and set() it. That would allow an environment to allocate and set() the configuration in the build_phase() or not. Any modification of the configuration can be done by calling get()+assign in connect_phase() or later.

Link to comment
Share on other sites

Hi,

I just tried with the following plan, but I found that the env_obj is still null after I call uvm_config_db#::set method(I never new() the test_obj in TB env level as I think the set method can pass the obj down which is new in Test case level), please help me to point out where is wrong, thanks

==============================

1. Define the test_obj class:

class test_obj extends uvm_object;

rand bit test;

`uvm_object_utils(test_obj)

function new(string name="test_obj");

super.new(name);

test = 0;

endfunction

endclass : test_obj

2. in TB env level:

class tb_axi_ovc_self_loop extends uvm_component;

test_obj env_obj; // the object that I want to override

`uvm_component_utils_begin(tb_axi_ovc_self_loop)

`uvm_field_object (env_obj, UVM_ALL_ON)

`uvm_component_utils_end

function void build_phase(uvm_phase phase);

super.build_phase(phase);

endfunction : build_phase

endclass

3.in Test Case level

class test_axi_ovc extends uvm_test;

tb_axi_ovc_self_loop tb_axi_ovc_self_loop_inst;

string seq_name_s;

test_obj tc_obj;

`uvm_component_utils(test_axi_ovc)

function new(string name="test_axi_ovc", uvm_component parent);

super.new(name, parent);

tc_obj = new("test_object");

endfunction: new

function void build_phase(uvm_phase phase);

super.build_phase(phase);

uvm_config_db#(test_obj)::set(this, "tb_axi_ovc_self_loop_inst","env_obj", tc_obj); //try to set the env_obj in TB level

tb_axi_ovc_self_loop_inst = tb_axi_ovc_self_loop::type_id::create("tb_axi_ovc_self_loop_inst", this);

endfunction : build_phase

function void connect_phase(uvm_phase phase);

super.connect_phase(phase);

//get the test object

void'(uvm_config_db#(test_obj)::get(this, "tb_axi_ovc_self_loop_inst","env_obj", tc_obj));

//modify the object if needed

tc_obj.test = 1;

endfunction : connect_phase

task run_phase(uvm_phase phase);

phase.phase_done.set_drain_time(this,100);

factory.print();

uvm_top.print(); //from here, I found that the env_obj in TB env level is still null, please correct me, thanks.

endtask: run_phase

endclass : test_axi_ovc

BR

MIKE

Link to comment
Share on other sites

That's because you are using the uvm_config_db#(test_obj)::set() method and the `uvm_field_object automation uses uvm_config_db#(uvm_object)::get(). The types don't match.

Instead of relying on the field automation macro, you should use this approach in your component (syntax is approximate):

class tb_axi_ovc_self_loop extends uvm_component;

test_obj env_obj; // the object that I want to override

`uvm_component_utils(tb_axi_ovc_self_loop)

function void build_phase(uvm_phase phase);
  super.build_phase(phase);
  if (!uvm_config_db#(test_obj).get(this, "", "env_obj", env_obj)) begin
     env_obj = new();
     uvm_config_db#(test_obj).set(this, "", env_obj", env_obj);
  end
endfunction : build_phase

endclass

Link to comment
Share on other sites

Hi, I have another question, if I created many config objects in TB env level, and in one test case, I want to change only one field of all these config objects, is there some way to avoid changing this field one by one in connect_phase? Here is example:

1. in test env level:

class tb_axi_ovc_self_loop extends uvm_component;

test_obj env_obj; // the object that I want to override

test_obj env_obj1; // the object that I want to override

test_obj env_obj2; // the object that I want to override

test_obj env_obj3; // the object that I want to override

test_obj env_obj4; // the object that I want to override

`uvm_component_utils_begin(tb_axi_ovc_self_loop)

`uvm_field_object (env_obj, UVM_ALL_ON)

`uvm_field_object (env_obj1, UVM_ALL_ON)

`uvm_field_object (env_obj2, UVM_ALL_ON)

`uvm_field_object (env_obj3, UVM_ALL_ON)

`uvm_field_object (env_obj4, UVM_ALL_ON)

`uvm_component_utils_end

function void build_phase(uvm_phase phase);

super.build_phase(phase);

endfunction : build_phase

endclass

2. in Test Case level:

class test_axi_ovc extends uvm_test;

tb_axi_ovc_self_loop tb_axi_ovc_self_loop_inst;

test_obj tc_obj;

`uvm_component_utils(test_axi_ovc)

function new(string name="test_axi_ovc", uvm_component parent);

super.new(name, parent);

endfunction: new

function void build_phase(uvm_phase phase);

super.build_phase(phase);

uvm_config_db#(test_obj)::set(this, "tb_axi_ovc_self_loop_inst","env_obj", tc_obj); //try to set the env_obj in TB level

tb_axi_ovc_self_loop_inst = tb_axi_ovc_self_loop::type_id::create("tb_axi_ovc_ self_loop_inst", this);

endfunction : build_phase

function void connect_phase(uvm_phase phase);

super.connect_phase(phase);

//get the test object

void'(uvm_config_db#(test_obj)::get(this, "tb_axi_ovc_self_loop_inst","env_obj", tc_obj));

//modify the object if needed

tc_obj.test = 1;

//get the test object

void'(uvm_config_db#(test_obj)::get(this, "tb_axi_ovc_self_loop_inst","env_obj1", tc_obj));

//modify the object if needed

tc_obj.test = 1; //Is there some efficient way to modify such field value in config object?

......

endfunction : connect_phase

endclass : test_axi_ovc

Link to comment
Share on other sites

UVM is built on top of SystemVerilog. You are still dependent on SV's programming model. In this case, changing a value in multiple instances of an object requires multiple assignments.

If the same configuration is to be used for multiple instances, you could allocate only one configuration object then apply it to multiple instances using a match pattern. Any change to that one configuration object would apply to all component instances. But that is unlikely to be the case.

You could make that one data member static which would make it shared by all instances of the configuration object, but that make it impossible to have different components configured differently for that one parameters. That too is unlikely to work.

You could keep your configuration objects in an array to easily access/iterate over them. The config DB need not be the only place where these configuration objects are references/stored.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...