Can we set a config db in sequence body() method and get it in scoreboard?

Can we set a config db in sequence body() method and get it in scoreboard?
I know that we have to set config db in build phase. But is it possible?

In reply to Subhra Bera:

You can, you just need to make sure that the set() comes before the get(). You don’t want to be doing a lot of communication this way; string based look-ups are expensive.

A better mechanism might be the uvm_event_pool, which could be a member of a shared configuration object.

In reply to dave_59:

Could you please give an example? I have tried in this way,

class mem_sequence extends uvm_sequence#(mem_seq_item);
   
  `uvm_object_utils(mem_sequence)
    
  //Constructor
  function new(string name = "mem_sequence");
    super.new(name);
  endfunction
   
  virtual task body();
 
 req = mem_seq_item::type_id::create("req"); //create the req (seq item)
 uvm_config_db#(mem_seq_item)::set(null,"uvm_test_top.*","user_config",this.req);  //set method                                                   
    wait_for_grant();                            //wait for grant
    assert(req.randomize());                     //randomize the req                   
    send_request(req);                           //send req to driver
    wait_for_item_done();                        //wait for item done from driver
    get_response(rsp);                           //get response from driver
 
  endtask
endclass

And in scoreboard tried to get like this:


task run_phase(uvm_phase phase);
if(!(uvm_config_db#(mem_seq_item)::get(this,"","user_config",req1) )
 `uvm_fatal(get_full_name(),{"Did not get the user Config"})
endtask

After you mentioned about uvm_event_pool I have looked into it did not understand how to incorporate that concept in my code. As per my understanding of uvm_event_pool we will create and event as soon as the sequence generates and in scoreboard we will for that event. As soon as we get that event our scoreboard run_phase will continue. Is this understanding correct? Correct me if I am wrong.

In reply to Subhra Bera:

The code you are using is not good. The reason that your sequence is normally started in run_phase or sub-task-phases, but you are getting the config in run_phase of scoreboard, it will not be sure that the set() method is called before the get() method. That’s why you may not be able to get the config correctly.

As @dave_59 suggested, using event pool is the good approach for your case. Here is an example:

In your sequence, you get uvm_event from uvm_event_pool for a specific key:


class mem_sequence extends uvm_sequence#(mem_seq_item);
 
  `uvm_object_utils(mem_sequence)
 
  //Constructor
  function new(string name = "mem_sequence");
    super.new(name);
  endfunction
 
  virtual task body();
    uvm_event ev = uvm_event_pool::get_global("user_config"); // key = user_config
    req = mem_seq_item::type_id::create("req"); //create the req (seq item)
    ev.trigger(this.req);                                                
    wait_for_grant();                            //wait for grant
    assert(req.randomize());                     //randomize the req                   
    send_request(req);                           //send req to driver
    wait_for_item_done();                        //wait for item done from driver
    get_response(rsp);                           //get response from driver
  endtask
endclass

And in your scoreboard, you get the object from uvm_event for the same key:


task run_phase(uvm_phase phase);
    uvm_object data;
    uvm_event ev = uvm_event_pool::get_global("user_config"); // key = user_config
    ev.wait_ptrigger_data(data);
    $cast(req1, data);
endtask

Note:
The uvm_event becomes parameterized class which take uvm_object as default type since uvm-1.2
So, if you are using uvm-1.2 or later, please use the following code instead, to avoid any compilation error in some simulators:


uvm_event#(uvm_object) ev = uvm_event_pool::get_global("user_config");

Also, the dynamic casting $cast is necessary because uvm_event_pool uses uvm_object as default data type, snd you should use wait_ptrigger_data to avoid race condition if the wait_ptrigger_data() method is executed after trigger() method.

In reply to cuonghle:

Also, if your intent is just sending the same transaction your sequence is sending to the driver, it would be easier to set up an analysis port in the driver, and write() the transaction as the driver receives it.