Search code examples
vhdl

VHDL: Using aggregate others to assign value to more than one data type


Given that I have a type

type sFoo is record 
    A : std_logic;
    B : std_logic_vector(2 downto 0);
    C : std_logic;
end record;

and I have vector form of sFoo, sFoo_Vector

type sFoo_Vector is array (natural range <>) of sFoo;

and a null constant cNull_Foo

constant cNull_Foo: sFoo := (A => '0', B => (others => '0'), C => '0');

In addition, I create a record of sFoos in sBar

type sBar is record 
    A   : sFoo; 
    B   : sFoo;
    C   : sFoo;
end record; 

it is possible for me to initialize a constant like:

constant Var1 : sBar := (others => cNull_Foo);

However, if i create another record sBaz, containing both sFoo and sFoo_Vector, is it possible to use the others aggregate to initialise more than one data type (ie sFoo and sFoo_Vector)?

type sBaz is record 
    A   : sFoo; 
    B   : sFoo;
    C   : sFoo;
    D   : sFoo_Vector;
end record;

constant Var2 : sBaz := (others => ???)

Solution

  • It's risky addressing a bunch of snippets.

    If sBaz D were constrained:

    D   : sFoo_Vector (0 to 3);
    

    the initial value could be

    (D => (others =>  cNull_Foo), others => cNull_Foo);
    

    Providing a record constraint in the subtype indication for element D without constraining the type definition:

    constant Var2 : sBaz (D (3 downto 0)) := (D =>  (3 downto 0 => cNull_Foo), others => cNull_Foo);
    

    According to ghdl the D element association can't have others instead of 3 downto 0, D isn't fully constrained.

    IEEE Std 1076-2008

    9.3.3.2 Record aggregates

    If the type of an aggregate is a record type, the element names given as choices shall denote elements of that record type. If the choice others is given as a choice of a record aggregate, it shall represent at least one element. An element association with more than one choice, or with the choice others, is only allowed if the elements specified are all of the same type. The expression of an element association shall have the type of the associated record elements.

    No help there, we can concentrate on D.

    9.3.3.3 Array aggregates

    The index range of an array aggregate that has an others choice shall be determinable from the context. That is, an array aggregate with an others choice shall appear only in one of the following contexts:

    ...
    f) As the expression defining the initial value of a constant or variable object, where that object is declared to be of a fully constrained array subtype
    ...

    6.4 Objects
    6.4.1 General

    In addition, the following are objects, but are not named entities:

    ..
    — An element or slice of another object (see 8.3, 8.4, and 8.5)

    8.3 Selected names

    A selected name is used to denote a named entity whose declaration appears either within the declaration of another named entity or within a design library.

    ...
    A selected name can denote an element of a record, an object designated by an access value, or a named entity whose declaration is contained within another named entity, particularly within a library, a package, or a protected type. ...

    So an element of a record is an object. It's not a name entity it uses a selected name. The named entity is the object of the record type.

    So far the D element defined the initial value of an object of an array type. Does it have a fully constrained array subtype?

    9.4.2 Locally static primaries

    ...A locally static array subtype is a fully constrained array subtype formed by imposing on an unconstrained array type a locally static array constraint. The unconstrained array type shall have a locally static index subtype for each index position and a locally static index subtype for each index position of each array subelement, if any. A locally static record constraint is a record constraint with a locally static constraint in each record element constraint. A locally static record subtype is a fully constrained record type whose elements are all of locally static subtypes, or a fully constrained record subtype formed by imposing on an unconstrained record type a locally static record constraint. The unconstrained record type shall have a locally static index subtype for each index position of each array subelement, if any....

    Well that looks almost convincing. Except

    6.4.2 Object declarations
    6.4.2.1 General

    An object declaration declares an object of a specified type. Such an object is called an explicitly declared object.

    object_declaration ::=
         constant_declaration
       | signal_declaration
       | variable_declaration
       | file_declaration

    An object declaration is called a single-object declaration if its identifier list has a single identifier; it is called a multiple-object declaration if the identifier list has two or more identifiers....

    The constant declaration is a single object declaration of a fully constrained record subtype. And that's not mentioned in 9.3.3.3 Array aggregates.

    If you were to look in IEEE Std 610.12-1990 the IEEE Software Engineering Glossary whose definition of object would be in effect at the time of the -1987 standard:

    object. (1) Pertaining to the outcome of an assembly or compilation process. See also" object code; object module; object program.
    (2) A program constant or variable.
    (3) An encapsulation of data and services that manipulate that data. See also: **object-oriented design.

    You can see (3) pertains to objects of a protected type.

    If we look in the glossary (Annex I of the LRM, informative):

    object: (A) A named entity that has a value of a given type. An object can be a constant, signal, variable, or file. (6.4.1) (B) An instance of a class in an information model. An object is also an instance of each superclass of the class. (17.2.1)

    We see the distinction that an object is a named entity. The (A) definition was used exclusively in earlier revisions of the standard. "An entity" became "A named entity" in the -1993 revision along with expressing that elements are not named entities in 4.3 Objects (as shown in -2008 6.4.1 Objects, above.

    A record element that is an array subtype is not a constant object for purposes of 9.3.3.3 Array Aggregates f).

    A complete example would look like:

    library ieee;
    use ieee.std_logic_1164.all;
    
    package foobat is
        type sFoo is record 
            A : std_logic;
            B : std_logic_vector(2 downto 0);
            C : std_logic;
        end record;
    
        type sFoo_Vector is array (natural range <>) of sFoo;
    
        constant cNull_Foo: sFoo := (A => '0', B => (others => '0'), C => '0');
    
        type sBar is record 
            A   : sFoo; 
            B   : sFoo;
            C   : sFoo;
        end record; 
    
        constant Var1 : sBar := (others => cNull_Foo);
    
        type sBaz is record 
            A   : sFoo;
            B   : sFoo;
            C   : sFoo;
            D   : sFoo_Vector;
        end record;
    
        constant Var2 : sBaz (D (3 downto 0)) :=
                (D =>  (3 downto 0 => cNull_Foo), others => cNull_Foo);
    
        --  fully constrained type declaration:
    
        -- type sBaz is record
        --     A   : sFoo;
        --     B   : sFoo;
        --     C   : sFoo;
        --     D   : sFoo_Vector (0 to 3);
        -- end record;
        --
        -- constant Var2 : sBaz :=
        --       (D => (others =>  cNull_Foo), others => cNull_Foo);
    
    end package;