Part 10 · Advanced Topics · Intermediate
Compatibility Layer: What It Preserves and What It Hides
How compatibility wrappers keep UVM 1.2 code running, and where strict-mode behavior exposes hidden debt.
The compatibility contract
Compatibility layers are not random helper piles; they are intentional bridges. Their job is to preserve productivity for existing code while the ecosystem converges on standardized naming and semantics.
The bridge usually includes alias methods, retained macros, and convenience wrappers. These features reduce immediate breakage, but they can also hide migration debt if teams never test strict mode.
Legend: [UVM] [ADV]
Legacy 1.2-style calls
│
▼
+----------------------------------+
| [ADV] compatibility wrappers |
| alias names, convenience APIs |
+----------------------------------+
│ forwards to
▼
+----------------------------------+
| [UVM] IEEE-oriented core API |
+----------------------------------+Compatibility is a transition mechanism, not a permanent architecture goal.
Strict mode intentionally removes or tightens parts of this bridge.
Run both modes to distinguish breakage from genuine DUT/testbench issues.
Strict vs compatibility mode behaviors
Many teams only validate one simulator default mode and assume they are portable. A better approach is explicit mode control in every CI job so behavior differences become deterministic and reviewable.
[UVM] mode behavior matrix
Area Compatibility mode Strict mode
--------------------------------------------------------------------------------
Legacy aliases Usually accepted Often rejected
Deprecated helpers Usually present May warn/error
Diagnostics Familiar 1.2 style Standard-focused wording
Migration signal Low (debt hidden) High (debt exposed)
Portability confidence Medium High when passing# Pseudo flow for CI (vendor flags differ by simulator)
# lane A: permissive compatibility
make sim MODE=compat TEST=smoke
# lane B: strict 1800.2 expectations
make sim MODE=strict TEST=smokeKeep testlists identical between lanes to isolate mode effects.
Collect mode-specific log signatures to simplify triage ownership.
Avoid debugging functional failures until mode-mismatch failures are classified.
Compatibility anti-patterns
Compatibility makes short-term delivery easier, which can unintentionally create long-term debt. The most common anti-pattern is new code adopting old helper calls because they are still accepted.
Copying old examples that rely on alias APIs into new VIP.
Using permissive mode in all lanes because strict mode is noisy.
Treating strict failures as tooling defects without root-cause labeling.
Refactoring only failing files while allowing unaffected files to retain legacy style.
[ADV] debt growth curve
Quarter Strict failures New legacy callsites added Net migration progress
-------------------------------------------------------------------------------
Q1 120 85 negative
Q2 90 70 near-zero
Q3 55 15 positive
Q4 18 3 strong positive
Interpretation:
Reducing failures is not enough if new debt keeps landing.Hardening strategy for compatibility usage
The safest strategy is two-speed governance: legacy code can pass through controlled migration queues, but new code must be strict-clean from day one. This stops debt growth while existing debt is retired.
// Example policy helper: fail fast in strict-only branch
function void pre_run_policy_check();
if ($test$plusargs("STRICT_1800_2_REQUIRED")) begin
// Project-specific policy hooks, e.g. check forbidden macros list
`uvm_info("POLICY", "strict policy enabled", UVM_LOW)
end
endfunction[UVM] policy checklist
New file policy:
- must pass strict lane
- must avoid compatibility-only aliases
- must include migration-safe reporting/factory usage
Legacy file policy:
- allowed in compat lane
- strict failures tracked with owner + ETA
- touched lines converted opportunisticallyKey takeaways
Compatibility layers should buy time, not define your end state.
Dual-lane CI (compat + strict) turns hidden debt into actionable work.
Stop debt growth by requiring strict-clean standards for new code.
Common pitfalls
Leaving strict mode disabled because initial failure volume is high.
Allowing copy-paste of compatibility-only patterns into new modules.
Tracking migration as anecdotes instead of lane metrics.