What is the correct way of referencing subinterface instances generated inside another interface via a generate block

Hi,

I have an interface, say ‘top_interface’.

It takes a parameter called ‘NUM_INSTS’. Based on this parameter there is an internal generate block which instantiates two other interfaces, say ‘sub_if0’ and ‘sub_if1’.

Below code for reference


interface top_interface #(parameter NUM_INSTS=2);
genvar ii;
generate
  for(ii=0 ; ii<NUM_INSTS ; ii++)
    begin : per_inst_if
    // Sub interfaces
    sub_if0   sif0();
    sub_if1   sif1();
    end
endgenerate
endinterface

Now, I pass this interface to my uvm_test_top using config_db. Code below (top interface instance name being ‘top_intf’)

uvm_config_db #(virtual top_interface#(.NUM_INSTS(1)))::set(null, "uvm_test_top", "top_if", top_intf)

In the base test when I get the top interface using config_db::get(), I would like to pick and pass the sub interfaces to the env hierarchy. using config_db::set()

When I try to pass, say ‘sub_if0’ from handle of the virtual interface after fetching, to the env hierarchy, I am getting compilation errors stating [MFNF] i.e. member not found.

My code for setting the sub interface to the sub hierarchy in my uvm test top. (Assume that the virtual interface handle name of ‘top_interface’ in my test top is ‘top_intf’)

foreach(top_intf.genblk1[i])
  begin
    uvm_config_db #(virtual sub_if0)::set(this, "*", "sif0", top_intf.per_inst_if[i].sif0);
  end

What is the correct way to reference the sub interface which is part of the generate block when working with config db’s ?.

I have also tried naming the generate block, but to no avail.

Thanks
Jayant Y

You cannot procedurally iterate over generated or arrays of instance names, You can either put all the uvm_config_dv::set()'s in generate loops, or create an intermediate array of virtual interface variables as shown below.

interface top_interface #(parameter NUM_INSTS=2);
  virtual sub_if0   vsif0[NUM_INSTS];
  virtual sub_if1   vsif1[NUM_INSTS];
  for(genvar ii=0 ; ii<NUM_INSTS ; ii++)
    begin : per_inst_if
      // Sub interfaces
      sub_if0   sif0();
      sub_if1   sif1();
      initial begin
        vsif0[ii] = sif0;
        vsif1[ii] = sif1;
      end
    end
endinterface
interface sub_if0;
endinterface
interface sub_if1;
endinterface

import uvm_pkg::*;
`include "uvm_macros.svh"
class test extends uvm_test;
  `uvm_component_utils(test);
  function new(string name, uvm_component parent);
    super.new(name,parent);
  endfunction
  function void build_phase(uvm_phase phase);
    virtual top_interface#(.NUM_INSTS(1)) top_intf;
    if (!uvm_config_db #(virtual top_interface#(.NUM_INSTS(1)))::get(this, "", "top_if", top_intf))
      `uvm_error("NOTOPINTF","Not top_intf found")
    foreach(top_intf.vsif0[i])
      begin
        uvm_config_db #(virtual sub_if0)::set(this, "*", $sformatf("vsif0_%0d",i), top_intf.vsif0[i]);
      end
  endfunction
endclass

module top;
  top_interface #(1)top_intf();
  initial begin
    uvm_config_db #(virtual top_interface#(.NUM_INSTS(1)))::set(null, "uvm_test_top", "top_if", top_intf);
    run_test("test");
  end
endmodule

Thanks Dave for the solution.
While the above solution will work, my requirement is a bit more complex.

The ‘top_interface’ which I am intending to use takes in a few more parameters which will be used to parameterize the sub interfaces internally. For example consider below modified example code

// Parameterized Sub Interface definitions
interface sub_if0 #(parameter PM = 1);
endinterface

interface sub_if1 #(parameter PM = 1);
endinterface

// Parameterized Top Interface
interface top_interface #(parameter NUM_INSTS=2,
                          parameter SUBP0 [NUM_INSTS-1:0] = '{NUM_INSTS{1}},
                          parameter SUBP1 [NUM_INSTS-1:0] = '{NUM_INSTS{1}}
                         );

// Intermediate Virtual Interfaces
virtual sub_if0   vsif0[NUM_INSTS];
virtual sub_if1   vsif1[NUM_INSTS];

genvar ii;
generate
  for(ii=0 ; ii<NUM_INSTS ; ii++)
    begin : per_inst_if
    // Sub interfaces
    sub_if0  #(.PM(SUBP0[ii])) sif0();
    sub_if1  #(.PM(SUBP1[ii])) sif1();
    initial 
      begin
        // Assignment to virtual interfaces
        vsif0[ii] = sif0;
        vsif1[ii] = sif1;
      end
    end
endgenerate
endinterface

With reference to the above code, I would like to pick the parameters from the top and have the sub interface instance with the respective parameters (from top.)

However this will yield in type mismatch as the intermediate virtual interfaces declared and the ones being assigned inside the generate loop’s initial block will not be compatible.

Thanks

Update,
I tried your first alternative suggested.
Where I put uvm_config_db::set() as part of generate statement and it worked for me.

Thanks