How can I loop through a series of separate interfaces?

Good day,

I am working on a testbench for a design which has a large amount of individually instantiated interfaces. These interfaces should be connected to several modules each, and all-in-all the code for handling one of these interfaces is substantial. Therefore, I wish to find a way to loop through the individual interfaces and apply the same code to each of them. I first tried to make an array of the interfaces, but after some searching I found that this is not allowed in SystemVerilog.

So I thought: the generate construct’s for loops create indexable blocks which can contain modules. So if I create a module which does nothing but take in an interface, I can effectively create an array of these modules and plug each interface into one of them. Then I can use hierarchical access to get the interface by index. This is what the code below is attempting to do.

However, the if-statements in the ‘containers’ block are creating their own blocks, and I am only allowed to name them differently from each other. This means I am back to square one.

Is there any way in which I can get the below code to work, OR I can in some other way make the interfaces indexable without changing the ports of the TB? I cannot change the way in which the interfaces are instantiated.


interface in;
  // contains interface signals
endinterface

module top (
  in uin_0,
  in uin_1,
  in uin_2,
  in uin_3
);
  // design code
endmodule

module driver (in uin);
  // drives interface
endmodule

module container (in uin);
  // does nothing
endmodule

module tb (
  in uin_0,
  in uin_1,
  in uin_2,
  in uin_3
);
  generate
    // This part has some duplicate code, but is perhaps a necessary evil
    for (genvar i=0; i<4; i++) begin : containers
      if (i==0) begin container inst ( .uin(uin_0) ); end
      if (i==1) begin container inst ( .uin(uin_1) ); end
      if (i==2) begin container inst ( .uin(uin_2) ); end
      if (i==3) begin container inst ( .uin(uin_3) ); end
    end
  endgenerate

  generate
    for (genvar i=0; i<4; i++) begin : drivers
      // This loop contains a lot more code which I do not wish to duplicate for each uin
      driver u_driver (containers[i].inst.uin);
    end
  endgenerate
endmodule

module harness ();
  // Declare interfaces
  in uin_0 ();
  in uin_1 ();
  in uin_2 ();
  in uin_3 ();

  top u_dut ( .uin_0(uin_0), .uin_1(uin_1), .uin_2(uin_2), .uin_3(uin_3) );
  tb  u_tb  ( .uin_0(uin_0), .uin_1(uin_1), .uin_2(uin_2), .uin_3(uin_3) );
endmodule