Setting An interface array for hierarchical elements from top

Hi,
Actually i want to set an array of interfaces from the top file and want to get from test file.And here is the piece of code i m using,

for(i=`num_of_master;i>0;i–) begin
uvm_config_db#(virtual tv_ahb_master_intf)::set(null, “*”, “vintf_master”, vintf_master[i]);
end

I am getting the err “Illegal index into array of interfaces”. So please help me to get the problem with code and method to solve it.

You can’t use a variable to dynamically index an array of interface or module instances. And even if you could, your piece of code would only set vintf_master[1] to the config entry named “vintf_master”. Only the last call to set() would take effect.

You need to use a generate statement to access an individual instance. How you do that depends on whether you need to send each instance to an individual agent, or does the agent need the whole array of interfaces?

for(genvar i=`num_of_master;i>0;i--) begin
  initial uvm_config_db#(virtual tv_ahb_master_intf)::set(null, 
                                                          $sformatf("*.agent%0d",i),
                                                          "vintf_master", 
                                                          vintf_master[i]);
end

In reply to dave_59:

Hi Dave,
Thanks for the reply.Actually i am setting every instance for different Agents.As I tried exactly like you suggested.Its working fine but when i am getting these instances from my env class its showing error-
“virtual interface must be set for: uvm_test_top.env_h”

piece of code used in top is-
for(genvar i=0;i<`num_of_master;i++) begin
initial begin
uvm_config_db#(virtual tv_ahb_master_intf)::set(null, “*”, $sformatf(“vintf_master[%0d]”,i), vintf_master[i]);
end
end

piece of code used in env is-
for( i=0;i<num_of_master;i++) begin uvm_config_db#(virtual tv_ahb_master_intf)::get(this, "", $sformatf("vintf_master[%0d]",i), vintf_master[i]); uvm_fatal(“NOVIF”,{“virtual interface must be set for: “,get_full_name(),”.vintf_master”});
end

In reply to dave_59:

I know this is an old thread but I ran into a similar issue and can’t find a good way to solve it.

Basically in my Testbench I want to instantiate a variable number of instances of a given module. Each of this modules has a number of SV interfaces ports. So far this is no problem, I declare an array of interfaces and instantiate the modules with a generate block.

Now what I want to do is, inside my procedural block (initial) I want create an instance of a class for each of those module instances (the class is the object’s driver). So again I declare an array of instances of that class and then loop through them to initialize them.

Since that class is a driver for the module it requires access to the module’s interfaces, so when creating each of those class instances I pass it the corresponding element from the array of interfaces, sort of like this:



MyInterface #(...) interface_array [NUM_INSTANCES] (...);

genvar i;
generate for ( i = 0 ; i < NUM_INSTANCES ; i++ ) begin
    MyModule #(...) my_module (
        .ItfPort(interface_array[i])
    );
end endgenerate

initial begin
    MyDriverClass driver_array [NUM_INSTANCES];

    for ( int i = 0 ; i < NUM_INSTANCES ; i++ ) begin
        driver_array[i] = new(.module_itf(interface_array[i]));
    end
end

I am getting the same error saying “Illegal index into array of interfaces”, however generate blocks are not allowed inside initial blocks, so I am stuck finding an elegant way to solve this. Of course un-rolling the loops is not an option…

Thansk!

In reply to arquer:

Move the initial block with the assignment inside the generate as I showed earlier. Move the declaration of driver_Array outside the generate block.

In reply to dave_59:

Hi Dave,

Thanks this worked, however I always wonder, I have an initial block which creates those driver instances, and then another initial block which uses them, how do I know the first block will be executed before the second one? Should I put a #0; somewhere in my second block before ever using any of those instances?

In reply to arquer:

#0’s create messy code. Wait for instance != null.

In reply to dave_59:

Hi Dave,

In top module I am setting interface using config_db and in transceiver class I am getting interface both code below but still I am getting fatal error.

//Top


genvar i2c_inst;
i2c_interface intf[`I2C_INTF_INST_CNT](clk,rst);

generate
    for (i2c_inst=0; i2c_inst<`I2C_INTF_INST_CNT; i2c_inst = i2c_inst+1)
    begin
      initial begin
        uvm_config_db#(virtual i2c_interface)::set(null,"*",$sformatf("i2c_intf_%0d",i2c_inst),intf[i2c_inst]);
      end
    end
endgenerate

//transceiver


int count = `I2C_INTF_INST_CNT;
  if(!uvm_config_db#(virtual i2c_interface)::get(this,"*",$sformatf("i2c_intf_%0d",count),intf[count]))
  begin
    `uvm_fatal("NO_INTERFACE",{"Virtual Interface must be set for : ",get_full_name(),".intf"});
  end

fatal error
UVM_FATAL i2c_transceiver.sv(63) @ 0: tranc [NO_INTERFACE] Virtual Interface must be set for : tranc.intf

In reply to J_M:

Replace “*” with “” in the get().