VHDL 从二维数组的列中添加特定元素
VHDL Add specific elements from a column of a 2d array
我有一个 std_logic_vector 的二维数组,大小为 10x10。我想添加数组列的特定元素,例如:
array(4 downto 0,1) <= std_logic_vector(unsigned('0'&array(3 downto 2,2)) + unsigned('0'&array(1 downto 0,2)));
但我收到错误消息:"array" 的索引名称格式错误。索引#1 是一个范围。
为什么我不能添加这些向量?
在 VHDL-2008 之前的 VHDL 中不能对真正的 n 维数组进行切片。
您应该将代码重新编写为两个嵌套的一维数组。
注意数组是VHDL中的保留字。我们可以假设您有意尝试在不符合 Minimal, Complete, and Verifiable example.
条件的代码片段中抽象您的对象名称
问题
明显的 Modelsim 错误消息引用了切片的定义。请参见 IEEE Std 1076-2008,8.5 切片名称:
A slice name denotes a one-dimensional array composed of a sequence of consecutive elements of another one-dimensional array. A slice of a signal is a signal; a slice of a variable is a variable; a slice of a constant is a constant; a slice of a value is a value.
slice_name ::= prefix ( discrete_range )
The prefix of a slice shall be appropriate for a one-dimensional array object. The base type of this array type is the type of the slice.
该标准没有直接解释为什么切片仅适用于一维数组对象,但它与表达式中找到的值的类型有关。
参见 5.3.2 数组类型、5.3.2.1 概述:
An array object is a composite object consisting of elements that have the same subtype. The name for an element of an array uses one or more index values belonging to specified discrete types. The value of an array object is a composite value consisting of the values of its elements.
多维数组的维索引中的切片不是元素类型。除了没有可识别和声明的类型之外,您可能需要的类型声明的数量取决于维度的数量和每个维度中可能的切片 lengths 的数量。
定义这些不同的类型将是让赋值工作的唯一方法,赋值是一个基本操作而不是要重载的子程序。
解决方案
根据定义,您可以使用一系列语句来执行此操作,在这种情况下,您可以对从数组中收集的元素构成的聚合体执行加法运算。聚合赋值将用于将添加的元素放在适当的位置。这取决于所声明的所需类型,您可能会注意到有效地使操作发生在一维元素数组的切片上。
子程序
可以编写子程序来执行您所表达的功能。它涉及传递所有涉及的多维数组类型的值以及分别提供任何 'slices' 和索引 'operands' 的维度的表达式。
这类似于扫除地毯下的复杂性。
您也可以使用信号端口模式为 inout 的过程折叠作业。
数组的数组
您的示例在二维数组中的一维数组切片上使用运算符和赋值。要处理切片,我们需要将被切片的数组类型作为数组的元素类型。
通过反转维度索引顺序并将数组类型定义为数组类型的元素数组,我们可以避免各种复杂性:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity foo is
end entity;
architecture fum of foo is
type array_type is array (natural range 0 to 9) of
std_logic_vector(9 downto 0);
signal some_array: array_type;
begin
-- The original code snippet formatted for readability:
-- array(4 downto 0,1) <= std_logic_vector(
-- unsigned('0' & array(3 downto 2,2)) +
-- unsigned('0' & array(1 downto 0,2))
-- );
some_array(1)(2 downto 0) <=
std_logic_vector (
('0' & unsigned(some_array(2)(3 downto 2))) +
('0' & unsigned(some_array(2)(1 downto 0)))
);
end architecture;
现在切片是一维数组。我们得到了一些分析、阐述和运行的东西(证明赋值中没有边界错误)。
如果您需要 5 元素赋值:
some_array(1)(4 downto 0) <=
std_logic_vector (
("000" & unsigned(some_array(2)(3 downto 2))) +
("000" & unsigned(some_array(2)(1 downto 0)))
);
Renaud Pacalet 评论说您的原始作业因运算符结果与作业左侧的边界(长度)不匹配而受到影响。
在这两种情况下,您最终只会得到一个带进位的两位加法器。
仅当您不需要在多维切片上对 10x10 数组进行操作时,数组方法的数组才有效。在第二个索引上切片,您将需要子程序或语句序列。
我有一个 std_logic_vector 的二维数组,大小为 10x10。我想添加数组列的特定元素,例如:
array(4 downto 0,1) <= std_logic_vector(unsigned('0'&array(3 downto 2,2)) + unsigned('0'&array(1 downto 0,2)));
但我收到错误消息:"array" 的索引名称格式错误。索引#1 是一个范围。 为什么我不能添加这些向量?
在 VHDL-2008 之前的 VHDL 中不能对真正的 n 维数组进行切片。
您应该将代码重新编写为两个嵌套的一维数组。
注意数组是VHDL中的保留字。我们可以假设您有意尝试在不符合 Minimal, Complete, and Verifiable example.
条件的代码片段中抽象您的对象名称问题
明显的 Modelsim 错误消息引用了切片的定义。请参见 IEEE Std 1076-2008,8.5 切片名称:
A slice name denotes a one-dimensional array composed of a sequence of consecutive elements of another one-dimensional array. A slice of a signal is a signal; a slice of a variable is a variable; a slice of a constant is a constant; a slice of a value is a value.
slice_name ::= prefix ( discrete_range )
The prefix of a slice shall be appropriate for a one-dimensional array object. The base type of this array type is the type of the slice.
该标准没有直接解释为什么切片仅适用于一维数组对象,但它与表达式中找到的值的类型有关。
参见 5.3.2 数组类型、5.3.2.1 概述:
An array object is a composite object consisting of elements that have the same subtype. The name for an element of an array uses one or more index values belonging to specified discrete types. The value of an array object is a composite value consisting of the values of its elements.
多维数组的维索引中的切片不是元素类型。除了没有可识别和声明的类型之外,您可能需要的类型声明的数量取决于维度的数量和每个维度中可能的切片 lengths 的数量。
定义这些不同的类型将是让赋值工作的唯一方法,赋值是一个基本操作而不是要重载的子程序。
解决方案
根据定义,您可以使用一系列语句来执行此操作,在这种情况下,您可以对从数组中收集的元素构成的聚合体执行加法运算。聚合赋值将用于将添加的元素放在适当的位置。这取决于所声明的所需类型,您可能会注意到有效地使操作发生在一维元素数组的切片上。
子程序
可以编写子程序来执行您所表达的功能。它涉及传递所有涉及的多维数组类型的值以及分别提供任何 'slices' 和索引 'operands' 的维度的表达式。
这类似于扫除地毯下的复杂性。
您也可以使用信号端口模式为 inout 的过程折叠作业。
数组的数组
您的示例在二维数组中的一维数组切片上使用运算符和赋值。要处理切片,我们需要将被切片的数组类型作为数组的元素类型。
通过反转维度索引顺序并将数组类型定义为数组类型的元素数组,我们可以避免各种复杂性:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity foo is
end entity;
architecture fum of foo is
type array_type is array (natural range 0 to 9) of
std_logic_vector(9 downto 0);
signal some_array: array_type;
begin
-- The original code snippet formatted for readability:
-- array(4 downto 0,1) <= std_logic_vector(
-- unsigned('0' & array(3 downto 2,2)) +
-- unsigned('0' & array(1 downto 0,2))
-- );
some_array(1)(2 downto 0) <=
std_logic_vector (
('0' & unsigned(some_array(2)(3 downto 2))) +
('0' & unsigned(some_array(2)(1 downto 0)))
);
end architecture;
现在切片是一维数组。我们得到了一些分析、阐述和运行的东西(证明赋值中没有边界错误)。
如果您需要 5 元素赋值:
some_array(1)(4 downto 0) <=
std_logic_vector (
("000" & unsigned(some_array(2)(3 downto 2))) +
("000" & unsigned(some_array(2)(1 downto 0)))
);
Renaud Pacalet 评论说您的原始作业因运算符结果与作业左侧的边界(长度)不匹配而受到影响。
在这两种情况下,您最终只会得到一个带进位的两位加法器。
仅当您不需要在多维切片上对 10x10 数组进行操作时,数组方法的数组才有效。在第二个索引上切片,您将需要子程序或语句序列。