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
- class virtual_seqr extend uvm_sequencer;
- `uvm_component_utils(virtual_seqr)
- /// Handles of different sequencer
- type1_seqr seqr1;
- type2_seqr seqr2;
- /// Constructor
- function new (string name = “virtual_seqr”, uvm_component parent);
- super.new(name, parent);
- endfunction: new
- endclass: virtual_seqr
Now if we go further
how virtual sequencer is instantiated in virtual sequence
for that lets define base sequence class
- ///// Virtual Sequence Class
- class virtual_base_seq extend uvm_sequence #(uvm_sequence_item) ;
- `uvm_component_utils(virtual_base_seq )
- type1_seqr seqr_b1;
- type2_seqr seqr_b2;
- // Virtual sequencer handle
- virtual_seqr v_seqr;
- /// Constructor
- function new (string name = “virtual_base_seq”);
- super.new(name);
- endfunction: new
- task body ();
- if (!$cast(v_seqr, m_sequencer)) begin
- `uvm_error(get_full_name(), “Virtual Seqr pointer cast failed”)
- end
- seqr_b1= v_seqr.seqr1;
- seqr_b2= v_seqr.seqr2;
- endtask: body
- endclass: virtual_base_seq
Now lets lets define virtual sequence
- class virtual_seq extend virtual_base_seq ;
- `uvm_component_utils(virtual_seq )
- type1_seqr seqr_b1;
- type2_seqr seqr_b2;
- // Virtual sequencer handle
- virtual_seqr v_seqr;
- /// Constructor
- function new (string name = “virtual_seq”);
- super.new(name, parent);
- endfunction: new
- task body ();
- // call parent file to assign sub sequence handles
- super.body();
- type1_seq seq1;
- type2_seq seq2;
- //create seq
- seq1= type1_seq::type_id::create(“type1_seq “);
- seq2= type1_seq::type_id::create(“type1_seq “);
- repeat (10) begin
- seq1.start();
- seq2.start();
- end
- endtask: body
- 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
- function void connect_phase (uvm_phase phase);
- v_seqr.seqr1 = seg1_agent.m_sequencer;
- v_seqr.seqr2 = seq2_agent.m_sequencer;
- endfunction: connect_phase
also test will instantiate virtual sequence , environment
and its run phase will be like
- task run_phase (uvm_phase phase);
- /// Create the Virtual Sequence
- v_seq_test = virtual_seq::type_id::create(“v_seq_test”);
- phase.raise_objection(this);
- /// Start the Virtual Sequence
- v_seq_test.start(env.v_seqr_env);
- phase.drop_objection(this);
- endtask: run_phase