Accessing elements in an array of interfaces

Accessing elements of instance arrays in SystemVerilog requires elaboration-time constants, which can limit flexibility and scalability.

Using generate constructs or virtual interfaces helps overcome these limitations, enabling more robust and adaptable verification environments. 

The Problem

When writing a testbench, we often need to access specific elements from various arrays of instances.

According to the IEEE 1800-2023 Standard for SystemVerilog, hierarchical access can be achieved using the following syntax (Chapter 23.6, Syntax 23-7):

hierarchical_identifier ::= [ $root . ] { identifier constant_bit_select . } identifier

In other words, you need a constant to access elements of an array.

Let’s say we need to configure five instances of the following interface:

interface intf;
  logic [2:0] signal;
endinterface

Accessing them using constants could look something like this:

module top;
 localparam nof_ifs = 5;
 parameter zero = 0;
 `define one 1
 const int two = 2;

 //Array of interfaces
 intf intf_array[nof_ifs]();

 initial begin
  //Accessing by constants
  intf_array[zero].signal = 0;
  intf_array[`one].signal = 1;
  //const variables will not work since they are run-time constants
  //and will result in an error
  intf_array[two].signal = 2;
  intf_array[3].signal = 3;
  intf_array[nof_ifs-1].signal = 4;
 end
endmodule

In this example the following types of constants are used for accessing the elements of an array: parameters, defines and literal numbers.

You might assume that a const variable could be used to access elements of an array – but that’s not actually the case. The LRM states (Chapter 6.20) that the const keyword defines a run-time constant. However, for this type of element accessing, elaboration-time constants need to be used. You can find a more detailed explanation on the differences between parameters and const variables in this paper

Using constants to access elements can be a hassle. It leads to repetitive code and doesn’t scale well if the number of instances increases or decreases.

One might think of using a loop to simplify access – but that approach doesn’t work as expected. The loop iterator isn’t treated as a constant during elaboration.

For example:

module top;
  localparam nof_ifs = 5;

  // Array of interfaces
  intf intf_array[nof_ifs]();

  initial begin
    for(int i = 0; i < nof_ifs; i++)
      intf_array[i].signal = i;
  end
endmodule

[OUTPUT]: *Error: Illegal operand for constant expression [4(IEEE)].

First Solution – Use Generate

To address this limitation and make the testbench more robust and maintainable, there are more effective alternatives.

One possible solution is to take advantage of generate constructs. generate constructs, together with genvars are evaluated during elaboration time, allowing the use of loops for array index accessing.

Therefore, they offer a scalable and clean structure for growing designs.

module top;
  localparam nof_ifs = 5;
  
  // Array of interfaces
  intf intf_array[nof_ifs]();
  
  generate
    for(genvar i = 0; i < nof_ifs; i++)
      initial begin
        intf_array[i].signal = i;
      end
  endgenerate
endmodule

Second Solution – Use Virtual Interfaces

Another, less common, but powerful approach involves the use of virtual interfaces. This method decouples the interface from its physical instance. It enables dynamic access through handles, which can be passed around and managed more flexibly during simulation.

module top;
  localparam nof_ifs = 5;
  
  // Array of interfaces
  intf intf_array[nof_ifs]();
  // Array of virtual interfaces
  virtual intf virtual_intf_array[nof_ifs] = intf_array;

  initial begin
    for(int i = 0; i < nof_ifs; i++)
      virtual_intf_array[i].signal = i;

endmodule

That’s all! Read, Share and Subscribe to keep the community alive!

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Subscribe to our newsletter

Do you want to be up to date with our latest articles?