Tuesday, 27 June 2017

Do we need p_sequencer?

You need p_sequencer only if you want to access the property of user defined sequencer.

Let us understand this with example.
User defined sequencer:
--------------------------------------------------------------------------
class user_seqr extends uvm_sequencer;
  int agent_id = 1;
 
endclass: user_seqr
-------------------------------------------------------------------------

Trying to access the property of user_seqr using m_sequencer:
--------------------------------------------------------------------------
class user_seq extends uvm_sequence

  $display(“Agent ID: %0d”, m_sequnencer.agent_id);

endcalss: user_seq
--------------------------------------------------------------------------
Output:
Error-[MFNF] Member not found
my_seq.sv, 20
"this.m_sequencer."
  Could not find member 'agent_id' in class 'uvm_sequencer_base'


Trying same with p_sequencer:
--------------------------------------------------------------------------
class user_seq extends uvm_sequence

`uvm_declare_p_sequencer(user_seqr)

  $display(“Agent ID: %0d”, p_sequnencer.agent_id);

endcalss: user_seq
--------------------------------------------------------------------------
Output:
Agent ID: 1

Why this difference?


So this difference can be explained with OOP example:
--------------------------------------------------------------------------
class parent;
endclass: parent
class child extends parent;

  virtual function info();
   $display("Child::info");
  endfunction: info

endclass: child

module tb_top();
  parent p;
  child  c1;
  child  c2;

  initial
  begin
    c1 = new();
    p = c1;
    p.info();
  end
endmodule: top
--------------------------------------------------------------------------
Output:
Error-[MFNF] Member not found
tb_top.sv, 39
"p."
  Could not find member 'info' in class 'parent'


[We can access the property of child class if parent class handle is pointing to child class,ut only condition is that property definition must be there inside parent class.]

Same case is here for m_sequencer and p_sequencer, where m_seuqencer is handle of uvm_sequencer_base class and p_sequecner is handle of user_sequencer.

So when we call,

  `uvm_declare_p_sequecner(user_seqeucner)

UVM takes the handle of user_sequencer called p_sequencer and do the casting of m_sequencer into p_sequencer.

Same way we can do in our polymorphism example, we will just modify our tb_top file
--------------------------------------------------------------------------

module tb_top();
  parent p;
  child  c1;
  child  c2;

 
initial
  begin
    c1 = new();
    p = c1;
    $cast(c2, p);
    c2.info();

  end
endmodule: top

--------------------------------------------------------------------------
Output:
Child::info


So difference between m_sequencer and p_sequencer is the difference between p and c2 in our example.

If we map our example p_sequencer and m_sequencer:
parent is uvm_sequencer_base and its handle p is m_sequencer.
child is user_sequencer and its handle c2 is p_sequencer.

No comments:

Post a Comment