SystemVerilog for Verification: Comprehensive Study Guide

VERIFICATION GUIDELINES

Introduction to SystemVerilog for Verification

  • Goal of Verification: To ensure a design matches its specification. Bugs are defined as discrepancies between the device's behavior and the documentation.
  • Hardware Verification Language (HVL) Features:
    • Constrained-random stimulus generation (CRSGCRSG).
    • Functional coverage to measure progress.
    • Object-Oriented Programming (OOPOOP) for higher abstraction.
    • Multi-threading and interprocess communication (IPCIPC).
    • Tight integration with event-simulators.

The Verification Process and Plan

  • Levels of Verification:
    • Block Level: Focuses on individual modules and sub-components.
    • Integration Level: Focuses on interfaces and interactions between blocks.
    • System Level: Full Design Under Test (DUTDUT) executing concurrent operations.
  • Verification Plan: A document derived from the hardware specification detailing features to exercise and techniques (random testing, assertions, formal proofs) to be used.

Methodology: Directed vs. Constrained-Random Testing

  • Directed Testing: Incremental, manual creation of specific stimulus vectors. Pros: predictable progress early on. Cons: scales linearly with complexity (O(n)O(n)) and misses unanticipated bugs.
  • Constrained-Random Testing (CRTCRT): Automated generation of stimulus within defined constraints.
    • Uses a Layered Testbench architecture.
    • Functional Coverage acts as the feedback loop to identify "holes" in the testing space.
    • Randomizing configuration, data, protocol exceptions, and delays creates high-pressure scenarios for the control logic.

Layered Testbench Structure

  1. Signal Layer: The physical wires and pin-level connections to the DUTDUT.
  2. Command Layer: Drivers and monitors that translate signals into discrete commands (e.g., Read, Write).
  3. Functional Layer: Agents and transactors that manage higher-level transactions (e.g., a DMA transfer) and include scoreboards/checkers.
  4. Scenario Layer: Generators that orchestrate complex sequences of transactions.
  5. Test Layer: The highest level containing specific constraints and coverage goals.

DATA TYPES

Built-in and Logic Types

  • logic: A 4-state type (0, 1, X, Z) that replaces Verilog’s reg and wire (except for multi-driver nets).
  • 2-state Types: Optimized for performance and memory.
    • bit: Unsigned.
    • byte, shortint, int, longint: Signed.
  • $isunknown(expression): Returns 1 if any bit is X or Z.

Arrays and Storage

  • Fixed-Size Arrays:
    • Unpacked: int array[8][4]; (Contiguous logic, fragmented memory storage).
    • Packed: bit [3:0][7:0] bytes; (Stored as a single contiguous bit-vector).
  • Dynamic Arrays: Declared with []. Space allocated at runtime via new[size]. Usage: dyn = new[20](dyn); (to resize and copy).
  • Queues: Declared with [$]. Support efficient insertion/deletion at any position.
    • Methods: push_front(), pop_back(), insert(index, val).
  • Associative Arrays: Sparse storage declared with [*]. Ideal for large, non-contiguous memory modeling.
  • Array Methods:
    • Reduction: .sum, .product, .and, .or, .xor.
    • Locator: .find, .find_index, .min, .max, .unique.

User-Defined Types and Strings

  • typedef: Creates new type aliases (e.g., typedef bit [31:0] uint;).
  • struct: Groups multiple variables.
  • enum: Strong variable types with named constants. Methods: .first, .last, .next, .prev, .name.
  • Strings: Dynamic length. Methods: $psprintf (returns formatted string), .getc(N), .toupper().

PROCEDURAL STATEMENTS AND ROUTINES

Control Flow and Tasks/Functions

  • Operators: Implementation of ++, --, +=, -=, *=, /=.
  • Loops: break to exit, continue to skip iteration. do...while support.
  • Functions: Can return void. Cannot consume time.
  • Tasks: Can consume time.

Routine Arguments

  • Direction: input, output, inout, and ref.
  • Pass-by-Reference (ref): Allows routines to modify original variables without copying. Required for arrays and large objects for performance.
  • const ref: Pass by reference but prevent modification.
  • Default values: task t(int a=0); allows calling without parameters.

Storage and Timing

  • Automatic Storage: Required for recursive routines and re-entrant tasks. Declared using the automatic keyword in program or module headers.
  • Time Units: timeunit 1ns; timeprecision 1ps; replaces ambiguous \timescale`.

BASIC OBJECT-ORIENTED PROGRAMMING (OOP)

Classes and Objects

  • Class: The blueprint/template containing data and methods.
  • Object: An instance of a class.
  • Handle: A pointer/reference to an object. Initialized to null.
  • Constructor: The new() function. Allocates memory and initializes variables. Can be customized with arguments.

Static Variables and Methods

  • Static Variables: Shared across all instances of a class (e.g., a packet counter).
  • Static Methods: Can be called without an object instance (only access static members).

Scoping and Memory

  • this: Resolves ambiguity between class properties and local variables.
  • Garbage Collection: SystemVerilog automatically deallocates objects when no handles point to them.
  • Shallow Copy: dst = new src; copies properties but not nested objects.
  • Deep Copy: A custom method must be written to recursively copy nested object instances.

CONNECTING THE TESTBENCH AND DESIGN

The Interface Construct

  • Definition: Bundles signals into a single named entity to simplify top-level connectivity.
  • modport: Defines signal directions for specific components (e.g., DUT vs TEST).
  • Virtual Interface: A reference/pointer to an interface instance. Essential for use within classes to access physical design signals.

The Program Block

  • Function: Houses testbench code.
  • Scheduling: Executes in the Reactive region of the SystemVerilog Scheduler to eliminate race conditions with the design (which runs in the Active region).
  • Implicit $exit: Simulation terminates when all initial blocks in all program blocks finish.

Clocking Blocks

  • Purpose: Synchronizes design signals with a clock.
  • Skew: Defines when to sample (input) and drive (output). Default: Input sampled at 1step (before clock edge), Output driven at 0 (at clock edge).
  • Syntax: ##n (cycle delay).

RANDOMIZATION

Constrained Randomization

  • rand/randc: Member variables for randomization. randc (Random-Cyclic) ensures no repeats until all values are used.
  • Constraints: Declarative blocks that limit variable values.
    • inside {range}: Set membership.
    • dist {val := weight, [r1:r2] :/ weight}: Weighted distributions.
    • -> (Implication) and if-else: Conditional constraints.
  • solve…before: Forces the solver to prioritize the distribution of one variable to influence another in implication constraints.

Randomization Methods

  • obj.randomize(): Attempts to solve all constraints. Returns 1 for success, 0 for failure.
  • obj.randomize() with {extra_constraints}: Inline constraints that exist for a single call.
  • prerandomize() / postrandomize(): Built-in callbacks to perform calculations before/after the solver runs.
  • rand_mode(1/0): Enable/disable randomization for specific variables.
  • constraint_mode(1/0): Enable/disable specific constraint blocks.

THREADS AND IPC

Fork-Join Variants

  • fork…join: Waits for all spawned threads to finish.
  • fork…join_any: Waits for the first spawned thread to finish; others continue.
  • fork…join_none: Parent thread continues immediately after spawning.

Interprocess Communication (IPC)

  • Events: Edge-triggered synchronization via -> and @ (or wait(e.triggered)).
  • Semaphores: Used for resource control (mutex). Methods: get(keys), put(keys), try_get(keys).
  • Mailboxes: Synchronous FIFOs for passing data (handles) between transactors.
    • Methods: put(), get(), peek(), try_get(), num().
    • Bounded mailboxes cause the producer to block if full.

ADVANCED OOP AND FUNCTIONAL COVERAGE

Inheritance and Polymorphism

  • extends: Defines a subclass that inherits from a base class.
  • virtual methods: Ensures the correct method is called based on the object type, not the handle type (Polymorphism).
  • super: Calls methods from the parent class.
  • $cast(handle, source): Dynamic type casting for down-casting from base to extended handles.

Callbacks

  • Mechanism: Empty virtual methods in a transactor that are called at specific execution points.
  • Application: Allows users to inject functional coverage, scoreboarding, or error injection into a generic transactor without modifying its source code.

Functional Coverage

  • covergroup: A container for coverage measurement.
  • coverpoint: Tracks specific variables or expressions.
  • bins: Segments of the value range for a coverpoint.
    • bins b[] = {[0:7]}; individual bins.
    • ignore_bins, illegal_bins.
  • cross: Measures the Cartesian product/correlation of multiple coverpoints.
  • Triggering: Can be explicit via .sample() or event-based using a clocking block or assertion.