SystemVerilog for Verification
OOP, constrained random, coverage, and assertions.
The verification half of SystemVerilog: object-oriented testbench programming, constrained-random stimulus, functional coverage, assertions, and the concurrency that ties a testbench together. It continues directly from SystemVerilog Fundamentals into the language features verification engineers use every day — the groundwork for UVM.
Prerequisites
What you'll be able to do
- Build reusable, polymorphic verification components with SystemVerilog classes.
- Drive constrained-random stimulus and steer it toward corner cases.
- Measure verification completeness with functional coverage.
- Specify and check temporal behavior with SystemVerilog Assertions.
Competencies you'll develop
SystemVerilog object-oriented programming
Model verification components with classes, inheritance, polymorphism, and virtual methods.
Constrained random verification
Drive stimulus with random variables, constraints, and randomization control to reach hard-to-hit states.
Functional coverage
Measure verification completeness with covergroups, coverpoints, bins, and cross coverage.
SystemVerilog assertions
Specify and check temporal behavior with immediate and concurrent SVA sequences and properties.
Concurrency & inter-process communication
Coordinate concurrent testbench processes with fork/join, events, mailboxes, semaphores, and fine-grained process control.
Curriculum
Object-Oriented Programming
16 lessons- 01Introduction to OOP in SystemVerilogWhy OOP belongs in verification, what classes give you over structs and modules, and the OO mindset every modern UVM environment is built on.
- 02Classes & Objects — BasicsThe anatomy of a class, how objects are allocated on the heap, handles as pointers, and the construction lifecycle from new() to garbage collection.
- 03Properties & MethodsPer-instance data fields, methods that operate on them, and the difference between functions and tasks inside a class.
- 04Constructors & new()Custom constructors, default argument values, explicit vs implicit initialization, and the rules that govern construction across an inheritance chain.
- 05Encapsulation — public, protected, localAccess modifiers, the encapsulation contract, getter/setter patterns, and why local is strictly stronger than protected.
- 06The this KeywordThe hidden instance pointer, disambiguating shadowed names, passing self by reference, and idiomatic builder-style chaining.
- 07Static Properties & MethodsClass-wide storage, auto-ID generators, singletons, global verbosity controllers, and the static-vs-instance trap that catches every new OOP developer.
- 08Inheritance & extendsBuilding child classes on top of existing ones, method override mechanics, multi-level hierarchies, type compatibility, and why SystemVerilog forbids multiple inheritance.
- 09The super KeywordReaching the parent's constructor and overridden methods, the static-resolution rule that prevents recursion, UVM phase chaining, and the do_copy / do_compare hook discipline.
- 10Polymorphism & Virtual MethodsStatic vs dynamic dispatch, the vtable model, polymorphic containers, the UVM factory pattern, and the canonical 'override never runs' debugging trap.
- 11Abstract Classes & Pure Virtual MethodsContracts every subclass must implement, compile-time enforcement, the protocol-agnostic driver pattern, and the backward-compatibility hazards of evolving a shipped abstract base.
- 12Parameterised ClassesType and value parameters, per-specialisation static storage, the UVM driver/scoreboard/analysis-port template pattern, and why typedef is mandatory for non-trivial specialisations.
- 13Nested ClassesClass-scoped helper types, qualified-name discipline, no implicit enclosing-instance access, and the namespace-hygiene wins of nesting class-local state enums.
- 14Handles — Shallow Copy, Deep Copy, ComparisonThe handle-is-a-pointer mental model, the shallow-vs-deep copy trap, UVM-style copy()/clone()/compare(), and the scoreboard aliasing bugs that haunt every new verification engineer.
- 15typedef class — Forward DeclarationsBreaking circular references between mutually-referencing classes, request/response pairs, callback patterns, and the orphan-forward trap that surfaces as cryptic 'incomplete type' errors.
- 16Class Scope Resolution (::)Reaching static members, package symbols, class-scoped enums, parameterised specialisations, and the UVM factory's type_id::create() idiom — names vs instances at compile time.
Constrained Random Verification
15 lessons- 17Introduction to Constrained Random VerificationWhy CRV exists, where it sits between directed and pure random, the five-step generate→drive→observe→score→cover loop, and how it pairs with functional coverage.
- 18rand & randc KeywordsProperty modifiers that mark class fields randomisable, the difference between independent draws and cyclic without-repeat, per-instance state, and the 8-bit ceiling on randc.
- 19The randomize() Method & Return ValueThe single entry point between test layer and solver, the four canonical call patterns, the synchronous-on-host-CPU model, and why discarding the return value is the most common CRV bug.
- 20Constraint BlocksNamed declarative protocol contracts, three architectural roles (legality/shaping/injection), joint-AND semantics with no semicolon sequencing, and the test-layer reach via constraint_mode.
- 21Inline Constraints — the with ClausePer-call constraint additions inside randomize() with { … }, scope and local-variable capture, the AND-not-substitute combination with class constraints, and the three-sites refactor signal.
- 22Constraint Modes — constraint_mode()Per-object, per-block enable bitmap; surgical block-level disable vs whole-object disable; save/restore discipline; inheritance-aware access; TLM-port leak gotchas.
- 23Soft ConstraintsOverridable defaults the solver drops when contradicted, per-expression granularity, distinct from constraint_mode and inline with, and the danger of marking protocol legality soft.
- 24Weighted Distributions — distProbabilistic stimulus shaping with relative weights, the := vs :/ operator semantics on ranges, the two-stage filter-then-sample model, and pairing every dist with a coverpoint.
- 25Implication & Conditional ConstraintsProtocol dependencies encoded with -> one-directional, if-else two-branch, and <-> biconditional; flatten nested implications for solver efficiency and readability.
- 26Iterative Constraints — foreach in ConstraintsPer-element burst payload rules, guarded inter-element references, unique vs O(N²) pairwise, and when to push per-element dist into post_randomize.
- 27Randomising ArraysFixed and dynamic array rand, the mandatory size constraint, object-handle array pre_randomize construction, and the associative-array workaround via parallel key/value lists.
- 28pre_randomize & post_randomize CallbacksSetup-before-solve vs derive-and-log-after-success; mandatory super chaining; post_randomize skipped on failure; canonical UVM patterns for sub-object construction, scenario gating, and CRC computation.
- 29randcase StatementProcedural weighted choice without classes or constraints; config-driven weights as an architectural power move; the safety-branch pattern that prevents all-zero-weight undefined behaviour.
- 30randsequence StatementCompositional grammar generator that mirrors a protocol's BNF; weighted alternatives, repeat-bounded iteration, expansion-time vs execution-time semantics; coexistence with UVM sequences.
- 31Solve Before ConstraintsDistribution-shaping directive (not legality) for asymmetric implication branches; two-phase pick-uniform-then-constrain semantics; the canonical mode/payload pair coverage fix.
Functional Coverage
10 lessons- 32Introduction to Functional CoverageWhy functional coverage is the only honest verification-closure metric, the four goals every plan must satisfy, the CRV feedback loop, and the trap of 100% code coverage with 0% functional coverage.
- 33Covergroups & CoverpointsThe two coverage primitives — covergroup as a class-like type, coverpoint as its measurable field. Three coverpoint forms, label semantics, the four legal scopes, the built-in method API, and the constructor-omission bug every team ships at least once.
- 34Automatic BinsThe simulator's default bin partition when no bins block is declared. The 1-bin-per-value vs bucketed regimes at the auto_bin_max boundary, the 100%-coverage-that-means-nothing trap on wide fields, and the prototype-to-sign-off lifecycle.
- 35Named Bins — Explicit Coverage PartitionsThe four explicit-bin forms — single-value, range, multi-value, and array — plus transition bins, per-bin options (at_least, weight, comment), and the discipline that every sign-off coverpoint on a wide field uses named bins mapped one-to-one to verification-plan rows.
- 36Wildcard, Illegal & Ignore BinsThe three special-purpose bin forms — wildcard for bit-pattern matching, illegal for must-never-occur scenarios that fire runtime errors, and ignore for valid-but-irrelevant values. The decision tree for picking between illegal, ignore, narrower bins, and constraints, plus the tool-specific severity model.
- 37Transition CoverageCoverage of value sequences across consecutive samples. The => operator, multi-step chains, range and list endpoints, the three repetition forms ([*N], [=N], [->N]), and the sampling-granularity-vs-transition decision that separates working FSM coverage from silently-broken FSM coverage.
- 38Cross CoverageThe Cartesian product of two or more coverpoints' bins — measuring feature combinations rather than features in isolation. Two-way and N-way cross, binsof / intersect bin selection, illegal and ignore bins inside crosses, the cross-bin explosion trap, and why crossing auto-binned coverpoints is a project-killer.
- 39Coverage OptionsThe full vocabulary of option.* and type_option.* settings — at_least, weight, goal, comment, per_instance, auto_bin_max, illegal_bins_error, name — that tune coverage models toward sign-off. The instance-vs-type-scope rule, the option-precedence hierarchy, and the practical patterns that separate working coverage from hand-waving.
- 40Sampling EventsThe mechanism that determines when coverage data lands in the bins. Event-driven vs manual sampling, the @(event) syntax variants, conditional sampling with iff, argument-bearing samples via `with sample()`, the Postponed-region timing model, and why the sampling event is part of every coverage contract.
- 41Instance vs Type CoverageThe distinction between per-instance and per-type coverage. The get_inst_coverage / get_coverage API, the per_instance option, cross-regression UCDB merge semantics, the multi-instance environments where per-instance breakdown is mandatory, and how the choice shapes the sign-off dashboard.
SystemVerilog Assertions
12 lessons- 42Introduction to SystemVerilog Assertions (SVA)Assertions as executable specifications — the temporal-contract layer that complements coverage. Immediate vs concurrent assertions, the four SVA constructs (assert / assume / cover / restrict), the temporal operator preview, and why SVA is the right tool for catching protocol bugs at the exact cycle they occur.
- 43Immediate AssertionsThe procedural, same-instant SVA form — used inside always blocks, tasks, and functions. The three forms (fail-only, pass+fail, bare), the four severity levels ($fatal/$error/$warning/$info), placement rules, the Active-region race-condition gotcha that motivates deferred assertions, and the canonical FIFO-checker pattern.
- 44Deferred Immediate AssertionsThe `assert #0` and `assert final` forms — immediate assertions that defer evaluation to the Observed or Final region so they see settled signals instead of mid-cycle glitches. The simulation-region model, the two forms compared, when to use each, and why combinational checkers belong in deferred form to avoid false-failure noise.
- 45Concurrent AssertionsThe clock-driven SVA form that does most of the heavy lifting — runs in parallel with the design across every clock cycle. Structure, the Preponed-sampling / Observed-evaluation timing model, placement options (inline, separate file, bind), why `disable iff` is non-negotiable in clocked-RTL environments, and the assert+cover pairing pattern.
- 46SVA SequencesThe temporal-pattern building blocks of concurrent assertions. The `sequence ... endsequence` construct, the `##n` and `##[m:n]` delay operators, the `and` / `or` / `intersect` composition operators, `first_match` and `throughout`, and the discipline that makes sequence libraries reusable across an entire verification environment.
- 47SVA PropertiesThe named-contract layer above sequences. `property ... endproperty`, the parts a property gates around a sequence (clocking, disable iff, implication, negation), local variables for cross-cycle value capture, parameterised properties, and the discipline that turns sequences into reviewable spec rules with grep-friendly names.
- 48Clocking & disable iffThe two clauses that determine when a concurrent assertion fires and when it stays dormant. Explicit clocking vs default clocking, multi-clock properties, the disable iff reset clause, scoping (per-property vs default), restart-on-deassert semantics, and why this single discipline rule prevents the most common SVA debugging session.
- 49Implication OperatorsThe deep dive on the two SVA implication operators that encode conditional spec rules. Same-cycle vs next-cycle distinction, vacuous-truth semantics, sequence antecedents, the not-overlap complement pattern, and how matching the operator to the spec's exact wording is the discipline that separates real bug catches from false-pass assertions.
- 50Repetition OperatorsThe three SVA repetition operators — consecutive, non-consecutive, and goto — and their range forms. The semantic distinctions, how each operator encodes a different spec rule, and the discipline that picks the right operator for burst protocols, retry sequences, and fault-recovery contracts.
- 51assert, assume, cover, restrictThe four SVA constructs that turn properties into verification evidence. assert catches violations; cover measures exercise; assume constrains formal inputs; restrict scopes formal proof search. Simulation vs formal semantics, the assert+cover pairing pattern, and why getting the construct wrong is one of the most expensive verification mistakes.
- 52Assertion Severity & Action BlocksThe four severity system tasks — $fatal, $error, $warning, $info — and the action-block syntax that runs them. How severity choice shapes regression behaviour, the pass-action vs fail-action distinction, custom message formatting, and why matching severity to spec criticality is one of the most consequential SVA-discipline decisions.
- 53Assertion Control System TasksThe three runtime assertion-control tasks — $assertoff, $asserton, $assertkill — that enable selective disabling and re-enabling of assertions during reset, scan, low-power, and debug phases. Hierarchical scoping rules, the difference between off and kill, and the production patterns that let one assertion file serve multiple verification modes without code duplication.
Inter-Process Communication
4 lessons- 54Introduction to Inter-Process CommunicationWhy IPC exists in concurrent SystemVerilog testbenches — the three mechanisms (events, semaphores, mailboxes), where each one fits, the IEEE 1800-2017 scheduling-region rules that govern them, and the canonical bugs (missed-trigger race, cross-locked semaphores, handle aliasing, unbounded mailboxes) every verification engineer ships at least once.
- 55EventsSystemVerilog events — declaring with event, triggering with -> (Active region) and ->> (NBA region), waiting with @ and wait(triggered), the same-time-step race that hides the single most common event bug, broadcast semantics, passing events by ref, barrier and phase patterns, and the failure modes every verification engineer ships at least once.
- 56SemaphoresSystemVerilog semaphores — the counting concurrency primitive. Binary semaphore as a mutex; counting semaphore as a credit pool; get / put / try_get semantics; atomic multi-key acquisition; deadlock causes and four prevention strategies; the leaked-put bug; AXI / DDR / DMA real-world patterns; and the failure modes every verification engineer ships at least once.
- 57MailboxesSystemVerilog mailboxes — the typed FIFO that decouples producer from consumer. Bounded vs unbounded back-pressure, typed vs untyped type safety, put / get / peek / try_* / num semantics, the canonical generator → driver → monitor → scoreboard pipeline, mailbox-in-a-class wiring, the handle-aliasing bug every shop ships at least once, and the UVM TLM-FIFO connection.
Process Control
5 lessons- 58fork-joinSystemVerilog fork-join — the fundamental concurrency primitive. Spawn N parallel threads, block the parent until every thread completes, master the loop-variable capture bug, use automatic tasks safely from concurrent calls, nest forks for hierarchical parallelism, and ship multi-channel testbenches that scale.
- 59fork-join_anySystemVerilog fork-join_any — the variant where the parent resumes when any one thread finishes. The basis for the canonical timeout pattern, watchdog timers, first-responder races, and clock-plus-finite-init startup. The one rule juniors miss: surviving threads do not stop automatically — disable fork.
- 60fork-join_noneSystemVerilog fork-join_none — the variant where the parent does not block at all. The basis for daemon threads (clocks, monitors, coverage samplers), loop-spawned N-channel agents, the canonical fork-join_none + wait fork pattern for variable N, and the $finish race that silently kills the last few transactions.
- 61disable fork & wait forkSystemVerilog disable fork and wait fork — the lifecycle controls for background threads. disable fork kills; wait fork waits; both operate on a process scope, not on a specific thread. The scope-isolation discipline (wrap forks in tasks) is what separates engineers who use these correctly from those who silently kill monitors.
- 62The process ClassSystemVerilog process class — the precision counterpart to disable fork. Get a handle via process::self(), then kill / suspend / resume / await an exact thread by reference. Five states (RUNNING, WAITING, SUSPENDED, KILLED, FINISHED), six methods, and the canonical agent-with-handle-control pattern.
Completion: work through all 6 required modules (62 lessons) to develop the 5 competencies above. Reading is the medium — there is nothing to enrol in or unlock.
Assessment
PlannedHow understanding in this program would be checked. Assessment measures engineering reasoning against the competencies above — it is not part of the reading, and there is nothing to start or score here.
SystemVerilog for Verification — mastery assessment
Reasoning challengeA reasoning-first assessment across object-oriented testbench programming, constrained-random stimulus, functional coverage, assertions, and testbench concurrency.
Per-module knowledge checks
- Object-Oriented Programming
- Constrained Random Verification
- Functional Coverage
- SystemVerilog Assertions
- Inter-Process Communication
- Process Control