Part 5 · Sequences · Intermediate

Sequence Library Registration: uvm_sequence_library

Register candidate sequences, selection modes, min/max random count, and running the library from a test.

What uvm_sequence_library solves

Regression diversity traditionally means writing one test per stimulus variant. uvm_sequence_library registers multiple sequence types as candidates and randomly selects one (or a random count of them) per invocation. One test class can exercise burst, fixed-address, and error-injection sequences across hundreds of seeds without source changes.

diagram
[STIM] regression diversity without N tests

  WITHOUT library:
    test_burst.sv, test_fixed.sv, test_err.sv … 40 files

  WITH axi_seq_lib:
    one test_axi_lib.sv
    lib.selection_mode = UVM_SEQ_LIB_RAND
    lib.min_random_count = 3; lib.max_random_count = 10
    each seed picks different sequence mix

Library class and registration

systemverilog
class axi_seq_lib extends uvm_sequence_library #(axi_item);
  `uvm_object_utils(axi_seq_lib)
  `uvm_sequence_library_utils(axi_seq_lib)

  function new(string name = "axi_seq_lib");
    super.new(name);
    init_sequence_library();  // required — builds internal candidate list
  endfunction
endclass

// Register candidates — macro expands to add_sequence() calls
`uvm_add_to_seq_lib(axi_rand_burst_seq, axi_seq_lib)
`uvm_add_to_seq_lib(axi_fixed_addr_seq, axi_seq_lib)
`uvm_add_to_seq_lib(axi_error_inj_seq, axi_seq_lib)
`uvm_add_to_seq_lib(axi_backpressure_seq, axi_seq_lib)

Each `uvm_add_to_seq_lib macro registers a sequence type with the library's internal queue. The library does not contain sequence bodies — it only holds type handles for selection.

  • init_sequence_library() in new() is mandatory — without it, candidate list is empty.

  • All candidates must extend uvm_sequence #(axi_item) — same item type as library param.

  • Registration can also use add_sequence() in new() for dynamic registration.


Running from a test

systemverilog
class test_axi_lib extends uvm_test;
  `uvm_component_utils(test_axi_lib)

  task run_phase(uvm_phase phase);
    axi_seq_lib lib;
    phase.raise_objection(this);
    lib = axi_seq_lib::type_id::create("lib");
    lib.selection_mode   = UVM_SEQ_LIB_RAND;
    lib.min_random_count = 3;
    lib.max_random_count = 10;
    `uvm_info("TEST", $sformatf(
      "starting seq lib on %s", env.axi_agent.sqr.get_full_name()), UVM_LOW)
    lib.start(env.axi_agent.sqr);
    phase.drop_objection(this);
  endtask
endclass

Walkthrough — one library invocation

diagram
Legend: [STIM] [SEQ] [UVM]

  T0  test run_phase: lib.start(axi_sqr)
  T1  library picks random_count = 7 (between min 3 and max 10)
  T2  iteration 0: select axi_rand_burst_seq  start on sqr  body runs  done
  T3  iteration 1: select axi_error_inj_seq   start on sqr  body runs  done
  T4  iteration 2: select axi_fixed_addr_seq  start on sqr  body runs  done
  …
  T8  iteration 6: select axi_backpressure_seq  done
  T9  lib.body() returns; test drops objection

Each selected sequence gets a full start() — with its own arbitration rounds and body() execution.


Selection modes

The selection_mode field controls how the library picks candidates each iteration:

diagram
[SEQ] UVM sequence library selection modes

  UVM_SEQ_LIB_RAND
    random pick each iteration — same type may repeat back-to-back

  UVM_SEQ_LIB_RANDC
    random cyclic — all registered types run once before any repeat
    best for coverage of every candidate per library invocation

  UVM_SEQ_LIB_ITEM
    one sequence per library run — library acts as typed factory wrapper

  UVM_SEQ_LIB_USER
    custom selection via callback — advanced weighted or directed pick
  • UVM_SEQ_LIB_RANDC for sign-off runs where every candidate must fire at least once.

  • UVM_SEQ_LIB_RAND for long stress where statistical mix matters more than completeness.

  • min_random_count / max_random_count bound total iterations per lib.start() call.

Composing with virtual sequences

systemverilog
// vseq starts library on one agent while another runs directed seq
task body();
  axi_seq_lib lib = axi_seq_lib::type_id::create("lib");
  lib.selection_mode = UVM_SEQ_LIB_RANDC;
  fork
    lib.start(p_sequencer.axi_sqr);
    dma_stress_seq.start(p_sequencer.dma_sqr);
  join
endtask

Key takeaways

  • uvm_sequence_library registers types; init_sequence_library() in new() is required.

  • selection_mode controls pick strategy; min/max_random_count bounds iteration count.

  • One test + library replaces many near-duplicate test files in regression.

Common pitfalls

  • Library with only one registered type — overhead without diversity benefit.

  • Forgot init_sequence_library() — library runs zero sequences, silent pass.

  • Candidate sequence with wrong item type param — compile error or runtime mismatch.

  • max_random_count = 0 — library may run nothing depending on UVM version defaults.