Policy rules, UVM naming conventions (m_ prefix, u_dut instance), commercial simulator requirements, coverage collection rules, and checklists. Pure reference — no orchestration.
UVM environment code MUST follow the project coding conventions (CLAUDE.md):
i_ prefix for inputs, o_ prefix for outputsclk (single domain) or {domain}_clk (multiple domains, e.g., sys_clk) — NOT clk_irst_n (single domain) or {domain}_rst_n (multiple domains, e.g., sys_rst_n) — NOT rst_niu_dut with u_ prefixm_ prefix (e.g., m_agent, m_scoreboard, m_driver, m_monitor)logic in all SV declarations (NOT reg/wire)i_datao_valid| Coverage Type | Target | Tool Flag (VCS) | Notes |
|---|---|---|---|
| Line | ≥ 90% | -cm line | Every executable line exercised |
| Toggle | ≥ 80% | -cm tgl | Signal 0→1 and 1→0 transitions |
| FSM | ≥ 70% | -cm fsm | State and transition coverage |
| Branch | ≥ 80% | -cm cond | if/case branch coverage |
| Functional | ≥ 95% | UVM covergroups | Architect-defined coverpoints |
Code coverage is always enabled during regression (-cm line+cond+fsm+tgl+branch for VCS,
-coverage all for Xcelium, -coverage for Questa). Merged from all seeds before evaluation.
Functional coverage is collected via uvm_subscriber-based coverage collectors in the
testbench. Covergroups must be mapped to requirements (REQ-U-*).
When merged coverage falls below targets after regression, run a structured 3-round loop:
Round N: coverage-analyst → CDTG feedback table (gap analysis)
test-plan-writer → systematic test plan (ECP/BVA for config-dependent gaps)
testbench-dev → directed UVM sequences per gap row + test plan
eda-runner → regression with new tests → re-merge coverage
Round N+1: coverage-analyst re-analyzes → new guidance for remaining gaps
coverage-analyst identifies uncovered bins, states, branches. Produces CDTG feedback table:
| Gap ID | Uncovered Bin | REQ | Constraint | Sequence | Expected |
test-plan-writer applies ECP/BVA methodology for config-dependent gaps (parameter combinations)testbench-dev writes directed UVM sequences per gap row using the systematic test planrtl-p5s-coverage-policy
(classify remaining bins as STIMULUS_GAP/STRUCTURAL_DEAD/INFRA_CODE, generate exclusion artifacts)Before running regression, verify stimulus actually reaches the DUT:
rand fields in test class must be randomized
this.randomize() called in build_phase or run_phaserand logic field declared but never randomize()-drand cfg_xxx in test class but DUT port hardcoded in TB topp5s-uvm-orchestrator checks coverage delta after first regression iteration (Step 4). If delta < 0.1% across seeds → invoke uvm-reviewer to diagnose stimulus connectivity before running additional iterations.
Use skills/rtl-p5s-uvm-verify/scripts/run_regression_uvm.sh for multi-seed regression:
bash run_regression_uvm.sh --sim vcs --seeds "42 123 456 789 1337" --test base_test --module {module}
urg, Xcelium imc, Questa vcoveri_/o_ prefix, sys_clk/sys_rst_n, m_ UVM member prefix, u_ RTL instance prefix)UVM component naming conventions (aligned with project style):
m_agent, m_axi_agent, m_apb_agent (m_ prefix for UVM class members)m_driver, m_monitor (m_ prefix for UVM class members)u_dut (u_ prefix for RTL instances only)logic (never reg/wire)Simulator-specific coverage flags — both compile and run must enable coverage:
# VCS — compile + run
vcs -full64 -sverilog -ntb_opts uvm-1.2 \
-cm line+cond+fsm+tgl+branch \
-cm_hier sim/uvm/coverage/hier.cfg \
-timescale=1ns/1ps -f rtl/filelist_top.f \
sim/uvm/agents/*/*.sv sim/uvm/env/*.sv sim/uvm/seq/*.sv \
sim/uvm/tests/*.sv sim/uvm/tb/*.sv -o simv
./simv +UVM_TESTNAME={test} +ntb_random_seed={seed} \
-cm line+cond+fsm+tgl+branch -cm_dir sim/uvm/coverage/seed_{seed}.vdb
# VCS — merge (text + XML for coverage-analyst parsing)
urg -dir sim/uvm/coverage/seed_*.vdb -report sim/uvm/coverage/merged \
-elfile sim/uvm/coverage/exclusion.el -format both
# Questa — compile (MUST include +cover) + run
vlog -sv +cover=bcestf +incdir+sim/uvm \
-f rtl/filelist_top.f sim/uvm/agents/*/*.sv sim/uvm/env/*.sv \
sim/uvm/seq/*.sv sim/uvm/tests/*.sv sim/uvm/tb/*.sv
vsim -c -coverage tb_top +UVM_TESTNAME={test} -sv_seed {seed} \
-do "coverage save -onexit sim/uvm/coverage/seed_{seed}.ucdb; run -all; quit -f"
# Questa — merge
vcover merge sim/uvm/coverage/merged.ucdb sim/uvm/coverage/seed_*.ucdb
vcover report -details sim/uvm/coverage/merged.ucdb
# Xcelium — compile + run (separate phases)
xrun -sv -uvm -compile -coverage all -timescale 1ns/1ps \
-f rtl/filelist_top.f sim/uvm/agents/*/*.sv sim/uvm/env/*.sv \
sim/uvm/seq/*.sv sim/uvm/tests/*.sv sim/uvm/tb/*.sv \
-xmlibdirpath build/xcelium
xrun -R +UVM_TESTNAME={test} -seed {seed} \
-coverage all -covworkdir sim/uvm/coverage/seed_{seed}/cov_work -covscope tb_top \
-xmlibdirpath build/xcelium
# Xcelium — merge (via imc TCL script)
imc -exec merge_script.tcl # merge -run seed_*/cov_work → report
Common mistakes to avoid:
+cover=bcestf at vlog compile → runtime -coverage collects nothing-cm at runtime → compile instrumentation wasted-R without matching -xmlibdirpath → snapshot not foundSee references/uvm-architecture.md for complete UVM class hierarchy, phase order,
and common UVM mistakes to avoid.