2

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?

njg
  • 45
  • 6
  • The same warning is issued when using the `'range` attribute on a `downto`vector (such as `if foo = (foo'range => '1') then`). Similarly to the original question, `reverse_range` does not trigger the warning on a `downto` vector. – njg Mar 19 '19 at 10:34

1 Answers1

4

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;
Matthew Taylor
  • 13,365
  • 3
  • 17
  • 44
  • 1
    The rules for determining the index range of an aggregate are found in IEEE Std 1076-2008 9.3.3.3 Array aggregates. Also see 9.3.5 Qualified expressions "A qualified expression is a basic operation (see 5.1) that is used to explicitly state the type, and possibly the subtype, of an operand that is an expression or an aggregate." Where `subtype foo_st is unsigned (4 downto 0);` and for `display(foo_st'(foo'high => '1', foo'high - 1 downto foo'low => '0'));` the aggregate will have an index range 4 downto 0. –  Mar 19 '19 at 19:37