Part 7 · Environment & Tests · Intermediate

Virtual Sequence Start Patterns: Objection and Profile Discipline

Start virtual sequences with stable objection handling, profile-driven knobs, and explicit startup diagnostics.

Canonical Start Template

Keep test run_phase concise: raise objection, build/configure vseq, validate requirements, start on env.v_sqr, drop objection after closure.

systemverilog
task run_phase(uvm_phase phase);
  stream_profile_vseq vseq;
  phase.raise_objection(this, "stream_profile");

  vseq = stream_profile_vseq::type_id::create("vseq");
  vseq.need_apb = 1;
  vseq.need_axi = 1;
  vseq.need_irq = 0;
  vseq.profile_name = cfg.profile_name;
  vseq.max_packets = cfg.max_packets;

  if (env.v_sqr == null)
    `uvm_fatal("NO_VSQR", "env.v_sqr null before vseq.start")

  vseq.start(env.v_sqr);
  phase.drop_objection(this, "stream_profile_done");
endtask
diagram
[TEST][UVM] objection ownership

raise:
  immediately before vseq lifecycle

drop:
  after vseq completes and closure checks pass

avoid:
  hidden objection ownership inside random helper components

Key takeaways

  • A short canonical template prevents objection and startup regressions.

  • Profile knobs should be visible before start() call.

  • Fast fatal checks for env.v_sqr existence reduce opaque hangs.

Common pitfalls

  • Starting virtual sequences without explicit objection envelope.

  • Passing raw plusargs everywhere instead of typed config values.

  • Hiding profile choice in deep helper code paths.


Profile-Driven Launch

diagram
[TEST][UVM][VSEQ] profile map

profile      need_apb  need_axi  need_irq  max_packets
-------------------------------------------------------
smoke         1         1         0         32
nightly       1         1         1         512
stress        1         1         1         4000
irq_focus     1         0         1         64
systemverilog
function void apply_profile(string profile);
  if (profile == "smoke") begin
    need_apb = 1; need_axi = 1; need_irq = 0; max_packets = 32;
  end
  else if (profile == "nightly") begin
    need_apb = 1; need_axi = 1; need_irq = 1; max_packets = 512;
  end
  else if (profile == "stress") begin
    need_apb = 1; need_axi = 1; need_irq = 1; max_packets = 4000;
  end
  else if (profile == "irq_focus") begin
    need_apb = 1; need_axi = 0; need_irq = 1; max_packets = 64;
  end
  else begin
    `uvm_fatal("BAD_PROFILE", $sformatf("unknown profile=%s", profile))
  end
endfunction
diagram
[TEST][UVM] profile logging contract

startup log must include:
  profile name
  required handles
  key numeric knobs
  seed
  selected test

this turns launcher issues into immediate visibility
  • Treat profile names as API and keep them versioned/documented.

  • Unknown profile should fail loudly, never silently fallback.

  • Log profile resolution before any traffic starts.


Applied Patterns

diagram
[TEST][UVM][VSEQ] launch checklist

before start():
  verify env.v_sqr exists
  apply profile -> typed config
  validate required handles
  emit startup summary

during start():
  use barrier-based sequencing
  timeout every wait

after completion:
  verify quiet window
  drop objection
  report key counters
systemverilog
function void print_launch_banner(string profile);
  `uvm_info("VSEQ_LAUNCH",
    $sformatf("profile=%s need_apb=%0d need_axi=%0d need_irq=%0d max_packets=%0d",
      profile, need_apb, need_axi, need_irq, max_packets),
    UVM_LOW)
endfunction
  • Launch discipline dramatically reduces startup-flake noise.

  • Consistent banners simplify CI triage for failed seeds.

  • Profiles make scenario intent inspectable and reproducible.