Sequence library - naveen0215/uvm_sequence_library GitHub Wiki

SEQUENCE LIBRARY :

UVM provides a class for randomly creating and running sequences. This class is called uvm_sequence_library. The uvm_sequence_library class is generally inherited from uvm_sequence, from this we can know that sequence library is also similar to a sequence. We can define multiple derived test sequences in a program and this is merged into a single test sequence which increases the random nature of execution. Such merging can be achieved by using uvm_sequence_library.

sequence_library

           Figure 1. Above figure shows the merging of many  sequences into a single sequence.   

The uvm_sequence_library also provides control to user in terms of sequence selection logic and which sequences to be executed prior to any other sequences. You can ever order the sequence items and can even remove the irrelevant sequence items.

sequence library hierarchy

           Figure 2. sequence library heirarchy.   

1. Sequence Registration Inside Sequence Library :

Sequences can be registered with a sequence library either by using a macro or function calls. To register a sequence(s) with every instance of a particular type of sequence library, the add_typewide_sequence() is used.
Code snippets for multiple uvm components and objects are shown below.

1. Calling “add_typewide_sequence” from sequence library:

add_typewide_sequence()is one of the method for registering the multiple sequences into a single sequence_library. This syntax is used when we are defining the sequences inside the sequence library class.

   class my_seq_lib extends uvm_sequence_library #(my_packet);
       . . .
       function new(string name = "my_seq_lib");
       . . .
          add_typewide_sequence(my_seq.get_type());
          add_typewide_sequence(my_seq2.get_type());
       endfunction
      . . .
    endclass: my_seq_lib

2. Calling “add_sequence” from testcase:

add_sequence()is one of the method for registering the multiple sequences into a single sequence_library. This syntax is used when we are defining the sequences inside the test class.

       class my_test extends uvm_test;
        . . .

             virtual function void build_phase(uvm_phase phase);
              . . .
                   seq_lib.add_sequence(my_seq.get_type());
                   seq_lib.add_sequence(my_seq2.get_type());
              endfunction: build_phase
          . . .
        endclass  

3. Calling “uvm_add_to_seq_lib” from testcase:

uvm_add_to_seq_lib() is one of the method for registering the multiple sequences into a single sequence_library. This syntax is used when we are defining the sequences inside the test class and that too outside uvm_phases.

            class my_test extends uvm_test;

           `uvm_add_to_seq_lib(my_seq, my_seq_lib)
          `uvm_add_to_seq_lib(my_seq2, my_seq_lib)
           . . .
            
           endclass    

4. Calling “add_typewide_sequences” from sequence library:

add_typewide_sequences()is one of the method for registering the multiple sequences into a single sequence_library. This syntax is used when we are defining the sequences inside the sequence library class. Instead of adding each sequence one by one into the sequence_library, we can driectly add multiple sequences with the use of only one add_typewide_sequences(). By observing the below code snippet we can have the understand this method.

               class my_seq_lib extends uvm_sequence_library #(my_packet);
                . . .
                    function new(string name = "my_seq_lib");
                     . . .
                        add_typewide_sequences({my_seq.get_type(),
                         my_seq2.get_type()});
                     endfunction
                 . . .
                 endclass: my_seq_lib  

5. Calling “add_sequences’ from testcase:

add_sequences()is one of the method for registering the multiple sequences into a single sequence_library. This syntax is used when we are defining the sequences inside the test class. Instead of adding each sequence one by one into the sequence_library, we can driectly add multiple sequences with the use of only one add_sequences(). By observing the below code snippet we can have the understand this method.

                      class my_test extends uvm_test;
                         . . .

                          virtual function void build_phase(uvm_phase phase);
                             . . .
                             seq_lib.add_sequences({my_seq.get_type(),
                             my_seq2.get_type()});
                          endfunction: build_phase
                         . . .
                      endclass    

2. Sequence Library Controls :

Selection mode:

  • Syntax : uvm_sequence_lib_mode selection_mode

It specifies the mode or the order in which the sequences to be executed and the selection of the sequence can be customized by the user using 4 variations. They are,

Enum Value Description
UVM_SEQ_LIB_RAND Random sequence selection (Default selection_mode).
UVM_SEQ_LIB_RANDC Random cyclic sequence selection
UVM_SEQ_LIB_ITEM Emit only items, no sequence execution
UVM_SEQ_LIB_USER Apply a user-defined random-selection algorithm
  1. Select rand : The index variable that is randomized to select the next sequence to execute when in UVM_SEQ_LIB_RAND mode.
  2. Select randc : The index variable that is randomized to select the next sequence to execute when in UVM_SEQ_LIB_RANDC mode.
  3. Select item : Generates data items only, no sequence is executed by using UVM_SEQ_LIB_ITEM mode.
  4. select sequence : Generates an index used to select the next sequence to execute. Overrides must return a value between 0 and max, inclusive. Used only for UVM_SEQ_LIB_USER selection mode.

Library behavior is controlled by properties.

  1. min_random_count : Lower constraint for random number (default 10).
  2. max_random_count : Upper constraint for random number (default 10).

This min and max random count helps in execution of sequence library class. There will be random number generated between this range and for that number of times the sequence library gets executed. For example, if there are 3 sequences added into a sequence_library and if min_random_count=5 and max_random_count=9, then the simulator will choose a number between this range(lets say it as 7). Generally the execution of the sequences depends on the selection_mode(here let us consider "randc" mode),then sequence1,sequence2 and sequence3 are executed for 2 times each and any one sequence will be executed for one more iteration.

Sequence Registration :

All classes of sequences are derived directly from uvm_sequence (as shown in figure 2) and those sequences are merged into a single sequence using uvm_sequence_library. This sequence_library has to be registered with the factory using uvm_sequence_library_utils macro.

This class must be instantiated and also need to create constructor while using in the other classes. We also need to call init_sequence_library in the constructor in order to setup and construct the library infrastructure. Init library cannot have a task body, cannot define its own sequence but it can only have predefined sequences into the library.

  • Example :
     class my_seq_lib extends uvm_sequence_library#(transaction);
          `uvm_object_utils(my_seq_lib)
          `uvm_sequence_library_utils(my_seq_lib)
           seq1 s1;
           seq2 s2;
                  
           function new(string name="my_seq_lib");
                 super.new(name);
              selection_mode=UVM_SEQ_LIB_RANDC;
              min_random_count=5;
              max_random_count=10;

             s1=seq1::type_id::create("s1");
             s2=seq2::type_id::create("s2");
             add_typewide_sequence(s1.get_type());
             add_typewide_sequence(s2.get_type());

             init_sequence_library();
       endfunction

  endclass



 class test extends uvm_test;
   `uvm_component_utils(test)
     my_seq_lib seq_lib;
    environment env;

  function new(string name="test",uvm_component parent=null);
    super.new(name,parent);
  endfunction

  virtual function void build_phase(uvm_phase phase);
     super.build_phase(phase);
     env = environment::type_id::create("env",this);
     seq_lib=my_seq_lib::type_id::create("seq_lib");
  endfunction

  virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);
     uvm_config_db#(uvm_sequence_base)::set(this,"env.a.seqr.main_phase","default_sequence",seq_lib);
     seq_lib.print();
   phase.drop_objection(this);
  endtask

endclass

   module tb;
     initial begin
       run_test("test");
      end
              endmodule

In the above example, we extended sequence1 and sequence 2 from the uvm_sequence and for that we created a factory in the method by using the create method. Also we extend the class name by my_seq_lib by using UVM inbuild library uvm_sequence_library and after that initializing the Factory registration Macro. Then declaring the constructor method. seq_lib,s1 and s2 are the handles of the sequence library and seq classes. By using the following syntax, created the Factory method handle_name= class_name::type_id::create("handle_name");

Library behavior is controlled by properties that is min_random_count and max_random_count and it generates a random number between that range. For the selection of sequences from the library we have selection modes. In this example we used randc as a selection mode and we used init_sequence_library to set and construct the sequence_library class in order to generate the sequences from sequence_library we used uvm_config_db method.

In our example the field name for config_db is default_sequence which internally generates the random sequence based on the specified selection_mode and passes that sequence to sequence_libary without calling any get method in sequence_library class. This is because default_sequence field internally have a get method which is pointing to the sequence_library class.

  • Output Snap : uvm_seq_lib

          Output 1. Output of different sequences obtained after merging them into a single sequence library.   
    

uvm_seq_lib_report

                                       Output 2. Output for uvm report.