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
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
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…
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 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