Virtual sequencer UVM: choose the right child sequencer

I have a question about the virtual sequencer in UVM. Suppose I have N equal interfaces driven by N equal drivers, each associated with its own sequencer. I want to make a transaction like:

    class my_transaction extends uvm_sequence_item;
         logic data;
         int num_if;
    endclass

      

which when executed with `uvm_do () is sent to the driver number num_if. My idea is that for this kind of work I need a virtual sequencer that "translates" the transaction into the right sequencer (number num_if). It is right? If so, how can this be done? Thank.

+3


source to share


2 answers


While Tudor's answer will work technically, conceptually deciding which of the interfaces to run (num_if) is a value that shouldn't belong to the transaction, but to the sequence that calls it (which of course should also be randomized) ... Transactions should only contain a representation of the value that moves from A to B and the way it moves for that protocol. Specification A and B are usually not included in the transaction price.

In this case, a variation on your Tudor transaction and sequence would look like this:

class my_transaction extends uvm_sequence_item;
   rand logic data;
endclass

      

.. and ..



class some_virtual_sequence extends uvm_sequence;
  `uvm_declare_p_sequencer(virtual_seqr)
  rand int num_if; constraint.....
  task body();
    my_transaction trans = my_transaction::type_id::create("my_transaction");
    start_item(trans, , p_sequencer.seqrs[num_if]);
    trans.randomize(); // randomization should be done after start_item()
    finish_item(trans);
  endtask
endclass

      

.. runs on a virtual sequencer, as Tudor says:

class virtual_seqr extends uvm_sequencer;
  my_sequencer seqrs[10];
endclass

      

The above approach also allows you to randomize in the correct place: after start_item () returns and immediately before calling finish_item (), which ends the sequence item.

+3


source


You are right about the virtual sequencer. I'll show you an idea of ​​how to do this (all pseudocode, you'll have to work with the details yourself).

Let's say we have a virtual sequencer containing an array of all bus sequencers:

class virtual_seqr extends uvm_sequencer;
  my_sequencer seqrs[10];
endclass

      



We will assume that these descriptors are passed correctly. In our virtual sequence, we can create a transaction, randomize it, and then send it to the appropriate sequencer.

class some_virtual_sequence extends uvm_sequence;
  `uvm_declare_p_sequencer(virtual_seqr)

  task body();
    my_transaction trans = my_transaction::type_id::create("my_transaction");
    my_transaction.randomize();
    start_item (my_transaction, , p_sequencer.seqrs[my_transaction.num_if]);
    finish_item(my_transaction);
  endtask
endclass

      

We cannot use uvm_do

because it does not know where to send. We also can't use it uvm_do_on

, because the field num_if

must be randomized before knowing where to send the item.

+1


source







All Articles