 # Gotcha: Using SystemVerilog Expressions as Array Indices

Using expressions in arrays indices may lead to unexpected behavior. For example:

``````module top;
initial begin
automatic int array = {0,1,2,3,4,5,6,7,8,9};
automatic bit idx1 = 1;
automatic bit[1:0] idx2 = 3;

// Is idx1+idx2 equal to 4 ?
if (array[idx1+idx2] != array) begin
\$error(\$sformatf("array[%0d] != array",idx1+idx2));
end
end
endmodule``````
``````OUTPUT:
Error: array != array``````

In the array[idx1+idx2] context, since idx1 is 1 and idx2 is 3, one would expect that idx1+idx2 is equal to 4, thus accessing the array. But, the sum of indices (idx1+idx2) is not equal to 4! It is equal to 0!

The explanation can be found in SystemVerilog IEEE 1800-2012 standard, chapter “11.6.1 Rules for expression bit lengths”:

A self-determined expression is one where the bit length of the expression is solely determined by the expression itself—for example, an expression representing a delay value.

A context-determined expression is one where the bit length of the expression is determined by the bit length of the expression and by the fact that it is part of another expression. For example, the bit size of the right-hand expression of an assignment depends on itself and the size of the left-hand side.

In the example above, (idx1+idx2) is a self-determined expression, so it will be evaluated using the maximum width of its operands, in our case 2 bits.

Instead of that, we should pre-compute the index using a wide enough variable like int:

``````begin
automatic int index=idx1+idx2;
if (array[index] != array) begin
\$error(\$sformatf("array[%0d] != array",index));
end
else begin
\$display("solution #1 worked!");
end
end``````

or cast the expression to a wide enough type:

``````begin
if (array[int'(idx1+idx2)] != array) begin
\$error(\$sformatf("array[%0d] != array",int'(idx1+idx2)));
end
else begin
\$display("solution #2 worked!");
end
end``````

Pay attention on how you access array contents!