VHDL:使用聚合他人为多个数据类型赋值
VHDL: Using aggregate others to assign value to more than one data type
鉴于我有类型
type sFoo is record
A : std_logic;
B : std_logic_vector(2 downto 0);
C : std_logic;
end record;
我有 sFoo 的矢量形式,sFoo_Vector
type sFoo_Vector is array (natural range <>) of sFoo;
和一个空常量cNull_Foo
constant cNull_Foo: sFoo := (A => '0', B => (others => '0'), C => '0');
另外,我在sBar中创建了一条sFoos的记录
type sBar is record
A : sFoo;
B : sFoo;
C : sFoo;
end record;
我可以像这样初始化一个常量:
constant Var1 : sBar := (others => cNull_Foo);
但是,如果我创建另一个包含 sFoo 和 sFoo_Vector 的记录 sBaz,是否可以使用其他聚合来初始化多个数据类型(即 sFoo 和 sFoo_Vector)?
type sBaz is record
A : sFoo;
B : sFoo;
C : sFoo;
D : sFoo_Vector;
end record;
constant Var2 : sBaz := (others => ???)
处理一堆片段是有风险的。
如果 sBaz D 受到限制:
D : sFoo_Vector (0 to 3);
初始值可以是
(D => (others => cNull_Foo), others => cNull_Foo);
在不限制类型定义的情况下,在元素 D 的子类型指示中提供记录限制:
constant Var2 : sBaz (D (3 downto 0)) := (D => (3 downto 0 => cNull_Foo), others => cNull_Foo);
根据ghdl,D元素关联不能有others
而不是3到0,D没有完全约束。
IEEE 标准 1076-2008
9.3.3.2 记录聚合
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.
没办法,我们可以专注于D。
9.3.3.3 数组聚合
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 对象
6.4.1 一般
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 已选名称
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. ...
所以记录的一个元素是一个对象。它不是使用选定名称的名称实体。命名实体是记录类型的对象。
至此D元素定义了数组类型对象的初始值。它有完全约束的数组子类型吗?
9.4.2 本地静态初选
...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....
嗯,这看起来很有说服力。 除了
6.4.2 对象声明
6.4.2.1 一般
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....
常量声明是完全约束记录子类型的单个对象声明。这在 9.3.3.3 数组聚合中没有提到。
如果您要查看 IEEE 标准 610.12-1990 IEEE 软件工程词汇表,其对象定义将在 -1987 标准时生效:
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.
您可以看到 (3) 属于受保护类型的对象。
如果我们查看词汇表(LRM 的附件 I,信息性):
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)
我们看到了对象是命名实体的区别。 (A) 定义专门用于该标准的早期修订版。 "An entity" 在 -1993 修订版中变为 "A named entity",同时表示元素不是 4.3 对象中的命名实体(如上文 -2008 6.4.1 对象所示。
对于 9.3.3.3 数组聚合 f) 而言,作为数组子类型的记录元素不是常量对象。
一个完整的例子如下:
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;
鉴于我有类型
type sFoo is record
A : std_logic;
B : std_logic_vector(2 downto 0);
C : std_logic;
end record;
我有 sFoo 的矢量形式,sFoo_Vector
type sFoo_Vector is array (natural range <>) of sFoo;
和一个空常量cNull_Foo
constant cNull_Foo: sFoo := (A => '0', B => (others => '0'), C => '0');
另外,我在sBar中创建了一条sFoos的记录
type sBar is record
A : sFoo;
B : sFoo;
C : sFoo;
end record;
我可以像这样初始化一个常量:
constant Var1 : sBar := (others => cNull_Foo);
但是,如果我创建另一个包含 sFoo 和 sFoo_Vector 的记录 sBaz,是否可以使用其他聚合来初始化多个数据类型(即 sFoo 和 sFoo_Vector)?
type sBaz is record
A : sFoo;
B : sFoo;
C : sFoo;
D : sFoo_Vector;
end record;
constant Var2 : sBaz := (others => ???)
处理一堆片段是有风险的。
如果 sBaz D 受到限制:
D : sFoo_Vector (0 to 3);
初始值可以是
(D => (others => cNull_Foo), others => cNull_Foo);
在不限制类型定义的情况下,在元素 D 的子类型指示中提供记录限制:
constant Var2 : sBaz (D (3 downto 0)) := (D => (3 downto 0 => cNull_Foo), others => cNull_Foo);
根据ghdl,D元素关联不能有others
而不是3到0,D没有完全约束。
IEEE 标准 1076-2008
9.3.3.2 记录聚合
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.
没办法,我们可以专注于D。
9.3.3.3 数组聚合
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 对象
6.4.1 一般
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 已选名称
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. ...
所以记录的一个元素是一个对象。它不是使用选定名称的名称实体。命名实体是记录类型的对象。
至此D元素定义了数组类型对象的初始值。它有完全约束的数组子类型吗?
9.4.2 本地静态初选
...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....
嗯,这看起来很有说服力。 除了
6.4.2 对象声明
6.4.2.1 一般
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_declarationAn 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....
常量声明是完全约束记录子类型的单个对象声明。这在 9.3.3.3 数组聚合中没有提到。
如果您要查看 IEEE 标准 610.12-1990 IEEE 软件工程词汇表,其对象定义将在 -1987 标准时生效:
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.
您可以看到 (3) 属于受保护类型的对象。
如果我们查看词汇表(LRM 的附件 I,信息性):
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)
我们看到了对象是命名实体的区别。 (A) 定义专门用于该标准的早期修订版。 "An entity" 在 -1993 修订版中变为 "A named entity",同时表示元素不是 4.3 对象中的命名实体(如上文 -2008 6.4.1 对象所示。
对于 9.3.3.3 数组聚合 f) 而言,作为数组子类型的记录元素不是常量对象。
一个完整的例子如下:
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;