# SV Part-4 OOPs

programming will be done in two ways in system Verilog

* **module level programming**
    
* **object oriented programming**
    

| module level programming | object oriented programming |
| --- | --- |
| programming will be done by using module | programming will be done by using objects |
| in module signal to signal communication will be happened | in oops transaction level communication will be happened |

### **module**:

* module is a reusable hardware block type.
    
* module is a static in nature.
    
* memory allocation at compile time
    
* module consists
    
    ```verilog
    module module_name;
       ports;
       builtin gates;
       continous assisgnments;
       procedural blocks;
         procedural statements
           conditional statements
           //if,else,els if
           case statements
           //case,casez,casex
           blocking and non blocking statements
           fork join
           delays
           system task and function
    endmodule
    ```
    

**terminology:**

* **instance:(copy)**
    
    ***Static***: Module instances are created at compile time (during elaboration) and remain fixed throughout the simulation.
    
    Each instance has its own memory for non-static variables (e.g., reg, wire) unless explicitly shared (e.g., via static or external references).
    
    ***Dynamic***:
    
    for dynamic things if we create an instance, it will just create an imaginary reference, so we need to create the memory for that imaginary reference using **new()**
    
* **instantiation:**
    
    instance of module
    

### **class:**

* class is a user defined data type
    
* class is a dynamic in nature, so we need to allocate the memory during run time.
    
* for allocating the memory for the class we need to consider new constructor.
    
* class consists of properties, methods, and constraints.
    
    class consists
    
    ```verilog
    class class_name;
       properties
       methods
       constraints
    endclass
    ```
    

**terminology:**

* **instance:(copy)**
    
    ***Static***: Module instances are created at compile time and remain fixed throughout the simulation.
    
    Each instance has its own memory for non-static variables (e.g., reg, wire) unless explicitly shared (e.g., via static or external references).
    
    ***Dynamic***:
    
    for dynamic things if we create an instance, it will just create an imaginary reference, so we need to create the memory for that imaginary reference using **new()**
    
* **object**:
    
    it is an instance of the class
    

### **module and class**

* **Purpose**:
    
    * **Module**: Models hardware (e.g., gates, counters). For RTL design.
        
    * **Class**: Models data/transactions for verification (e.g., packets in testbenches).
        
* **Instantiation**:
    
    * **Module**: Static (fixed at compile time), like inst\_name dut();.
        
    * **Class**: Dynamic (runtime with new()), objects can be created/deleted.
        
* **Synthesizable?**:
    
    * **Module**: Yes (becomes real hardware).
        
    * **Class**: No (simulation only).
        
* **Features**:
    
    * **Module**: Ports, always/initial blocks, no inheritance/randomization.
        
    * **Class**: OOP (inheritance, polymorphism), rand variables, constraints, static members.
        
* **Lifetime**:
    
    * **Module**: Entire simulation.
        
    * **Class**: Object-specific, dynamic.
        

## **Properties**

### **static methods and static properties**

1. static methods & properties point to a common memory for all objects of a class.
    
2. memory for static methods & properties is allocated with the class defination
    
    * There is no need to create object to access static methods and properties.
        
        example: \[[click me](https://edaplayground.com/x/iLYG)\]
        
        **note**: static method is implemented with the class definition, we don’t need to create an object to access this method. we can run static method directly on class name. using scope resolution operator(::).
        
        ```verilog
        module tb;
          eth_common::testname;
          eth_common::count;
          eth_common::mbox;
        endmodule
        ```
        
        **above 3 shared variables can be accessed anywhere in the TB.**
        
        **By using static variables, TB development gets easier.**
        
3. methods and properties in a class are automatic by default
    
    * user need to explicitly declare static.
        

### class properties:

class consists of

* properties
    
* methods
    
* constraints
    

1. **class properties**
    
    * [object properties:](https://edaplayground.com/x/CGWS)
        
        the properties which are involved with the object is known as object properties.
        
        ex: object.propertie1, object.propertie2……
        
    * [non- object properties:](https://edaplayground.com/x/JD5g)
        
        the properties which are not involved in the object is known as non-object properties.
        
        ex: static int a, static int b
        
2. **methods**
    
    * In System Verilog methods can be classified into two types.
        
        1. **pre\_defined method**
            
            the methods which are pre-implemented in the class.
            
            * **new**
                
                new is a constructor
                
                new method is used for allocating the memory for the dynamic things.
                
                by default new method is existed in every sv file.
                
                new method can be used in 4 ways
                
                * [empty new method](https://edaplayground.com/x/MWDu)
                    
                * [new method with values](https://edaplayground.com/x/tGS7)
                    
                * [new method with arguments](https://edaplayground.com/x/aQv_)
                    
                * [new method with default arguments](https://edaplayground.com/x/aQvh)
                    
            * **randomize**
                
                * it is used for generating the random values from the variables which are mentioned with **rand** or **randc**
                    
                * randomize method is a call back, if we call randomize method, first it will call pre\_randomize method next randomize and post\_randomize
                    
                    in randomization we have 2 modes
                    
                    1. [rand\_mode](https://edaplayground.com/x/Gcw6)(0 or 1);
                        
                        syntax: &lt;property\_name&gt;.rand\_mode(0 or 1);
                        
                        0 means disable randomization and 1 means enable the randomization.
                        
            * [**pre\_randomize**](https://edaplayground.com/x/kTcr) :if we call randomize method, first it will call pre\_randomize method
                
            * [**post\_randomize**](https://edaplayground.com/x/V3qy) **:** after randomization it will call the post randomization and it is the final
                
        2. **user\_defined method**
            
            the methods which are implemented by the user.
            
            * [print](https://edaplayground.com/x/B_qU)
                
            * [copy](https://edaplayground.com/x/eX4b)
                
            * [compare](https://edaplayground.com/x/cXBN)
                
            * [pack](https://edaplayground.com/x/sTvN)
                
            * [unpack](https://edaplayground.com/x/VTck)
                

[inheritance](https://edaplayground.com/x/KSQH) : creating a new class (child) from an existing class (parent) and reusing its variables & functions.

* Parent class - base features
    
* Child class - gets all features + can add its own
    

[encapsulation](https://edaplayground.com/x/tuWR) : Encapsulation means hiding the internal data of a class and allowing access only through functions.

Using access specifiers:

* `local` – only inside class
    
* `protected` – inside class + child class
    
* `public` – accessible anywhere
    

[polymorphism](https://edaplayground.com/x/TYhA) : changing the object at run time.

one parent handle can point to different child objects, and the correct child’s function runs.

## **abstraction class**

**Purpose**:

* Abstract classes serve as templates or blueprints for derived classes.
    
* They are used to define common interfaces, methods, or properties that derived classes must implement or inherit.
    
* They promote code reuse and modularity in verification environments.
    

[click for abstraction class example](https://edaplayground.com/x/aaFT)

> if we mentioned virtual keyword infront of the class is known as abstract class
> 
> oops does not allow to create memory for the abstract class.
> 
> by using inheritence we can create a child class to that abstract class. through that child class we can access the abstract class properties, methods and constraints
> 
> in abstract class we can consider the empty methods

note:

* **virtual methods** means, we use `virtual` to let the **child’s version of a function** run **through the parent handle**.
    
* **Pure virtual method:**  
    A pure virtual method in System Verilog is a function or task declared in a parent class **without any definition**, which **must be implemented by the child class**.
    

## Interface class

[click for interface class example](https://edaplayground.com/x/8_rg)

> it is almost similar to abstract class
> 
> if we maintain interface keyword infront of the class is known as interface class.
> 
> oops does not support interface class so we can’t create the child class by assign extends keyword
> 
> for creating the child class we need to consider “Implements“ keyword.

| in abstract class we can write virtual methods, pure virtual methods or normal methods. | in interface class we can write only pure virtual methods. |
| --- | --- |
| in abstract class whatever the methods we consider if we want we can consider in the child class or else we can ignore those methods | in interface class whatever the methods we consider those methods should be consider in implements class |

### sv parameterized class

A **parameterized class** in System Verilog allows you to create a **generic class** whose behavior or data types can be customized **by passing parameters** either **values** or **types** at instantiation time.

**Why Use Parameterized Classes?**

1. You want **reusable code** (e.g., same class works for `int`, `bit[7:0]`, or custom `packet` type).
    
2. You want to **change widths or data types dynamically**.
    
3. You want to **avoid rewriting the same class** for different data sizes or data types.
    
4. You want **generic utilities**, e.g., queues, FIFOs, scoreboards, etc.
    

**1.value parameterized class**

syntax: parameter int &lt;name&gt;= &lt;value&gt; [example](https://edaplayground.com/x/BTXD)

**2.type parameterized class**

syntax: parameter type &lt;name&gt; = &lt;data type&gt; [example](https://edaplayground.com/x/Fwzc)

| Type | Keyword | Example | Use Case |
| --- | --- | --- | --- |
| [Value parameter](https://edaplayground.com/x/BTXD) | `parameter` | `#(parameter int WIDTH=8)` | Change numeric constants (e.g., width, depth) |
| [Type parameter](https://edaplayground.com/x/Fwzc) | `type` | `#(type T=int)` | Change data type (e.g., `int`, `bit[7:0]`, custom struct) |

### *practice makes men/women perfect*

| [fifo using parameterized class](https://edaplayground.com/x/gMBs) |
| --- |
| [lifo using parameterized class](https://edaplayground.com/x/YnHT) |

**Types of parameterized class**

1. [non parameterized parent and parameterized child class.](https://www.edaplayground.com/x/abpQ)
    
2. [parameterized parent and non paramterized child class.](https://www.edaplayground.com/x/sUcu)
    
3. [non paramerized parent and non parameterized child class.](https://www.edaplayground.com/x/mF5M)
    
4. [parameterized parent and parametrized child class.](https://www.edaplayground.com/x/XgXG)
    

### **extern keyword**

The [extern keyword](https://edaplayground.com/x/QxQX) in System Verilog is used to declare a method (function or task) in a class without providing its implementation in the class body. The actual implementation is defined outside the class, typically with a scope resolution operator (::). This is useful for organizing code, improving readability, or separating method declarations from their definitions.

**When to Use**

* When the method body is complex and would clutter the class definition.
    
* In large projects to improve maintainability.
    

### Interface

it is a System Verilog construct, which is used to connect the class and module.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1760706868771/c145d921-b1dc-46e8-a5fc-e911d0a10786.jpeg align="center")

* interface is almost similar to module.
    
* The interface is static in nature. Like a module, if we create an instance of the interface, memory allocation will happen automatically.
    

```verilog
interface <interface_name> (input port list name);
  //signals name
  //clocking blocks
  // assertions
endinterface
```

Similarities with module:

* in interface we can consider port list like module.
    
* In an interface, we can use initial blocks, tasks, functions, and declare ports.
    

**Differences with module:**

* we can consider only input port list in the interface
    
* we can pass interface as port to the other module or an argument to the task and function which is not possible with the module. like through virtual
    
    * Physical interface
        
        * interface which having the the physical appearance is known as physical interface.
            
        * we don’t need to allocate memory for the physical interface.
            
    * Virtual interface (virtual keyword)
        
        * interface which does not have the physical appearance is known as virtual interface.
            
        * we need to point or assign physical interface memory for the virtual interface memory.
            
        * virtual interface having the capability of accessing the physical interface memory.
            

// data driving from bfm to dut through interface is happend aut

omatically, so some sampling issues will be happend while driving the data. to avoid that sampling issue we need to consider clocking blocks.

### clocking blocks

* it is a system verilog construct used in interface
    
* clocking are used to avoid the sampling issues happend while driving the data from bfm to dut through interface.
    
* **skew**
    
    * skew is used to delay the data.
        
        1. input skew : it tells about that at what time we need to sample the data before posedge clk.
            
        2. output skew : it tells about that at what time we need to sample the data after posedge clk.
            

```verilog
clocking <clocking_block_name> <clocking_event>
  default input #<delay> output #<delay>
  input signal1;
  input signal2;
  .......
  output signal1;
  output signal2;
  .......
endclocking
```

### object copying

1. [copy by handle](https://edaplayground.com/x/VmbV)
    
2. [shallow copy](https://edaplayground.com/x/bmFB)
    
3. [deep copy](https://edaplayground.com/x/Se64)
    
4. [by using casting](https://edaplayground.com/x/pN8X)
    

1.static casting or type casting(I have already discussed this in the random strings topic. refer SV Part-1 Basics)

2.[dynamic casting](https://edaplayground.com/x/7nuz)

\--&gt; it is used for copying the object data into another object.

\--&gt; it will work like copy by handle

\--&gt; syntax: $cast(&lt;destionation\_object&gt;,&lt;source\_object&gt;);

casting can be possible whenever the object will be same class or else both the objects having parent and child relation.

| destination\_object | source\_object | possible or not |
| --- | --- | --- |
| parent\_object1 | parent\_object2 | yes |
| child\_object | parent\_object | No |
| child\_objec1 | child\_object | yes |
| parent\_object | child\_object | yes |
