Why do uvm_*_port classes have its parent parameterized to uvm_tlm_if_base?

Hi ,

I see that uvm_*_port classes are declared as ::


class uvm_put_port #( type T = int ) extends uvm_port_base # ( uvm_tlm_if_base #(T,T) ) ;

What does it accomplish by passing a class ( parameterized one ) as a parameter ? .
I see that type T is used inside the classes .

By extending from uvm_port_base all its methods and properties would be available in uvm_*_port classes

Thanks in advance

In reply to Have_A_Doubt:

This code came from early AVM, which got absorbed by OVM which got absorbed by UVM.

The AVM was developed around the same time as the first IEEE version of SystemVerilog in 2005. This was long before interface classed had been introduced into the language. The uvm_tlm_if_bsse base class is a workaround for multiple interface class inheritance.

There’s nothing particularly special about passing a class as a type parameter compared to any other type, like an int. Except that you get to use that type in places only classes are allowed. In this case, the class parameter is being used as the super class name. It just makes it more difficult to follow.

In reply to dave_59:

Hi Dave ,

Thanks for the detailed reply . I have a few questions related to passing tlm_if_base as parameter

Abstract class uvm_tlm_if_base has all methods as virtual , plus it flashes an error if its method gets called .

I see that inside abstract class uvm_port_base , uvm_tlm_if_base type ( though parameter type ) is used for declaring handle with name “m_if”

Inside class uvm_blocking_put_port , put() method gets called using m_if.put(t) ,

[Q1] So how does the user implementated method get called , ( Is it through parent argument in constructor of uvm_blocking_put_port ) ?

[Q2] Does the user’s implementation override the method in uvm_tlm_if_base ?
Cos virtual functions ( methods defined in uvm_tlm_if_base are virtual ) require same prototype and the user gets away without even keeping the same prototype .

Eg ::


// Inside uvm_tlm_if_base 

   virtual task put ( input T t ) ; // t is used as argument name

// User implementation of put()

   virtual task put ( T pkt);  // pkt is argument name


Normally while overriding virtual methods the argument name should remain same , but this works , how ??
( For classes extended from uvm_subscriber the argument name remains ‘t’ since its pure virtual in base class )

Thanks

In reply to Have_A_Doubt:

See TLM1 Method | Verification Academy

When using call wrappers, there’s no requirement to keep the argument names the same. Virtual method must have the same argument names because of the argument passing by name feature of SystemVerilog.