Search code examples
arraystypesvhdlvariable-assignment

VHDL assignment to an array type


Consider a type

type foo is array (0 downto 0) of std_logic_vector(7 downto 0);

Why do I get a compiler error when I try to create a constant value of this type, for example. Note that I have only tried using Altera's Quartus II.

constant cFoo : foo := ( x"11" );

Error: VHDL Type mismatch error at [filename.vhd](line number): cFoo type does not match string literal.

However everything is ok if my type is

type foo is array (0 downto 0) of std_logic_vector(7 downto 0); 

with an example assignment to a constant of:

constant cFoo : foo := ( x"00", x"11" );

Moreover consider that I try to assign index 0 with another constant. For example.

type foo is array (0 downto 0) of std_logic_vector(7 downto 0);
constant cBar : std_logic_vector(7 downto 0); 
constant cFoo : foo := ( cBar  );

To which the error the compiler spits out is now:

VHDL error at [filename.vhd](line number): type of identifier "cBar" does not agree with its usage as "foo" type.

So basically its telling me that the compiler does not realize that the assignment is to the index of 0 but instead an assignment to the the array type.

How can I let the compiler know that the assignment is to only index 0?


Solution

  • IEEE Std 1076 9.3.3 Aggregates, 9.3.3.1 para 4:

    Both named and positional associations can be used in the same aggregate, with all positional associations appearing first (in textual order) and all named associations appearing next (in any order, except that it is an error if any associations follow an others association). Aggregates containing a single element association shall always be specified using named association in order to distinguish them from parenthesized expressions.

    With an MCVE:

    library ieee;
    use ieee.std_logic_1164.all;
    
    package ceefoo is
        type foo is array (0 downto 0) of std_logic_vector(7 downto 0);
        -- constant cFoo : foo := ( x"11" );
        constant cfoo:  foo := (0 => x"11");
        -- or
        constant cefoo: foo := (others => x"11");
    end package;
    

    You need to use named association with a single element. The first example specifies index 0, the second any elements.

    Para 3 of the above quoted subsection:

    Each element association associates an expression with elements (possibly none). An element association is said to be named if the elements are specified explicitly by choices; otherwise, it is said to be positional. For a positional association, each element is implicitly specified by position in the textual order of the elements in the corresponding type declaration.

    It's helpful to see the BNF:

    aggregate ::=
    ( element_association { , element_association } )

    element_association ::=
         [ choices => ] expression

    choices ::= choice { | choice }

    choice ::=
         simple_expression
         | discrete_range
         | element_simple_name
         | others