Login or Signup
You must be logged in to perform this action.
Track your Progress
Login and use one of the options listed below.
Click the roadmap topics and use Update Progress dropdown to update your progress.
Use the keyboard shortcuts listed below.
- Right Mouse Click to mark as Done.
- Shift + Click to mark as in progress.
- Option / Alt + Click to mark as skipped.
Design Verification (DV)
Verify chip functionality: UVM testbenches, coverage-driven verification, formal methods, and debugging.
SEARCHABLE ROADMAP INDEX
Topics in this roadmap
Open any concept as a complete, shareable learning page with its own URL and related-topic navigation.- Architecture The Universal Verification Methodology (UVM) defines a standardized class library and architectural pattern for building reusable, layered testbenches in SystemVerilog. The canonical UVM testbench structure consists of a uvm_test at the top, which configures and instantiates a uvm_env (environment), which in turn contains one or more uvm_agent s — one per DUT interface. Each agent bundles a uvm_sequencer (which arbitrates and forwards sequence items), a uvm_driver (which converts transactions into pin-level activity on a virtual interface), and a uvm_monitor (which passively observes the interface and reconstructs transactions for coverage and checking). Agents can be configured as active (driving stimulus) or passive (monitor-only).
- Assertions SystemVerilog Assertions (SVA) provide a concise, formal way to specify temporal properties of design behavior directly in the RTL or bind files, and they are checked continuously throughout simulation rather than only at the end of a test. An immediate assertion checks a condition combinationally at the point it's evaluated (similar to a procedural if with an error message), while a concurrent assertion ( property / sequence constructs evaluated with assert property ) checks temporal relationships across clock cycles — for example, "if req is asserted, then ack must be asserted within 4 cycles" or "once valid goes high, data must remain stable until ready ."
- Bugs Understanding how bugs originate and propagate is fundamental to designing effective verification strategies. RTL bugs broadly fall into a few categories: functional logic errors (wrong Boolean expression, incorrect state machine transition, off-by-one in a counter or address decode), interface/protocol violations (incorrect handshake timing, missing back-pressure handling, violating bus protocol ordering rules), clock-domain crossing (CDC) issues (metastability, data corruption when signals cross asynchronous boundaries without proper synchronization), reset issues (incomplete reset of state, X-propagation from uninitialized registers), and corner cases (FIFO full/empty, counter wraparound, arithmetic overflow/underflow).
- Coverage Functional coverage answers the question that code coverage cannot: has the design actually been exercised in the scenarios the specification cares about, not just which lines of RTL executed. SystemVerilog covergroup / coverpoint / bins constructs let you define exactly what to measure — for example, a coverpoint on a transaction's opcode field with explicit bins for each instruction type, or a cross between opcode and a "queue full" flag to confirm every instruction type has been tried while the queue was full. Coverage is sampled (often via sample() calls triggered by a clocking event) and aggregated across all tests in a regression into a merged coverage database.
- Emulation Hardware emulation maps a design's RTL onto an array of FPGAs or custom emulation processors (platforms such as Cadence Palladium, Synopsys ZeBu, or Siemens Veloce) to run at speeds orders of magnitude faster than software simulation — typically in the range of hundreds of kHz to a few MHz, versus simulation's tens or hundreds of Hz for large SoCs. This speed makes emulation the practical choice for running workloads that are simply too long for simulation: booting an operating system, running real firmware and device drivers, executing graphics or video codec test content, or running millions of cycles of traffic needed to hit rare corner-case interactions in a large SoC.
- Formal Formal verification uses mathematical techniques — model checking and theorem proving — to exhaustively prove or disprove properties about a design, rather than relying on simulation vectors. The two formal flows most relevant to DV are property checking (also called formal model checking) and equivalence checking. In property checking, SVA assertions written as property / assert statements are fed into a formal tool (e.g., Cadence JasperGold, Synopsys VC Formal, Siemens Questa Formal), which explores the design's entire reachable state space using techniques like BDDs, SAT/SMT solving, and bounded model checking to either prove the property holds for all possible inputs and states, or generate a concrete counterexample waveform showing exactly how it can be violated.
- Gate Sims Gate-level simulation (GLS) runs the testbench against the post-synthesis (or post-layout) netlist instead of the RTL, using the actual standard-cell library models and back-annotated timing delays (from SDF — Standard Delay Format — files) rather than the zero-delay or unit-delay behavior of RTL simulation. The primary purposes are to verify that synthesis, scan insertion (for DFT), clock-tree insertion, and any ECOs did not change functional behavior, and to check that the design works correctly with realistic gate and wire delays — catching issues that RTL simulation, with its idealized timing, cannot see.
- Mindset Design verification requires a fundamentally different mindset from RTL design. Where a designer asks "how do I build this to work correctly," a verification engineer asks "how could this fail, and how do I prove it doesn't." This adversarial, proof-by-exhaustion mentality drives every decision in a verification flow. A good DV engineer assumes the design under test (DUT) is guilty until proven innocent through evidence — simulation logs, coverage reports, and assertion results.
- OOP SystemVerilog testbenches rely heavily on object-oriented programming (OOP), and this is one of the biggest conceptual jumps for engineers coming from RTL-only Verilog. Classes encapsulate data and behavior — a transaction class might hold address, data, and control fields plus a display() method, while a driver class holds a virtual interface handle and a run_phase() task. Understanding class declarations , constructors ( new() ), member variables , and methods is the entry point, but the real power comes from inheritance and polymorphism : a base bus_transaction class can be extended into read_transaction and write_transaction subclasses, and a driver written to operate on the base class handle will correctly dispatch to overridden methods on derived objects at run time.
- Perf DV Performance verification focuses on confirming that a design meets its quantitative throughput, latency, and bandwidth targets under realistic and worst-case traffic conditions — a different goal from functional correctness verification, which only asks whether the result is correct, not how fast it was produced. This is especially important for components like caches, memory controllers, NoC (network-on-chip) fabrics, and DMA engines, where the architectural spec often includes explicit numeric targets (e.g., "sustain 90% of peak DRAM bandwidth under streaming access patterns" or "average read latency under 50 cycles at 80% queue occupancy").
- Random Constrained-random verification (CRV) is the core technique that lets SystemVerilog testbenches explore far more of a design's state space than directed tests ever could. Instead of hand-writing every stimulus sequence, you define rand and randc class member variables and apply constraint blocks that restrict legal values — for example, constraining an address field to stay within a memory's valid range while still randomizing across that entire range, or weighting transaction types with dist so that error cases occur with realistic but non-zero probability. Calling randomize() on an object then solves the constraints and produces a legal, pseudo-random transaction.
- Reg Layer The UVM register abstraction layer (RAL, often called UVM RegModel) provides a structured, object-oriented model of a design's memory-mapped register space, generated from an IP-XACT, SystemRDL, or IP-specific spreadsheet description. Each register is modeled as a uvm_reg object with fields ( uvm_reg_field ) that capture bit-level attributes — access type (RW, RO, W1C, etc.), reset value, and width — while uvm_reg_block and uvm_reg_map organize registers into address maps that mirror the DUT's register address decode. This gives test writers a software-like view: instead of poking raw addresses and hex values, you call my_reg_block.ctrl_reg.write(status, value) or .read(status, data) .
- Scoreboard The scoreboard is the component that gives a UVM testbench its self-checking capability: it receives transactions from monitors (via uvm_analysis_export / uvm_analysis_imp ports), compares actual DUT behavior against expected behavior, and reports mismatches. In its most common form, a scoreboard maintains a reference model — either a behavioral SystemVerilog model, a C/C++ model integrated via DPI, or a simpler algorithmic prediction — that computes the expected output for each input transaction. When the monitor reports an actual output transaction, the scoreboard compares it against the predicted value, typically using queues to handle out-of-order or pipelined responses.
- Sequences In UVM, stimulus generation is decoupled from stimulus delivery through the sequence/sequencer/driver mechanism. A uvm_sequence is a class whose body() task generates one or more uvm_sequence_item transactions and sends them to a uvm_sequencer via start_item() / finish_item() (or the shorthand \ uvm_do macros). The **sequencer** arbitrates between multiple sequences that may be running concurrently, and the **driver** pulls items from the sequencer ( get_next_item() / item_done()`) and converts each one into pin-level signal activity over one or more clock cycles.
- Simulation Simulation is the primary engine of functional verification: an event-driven simulator (such as Synopsys VCS, Cadence Xcelium, or Siemens Questa) executes a compiled model of the RTL design alongside the testbench, processing signal changes ("events") in time order and updating downstream logic accordingly. Understanding the event-driven simulation algorithm — the scheduling regions of the SystemVerilog stratified event queue (active, inactive, NBA, observed, reactive, postponed) — is essential for explaining why race conditions occur and why nonblocking assignments ( <= ) are used for sequential logic while blocking assignments ( = ) and always_comb are used for combinational logic.
- Testbench A testbench is the verification harness that drives stimulus into a design under test (DUT), monitors its responses, and checks correctness — all without being synthesized into actual hardware. At its simplest, a testbench instantiates the DUT, generates a clock and reset, applies input vectors, and observes outputs, typically using SystemVerilog running on an HDL simulator. Even the most basic directed testbench needs to handle timing correctly: driving signals on the correct clock edge, respecting setup/hold relationships at the interface, and avoiding race conditions between the testbench and the DUT (commonly addressed by driving on one clock edge and sampling on another).