What is the purpose of UVM Virtual Sequencers

1.2k Views Asked by At

I am trying to figure out what the purpose of a UVM Virtual Sequencer is.

If you look at what verification academy says about it. It is basically a container class for other sequencers.

class sequencer extends uvm_virtual_sequencer;

`uvm_component_utils(virtual_sequencer)

 sequencer_a m_seq_a;
 sequencer_b m_seq_b;
...
...
endclass 

One just does a heretical reference to m_seq_a or m_seq_b when doing a start on their sequence.

Why isn't a virtual sequencer just a uvm_component? Is there something that a uvm_virtual_sequencer can do? One can't do a start on the virtual sequencer.

2

There are 2 best solutions below

0
On BEST ANSWER

There are 2 ways to start virtual sequences (which will in turn start different sequences on different sequencers).

  • Keep the handles of the target sequencers in the virtual sequences and then assign those handles before starting the sequence.

Like this.

vir_seq vira = vir_seq::type_id::create("virtual_sequence");

vira.sequencer_1 = .... ; // sequencer 1 hierarchical path
vira.sequencer_2 = .... ; // sequencer 2 hierarchical path

vira.start(null); // Start the virtual sequence using null
  • Keep the handles of the target sequencers in another sequencer (virtual sequencer) and start the virtual sequence on that virtual sequencer.

However the approach of Virtual Sequencer is not recommended, as it just adds another layer of hierarchy and is complicated for reuse.

Another point is that, uvm_virtual_sequencer is nothing but a uvm_sequencer only, and it can't be a uvm_component, as the virtual sequence will be started on it.

Here is the relevant code from the UVM 1.2 source code.

typedef uvm_sequencer #(uvm_sequence_item) uvm_virtual_sequencer
0
On

Typically, single driver-sequencer pair belongs to an agent. Thus, after sequence and sequencer got created, the agent.run_phase() will start to sending sequence_item when seq.start(sequencer) got executed. Let’s assume we have two agents, each has its own sequencer and driver pair. In that case, there is no easy way to orchestrate two sequences, such as start one sequence after finishing the other. I believe this is fundamental reason to use virtual sequence (or virtual sequencer). One approach is to use virtual sequence which has handles for the sequencers and runs (or fork) seq.start() in one place (body of virtual sequence), achieving timing control between multiple sequences.

The following site has a nice picture you can visualize. http://www.learnuvmverification.com/index.php/2016/02/23/how-virtual-sequence-works-part-1/#comment-38603

By the way, I believe that if you do not want to control timing between two sequences, you don't have to use virtual sequence. You can just place each sequencer-driver in separate agents and let them run in parallel. However, if you want more control of timings between two sequences down the road, you have to modify testbench. But you really don't want to modify testbench every time the need arises. Once you define virtual sequence, all you have to modify is the virtual sequence (or derive a child) not the testbench. Thus, the control of timing and reusable testbench can be achieved together.

I am sure experts in UVM will raise an issue if I am mistaken.