Class

In SystemVerilog, classes offer a way to structure your code based on the principles of Object-Oriented Programming (OOP). If you're new to this idea, think of a class as a blueprint for creating objects. These objects are instances of the class, each carrying their own set of data and behaviors defined by the class.

What is a Class?

A class in SystemVerilog is a type of user-defined data type. Just like how you can have integer or string data types, a class lets you create your own complex data type with a mixture of variables and methods (tasks and functions).

For example, let's say we want to represent a Car. We can create a Car class, where each Car object can have its own color and speed. We can also define methods like set_color and set_speed.

class Car;
    // These are called "data members"
    string color;
    integer speed;

    // These are called "methods"
    function void set_color(string c);
        color = c;
    endfunction

    task set_speed(integer s);
        speed = s;
    endtask
endclass

Creating Objects

Once you have a class, you can create "objects" or "instances" of that class. Think of it like producing cars from a blueprint. Each car (object) is an instance of the Car class.

To create an object, you use the new keyword.

Car myCar = new;

Now myCar is an instance of Car, and it has its own color and speed.

Using Objects

Now that we have a Car object, we can use the methods we defined to set its color and speed.

myCar.set_color("Red");
myCar.set_speed(60);

Class Constructors

A "constructor" is a special method in a class. It's called automatically when you create a new object. Its main use is to initialize data members of the class. In SystemVerilog, the constructor has the same name as the class.

class Car;
    string color;
    integer speed;

    // This is a constructor
    function new(string c, integer s);
        color = c;
        speed = s;
    endfunction
endclass

Car myCar = new("Red", 60);

Inheritance

"Inheritance" is a key concept in OOP that lets you create a new class based on an existing class. The new class "inherits" all the data members and methods of the existing class, and you can add more if you want.

class ElectricCar extends Car;
    integer battery_capacity;

    function new(string c, integer s, integer b);
        super.new(c, s);  // Call the constructor of the base class
        battery_capacity = b;
    endfunction
endclass

In this example, ElectricCar is a subclass of Car (meaning it's based on Car). It inherits color and speed, and adds a new data member battery_capacity.

Using classes in SystemVerilog allows you to organize your code in a way that's modular (broken into parts) and scalable (easy to expand). This can be very useful when you're building complex testbenches for verification. But remember, classes are generally not used in actual hardware design, they are primarily a tool for verification.

A virtual class in SystemVerilog, also known as an abstract class in some other languages, is a class that cannot be instantiated. It can only serve as a base class for other classes. Abstract classes are typically used to represent high-level, abstract concepts that should be implemented in more detail by derived classes.

A virtual class is declared by using the keyword virtual before the class keyword:

virtual class Vehicle;
  string color;
  
  // Abstract method
  pure virtual function void set_color(string c);
endclass

The Vehicle class can't be instantiated because it's a virtual class. Its purpose is to define a common interface for all types of vehicles. The set_color method is declared as pure virtual, which means it doesn't have a body in the Vehicle class and must be implemented in any non-virtual subclass.

Now, let's create a Car class that extends Vehicle and implements the set_color method:

class Car extends Vehicle;
  function void set_color(string c);
    color = c;
  endfunction
endclass

The Car class is a non-virtual subclass of Vehicle, and it provides an implementation for the set_color method. This makes Car a fully implementable class, and you can create instances of Car.

Virtual classes and methods play a crucial role in creating flexible and reusable code structures, especially when it comes to building complex testbenches. They allow us to create high-level templates for what a class should look like, leaving the detailed implementation to the specific derived classes.

Please note, pure virtual methods create an abstract class, and these are not synthesizable, which means they are typically used in the testbench environment for creating flexible verification architectures.

Have a Question?

Feel free to ask your question in the comments below.

Please Login to ask a question.

Login Now