Config_db specialization for virtual interface using modport


LRM  Syntax 25-5  quotes :
data_type ::= 
 virtual [ interface ] interface_identifier [ parameter_value_assignment ] [ . modport_identifier ]

So essentially keyword “interface” and .modport_name are optional.

This would mean within a driver component these 3 would be equivalent


     virtual  interface  intf.master_cb  vif ;  //  (a)
     virtual  intf.master_cb             vif ;  //  (b)
     virtual  interface  intf            vif   //  (c)
    

For any one of the above 3 handle declaration I wanted to know the legal ways to set and get the interface .

(1) What would be the correct way to set the virtual interface for above driver component ?


       //  Within  top_tb ::

        intf  intf_instance ( clk , rst ) ;
      
      initial  //  Keyword  "interface"  used  as  specialization  along  with  interface_type.modport 
        uvm_config_db #( virtual interface intf.master_cb ) :: set ( null , "uvm_test_top.env_h.agent_h.drvr_h" , "vif_intf" , intf_instance ) ;
       
      initial  //  Specialization  is  interface_type.modport 
        uvm_config_db #( virtual intf.master_cb ) :: set ( null , "uvm_test_top.env_h.agent_h.drvr_h" , "vif_intf" , intf_instance ) ;

      initial  //  Specialization  is  only  interface_type
        uvm_config_db #( virtual intf ) :: set ( null , "uvm_test_top.env_h.agent_h.drvr_h" , "vif_intf" , intf_instance ) ;
     

Are all 3 cases for uvm_config_db set equivalent ?
Can anyone of these 3 set be used for all 3 cases of handle declaration [ (a) , (b) and (c) ] interchangeably ?

(2) What would be the correct way to get the virtual interface for the driver component ?


       //  Within  driver  component's  build_phase() ::
       
       
       //  (i)   Keyword  "interface"  used  as  specialization  along  with  interface_type.modport 
        uvm_config_db #( virtual interface intf.master_cb ) :: get ( this , "" , "vif_intf" ,  vif ) ;
       
       //  (ii)  Specialization  is  interface_type.modport 
        uvm_config_db #( virtual intf.master_cb ) :: get ( this , "" , "vif_intf" , vif ) ;

       //  (iii)  Specialization  is  only  interface_type
        uvm_config_db #( virtual intf ) :: get (  this , "" , "vif_intf" , vif ) ;
     
 **Are  all  3  cases  for  uvm_config_db  get  equivalent ?
    Can  anyone of these 3 get be used for all 3 cases (a) , (b) and (c) interchangeably ?**

In reply to MICRO_91:

First of all, I recommend avoiding modports in testbench code; simulation tools ignore the directions that they are supposed to enforce.

Just because the BNF syntax shows something is optional does not necessarily mean it has no effect on the meaning.

The [interface] keyword is optional just there for visual clarity.

However, the LRM says this about modports in a virtual interface declaration.

A virtual interface declaration may select a modport of an interface in which case the modport is also part of its type. An interface instance or virtual interface with no modport selected may be assigned to a virtual interface with a modport selected.

That implies you cannot make assignments from something with a modport to without a modport, or from one modport selected to another modport selected.

Hi Dave ,

I have a clocking block as part of the modport to enforce the direction is followed by respective components.

If I were to declare virtual interface handle as :

virtual  interface  intf.Driver  vif ; //  Clocking  block  driver_cb  is  part of  the  modport  Driver

      //  Fetching  virtual  interface  :
if( ! uvm_config_db #( virtual interface  intf ) :: get( this , "" , "vif_intf"  ,  vif ) )
      `uvm_fatal( .. )
 

I observe elaboration error :

formal and actual do not have assignment compatible data types (expecting datatype compatible with ‘virtual interface intf.Driver’ but found ‘virtual interface intf’ instead)

As ’ vif ’ has modport in the declaration i.e intf.Driver whereas I am trying to assign non-modport type intf , this results in elaboration error .

The solution would to be use virtual interface intf.Driver as the specialization.

 i.e  uvm_config_db #( virtual interface  intf.Driver ) 

This also means the modport needs to be part of specialization when setting the virtual interface in top_tb else fatal message .


NOTE : uvm_config_db #( virtual interface  intf ) is a different specialization than uvm_config_db #( virtual interface  intf.Driver )

An interface instance or virtual interface with no modport selected may be assigned to a virtual interface with a modport selected.

Using the above quote an alternate solution would be :


 //  top_tb  would  simply  need  to  do  a  single  set  with  no  modport  specialization :

 uvm_config_db #( virtual interface intf ) :: set ( null , "uvm_test_top.env_h.agent_h*" , "vintf" , intf_instance );

 //  Then  within  Driver  and  Monitor  Components  with  virtual  interface  handles  using  a  modport :
 
    function  void  build_phase( uvm_phase  phase);
     virtual interface  intf  vintf ;

   if( ! uvm_cofig_db #( ( virtual interface intf ) :: get ( this , "" , "vintf" , vintf ) )
       `uvm_fatal( .. ) 
     
     //  LHS  is  declared  as  :  virtual  interface  intf.Driver  vintf_driver ;
      vintf_driver =  vintf ;  //  Assigning  virutal  interface with no modport to virtual interface with a modport 
      ....................