Back to Interview Prep

SystemVerilog Interview Questions - Part 1: OOP & Classes

May 16, 2026 HDL2Chips Team SystemVerilog

This part covers SystemVerilog OOP concepts including classes, inheritance, and polymorphism. These form the backbone of modern UVM-based verification.

Q1 What is the difference between logic and wire/reg in SystemVerilog?

logic is a 4-state type that replaces both wire and reg in most situations. It can be driven by continuous assignment, procedural blocks, or module outputs. Unlike wire, logic cannot have multiple drivers (for that, use wire or tri). Unlike reg, logic can be used on the left-hand side of assign statements and as a port direction type. This simplification removes the confusion between wire and reg that existed in Verilog.

Q2 How do you define a class in SystemVerilog?

A class is defined using the class keyword, followed by the class name and optional extends clause. Classes encapsulate data members and methods. Objects are created using new().

class Packet;
  rand bit [7:0] addr;
  rand bit [7:0] data;

  function new(bit [7:0] addr = 0);
    this.addr = addr;
  endfunction

  virtual function void display();
    $display("addr=%0h data=%0h", addr, data);
  endfunction
endclass
Q3 Explain the new() constructor in SystemVerilog.

new() is a special function that allocates memory for the object and initializes its members. It is called when an object is created: Packet p = new();. The constructor can take arguments to initialize the object with specific values. Classes can also have a new() that calls super.new() to invoke the parent class constructor. If no constructor is defined, a default new() with no arguments is implicitly created.

Q4 What is inheritance in SystemVerilog?

Inheritance allows a new class (derived/child) to extend an existing class (base/parent) using the extends keyword. The derived class inherits all members and methods of the base class and can add new members or override virtual methods. Inheritance enables code reuse and polymorphism.

class BadPacket extends Packet;
  constraint bad { addr inside {[8'hFF:8'hFF]}; }
  function void display();
    super.display();
    $display("bad packet");
  endfunction
endclass
Q5 How is polymorphism achieved in SystemVerilog?

Polymorphism is achieved through virtual methods and base-class handles pointing to derived-class objects. When a virtual method is called via a base-class handle, the actual method executed is determined at runtime based on the object type (dynamic dispatch). This allows writing generic code that works with any subclass.

Packet p;
BadPacket bp = new();
p = bp;
p.display();  // calls BadPacket's display() because it is virtual
Q6 What are virtual methods and why are they important?

Virtual methods (declared with the virtual keyword) enable dynamic dispatch: the method implementation called depends on the object's actual type, not the handle type. This is essential for polymorphism in OOP. If a method is not virtual, the base class version is always called even if the object is of a derived type. In UVM, virtually every method (like build_phase, connect_phase) is virtual to allow overriding.

Q7 Explain shallow copy vs deep copy in SystemVerilog.

Shallow copy copies the object handle but not the object itself. If you assign p2 = p1, both handles point to the same object. A deep copy creates a new object with copies of all member variables. SystemVerilog provides new() copy constructors and copy() methods for deep copies. For classes containing handles to other objects, deep copy must recursively copy those objects.

Packet p1 = new();
Packet p2 = new p1;  // deep copy via copy constructor
Q8 What are parameterized classes?

Parameterized classes allow the class to be defined with type or value parameters, similar to parameterized modules. This enables generic, reusable components.

class #(type T = int) Stack;
  T items[100];
  int top;

  function void push(T item);
    items[top++] = item;
  endfunction

  function T pop();
    return items[--top];
  endfunction
endclass

Stack#(bit [7:0]) byteStack;
Q9 What does the this keyword refer to?

this is a built-in handle that refers to the current object instance. It is used to disambiguate between class members and local variables or function arguments that share the same name. For example, this.addr = addr; assigns the argument addr to the class member addr. It is also used to call methods on the current instance.

Q10 Compare static and non-static class members.

Static members (static keyword) belong to the class itself rather than to any specific object instance. All objects share the same static variable. Static methods can only access static members. Non-static members are instance-specific: each object has its own copy. Static members are useful for shared counters, configuration, or factory registration. They can be accessed via the class name (Packet::count) or via an object handle.

Mastering OOP concepts is essential for SystemVerilog verification. Continue to Part 2 for randomization and coverage topics.