vhdl assign unconstraint std_logic_vector - lsb to msb or msb downto lsb

Viewed 1696

i'd like to assign a std_logic_vector without giving the bounds. Like this:

constant xy: std_logic_vector := "100111";

when i want to access single bits like:

xy(0), xy(1)...xy(5)

i get

1, 0, 0, 1, 1, 1

This is the same, as when i assign the vector like std_logic_vector(0 to 5).

Is this behaviour standardized, that assigning a unconstrained vector is interpreted like std_logic_vector(0 to x) and not like std_logic_vector(x downto 0), or is this depending on the implementation?

I'm using ghdl right now, but want to use vivado for synthesis.

1 Answers

In short, yes, standardised. When you declare an object of an unconstrained array type you need to supply a constraint to specify the index bounds (so that the compiler can allocate the required memory, and so on). There are several different ways to do this, most of which require you to explicitly specify the array limits and direction.

However, there's an exception for constants (only): the constraint can be inferred from the expression used to initialise the constant. If you initialise from a string literal or an aggregate with positional association (A and B below) then the index value of the first/left element is taken from the leftmost element of the type in the range declaration, and the direction is taken from the direction of that type. For std_logic_vector, the declarations are:

SUBTYPE NATURAL is integer range 0 to integer'high;
...
TYPE std_logic_vector IS ARRAY ( NATURAL RANGE <>) OF std_logic;

NATURAL is ascending, with leftmost index 0, so your xy is the same. OTOH, if the initialiser is an aggregate with named association (C below) then the index range of the constant is simply taken from the aggregate. The code below should show A and B as 111001, and C as 100111.

library IEEE;
use IEEE.std_logic_1164.all;

entity TOP is
end entity TOP;

architecture A of TOP is
begin
  process
    constant A : std_logic_vector := "100111";
    constant B : std_logic_vector := ('1', '0', '0', '1', '1', '1');
    constant C : std_logic_vector := 
      (5 => '1', 4 => '0', 3 => '0', 2 => '1', 1 => '1', 0 => '1');
  begin
    report "A is " &
      std_logic'image(A(5)) & std_logic'image(A(4)) & std_logic'image(A(3)) &
      std_logic'image(A(2)) & std_logic'image(A(1)) & std_logic'image(A(0));
    report "B is " &
      std_logic'image(B(5)) & std_logic'image(B(4)) & std_logic'image(B(3)) &
      std_logic'image(B(2)) & std_logic'image(B(1)) & std_logic'image(B(0));
    report "C is " &
      std_logic'image(C(5)) & std_logic'image(C(4)) & std_logic'image(C(3)) &
      std_logic'image(C(2)) & std_logic'image(C(1)) & std_logic'image(C(0));
    wait;
  end process;
end architecture A;

EDIT

As pointed out below, the report statements don't show the 'natural' order of these vectors, which was deliberate. You'll notice that this means that the literal value assigned toA is the reverse of the value shown by the report. If you don't like it, swap the indexing in the reports, or use to_string instead (2008-only).

Related