Jump to content

m_sequencer -vs- p_sequencer


Recommended Posts

I have read in some of the threads that m_sequencer is for internal use and should not be placed in user code while p_sequencer should be used, yet I have had better luck with m_sequencer in a virtual sequence base.

In fact, the UVM 1.1 Class Reference Manaual lists 10 different m_variables in the index (m_sequencer is not one of them) while there are no p_variables listed.

Consider this example:

class vseq_base extends ovm_sequence;

`ovm_object_utils(vseq_base)

function new(string name="vseq_base");

super.new(name);

endfunction

// Declare a virtual sequencer handle and

// Declare handles of the AHB and ethernet sequencer types

vsequencer v_sqr;

tb_ahb_sequencer ahb_sqr;

tb_eth_sequencer eth_sqr;

virtual task body();

// if(!$cast( v_sqr, p_sequencer))

// ERROR - Failed to find 'p_sequencer' in hierarchical name p_sequencer.

if(!$cast( v_sqr, m_sequencer))

`ovm_fatal("vseq_base","BAD v_sqr type");;

ahb_sqr = v_sqr.ahb_sqr;

eth_sqr = v_sqr.eth_sqr;

endtask

endclass

My notes on this example -

vseq_base.sv

Technically not required, but a virtual sequence base significantly simplifies the task of creating multiple virtual sequences - in the absence of a vseq_base, all of the virtual sequences would have to perform the following steps:

(1) Uses the UVM built-in m_sequencer handle. m_sequencer is a pre-defined handle inside of every sequence and is a handle to the sequencer that is running this sequence. The sequence references this handle to call the sequencer that is running this sequence. "this" is a handle to this sequence while "m_sequencer" is a handle to the sequencer that is running this sequence.

(2) Declares a handle to the virtual sequencer, v_sqr, but does not have the actual handle to the virtual sequencer.

(3) Uses casting to cast the m_sequencer handle (described in step (1)) to the v_sqr handle - now vseq_base has a copy of the actual handle to the virtual sequencer.

(4) Also declares sequencer handles (tb_ahb_sequencer & tb_eth_sequencer) that will be controlled by the virtual sequencer.

(5) Passes copies of the real sequencer handles from the virtual sequencer to the handles declared in step (4).

When I tried doing the same thing with p_sequencer, I saw the error:

ERROR - Failed to find 'p_sequencer' in hierarchical name p_sequencer.

m_sequencer seems to be a very convenient way to reference "the sequencer that is running this sequence."

Am I missing something?

Regards - Cliff Cummings

Verilog & SystemVerilog Guru

Sunburst Design

Link to comment
Share on other sites

If we're talking OVM here, then using the `ovm_sequence_utils instead of `ovm_object_utils will give you the p_sequencer handle to the sequencer it's running on.

If it's UVM you're interested in, then use the `uvm_declare_p_sequencer.

In either case, each macro must be given the class name of the sequencer on which it will run. Then, the p_sequencer is the casted version of m_sequencer that corresponds to what you declared it as.

I'm not sure why they changed it from OVM to UVM, but my guess is that everybody was using `ovm_sequence_utils whether they needed the p_sequencer reference or not, and its usage added some overhead.

Also, `uvm_sequence_utils_begin is defined for UVM, but it's listed in uvm_deprecated_defines.svh, so the `uvm_declare_p_sequencer is the preferred method.

This is that macro, which concisely does what you want for you:

`define uvm_declare_p_sequencer(SEQUENCER) \
  SEQUENCER p_sequencer;\
  virtual function void m_set_p_sequencer();\
    super.m_set_p_sequencer(); \
    if( !$cast(p_sequencer, m_sequencer)) \
        `uvm_fatal("DCLPSQ", \
        $sformatf("%m %s Error casting p_sequencer, please verify that this sequence/sequence item is intended to execute on this type of sequencer", get_full_name())) \
  endfunction  

I wouldn't have a problem using the m_sequencer variable in my sequence if you just need access to the component hierarchy. But it doesn't buy you much because it's just a reference to a generic uvm_sequencer.

A virtual sequencer will contain references to the sequencers throughout the environment that you have there. So, you could then do this to run my_seq on one of your sequencers:

`uvm_do_on(my_seq, p_sequencer.ahb_sqr);

I hope that answers your question.

Link to comment
Share on other sites

When I tried doing the same thing with p_sequencer, I saw the error:

ERROR - Failed to find 'p_sequencer' in hierarchical name p_sequencer.

m_sequencer seems to be a very convenient way to reference "the sequencer that is running this sequence."

Try get_sequencer(), for example:

class vseq_base extends ...

  MyVirtualSqr m_vsqr;

  task pre_body();
    super.pre_body();
    assert($cast(m_vsqr, get_sequencer()))
    else `Fatal("this sequence can only run on MyVirtualSqr")
  endtask: pre_body

The advantage is that there is no magic involved, and you can come back to your code in two weeks and still understand what it does. Avoid the uvm macro machinery as the plague :)

Erling

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...