Site icon Hardware Design and Verification

What is virtual sequencer ? when and how to use it ?

Virtual sequencer : it contains handles of the sequencer which are located in different agent

Q. Question is when do we use it ??

Why do use it

if something has to be synchronized , in general stimulus generation across different interface has to be synchronized, which is done by Virtual sequencer , virtual sequences

in practical if you have two ip on soc and you want to have stimulus control , virtual sequencer , virtual sequences helps to you achieve it

How do we use it

consider seqr1 , seqr2 are handles of sequencers ,also they belongs to two agent seq1_agent, seq2_agent, and have env as envionemnt

Lets see how to use it ??

Define Virtual sequence

///// Virtual Sequencer Class

  1. class virtual_seqr extend uvm_sequencer;
  2. `uvm_component_utils(virtual_seqr)
  3. /// Handles of different sequencer
  4. type1_seqr seqr1;
  5. type2_seqr seqr2;
  6. /// Constructor
  7. function new (string name = “virtual_seqr”, uvm_component parent);
  8. super.new(name, parent);
  9. endfunction: new
  10. endclass: virtual_seqr

Now if we go further

how virtual sequencer is instantiated in virtual sequence

for that lets define base sequence class

  1. ///// Virtual Sequence Class
  2. class virtual_base_seq extend uvm_sequence #(uvm_sequence_item) ;
  3. `uvm_component_utils(virtual_base_seq )
  4. type1_seqr seqr_b1;
  5. type2_seqr seqr_b2;
  6. // Virtual sequencer handle
  7. virtual_seqr v_seqr;
  8. /// Constructor
  9. function new (string name = “virtual_base_seq”);
  10. super.new(name);
  11. endfunction: new
  12. task body ();
  13. if (!$cast(v_seqr, m_sequencer)) begin
  14. `uvm_error(get_full_name(), “Virtual Seqr pointer cast failed”)
  15. end
  16. seqr_b1= v_seqr.seqr1;
  17. seqr_b2= v_seqr.seqr2;
  18. endtask: body
  19. endclass: virtual_base_seq

Now lets lets define virtual sequence

  1. class virtual_seq extend virtual_base_seq ;
  2. `uvm_component_utils(virtual_seq )
  3. type1_seqr seqr_b1;
  4. type2_seqr seqr_b2;
  5. // Virtual sequencer handle
  6. virtual_seqr v_seqr;
  7. /// Constructor
  8. function new (string name = “virtual_seq”);
  9. super.new(name, parent);
  10. endfunction: new
  11.  
  12. task body ();
  13. // call parent file to assign sub sequence handles
  14. super.body();
  15. type1_seq seq1;
  16. type2_seq seq2;
  17. //create seq
  18. seq1= type1_seq::type_id::create(“type1_seq “);
  19. seq2= type1_seq::type_id::create(“type1_seq “);
  20. repeat (10) begin
  21. seq1.start();
  22. seq2.start();
  23. end
  24. endtask: body
  25. endclass: virtual_base_seq

Environment will instantiate virtual sequencer , agent and make connection to virtual sequencer to agent sequencer

not going in details it’s connect phase will be like

  1. function void connect_phase (uvm_phase phase);
  2. v_seqr.seqr1 = seg1_agent.m_sequencer;
  3. v_seqr.seqr2 = seq2_agent.m_sequencer;
  4. endfunction: connect_phase

also test will instantiate virtual sequence , environment

and its run phase will be like

  1. task run_phase (uvm_phase phase);
  2. /// Create the Virtual Sequence
  3. v_seq_test = virtual_seq::type_id::create(“v_seq_test”);
  4. phase.raise_objection(this);
  5. /// Start the Virtual Sequence
  6. v_seq_test.start(env.v_seqr_env);
  7. phase.drop_objection(this);
  8. endtask: run_phase

 

Exit mobile version