Grab sequencer by sequence for register model

I am making an UVM environment which is used for exclusive APB bus by register model. But now, the grab() cannot return. So the sim process was hung there.

Let me introduce my situation.



ENV:
class tb_env extends uvm_env; 
…...
    virtual function void connect_phase(uvm_phase phase);
        if (regmodel.get_parent() == null) begin
             reg2apb_adapter reg2apb = reg2apb_adapter::type_id::create("reg2apb");
             regmodel.default_map.set_sequencer(apb.sqr,reg2apb);
             regmodel.default_map.set_auto_predict(1);
        end
    endfunction
endclass

Sequence :

class seq_mul extends seq_base ;
……
  `uvm_object_utils(seq_mul)
  virtual task body();
        `uvm_info("TB/TRACE", "mul seq  run phase...", UVM_NONE);
        for ( int i = 0 ; i < 5 ; i++ ) begin
            regmodel.IntMask.write(status, 8'hb0 +i ) ;    // write some data to the apb bus.
        end
  endtask
endclass

class seq_add extends seq_base ;
……
  virtual task body();
        super.body ;
        m_sequencer = regmodel.default_map.get_sequencer() ;
        $display( "m_sequencer: %s " , m_sequencer.get_full_name() ) ;
		m_sequencer.grab(this);  // run process cannot go on.
        for ( int i = 0 ; i < 5 ; i++ ) begin
            regmodel.TxRx.write(status, 8'ha0 + i ) ;
        end
        m_sequencer.ungrab(this);
  endtask
endclass 

In the test’s run phase :

task run_phase(uvm_phase phase);
      seq_mul m_seq_mul =  seq_mul::type_id::create("m_seq_mul");
      seq_add m_seq_add =  seq_add::type_id::create("m_seq_add");
      phase.raise_objection(this, "Test Started");
        `uvm_info("TB/TRACE", "in test run phase...", UVM_NONE);
        regmodel.IntSrc.write(status, 8'hff ) ;
      fork
        m_seq_mul.start(null) ;
        m_seq_add.start(null) ;
      join
    phase.drop_objection(this, "Test Finished");
  endtask: run_phase

when I run the case, the simulation hung at m_sequencer.grab(this);
if I remove the_m_sequencer.grab(this); and m_sequencer.ungrab(this);_ . The run phase could finish correct, and we can observe the write operation in the APB bus. Is the sequencer I figured incorrect? Or the register sequence has some special features? I suspect the adapter between the apb agent and regmodel is the reason. But I have no idea how to resolve it.
Would you please help me? Any advice is appreciated.

Thank you in advance.

I would have to take a longer look at what you are doing, but the variable m_sequencer contains the handle to the sequencer that the sequence is running on. You are trying to change m_sequencer to point to a different sequencer and this might be causing issues.

In reply to cgales:

But, from his code it doesn’t look like he is not changing the m_sequencer right?.

In reply to skumar:

He is starting ‘m_seq_add’ of type ‘seq_add’ on the a null sequencer, which will create an instance of a virtual sequencer to run on. He then seems to change the m_sequencer pointer to the sequencer used by the register model within the sequence itself. It’s hard to really tell without a complete example to trace through, but one should never have a need to change m_sequencer as it is set by UVM.

Thanks a lot for every comment.
Yes, I have a “change” for the m_sequencer, because I did not specify the sequencer when I start the sequences.

m_seq_mul.start(null) ;

if I did not give the m_sequencer an assign like this

m_sequencer = regmodel.default_map.get_sequencer() ;

The various m_sequencer in the sequence will be a null. So I could not use the grab() function either.

On the other hand, if I specified the sequencer when I start the sequence like this

m_seq_mul.start(m_env.apb.sqr) ;

, the m_sequencer in the sequence will not be null, but the grab will not return either.

I have done the other two labs.
The one: I remove the grab function from the sequence seq_add; the test work correctly.
The other: I made an environment for the grab function without register model, the grab function work correctly.

Just when I use the register model in the sequence, with the adapter and the APB agent, in order to access DUT by APB BUS, the grab hang the test and have no return.
I think this is a very useful method for CPU’s interrupt verification. If you have made this process successfully, would you like to share your experience?

If I did not introduce clearly, please let me know. Thanks again for your comments .

In reply to jtian:

You are incorrect in your assumption that m_sequencer will be null if you specify null in your start statement. If you pass in a null sequencer to your start command, a generic virtual sequencer will be automatically created and assigned to m_sequencer. Therefore, you should never have a need to change m_sequencer.

cgales, thanks a lot for your comments.

As your comments, I specify null in my start, and then, in the sequence, I printed the m_sequencer’s full name by m_sequencer.get_full_name(), and got the result : uvm_test_top.m_env.apb.sqr, what is the sequencer in my APB agent. I think this is because I have set the sequencer like this: regmodel.default_map.set_sequencer(apb.sqr,reg2apb); I think this is not a virtual sequencer assigned by UVM. correct me, Thanks.

And if I specified the sequencer when I start the sequence like this
m_seq_mul.start(m_env.apb.sqr) ; , the m_sequencer in the sequence will not be null, but the grab will not return either.
if possible, Could you please help me about this?

In reply to jtian:

Hi,

What Chuck meant is, if you print m_sequencer.get_full_name before you assign m_sequencer with some value. You shouldn’t get null.

Changing the order of your statements as below should not print you null.
$display( "m_sequencer: %s " , m_sequencer.get_full_name() ) ;
m_sequencer = regmodel.default_map.get_sequencer() ;

Thanks,
Skumar

Hi, Skumar,

If I print m_sequencer.get_full_name before assign m_sequencer with some value, I really got the null. The log is below:


Error-[NOA] Null object access
sequence.sv, 76
The object is being used before it was constructed/allocated.
Please make sure that the object is newed before using it.

// note: in sequence.sv line 76, the m_sequencer appeared first time.

And if I remove various m_sequencer from sequence, the regmodel access ( write/read) is correct.

In reply to jtian:

Hi,
I am facing same issue. Can you tell if your problem is solved? How did you solve it?

In reply to jtian:

did this issue resolved ? I am having the same issue.

I am also facing same issue. Is there a solution ?

In reply to ksiddav:

Any solutions found? Facing the same situation here.

my sequence is simple.

grab(p_sequencer.path_to_sequencer_of_the_bus_agent);
p_sequencer.regmodel.path_to_reg.write(status,value);
ungrab(p_sequencer.path_to_sequencer_of_the_bus_agent);

It will hang, but if i take out the grab/ungrab it will proceed normally.

In reply to nazucena84:

Found the solution to my problem,in the uvm reg apis there is a way to give the parent sequence.
It must be supplied explicitly.

grab(p_sequencer.path_to_sequencer_of_the_bus_agent);
p_sequencer.regmodel.path_to_reg.write(.status(status),.value(value),.parent(this));
ungrab(p_sequencer.path_to_sequencer_of_the_bus_agent);