top of page

8.8. Introduction to Polymorphism

​

Polymorphism is one of the most powerful features of Object-Oriented Programming. The word 'polymorphism' comes from Greek words meaning 'many forms'. In programming, it means that the same interface can be used to represent different underlying forms or data types.

​

Why Polymorphism Matters in VLSI Verification?

​

In VLSI verification, we deal with multiple protocols, transaction types, and verification components. Polymorphism allows us to:

​

  • Write generic code that works with different types of transactions

​

  • Create flexible testbenches that can handle multiple protocols

​

  • Build reusable verification IP (VIP) components

​

  • Implement design patterns like Strategy, Factory, and Observer

​

  • Reduce code duplication and improve maintainability

​

Real-World Analogy

​

Think of a TV remote control. The same 'Volume Up' button works differently for different TVs:

​

  • Sony TV: Increases volume using Sony's protocol

​

  • Samsung TV: Increases volume using Samsung's protocol

​

  • LG TV: Increases volume using LG's protocol

​

Same interface (the button), different implementations (each TV's protocol). This is polymorphism!

​

What is Polymorphism?

​

Polymorphism enables objects of different classes to be treated as objects of a common base class. The actual method that gets called is determined by the type of object being referenced, not the type of the reference variable.

​

Key Concept

​

Polymorphism allows you to:

​

  • Use a base class handle to point to derived class objects

​

  • Call methods on that handle

​

  • Have the correct derived class method execute automatically

Verilog

Output:​

​

Drawing a circle

Drawing a rectangle​​

Polymorphism Types.png

8.8.1. Types of Polymorphism

​

There are two main types of polymorphism in programming languages:​

8.8.1.1 Compile-Time Polymorphism (Static Polymorphism)

​

Compile-time polymorphism is resolved during compilation. The compiler knows exactly which function to call.

​

Examples include:

​

  • Function Overloading: Same function name, different parameters

​

  • Operator Overloading: Redefining operators for custom types

​

  • Template Specialization: Different implementations for different types

​

Note: SystemVerilog has LIMITED support for compile-time polymorphism. It does NOT support function overloading in the traditional sense.

​

8.8.1.2 Runtime Polymorphism (Dynamic Polymorphism)

​

Runtime polymorphism is resolved during program execution. The decision of which method to call is made at runtime based on the actual object type.

​

This is achieved through:

​

  • Virtual methods

​

  • Method overriding

​

  • Inheritance

​

SystemVerilog FULLY supports runtime polymorphism, which is what we focus on in verification.​​​​​

Static & Dynamic Binding.png

8.8.2. Static Binding vs Dynamic Binding

 

​Understanding the difference between static and dynamic binding is crucial for using polymorphism correctly.

8.8.2.1 Static Binding (Early Binding)

​

Static binding means the method to call is determined at COMPILE TIME based on the reference type.

​

Example: Without virtual keyword

Verilog

Output: Parent's display (This is NOT what we usually want!)

​

8.8.2.2 Dynamic Binding (Late Binding)

​

Dynamic binding means the method to call is determined at RUNTIME based on the actual object type.

​

Example: With virtual keyword

Verilog

Output: Child's display (This is what we want!)

​8.8.3. Virtual Methods in Depth

​

Virtual methods are the foundation of runtime polymorphism in SystemVerilog.

​

What Makes a Method Virtual?

​

A method becomes virtual when:

​

  • You add the 'virtual' keyword before the function/task declaration

​

  • It's declared in a base class

​

  • It enables dynamic binding for that method

​

How Virtual Methods Work?

​

Under the hood, virtual methods use a mechanism called the Virtual Table (vtable):

Virtual Deep.png

The Virtual Table Mechanism:

​

  • Each class with virtual methods has a vtable

​

  • The vtable contains pointers to the actual method implementations

​

  • Each object has a hidden pointer (vptr) to its class's vtable

​

  • When you call a virtual method, the call goes through the vtable

​

  • This allows the correct implementation to be called at runtime

​

Important Rules for Virtual Methods

​

  • The 'virtual' keyword appears ONLY in the base class declaration

​

  • Once a method is virtual, it remains virtual in ALL derived classes

​

  • You do NOT need to repeat 'virtual' in derived classes

​

  • Constructors CANNOT be virtual

​

  • Virtual methods have a slight performance overhead (usually negligible) 

​

Complete Example: Virtual Methods

Verilog

Casting in Polymorphism.png

8.8.4. Type Casting and Polymorphism

​

Type casting is the process of converting one data type to another. In polymorphism, we often need to cast between base and derived classes.

8.8.4.1 Upcasting (Implicit)

​

Upcasting is converting a derived class reference to a base class reference. This is ALWAYS SAFE and happens automatically.

Verilog

8.8.4.2 Downcasting (Explicit)

​

Downcasting is converting a base class reference to a derived class reference. This is RISKY and requires explicit casting with runtime checking.

Verilog

8.8.4.3 The $cast() Function

​

SystemVerilog provides $cast() for safe downcasting:

​

Returns 1 if cast is successful, 0 if it fails

​

Does runtime type checking

​

ALWAYS use $cast() for downcasting - never use direct assignment

​

8.8.4.4 Complete Example: Type Casting

Verilog

8.8.5. Real-World VLSI Verification Examples

​

Example 1: Multi-Protocol Driver

Verilog

Example 2: Scoreboard with Polymorphic Comparators

Verilog

Example 3: Factory Pattern

Verilog

8.8.6. Common Pitfalls and How to Avoid Them

​

Pitfall 1: Forgetting the 'virtual' Keyword

​

Problem: Without 'virtual', polymorphism doesn't work.

Verilog

Solution: Always use 'virtual' keyword for methods intended for polymorphism.

​

Pitfall 2: Trying to Instantiate Abstract Classes

Verilog

Solution: Only instantiate concrete classes that implement all pure virtual methods.

​

Pitfall 3: Not Implementing All Pure Virtual Methods

Verilog

Solution: Always use $cast() for downcasting.

​

Pitfall 5: Null Handle Dereferencing

Verilog

Solution: Use virtual keyword in base class for polymorphic behavior.​

8.8.7. Coding Guidelines and Best Practices

​​​

8.8.7.1. Virtual Method Guidelines

​

  • Always use 'virtual' for methods intended for overriding

​

  • Place 'virtual' only in base class, not in derived classes

​

  • Make destructors virtual if you have inheritance

​

  • Consider making all public methods virtual by default

​

8.8.7.2. Abstract Class Guidelines

​

  • Use pure virtual for methods that MUST be implemented

​

  • Use regular virtual for methods with default implementation

​

  • Name abstract classes clearly (e.g., BaseDriver, AbstractProtocol)

​

  • Document the contract in comments

​

  • Keep abstract classes focused on a single responsibility

​

8.8.7.3. Type Casting Guidelines

​

  • Always use $cast() for downcasting

​

  • Check the return value of $cast()

​

  • Avoid excessive casting - it indicates design issues

​

  • Prefer polymorphism over casting

​

8.8.7.4. Polymorphism Best Practices

​

  • Design base classes as interfaces or contracts

​

  • Keep base class interfaces stable

​

  • Use polymorphic collections (arrays/queues of base class)

​

  • Document polymorphic behavior clearly

​

  • Test polymorphic code with all derived class types

​

8.8.7.5. Naming Conventions

​

  • Abstract classes: Prefix with 'Abstract' or 'Base' or use descriptive names

​

  • Pure virtual methods: Use clear, action-oriented names

​

  • Derived classes: Use specific, descriptive names

​

  • Handles: Use descriptive names that indicate purpose

​

8.8.7.6. Code Organization

​

  • Group related classes in the same file or package

​

  • Place base/abstract classes before derived classes

​

  • Document inheritance relationships

​

  • Use packages to organize class hierarchies

Encapsulation

Virtual Interface

© Copyright 2025 VLSI Mentor. All Rights Reserved.©

Connect with us

  • Instagram
  • Facebook
  • Twitter
  • LinkedIn
  • YouTube
bottom of page