hugemx830202 Posted March 25, 2011 Report Share Posted March 25, 2011 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 Quote Link to comment Share on other sites More sharing options...
dave_59 Posted March 25, 2011 Report Share Posted March 25, 2011 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 Quote Link to comment Share on other sites More sharing options...
uwes Posted March 25, 2011 Report Share Posted March 25, 2011 hi, apart from the overhead you may want to generate config_class instances after the end_of_elaboration_phase for instance in a multi-test/config scenario. you cant generate uvm_components once you pass the elaboration_phase. /uwe Quote Link to comment Share on other sites More sharing options...
hugemx830202 Posted March 25, 2011 Author Report Share Posted March 25, 2011 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! Quote Link to comment Share on other sites More sharing options...
janick Posted March 25, 2011 Report Share Posted March 25, 2011 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. Quote Link to comment Share on other sites More sharing options...
hugemx830202 Posted March 25, 2011 Author Report Share Posted March 25, 2011 So do you mean in UVM1.0, we can use uvm_config_db#() to set the parameter defined in the class extended from uvm_object? But from the uvm1.0 class reference manual, seems it doesn't indicate that, could you show me? thanks a lot! Quote Link to comment Share on other sites More sharing options...
janick Posted March 25, 2011 Report Share Posted March 25, 2011 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, 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. Quote Link to comment Share on other sites More sharing options...
hugemx830202 Posted March 25, 2011 Author Report Share Posted March 25, 2011 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('=')? Quote Link to comment Share on other sites More sharing options...
janick Posted March 25, 2011 Report Share Posted March 25, 2011 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. Quote Link to comment Share on other sites More sharing options...
hugemx830202 Posted March 25, 2011 Author Report Share Posted March 25, 2011 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 Quote Link to comment Share on other sites More sharing options...
janick Posted March 25, 2011 Report Share Posted March 25, 2011 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. Quote Link to comment Share on other sites More sharing options...
uwes Posted March 25, 2011 Report Share Posted March 25, 2011 hi, there is no need to 'push' back the modified object. what you actually share is an object reference. your testcase::test_obj points after the get to the same object as the TB_env::myobj. /uwe Quote Link to comment Share on other sites More sharing options...
hugemx830202 Posted March 26, 2011 Author Report Share Posted March 26, 2011 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 Quote Link to comment Share on other sites More sharing options...
janick Posted March 26, 2011 Report Share Posted March 26, 2011 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. Quote Link to comment Share on other sites More sharing options...
hugemx830202 Posted March 28, 2011 Author Report Share Posted March 28, 2011 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 Quote Link to comment Share on other sites More sharing options...
janick Posted March 28, 2011 Report Share Posted March 28, 2011 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 Quote Link to comment Share on other sites More sharing options...
hugemx830202 Posted March 29, 2011 Author Report Share Posted March 29, 2011 Really thanks for your helps:) Quote Link to comment Share on other sites More sharing options...
hugemx830202 Posted March 29, 2011 Author Report Share Posted March 29, 2011 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 Quote Link to comment Share on other sites More sharing options...
janick Posted March 29, 2011 Report Share Posted March 29, 2011 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. Quote Link to comment Share on other sites More sharing options...
hugemx830202 Posted March 30, 2011 Author Report Share Posted March 30, 2011 thanks for your helps, seems I can use find_all() functions. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.