Search the Community
Showing results for tags 'uvm_config_db'.
-
c4brian and I have messaged a bunch about ways to share data and access between elements in SV/UVM code. I put common functions/tasks/constants into a package, which I think is standard. I realize that absolute dot notation of accessing elements (i.e. variable12 = smthgA.smthgB.smthgC.variableXYZ;) is frowned upon as it is not good for reuse. So, the UVM presents the uvm_config_db to facilitate reuse and simplify connectivity across a hierarchy.**1 Many folks have (including c4brian, I believe) commented that they don't like how verbose it is to ::get from the config db and to check the return result. if (! uvm_config_db#(integer)::get(this,"hiccup","xyz_important_var", important_var) ) begin `uvm_fatal("ERROR,"important_var not found in config_db") end In a recent testbench, I've done the following. I probably need to review how the config component is supposed to be used. I am curious what others think. My setup: 1) Create an object to store common variables and handles. //This should be a singleton and serve as a central point for others to access global connections. Likely not a good style. Discuss. class xyz_config extends uvm_component; `uvm_component_utils(xyz_config) static xyz_env m_env; static id_state m_id_state; static delay_ctl m_delayctl; function new(string name="xyz_config", uvm_component parent=null); super.new(name, parent); endfunction set_env_handle(input xyz_env handle); m_env=handle; endfunction : set_env_handle ... 2) When something is created that other code might want to access, I set a handle to it in xyz_config. ex1: In the test class constructor (which is declared inside top), create the env and set a handle to it in the xyz_config. (Probably these actions should be done in the build_phase rather than the constructor.) class test_base extends uvm_test; `uvm_component_utils(test_base) xyz_env env; function new(string name = "test_base", uvm_component parent = null); super.new(name, parent); env = xyz_env::type_id::create("env",this); xyz_config::set_env_handle(env); ex2: In the env build_phase, I set handles to some objects which track data which is useful in many sequences and other code function void xyz_env::build_phase(uvm_phase phase); super.build_phase(phase); ... // Create Helper Structures m_id_state = id_state::type_id::create("m_id_state",this); xyz_config::set_id_state_handle(m_id_state); m_delayctl = delay_ctl::type_id::create("m_delayctl",this); xyz_config::set_delayctl_handle(m_delayctl); 3) Now, in various parts of the tb (such as from sequences), I can access xyz_config as a singleton, and access its handles (using . "dot" notation) to whatever data structures it was given access to. (I'm thinking now that those data structures should be in the scoreboard.) The dot notation is much more concise than declaring a variable and then performing a uvm_config_db ::get and checking the return value. //in seq, id_state which tracks system-state used to set transaction variable jhg_input_trans.state = xyz_config::m_id_state.get_jhg_state(.loopback(loopback), .fce_1(fce_1)); or //in virtual seq, a call is made that turns off any internal stallers (special stallers to alter congestion in the dut) xyz_config::m_env.turn_off_internal_stallers(); or //in scoreboard, as monitors send in transactions, it adjusts state info which is used by sequences to make legal input xyz_config::m_id_state.move_some_id(.note("fuf->xyz"), .syd(t.fuf_xyz_read_syd), .from_q(Q001), .to_q(Q111)); A benefit of this is that the user can more easily (from this line of code), see what is being accessed, rather than needing to rerun a test and dump config_db or grep thru a bunch of files to see who did the ::set. With regards to reuse, it seems to me that as long as the new tb (that wants to benefit from reuse), sets the handles in the _config properly, it is just as reuse-able. Probably, I am missing something. I've have a vague notion and have heard soft feedback that this style (which I feel is unique to me) is not good. Maybe I'm imagining this or exaggerating it in my mind. I bring it up here, in the event anyone has feedback or a good scolding to give. **1 Conceptually I've been taught to think of uvm_config_db as a "string"-accessible associative array, or a group of associative arrays; something like 'one for each datatype'. I'm not poking into the uvm base class here, but just voicing my understanding out-loud for comments. Conceptually, I think of uvm_config_db as operating as follows. A user specifies the data type that they want to store or get - which 'conceptually' selects which associative array to access. A user specifies a "string-name" which is the key into that associate array. A user reads or writes that associative array as follows. To write, they use ::set, specify a "string-name", and provide a value. To read, they use ::get, specify a "string-name", and provide a variable, into which the value stored at "string-name" will be copied. (Note: I've modified the code examples to shorten them, so may have introduced typos.)
- 3 replies
-
- uvm_config_db
- hierarchical access
-
(and 5 more)
Tagged with:
-
Hi All, It seems that there is a problem for automatically updating components fields registered with uvm_field_* macros. It works fine if the field is of type int, but it fails if the field is of type enum. Do I miss something? (I tested this code with both UVM 1.1-d and UVM 1.2) class hs_driver extends uvm_driver #(hs_packet); hs_type_t driver_type; int my_param = 10; `uvm_component_utils_begin (hs_driver) `uvm_field_enum (hs_type_t, driver_type, UVM_ALL_ON) `uvm_field_int (my_param, UVM_ALL_ON) `uvm_component_utils_end [...] endclass: hs_driver class test_bench extends uvm_component; `uvm_component_utils (test_bench) hs_driver host; hs_driver device; [...] virtual function void build_phase(uvm_phase phase); super.build_phase(phase); uvm_config_db#(hs_type_t)::set (null, "*.device", "driver_type", DEVICE); uvm_config_db#(int)::set (null, "*.host", "my_param", 888); host = hs_driver::type_id::create ("host", this); device = hs_driver::type_id::create ("device", this); endfunction: build_phase endclass: test_bench Printing test topology: ------------------------------------------------------------- Name Type Size Value ------------------------------------------------------------- uvm_test_top simple_test - @1863 mtb test_bench - @1939 device hs_driver - @2089 rsp_port uvm_analysis_port - @2162 recording_detail integral 32 'd1 seq_item_port uvm_seq_item_pull_port - @2130 recording_detail integral 32 'd1 driver_type hs_type_t 32 HOST -> should have been DEVICE! my_param integral 32 'ha recording_detail integral 32 'd1 host hs_driver - @2024 rsp_port uvm_analysis_port - @2095 recording_detail integral 32 'd1 seq_item_port uvm_seq_item_pull_port - @2058 recording_detail integral 32 'd1 driver_type hs_type_t 32 HOST my_param integral 32 'h378 -> In this case (for an integer) the field has been updated followin uvm_config_db recording_detail integral 32 'd1 recording_detail integral 32 'd1
- 2 replies
-
- uvm_config_db
- int
-
(and 1 more)
Tagged with:
-
Hi, all - When using uvm_config_db#(...)::set(...) from a top-module, is there any difference between using set-context=null and inst_name "*" and using set-context=uvm_root::get(), and inst_name "*"? top-module examples: uvm_config_db#(virtual dut_if)::set(null, "*", "vif", dif); uvm_config_db#(virtual dut_if)::set(uvm_root::get(),, "*", "vif", dif); Of course, per the UVM Class Reference, setting a context to null means that the inst_name provides the complete scope and "*" means any scope. Setting the context to uvm_top (returned by uvm_root::get()) and indicating "*" any scope in uvm_top seems to do the same thing. It seems that both are making the dut_if handle globally accessible. Comments? Regards - Cliff Cummings
-
Hi, I have a question when I use uvm_config_db for interface connection. Generally, I know we use set() and get() function of "uvm_config_db" when we connect interface instance with virtual interface. As I know, uvm_config_db#(virtual aaa_intf)::set() is described inside top testbench module. And uvm_config_db#(virtual aaa_intf)::get() is some phase of inside class. What I want to do is to move set() function into some phase of class. Is it possible? If possible, which phase can I use not to be no problem in topology? Could you give me an example? I generally descirbes uvm_config_db#(virtual aaa_intf)::get() in connect_phase. Thanks & Regards, YYN
- 1 reply
-
- interface
- uvm_config_db
-
(and 1 more)
Tagged with:
-
In the env, there is such uvm_config_db::set(): for (int i = 0; i < host_num; i++) begin inst_name = $sformatf("*.v_seq.slv_seq[%0d]", i); uvm_config_db#(uvm_event)::set(uvm_root::get(), inst_name, "evt", env.subenv[i].slv_agt.slv_mon.evt); end in the slv_seq, there is such uvm_config_db::get(): if(!uvm_config_db#(uvm_event)::get(null, this.get_full_name(), "evt", evt)) `uvm_fatal("NOEVT",{"evt must be set for: ",get_full_name(),".evt"}); When I use +UVM_CONFIG_DB_TRACE, I found such message: UVM_INFO /EDA_Tools/synopsys/vcs1209/etc/uvm-1.1/uvm-1.1d/src/base/uvm_resource_db.svh(121) @ 2580000: reporter [CFGDB/GET] Configuration 'uvm_test_top.env.v_sqr.v_seq.slv_seq[k]evt' (type class uvm_pkg::uvm_event) read by = null (failed lookup) If I uvm_config_db::set() in slv_mon like this: uvm_config_db#(uvm_event)::set(uvm_root::get(), "*", "evt",evt); there isn't such message, I think it configures successfully. there are multiple slv_mon and slv_seq instances, when there is only one valid slv_mon and slv_seq, the evt cann't pass successfully when it triggered. So I want to config evt of slv_mon to slv_seq using the bijective way. It isn't success at the moment, can anybody tell me the graceful way? Thanks in advance mrforever
-
When agents are configured, I typically see something like this: uvm_config_db#(int)::set(this,"testbenchA.masterA_hostB.agentpink","is_active",UVM_ACTIVE); Isn't UVM_ACTIVE of type bit? I see it 'described' here in an enum and given a default value. src/base/uvm_object_globals.svh: typedef enum bit { UVM_PASSIVE=0, UVM_ACTIVE=1 } uvm_active_passive_enum; So shouldn't the uvm_config_db line not be: uvm_config_db#(int)::set(this,"testbenchA.masterA_hostB.agentpink","is_active",UVM_ACTIVE); but instead be: uvm_config_db#(bit)::set(this,"testbenchA.masterA_hostB.agentpink","is_active",UVM_ACTIVE); ? thx, (I sense that I probably don't have a solid enough understanding of enum and the relationship between bits and ints.)
- 3 replies
-
- uvm_config_db
- UVM_ACTIVE
-
(and 6 more)
Tagged with:
-
Hi all, Usually we use uvm_config_db::set from the higher hierarchy module and uvm_config_db::get in the lower hierarchy module, Can we use uvm_config_db::set and uvm_config_db::get from the opposite direction? Regards mrforever
-
Hi, all, I met one problem when i configure sub-sequencers of virtual sequencer using uvm_config_db. Here are the codes and VCS reports: -------codes------- class my_subenv extends uvm_env; ... function void build_phase(uvm_phase phase); ... v_sqr = vsequencer::type_id::create($sformatf("v_sqr%0d", subenv_ID), this); // configuration, set default_sequence as the virtual sequencer uvm_config_db#(uvm_object_wrapper)::set(this, "v_sqr.run_phase", "default_sequence", vsequence::type_id::get()); ... endfunction : build_phase function void connect_phase(uvm_phase phase); ... uvm_config_db#(uvm_sequencer)::set(this, "v_sqr", "cfg_sqr", this.cfg_agt.cfg_sqr); uvm_config_db#(uvm_sequencer)::set(this, "v_sqr", "str_sqr", this.str_agt.str_sqr); ... endfunction : connect_phase ... endclass : my_subenv -------VCS reports-------- Error-[iCTTFC] Incompatible complex type usage ../sv/00_top/my_subenv.sv, 101 Incompatible complex type usage in task or function call. The following expression is incompatible with the formal parameter of the function. The type of the actual is 'class my_pkg::my_config_sequencer', while the type of the formal is 'class uvm_pkg::uvm_sequencer#(class uvm_pkg::uvm_sequence_item,class uvm_pkg::uvm_sequence_item)'. Expression: this.cfg_agt.cfg_sqr Source info: vcs_paramclassrepository::__vcs_dummy_uvm_pkg_uvm_config_db_3133241903_.set(this, "v_sqr", "cfg_sqr", this.cfg_agt.cfg_sqr) Error-[iCTTFC] Incompatible complex type usage ../sv/00_top/my_subenv.sv, 102 Incompatible complex type usage in task or function call. The following expression is incompatible with the formal parameter of the function. The type of the actual is 'class my_pkg::my_str_sequencer', while the type of the formal is 'class uvm_pkg::uvm_sequencer#(class uvm_pkg::uvm_sequence_item,class uvm_pkg::uvm_sequence_item)'. Expression: this.str_agt.str_sqr Source info: vcs_paramclassrepository::__vcs_dummy_uvm_pkg_uvm_config_db_3133241903_.set(this, "v_sqr", "str_sqr", this.str_agt.str_sqr) By the way, my_config_sequencer and my_str_sequencer are classes derived from uvm_sequencer, so I think the complex type should be compatible. And the codes are wriiten according chapter 4.8 of the uvm_users_guide_1.1.pdf document. Should there be some phrases like uvm_config_db#(uvm_sequencer)::get() in my_subenv or other places? Thanks regards mrforever
- 2 replies
-
- sub-sequencer
- virtual sequencer
-
(and 1 more)
Tagged with: