How to create a parameterized virtual interface with a variable?

Hi,

I’m looking for a way to extend the idea of parameterized interface.

I have agent+drive+monitor+seq with a virtual interface for data packets, where the virtual interface gets a parameter of data width that sets its fields (the driver instances the virtual interface inside it)

I would like to use those modules for 2 places in my environment in which there are different data width (the whole agent+driver(+vif) + monitor )

how can i send the virtual interface a parameter which is actually a variable ?

Thanks !

Here is my thought, please check if it will work to meet your needs?

Method 1:
Declare a local “data_width” variable in driver and monitor etc. components where the virtual interface instance declaration locates. Use uvm_config_db::get to get “data_width” value in these components and use uvm_config_db::set “data_width” value at environment level.

For example:


class my_driver extends uvm_driver #(my_seq_item); 
   protected int data_width = 32; 
   protected virtual my_interface #(data_width) my_vif; 
  
   //enable "data_width" variable field automation 
  `uvm_component_utils_begin(my_driver) 
    `uvm_field_int(data_width, UVM_ALL_ON) 
  `uvm_component_utils_end 
   
   function void build_phase(uvm_phase phase); 
     super.build_phase(phase); 
     if(!uvm_config_db#(int)::get(this, “”,"data_width",data_width)) 
       `uvm_fatal("NODATAWIDTH", {"data_width must be set for: ", get_full_name(),".data_width"});  
    endfunction : build_phase 
    //... 
endclass  
  
class my_env extends uvm_env; 
  
   my_agent agent[2]; 
  
   virtual function void build_phase(uvm_phase phase); 
     super.build_phase(phase);  
     uvm_config_db#(int)::set(this,".agent[0].*","data_width", 16); 
     uvm_config_db#(int)::set(this,".agent[1].*","data_width", 32);
     // create agent[0], agent[1]... 
   endfunction : build_phase 
    //...
endclass 

Method 2:
Implement the driver, monitor, agent etc. with “data_width” as parameter and take it as as virtual interface’s parameter as well. Then you can assign the specific data_width value when agent is instanced in the environment.


class my_driver #(int data_width=32) extends uvm_driver #(my_seq_item); 
   protected virtual my_interface #(data_width) my_vif;
   //... 
endclass  
  
class my_agent #(int data_width=32) extends uvm_agent; 
  my_driver#(data_width) my_drv; 
  //... 
endclass  
  
class my_env extends uvm_env; 
  my_agent #(16) agent_w16; 
  my_agent #(32) agent_w32; 
  //... 
endclass 

In reply to Lina.Lin:

Hi

Thanks for answering !

About method 1 - i doesn’t work, since as much as i know you can not create an interface with a non-constant value (the data_width) is a variable and not a constant and you get compilation error.

I guess i will use method 2.

Do you if there is any other way to make method 1 work ?

Thanks !!!

In reply to snognogt:

Agree, method 1 won’t work because parameter is compile-time constant.

The doc verilab_dvcon_eu2015_6_params.pdf describes ways to use parameterized interface in UVM (see slide 16~26). Contents are listed as below

  • using parametrized class with parameterized virtual interface
  • using “accessor class” handle to replace virtual interface
  • using maximum footprint interface - avoid using parameterized virtual interface
  • using maximum footprint interface with wrapper - avoid using parameterized virtual

In reply to snognogt:

Hi,
how can i send the virtual interface a parameter which is actually a variable ?
Thanks !

A virtual interface can only be parameterized and a parameter cannot be a variable.
I do not understand why you want to use a variable.
If you want to use the same interface in your UVM environment in 2 different places with different data_with then you cane do this like this:

(1) interface #(parameter data_with = 8);

endinterface
(2) typedef interface #(data_width1) intf1_t;
typedef interface #(data_width2) intf2_t;

(3) virtual interface intf1_t vif1;
virtual interface intf2_t vif2;