Configuration of sequences started from a virtual sequence

In my testbench, all the agent sequences are started from a virtual sequence. Therefore if I use this code from the cookbook example:

scope_name = get_full_name(); // this is { sequencer.get_full_name() , get_name() }

Instead of getting “env.agent.sequencer.sequence_name”, I get “vseq.sequence_name” (where “vseq” is the virtual sequence).

Am I doing something wrong here? What would be the preferred way to set configuration for a sequence running on a specific agent for this case? The best solution I have thought of is to pass the m_sequencer to the uvm_config_db#()::get call instead of using get_full_name, but then I can’t set a different config for different sequences.

In reply to miketrim:

You are executing the get_full_name() on a sequence. And this Returns you as scope a sequence path.
But I do not understand why you are using this complicated construct.
I’m using in the virtual sequence references to the Agent sequencers like this:

//-----------------------------------------------------------------------------
class example_top_base_seq extends uvm_sequence #(uvm_sequence_item);
//-----------------------------------------------------------------------------

  `uvm_object_utils(example_top_base_seq)

  example_top_config  cfg;
  apb_sequencer	apb_sequencer_i;
  spi_sequencer	spi_sequencer_i;

  extern function new(string name = "example_top_base_seq");

  extern task body();
  //---------------------------------------------------------------------------
  // constraints
  //---------------------------------------------------------------------------

endclass : example_top_base_seq

This is in the base class. In the actual sequence I have the references of the corresponding sequences like this:

//=============================================================================
class example_top_default_seq extends example_top_base_seq;


  `uvm_object_utils(example_top_default_seq)

  // UVC sequences
  apb_default_seq	apb_seq;
  spi_default_seq	spi_seq;

  extern function new(string name = "example_top_default_seq");
  extern task body();

endclass : example_top_default_seq


I’m using this construct because that is what the UVM cookbook recommends: Config/ConfiguringSequences

My sequences are constructed in the same way as your examples. But that doesn’t explain how one should retrieve associated values from the config db.

In reply to miketrim:
Doing this you have to use the p_sequencer concept, because the sequence has no Position in the testbench hierarchy. This Looks like this:

class my_seq extends uvm_sequence #(instruction);
  `uvm_object_utils(my_seq)
  `uvm_declare_p_sequencer(my_sequencer)
  instruction minst;
  ....
  task pre_start;
    uvm_config_db #(my_config)::get( p_sequencer, "",
                                     "config", config);
  endtask

  task body;
    ...
    minst.randomize() with { max_data == config.max; };
  endtask
    ....
endclass

In reply to chr_sue:

Don’t use p_sequencer because that method requires you to define a sequencer and also makes the sequence dependent on a specific type of sequencer, limiting portability.

Use m_sequencer instead:

class my_seq extends uvm_sequence #(instruction);
  `uvm_object_utils(my_seq)

  instruction minst;
  ....
  task pre_start;
    uvm_config_db #(my_config)::get( m_sequencer, "",
                                     "config", config);
  endtask
 
  task body;
    ...
    minst.randomize() with { max_data == config.max; };
  endtask
    ....
endclass

I faced exactly the same issue as this post.
In addition to the way cgales suggested, I confirmed the following also works.

uvm_config_db #(my_config)::get( m_sequencer, get_name(), "config", config);

Then, you can set different config for different sequences based on their name.

I found a cookbook article mentioning the way cgales suggested.
ResourceAccessForSequences
But it doesn’t say anything about the case of a virtual sequence usage. The cookbook should be updated.

By the way, should get_sequencer() be used instead of m_sequencer?

uvm_config_db #(my_config)::get( get_sequencer(), get_name(), "config", config);

In reply to Orimitsu:

In my eyes the last line in your post using

get_sequencer

instead of

m_sequencer

is the prefered one.
m_sequencer relates to p_sequencer you normally should not use.

I looked up get_full_name() in sequece. It is defined in uvm_sequence_item as follow.


  function string get_full_name();

    if(m_parent_sequence != null) 
      get_full_name = {m_parent_sequence.get_full_name(), "."};
    else if(m_sequencer!=null)
      get_full_name = {m_sequencer.get_full_name(), "."};

    if(get_name() != "") 
      get_full_name = {get_full_name, get_name()};
    else begin
      get_full_name = {get_full_name, "_item"};
    end

  endfunction

That is, adding its name to its parrent sequence’s path name. In top sequence, adding its name to its sequencer’s path name. Therefore, no sequencer’s path name is gotten if a virtual sequencer with null sequencer is used as a top sequence.
Since each sequence is agnostic to top sequence, get_full_name() should never be used in sequeces. get_sequencer() and get_name() should be used instead. The cookbook should be modified.

I found another function, get_sequence_path(). This function returns the path name of a sequence from top sequence. This is better than get_name(). So, the description should be like the following.


uvm_config_db #(my_config)::get( get_sequencer(), get_sequence_path(), "config", config);

This is a definitive way. Sequence configuration of the cookbook should be rewritten in this way.