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[10] = {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[4]) begin
      $error($sformatf("array[%0d] != array[4]",idx1+idx2));
    end
  end
endmodule
OUTPUT:
Error: array[0] != array[4]

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[4]. 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[4]) begin
    $error($sformatf("array[%0d] != array[4]",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[4]) begin
    $error($sformatf("array[%0d] != array[4]",int'(idx1+idx2)));
  end
  else begin
    $display("solution #2 worked!");
  end
end

Pay attention on how you access array contents!

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?