Search code examples
vhdlquestasim

Warning "Range choice direction does not determine aggregate index range direction" when compiling VHDL with QuestaSim


I am getting a warning which I do not understand when compiling VHDL in QuestaSim:

(vcom-1514) Range choice direction (downto) does not determine aggregate index range direction (to).

The code which triggers the warning is similar to having

signal foo : unsigned(4 downto 0);

in the architecture before the begin and then inside some process

if foo = (foo'high => '1', foo'high - 1 downto foo'low => '0') then

The line above will trigger the warning while

if foo = (foo'high => '1', foo'low to foo'high - 1 => '0') then

does not, even though the index direction of foo is downto and not to.

Does anyone have an idea why I am supposed to do the indexing with to and not with downto in this case?


Solution

  • The aggregate

    (foo'high => '1', foo'high - 1 downto foo'low => '0')
    

    has the index range direction 'to'. Your warning is saying: don't imagine its direction is 'downto' just because you've included an array within in which is defined as 'downto'.

    Why is the default direction 'to'? Well, we need to think about what type this aggregate is. (Come on - this is VHDL - it must have a type).

    In my code, it's type is unsigned. Why? Well, because I have associated it with an input to the procedure of type unsigned. In your code its type is also unsigned. Why? Well, because it is the right hand argument of the = operator, whose left hand argument is definitely unsigned. There is only one possible version of the = operator that it could be, the one which tests two unsigneds.

    Now, we need to look at how the type unsigned is declared and when we do we see that it is declared as an unconstrained array with an index type of natural:

    type unsigned is array (natural range <>) of std_logic;
    

    The left hand value of type natural is 0. So, this is why your aggregate has the index range direction 'to'.


    If you execute this code, you can see how VHDL has defined the indexing on the aggregate:

    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.numeric_std.all;
    
    entity E is
    end entity ;
    
    architecture A of E is
      signal foo : unsigned(4 downto 0);
    begin
    
      process
        procedure display (constant foo : in unsigned) is
        begin
          report "foo'left= " & integer'image(foo'left);
          report "foo'right= " & integer'image(foo'right);
          report "foo'high= " & integer'image(foo'high);
          report "foo'low= " & integer'image(foo'low);
         end procedure;
      begin
        display((foo'high => '1', foo'high - 1 downto foo'low => '0'));
        wait;
      end process;
    
    end architecture A;