Uvm_config_db get method is failing when null is passed to seq.start() method

I’m studying RAL and I experienced this situation wherein the uvm_config_db get method is failing when I use null handle for the sequencer in the seq.start() method.

The uvm_config_db get method is in the body() task of my base_sequence class:


// From base_sequence class
virtual task body();
  if(!uvm_config_db#(testbench_env_config)::get(null, get_full_name(), "cfg", cfg)) begin
    `uvm_fatal("CFG_GET_FAILED", "Failed to get cfg from configuration database")
  end

  this.tb_reg_block = cfg.tb_reg_block;
endtask : body

In my test class, when I used env.agt.sqr for the seq.start() method, I’m not having any issues and the simulation is working fine. But when I used null, the uvm_config_db get method on the base sequence class is failing:


// In test class
virtual task run_phase(uvm_phase phase);
  super.run_phase(phase);

  phase.raise_objection(this);

  reg_type_b_seq = register_type_b_1_sequence::type_id::create("reg_type_b_seq");

  //reg_type_b_seq.start(env.mst_agt.sqr); // If this is used, there is no issue
  reg_type_b_seq.start(null); // If null is used, uvm_config_db get method is failing

  phase.drop_objection(this);
endtask : run_phase

This is the code of my sequence extended from base_sequence:


// In sequence class extended from base_sequence
virtual task body();
  super.body(); // This is will call uvm_config_db get method from the base_sequence class

  // The methods below use RAL methods like reg.write(), reg.peek(), etc.
  this.init_regs(); // Initialize the registers with a random value
  this.do_backdoor_read(); // Do backdoor read access to check initial random values
  this.do_frontdoor_wr_backdoor_rd(); // Do frontdoor write then backdoor read
endtask : body

What is the reason why the uvm_config_db get method is failing when I use null instead of env.agt.sqr?
I would like to use null because I’m using the register model to pass transaction to the agent. Take note that I don’t have start_item() and finish_item() in my sequence body() task, that’s why I think it’s okay to pass null for the seq.start() method.

In reply to Reuben:

Hi,

You might be aware of the fact that get_full_name() on sequence returns hierarchy through sequencer the sequence is started on.


uvm_config_db#(testbench_env_config)::get(null, get_full_name(), "cfg", cfg)
$display("Sequence hierarchy: %s", get_full_name());

Here display statement returns something like this - “test_h.env_h.agent_h.seqr_h.sequence_h”.

Problem can be in setting of configuration where you are using visibility of the config to env_h/agent_h only.

Try using above display when using “null” sequencer on sequence and see the sequence path. Set visibility in

uvm_config_db#(testbench_env_config)::set(<> , "visibility", "cfg", cfg)

accordingly.

In reply to mayurkubavat:

Hi Mayur,

Actually, I used “*” as the visibility for the set method. This is what I did in the build_phase() of my base_test:


uvm_config_db#(testbench_env_config)::set(this, "*", "cfg", cfg);

From my understanding, the visibility of “cfg” is “test_h.*”, which means it is visible everywhere. (Correct me if I’m wrong).

Another thing is, if the problem is in the visibility, then even if I use env.agt.sqr instead of null, uvm_fatal should have flagged too… But it didn’t. Therefore, my guess is there might be some connection with the use of a null sequencer and it somehow alters the set visibility… I’m guessing this could be a bug in the UVM itself. I don’t know.

In reply to Reuben:

Ok.

Can you also see (and post it here as well)output of

$display("Sequence hierarchy: %s", get_full_name());

in your sequence while using ‘null’ in place of sequencer.

Another thought is, setting configuration in test with

uvm_config_db#(testbench_env_config)::set(this, "*", "cfg", cfg);

makes configuration visible from test to downward hierarchy. But, the sequence is part of uvm_top/uvm_root where config visibility is not there. e.g. uvm_top.sequence_h

In reply to mayurkubavat:

Hi Mayur,

It looks like using a null sequencer alters the hierarchy of the sequence.
If I use reg_type_b_seq.start(env.agt.sqr), the result is:


Sequence hierarchy: uvm_test_top.env.agt.sqr.reg_type_b_seq

If I use reg_type_b_seq.start(null), the result is:


Sequence hierarchy: reg_type_b_seq

Notice that it removes all the higher hierarchies.

In reply to Reuben:

Reuben,

Sequences and uvm_object’s are not part of any hierarchy by default like component. When we pass sequencer to sequence it uses sequencer hierarchy. If you want to pass null as sequencer, you can pass an extra argument while instantiating sequence to put it under desired hierarchy. for ex :

seq_i = seq::type_id::create("seq_i", ,"uvm_test_top");

The third argument to create will put it under uvm_test_top hierarchy.

Thanks,
Rohit

In reply to Reuben:

That’s an interesting thing!

In this case reg_type_b_seq becomes part of uvm_root(e.g. top.reg_type_b_seq). I think setting configuration with respect to uvm_root might work here,

uvm_config_db#(testbench_env_config)::set(uvm_root::get(), "*","cfg", cfg);

In reply to mayurkubavat:

Hi Mayur,

I tried that and it works… I also tried this one below and it also works.


uvm_config_db#(testbench_env_config)::set(null, "*","cfg", cfg);

However, I’m not sure if this style is ok. It is visible everywhere even at hierarchies higher than uvm_test_top.