How to use config_db get() and set method to send array of interfaces?

Hi,
I am trying to set and get array of interfaces using config_db. I am able use generate method to set the interfaces but how do I get the interfaces?


module abc();
 ram_if intf[3](clk, rst_n);
 
 generate 
  	for (genvar i=0; i< 3; i++)begin
  	initial begin
      	uvm_config_db#(virtual ram_if)::set(null, "*", "vif", intf[i]);
    	end
  	end
  endgenerate
endmodule

//uvm env class - build_phase

  virtual ram_if vif[3];

virtual function void build_phase(uvm_phase phase);
     super.build_phase(phase);
     if(!uvm_config_db#(virtual ram_if)::get(this, "", "vif", vif)) //Error on this line
         `uvm_fatal(get_type_name, $sformatf("Did not receive ram_if"))
   endfunction


Error-[ICTTFC] Incompatible complex type usage
testbench.sv, 191
  Incompatible complex type usage in task or function call.
  The following expression is incompatible with the formal parameter of the 
  function. The type of the actual is 'virtual interface ram_if$[0:2]', while 
  the type of the formal is 'virtual interface ram_if'. Expression: this.vif
  Source info: uvm_config_db#(ram_if)::get(this, "\000", "vif", this.vif)


In reply to UVM_SV_101:

I tried for loop but it does not work. I tried to set vif[0].val=0, vif[0].val=1 ,vif[0].val=2 . But it prints 2 for all values of val



virtual function void build_phase(uvm_phase phase);
     super.build_phase(phase);
     //if(!uvm_config_db#(virtual ram_if)::get(this, "", "vif", vif))
     //    `uvm_fatal(get_type_name, $sformatf("Did not receive ram_if"))
       for(int i =0; i<3; i++)begin
         uvm_config_db#(virtual ram_if)::get(this, "", "vif", vif[i]);
       end
     `uvm_info("ram_monitor", $sformatf("val[0] %d val[1] %d val[2] %d",vif[0].val,vif[1].val,vif[2].val),UVM_LOW);

// [ram_monitor] val[0]   2 val[1]   2 val[2]   2
   endfunction

In reply to UVM_SV_101:

You are using the same name (“vif”) for all instances. You want to create unique names for each instance in the set() and get() calls.

In reply to cgales:

Thanks for finding the bug. It works with unique tag

uvm_config_db#(virtual ram_if)::get(this, "", $sformatf("vif_%0d",i), vif[i]

In reply to cgales:

In reply to UVM_SV_101:
You are using the same name (“vif”) for all instances. You want to create unique names for each instance in the set() and get() calls.

Do you know the reason why for loop cannot be used when using config_db set method?

In reply to UVM_SV_101:

Interfaces are design level constructs which imposes some limitations on how you can index them using variables.

However, virtual interfaces are verification constructs which aren’t limited to the same restrictions. You should be able to create an array of virtual interfaces, assign the array to the physical interfaces, and access the interface handle using an array index.


import uvm_pkg::*;
`include "uvm_macros.svh"

interface ram_if(input bit clk, input bit rst_n);
endinterface

module testbench();
  bit clk;
  bit rst_n;
  
  ram_if intf[3](clk, rst_n);
  virtual ram_if v_intf[3];
  
  initial begin
    v_intf = intf;
    
    for (int i=0; i<3; i++) begin
      uvm_config_db#(virtual ram_if)::set(null, "uvm_test_top", $sformatf("vif%0d", i), v_intf[i]);
    end
  end
endmodule