我有一个大小为10x10的std_logic_vector的二维数组。我想添加数组列的特定元素,例如:
array(4 downto 0,1) <= std_logic_vector(unsigned('0'&array(3 downto 2,2)) + unsigned('0'&array(1 downto 0,2)));
但是我得到了错误:错误地形成了“数组”的索引名称。索引#1是一个范围。 为什么我不能添加这些向量?
答案 0 :(得分:1)
注意数组是VHDL中的保留字。我们可以假设您有意尝试在不符合Minimal, Complete, and Verifiable example条件的代码段中抽象您的对象名称。
问题
显然,Modelsim错误消息引用了切片的定义。参见IEEE Std 1076-2008,8.5 Slice names:
切片名称表示由另一个一维数组的连续元素序列组成的一维数组。一片信号是一个信号;一片变量是一个变量;一片常数是一个常数;一片值是一个值。
slice_name :: = prefix(discrete_range)
切片的前缀应适合于一维数组对象。此数组类型的基类型是切片的类型。
该标准没有直接解释为什么切片仅适用于一维数组对象,但它与表达式中找到的值的类型有关。
见5.3.2数组类型,5.3.2.1概述:
数组对象是由具有相同子类型的元素组成的复合对象。数组元素的名称使用属于指定离散类型的一个或多个索引值。数组对象的值是由其元素的值组成的复合值。
多维数组的维度索引中的切片不是元素类型。除了没有可识别和声明的类型之外,您可能需要的类型声明的数量取决于每个维度中可能的维度数和切片长度的数量。
定义那些不同的类型将是分配工作的唯一方法,赋值是一个基本操作,而不是要重载的子程序。
解决方案
根据定义,您可以使用一系列语句执行此操作,在这种情况下,您可以在从数组中收集的元素构造的聚合上执行此操作。聚合赋值将用于将添加的元素放入适当的位置。这取决于声明所需的类型,您可能会注意到有效地进行在一维元素数组的切片上发生的操作。
<强> 子程序 强>
可以编写子程序来执行您正在表达的功能。它涉及传递所涉及的所有多维数组类型的值以及分别为“操作数”提供任何“切片”和索引的维度的表达式。
这类似于扫除地毯下的复杂性。
您也可以使用信号端口为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阵列进行操作时,数组方法的数组才有效。切片第二个索引,你需要子程序或语句序列。
答案 1 :(得分:0)
在VHDL-2008之前,无法在VHDL中对真正的n维数组进行切片。
您应该将代码重新编写为两个嵌套的一维数组。