A typical verification environment will have hundreds of tests with random seeds and configurations, which can be made simpler by having a variety of sequences to perform individual tasks. Now, you may create top level sequences that can spawn off smaller ones within its body() task, or create a randomized way of calling multiple sequences. A cleaner way would be to use the sequence library provided by UVM as uvm_sequence_library. As the name suggests, it keeps a track of the sequences that are registered with it, and calls them a number of times in a random fashion.

class hierarchy - uvm_sequence_library

Let's take an example of three sequences, all derived from the same base_sequence class, as we have seen before. Here, these three are individual sequences without being nested inside each other.


class seq1 extends base_sequence;
	...
	virtual task body ();
		`uvm_info ("SEQ1", "Starting seq1", UVM_MEDIUM)
		#10;
		`uvm_info ("SEQ1", "Ending seq1", UVM_MEDIUM)
	endtask
	...
endclass

class seq2 extends base_sequence;
	...
	virtual task body ();
         `uvm_info ("SEQ2", "Starting seq2", UVM_MEDIUM)
         #10;
         `uvm_info ("SEQ2", "Ending seq2", UVM_MEDIUM)
	endtask
    ...
endclass

class seq3 extends base_sequence;
	...
	virtual task body ();
    	`uvm_info ("SEQ3", "Starting seq3", UVM_MEDIUM)
		#10;
		`uvm_info ("SEQ3", "Ending seq3", UVM_MEDIUM)
	endtask
    ...
endclass

Now we need to create a custom sequence library which should be derived from uvm_sequence_library.


class my_seq_lib_v2 extends uvm_sequence_library #(my_data);
   `uvm_object_utils (my_seq_lib_v2)
   `uvm_sequence_library_utils (my_seq_lib_v2)

   function new (string name="my_seq_lib_v2");
      super.new (name);
      init_sequence_library();
   endfunction
endclass

Note that you have to call the macro `uvm_sequence_library_utils macro to define the infrastructure needed to define extensions to the uvm_sequence_library class. Each library, itself a sequence, can then be started independently on different sequencers or in different phases of the same sequencer. You can create an instance of this sequence library in a test or another sequence, configure it, and add the required set of sequences to the library. A good way to start the sequencer to execute sequences from this library is to make it a default sequence.

flow of sequence from library to driver

class feature_test extends base_test;
   `uvm_component_utils (feature_test)

   my_seq_lib m_seq_lib0;
   seq1 m_seq1;
   seq2 m_seq2;
   seq3 m_seq3;

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

   function void build_phase (uvm_phase phase);
      super.build_phase (phase);

      m_seq_lib0 = my_seq_lib::type_id::create ("m_seq_lib0");
   endfunction

   virtual task configure_phase (uvm_phase phase);
      super.configure_phase (phase); 
      `uvm_info ("CFG_PHASE", "Add sequences to library", UVM_MEDIUM)
      m_seq_lib0.selection_mode = UVM_SEQ_LIB_RANDC;
      m_seq_lib0.min_random_count = 5;
      m_seq_lib0.max_random_count = 10;

      m_seq_lib0.add_typewide_sequence (m_seq1.get_type());
      m_seq_lib0.add_typewide_sequence (m_seq2.get_type());
      m_seq_lib0.add_typewide_sequence (m_seq3.get_type());
      m_seq_lib0.init_sequence_library();
   endtask

   function void start_of_simulation_phase (uvm_phase phase);
      super.start_of_simulation_phase (phase);
      uvm_config_db#(uvm_sequence_base)::set(this,"m_top_env.m_seqr0.main_phase",
                                                   "default_sequence", m_seq_lib0);
   endfunction
endclass

add_typewide_sequence() function can be used to add sequences to the library. In this case, the minimum number of iterations done by the sequencer is set to 5, and maximum 10.

 Simulation Log
----------------------------------------------------------------
CDNS-UVM-1.1d (14.10-s013)
(C) 2007-2013 Mentor Graphics Corporation
(C) 2007-2013 Cadence Design Systems, Inc.
(C) 2006-2013 Synopsys, Inc.
(C) 2011-2013 Cypress Semiconductor Corp.
----------------------------------------------------------------
UVM_INFO @ 0: reporter [RNTST] Running test feature_test...
UVM_INFO @ 0: reporter [UVMTOP] UVM testbench topology:
------------------------------------------------------------
Name                     Type                    Size  Value
------------------------------------------------------------
uvm_test_top             feature_test            -     @2677
  m_top_env              my_env                  -     @229
    m_drv0               my_driver               -     @2793
      rsp_port           uvm_analysis_port       -     @2893
      seq_item_port      uvm_seq_item_pull_port  -     @2842
    m_seqr0              my_sequencer            -     @223
      rsp_export         uvm_analysis_export     -     @2983
      seq_item_export    uvm_seq_item_pull_imp   -     @3531
      arbitration_queue  array                   0     -
      lock_queue         array                   0     -
      num_last_reqs      integral                32    'd1
      num_last_rsps      integral                32    'd1
------------------------------------------------------------

UVM_INFO ./tb/my_pkg.sv(92) @ 0: uvm_test_top.m_top_env.m_drv0 [my_driver] Applying initial reset
UVM_INFO ./tb/my_pkg.sv(96) @ 390000: uvm_test_top.m_top_env.m_drv0 [my_driver] DUT is now out of reset
UVM_INFO ./tb/test_pkg.sv(89) @ 390000: uvm_test_top [CFG_PHASE] Add sequence to lib
UVM_INFO ./tb/my_pkg.sv(103) @ 390000: uvm_test_top.m_top_env.m_drv0 [my_driver] Waiting for data from sequencer
UVM_INFO /pkg/cadence-incisiv-/14.10.013/i686-linux/tools/methodology/UVM/CDNS-1.1d/sv/src/seq/uvm_sequence_library.svh(664) @ 390000: uvm_test_top.m_top_env.m_seqr0@@m_seq_lib0 [SEQLIB/START] Starting sequence library my_seq_lib in main phase: 5 iterations in mode UVM_SEQ_LIB_RANDC
UVM_INFO ./tb/my_pkg.sv(166) @ 390000: uvm_test_top.m_top_env.m_seqr0@@m_seq_lib0.seq1:1 [seq1] Executing pre_start()
UVM_INFO ./tb/my_pkg.sv(174) @ 390000: uvm_test_top.m_top_env.m_seqr0@@m_seq_lib0.seq1:1 [SEQ1] Starting seq1
UVM_INFO ./tb/my_pkg.sv(176) @ 400000: uvm_test_top.m_top_env.m_seqr0@@m_seq_lib0.seq1:1 [SEQ1] Ending seq1
UVM_INFO ./tb/my_pkg.sv(223) @ 400000: uvm_test_top.m_top_env.m_seqr0@@m_seq_lib0.seq3:2 [SEQ3] Starting seq3
UVM_INFO ./tb/my_pkg.sv(225) @ 410000: uvm_test_top.m_top_env.m_seqr0@@m_seq_lib0.seq3:2 [SEQ3] Ending seq3
UVM_INFO ./tb/my_pkg.sv(233) @ 410000: uvm_test_top.m_top_env.m_seqr0@@m_seq_lib0.seq3:2 [seq3] Executing post_start
UVM_INFO ./tb/my_pkg.sv(197) @ 410000: uvm_test_top.m_top_env.m_seqr0@@m_seq_lib0.seq2:3 [SEQ2] Starting seq2
UVM_INFO ./tb/my_pkg.sv(199) @ 420000: uvm_test_top.m_top_env.m_seqr0@@m_seq_lib0.seq2:3 [SEQ2] Ending seq2
UVM_INFO ./tb/my_pkg.sv(223) @ 420000: uvm_test_top.m_top_env.m_seqr0@@m_seq_lib0.seq3:4 [SEQ3] Starting seq3
UVM_INFO ./tb/my_pkg.sv(225) @ 430000: uvm_test_top.m_top_env.m_seqr0@@m_seq_lib0.seq3:4 [SEQ3] Ending seq3
UVM_INFO ./tb/my_pkg.sv(233) @ 430000: uvm_test_top.m_top_env.m_seqr0@@m_seq_lib0.seq3:4 [seq3] Executing post_start
UVM_INFO ./tb/my_pkg.sv(197) @ 430000: uvm_test_top.m_top_env.m_seqr0@@m_seq_lib0.seq2:5 [SEQ2] Starting seq2
UVM_INFO ./tb/my_pkg.sv(199) @ 440000: uvm_test_top.m_top_env.m_seqr0@@m_seq_lib0.seq2:5 [SEQ2] Ending seq2
UVM_INFO /pkg/cadence-incisiv-/14.10.013/i686-linux/tools/methodology/UVM/CDNS-1.1d/sv/src/seq/uvm_sequence_library.svh(738) @ 440000: uvm_test_top.m_top_env.m_seqr0@@m_seq_lib0 [SEQLIB/END] Ending sequence library in phase main
UVM_INFO /pkg/cadence-incisiv-/14.10.013/i686-linux/tools/methodology/UVM/CDNS-1.1d/sv/src/seq/uvm_sequence_library.svh(740) @ 440000: uvm_test_top.m_top_env.m_seqr0@@m_seq_lib0 [SEQLIB/DSTRB] '{"seq1":1, "seq2":2, "seq3":2}
UVM_INFO ./tb/my_pkg.sv(122) @ 440000: uvm_test_top.m_top_env.m_drv0 [my_driver] Finished DUT simulation

--- UVM Report catcher Summary ---