VHDL integer overflow in not taken `when` branch

vhdl

In the architecture of some VHDL entity I have something like this:

type some_array is array(integer range <>, integer range <>) of std_logic;
signal foo : some_array(0 to 3, 0 to 3);

(...)

some_loop: for i in 0 to 3 generate
    something(...) <= foo(i-1, i-1) when (i > 0) else '0';
end generate some_loop;

I expected this to work fine, since foo is only indexed when i > 0. Unfortunately, it seems that VHDL / ghdl evaluates the i-1 even when i > 0, because when I run the testbed for this entity ghdl complains: ghdl:error: overflow detected.

Is this something to be expected? What's the best solution / workaround?

Best Answer

This is to be expected since i-1 is potentially outside the index range for the array. Unfortunately you have to guard this case separately, the usual way to do it would be with an if ... generate statement.

some_loop: for i in 0 to 3 generate
    if i = 0 generate 
       ... 
    end generate;
    if i > 0 generate 
       ... 
    end generate;
end generate some_loop;

A limitation of the if ... generate construct is that (before VHDL-2008) there is no else part. So you either need the unfortunately clumsy form above, or update to the latest ghdl release (0.33) for its much improved VHDL-2008 support, which allows you to replace the second if ... generate with an else.

If you are assigning every element of some array or record called something simultaneously, you may find this alternative style simpler and cleaner:

something(0) <= '0';
some_loop: for i in 1 to 3 generate
    something(i) <= foo(i-1, i-1);
end generate some_loop;