Vhdl 如何从函数返回具有无约束2d数组的记录

Vhdl 如何从函数返回具有无约束2d数组的记录,vhdl,xilinx,vivado,Vhdl,Xilinx,Vivado,我有一个记录typeREC,其中包含一个类型为VECTOR的元素,该元素是STD_逻辑的无约束2d数组: 但在我试图设置数据大小的行中,Vivado抛出了以下错误: Sliced name is allowed only on single-dimensional arrays 这是否意味着我不能在记录中有一个无约束的二维数组,或者在con函数中有不同的方法来定义它的大小 --编辑-- 由于我现在了解到在这种情况下不可能使用2d数组,我应该使用什么方法来创建一个函数: 将两个二维数组或大小为[

我有一个记录typeREC,其中包含一个类型为VECTOR的元素,该元素是STD_逻辑的无约束2d数组:

但在我试图设置数据大小的行中,Vivado抛出了以下错误:

Sliced name is allowed only on single-dimensional arrays
这是否意味着我不能在记录中有一个无约束的二维数组,或者在con函数中有不同的方法来定义它的大小

--编辑--

由于我现在了解到在这种情况下不可能使用2d数组,我应该使用什么方法来创建一个函数:

将两个二维数组或大小为[x][y]和[z][y]的数组数组作为输入 输出大小为[x+z][y]的数组 两个输入数组都不受约束,而输出数组都被约束为大小[x+z][y] 所有输入和返回的数组都必须是记录类型
这是行和列合并的定义,请参见:

函数slm_merge_rowsslm1:T_slm;slm2:T_SLM返回T_SLM为 常量行:正:=slm1'长度1+slm2'长度1; 常数列:正:=slm1'长度2; 变量slm:T_SLMROWS-1向下到0,列-1向下到0; 开始 对于slm1'range1循环中的i 对于slm1'low2到slm1'high2循环中的j——变通方法:Xilinx iSIM变通方法,因为“range2”的计算结果是“range1”;请参阅T_SLM类型声明中的解决方法说明 slmi,j:=slm1i,j; 端环; 端环; 对于slm2'range1循环中的i 对于slm2'low2到slm2'high2循环中的j,解决方案:Xilinx iSIM解决方案,因为'range2'计算结果为'range1;请参阅T_SLM类型声明中的解决方法说明 slmslm1'长度1+i,j:=slm2i,j; 端环; 端环; 返回slm; 末端功能; 函数slm\u merge\u colsslm1:T\u slm;slm2:T_SLM返回T_SLM为 常量行:正:=slm1'长度1; 常数列:正:=slm1'长度2+slm2'长度2; 变量slm:T_SLMROWS-1向下到0,列-1向下到0; 开始 对于slm1'range1循环中的i 对于slm1'low2到slm1'high2循环中的j——变通方法:Xilinx iSIM变通方法,因为“range2”的计算结果是“range1”;请参阅T_SLM类型声明中的解决方法说明 slmi,j:=slm1i,j; 端环; 对于slm2'low2到slm2'high2循环中的j,解决方案:Xilinx iSIM解决方案,因为'range2'计算结果为'range1;请参阅T_SLM类型声明中的解决方法说明 slmi,slm1'长度2+j:=slm2i,j; 端环; 端环; 返回slm; 末端功能; T_SLM的定义是:

类型T_SLM是阵列自然范围,标准逻辑的自然范围; 目前,我认为将这段代码嵌套在另一层(如无约束记录)中没有问题

编辑:

上面的代码要求在Vivado中启用VHDL 2008

当VHDL文件被添加到Vivado中时,默认设置为使用VHDL 93,而不是2008。转到属性窗口,将文件类型从VHDL更改为VHDL 2008```。 打印的错误消息具有误导性,并指向正在使用的错误功能。正确的消息应该是它是VHDL-2008功能,请启用它


这是行和列合并的定义,请参见:

函数slm_merge_rowsslm1:T_slm;slm2:T_SLM返回T_SLM为 常量行:正:=slm1'长度1+slm2'长度1; 常数列:正:=slm1'长度2; 变量slm:T_SLMROWS-1向下到0,列-1向下到0; 开始 对于slm1'range1循环中的i 对于slm1'low2到slm1'high2循环中的j——变通方法:Xilinx iSIM变通方法,因为“range2”的计算结果是“range1”;请参阅T_SLM类型声明中的解决方法说明 slmi,j:=slm1i,j; 端环; 端环; 对于slm2'range1循环中的i 对于slm2'low2到slm2'high2循环中的j,解决方案:Xilinx iSIM解决方案,因为'range2'计算结果为'range1;请参阅T_SLM类型声明中的解决方法说明 slmslm1'长度1+i,j:=slm2i,j; 端环; 端环; 返回slm; 末端功能; 函数slm\u merge\u colsslm1:T\u slm;slm2:T_SLM返回T_SLM为 常量行:正:=slm1'长度1; 常数列:正:=slm1'长度2+slm2'长度2; 变量slm:T_SLMROWS-1向下到0,列-1向下到0; 开始 对于slm1'range1循环中的i 对于slm1'low2到slm1'high2循环中的j——变通方法:Xilinx iSIM变通方法,因为“range2”的计算结果是“range1”;请参阅T_SLM类型声明中的解决方法说明 slmi,j:=slm1i,j; 端环; 对于slm2'low2到slm2'high2循环中的j-解决方案:Xilinx iSIM解决方案 ,因为“range2”的计算结果为“range1”;请参阅T_SLM类型声明中的解决方法说明 slmi,slm1'长度2+j:=slm2i,j; 端环; 端环; 返回slm; 末端功能; T_SLM的定义是:

类型T_SLM是阵列自然范围,标准逻辑的自然范围; 目前,我认为将这段代码嵌套在另一层(如无约束记录)中没有问题

编辑:

上面的代码要求在Vivado中启用VHDL 2008

当VHDL文件被添加到Vivado中时,默认设置为使用VHDL 93,而不是2008。转到属性窗口,将文件类型从VHDL更改为VHDL 2008```。 打印的错误消息具有误导性,并指向正在使用的错误功能。正确的消息应该是它是VHDL-2008功能,请启用它

最初的评论是为了刁钻。函数con中缺少return语句,这将阻止在示例中使用

目前还不清楚Vivado模拟器是否支持记录约束a-2008特性。在Vivado合成指南UG901 2020.1中,我们看到了记录类型的各种奇妙用途,从一切到推断ram到记录类型的记录元素。Xilinx一直很忙

如果支持记录类型声明中的无约束元素,但不支持记录约束,这似乎有点奇怪——撇开双关语不谈,它们基本上是一个包交易。请注意,该评论称其为-2008特性

记录约束仅限于提供无约束类型(通常为数组)的元素或子元素的约束。VHDL始终能够提供多维数组约束。该标准的语言基于语法的灵活性而特殊

此代码与VHDL-2008兼容,并提供您的记录约束:

图书馆ieee;-为MCVe添加 使用ieee.std_logic_1164.all;-补充 包装测试是 类型向量是数组自然范围,STD_逻辑的自然范围; 类型REC是记录 数据:向量; 结束记录记录; 功能cona:REC;b:REC返回REC; 端包装试验; 包体测试是 功能cona:REC;b:REC return REC是 变量r: REC-记录约束: 数据 自然范围a.data'length1+b.data'length1-1向下至0, 自然范围a.数据长度2-1至0 ; 开始 - . . . 做事 返回r;-添加了必需的返回语句 端功能con; 端包体试验; 您将注意到,您对记录约束的更改是在元素数据约束的每个范围之前添加了自然范围

根据IEEE标准1076-2008 5.3.3记录类型:

记录约束::= 记录元素约束{,记录元素约束}

记录元素约束::=记录元素简单名称元素约束

从6.3子类型声明:

元素约束::= 数组约束 |记录|约束

这里元素数据是一个数组,因此数组_约束是合适的

从5.3.2阵列类型,5.3.2.1:

数组\u约束::=

索引约束[数组元素约束] |打开[数组_元素_约束]

因为元素数据数组元素是标量枚举类型STD_逻辑,所以我们遵循index_约束

索引_约束::=离散_范围{,离散_范围}

离散_范围::=离散_子类型_指示|范围

上面显示的代码使用离散子类型指示元素数据维度的索引范围,并成功地分析编译

根据5.2.2标量类型,5.2.2.1:

范围::= 范围\属性\名称 |简单_表达式方向简单_表达式

方向::=至|下至

问题中的约束使用具有简单表达式和方向的范围

那么为什么它会产生关于多维切片的错误信息呢

在9。表达式,9.1 BNF,简单表达式->术语->因子->主要->名称

在8。名称,8.1名称->切片\名称,在8.5切片名称中,仅多维切片在语义上是不允许的,谁的BNF告诉我们它在语法上是有效的:

切片\u名称::=前缀离散\u范围

切片的前缀应适用于一维数组对象。此数组类型的基类型是切片的类型

从语义上讲,前缀数据不适合一维数组对象

这些注释为问题提供了更多的上下文,尽管不清楚您在报告的最终成功中使用了哪个版本的记录约束:


@Mercury当您将VHDL文件添加到Vivado时,默认设置为使用VHDL 93,而不是2008。去 转到属性窗口,并将文件类型从VHDL更改为VHDL 2008。我不确定是什么 是吗 在您的案例中打印错误的错误消息。Vivado喜欢用错误的错误消息来迷惑用户 .... 无论如何,它应该报告您的功能仅在2008模式下受支持帕培尔3小时 以前
@Paebbels谢谢你,解决了这个问题,也许可以把它作为一个子注释添加到你的回复中,这样我就可以 将其标记为已接受答案。你刚刚帮我省去了几个小时的挫折。我已经很熟悉了 Vivado的恶作剧,我最喜欢的一个是错误接近。。。这肯定是最重要的 无用的错误信息我已经有很长时间的经验了:–Mercury 3小时前 就检测-2008源代码而言,主单元或辅单元中都没有-1993语法错误和-2008新保留字、分隔符、分隔符或图形字符

这就让你任由失败的语义分析摆布了。您还可以注意到,在分析包声明期间,未报告unconstratedrecord元素。它发生在变量r的计算过程中。所有声明的对象都需要约束。VHDL并没有一个对所有特性的叙述,语义也可能受到限制。在某些地方拥有不受约束的元素和对象是合法的

将标准文本中的语义规则与特定声明或语句的文本元素相关联可能是困难的,而吱吱作响的轮子则是润滑剂。记录约束对于VHDL实现来说相对较新

问题似乎在于对工具的熟悉程度

最初的评论是为了刁钻。函数con中缺少return语句,这将阻止在示例中使用

目前还不清楚Vivado模拟器是否支持记录约束a-2008特性。在Vivado合成指南UG901 2020.1中,我们看到了记录类型的各种奇妙用途,从一切到推断ram到记录类型的记录元素。Xilinx一直很忙

如果支持记录类型声明中的无约束元素,但不支持记录约束,这似乎有点奇怪——撇开双关语不谈,它们基本上是一个包交易。请注意,该评论称其为-2008特性

记录约束仅限于提供无约束类型(通常为数组)的元素或子元素的约束。VHDL始终能够提供多维数组约束。该标准的语言基于语法的灵活性而特殊

此代码与VHDL-2008兼容,并提供您的记录约束:

图书馆ieee;-为MCVe添加 使用ieee.std_logic_1164.all;-补充 包装测试是 类型向量是数组自然范围,STD_逻辑的自然范围; 类型REC是记录 数据:向量; 结束记录记录; 功能cona:REC;b:REC返回REC; 端包装试验; 包体测试是 功能cona:REC;b:REC return REC是 变量r: REC-记录约束: 数据 自然范围a.data'length1+b.data'length1-1向下至0, 自然范围a.数据长度2-1至0 ; 开始 - . . . 做事 返回r;-添加了必需的返回语句 端功能con; 端包体试验; 您将注意到,您对记录约束的更改是在元素数据约束的每个范围之前添加了自然范围

根据IEEE标准1076-2008 5.3.3记录类型:

记录约束::= 记录元素约束{,记录元素约束}

记录元素约束::=记录元素简单名称元素约束

从6.3子类型声明:

元素约束::= 数组约束 |记录|约束

这里元素数据是一个数组,因此数组_约束是合适的

从5.3.2阵列类型,5.3.2.1:

数组\u约束::=

索引约束[数组元素约束] |打开[数组_元素_约束]

因为元素数据数组元素是标量枚举类型STD_逻辑,所以我们遵循index_约束

索引_约束::=离散_范围{,离散_范围}

离散_范围::=离散_子类型_指示|范围

上面显示的代码使用离散子类型指示元素数据维度的索引范围,并成功地分析编译

根据5.2.2标量类型,5.2.2.1:

范围::= 范围\属性\名称 |简单_表达式方向简单_表达式

方向::=至|下至

问题中的约束使用具有简单表达式和方向的范围

那么为什么它会产生关于多维切片的错误信息呢

在9。表达式,9.1 BNF,简单表达式->术语->因子->主要->名称

在8。名称,8.1名称->切片\u名称,仅多维切片是不允许的 在8.5个片段名称中,谁的BNF告诉我们它在语法上是有效的:

切片\u名称::=前缀离散\u范围

切片的前缀应适用于一维数组对象。此数组类型的基类型是切片的类型

从语义上讲,前缀数据不适合一维数组对象

这些注释为问题提供了更多的上下文,尽管不清楚您在报告的最终成功中使用了哪个版本的记录约束:


@Mercury当您将VHDL文件添加到Vivado时,默认设置为使用VHDL 93,而不是2008。去 转到属性窗口,并将文件类型从VHDL更改为VHDL 2008。我不知道为什么 在您的案例中打印错误的错误消息。Vivado喜欢用错误的错误消息来迷惑用户 .... 无论如何,它应该报告您的功能仅在2008模式下受支持帕培尔3小时 以前
@Paebbels谢谢你,解决了这个问题,也许可以把它作为一个子注释添加到你的回复中,这样我就可以 将其标记为已接受答案。你刚刚帮我省去了几个小时的挫折。我已经很熟悉了 Vivado的恶作剧,我最喜欢的一个是错误接近。。。这肯定是最重要的 无用的错误信息我已经有很长时间的经验了:–Mercury 3小时前 就检测-2008源代码而言,主单元或辅单元中都没有-1993语法错误和-2008新保留字、分隔符、分隔符或图形字符

这就让你任由失败的语义分析摆布了。您还可以注意到,在分析包声明期间,未报告unconstratedrecord元素。它发生在变量r的计算过程中。所有声明的对象都需要约束。VHDL并没有一个对所有特性的叙述,语义也可能受到限制。在某些地方拥有不受约束的元素和对象是合法的

将标准文本中的语义规则与特定声明或语句的文本元素相关联可能是困难的,而吱吱作响的轮子则是润滑剂。记录约束对于VHDL实现来说相对较新


问题似乎在于对工具的熟悉程度。

VHDL不允许对N维数组进行切片,只能对1D数组进行切片。有什么原因使您创建了一个std_逻辑的2D数组,而不是一个可以切片的std_逻辑向量的1D数组?您确定错误指向变量声明吗?在您的代码示例中没有发生切片。OP试图使用-2008中发现的记录约束来提供对元素数据的约束,该元素数据是多维类型向量,所有这些都没有一个记录约束。了解为什么要花一些时间。@Mercury当您将VHDL文件添加到Vivado时,默认情况下它设置为使用VHDL 93,但不是2008。转到属性窗口,将文件类型从VHDL更改为VHDL 2008。我不知道为什么它在你的案例中打印了错误的错误消息。Vivado喜欢用错误的错误消息来迷惑用户。。。。无论如何,它应该报告您的功能仅在2008模式下受支持。@Paebbels谢谢您,解决了这个问题,也许可以将它作为子注释添加到您的响应中,以便我可以将其标记为已接受的答案。你刚刚帮我省去了几个小时的挫折。我已经开始熟悉Vivado的诡计了,我最喜欢的一个是错误接近。。。这肯定是我长期以来遇到的最无用的错误消息之一:VHDL不允许切片N维数组,只能切片1D数组。有什么原因使您创建了一个std_逻辑的2D数组,而不是一个可以切片的std_逻辑向量的1D数组?您确定错误指向变量声明吗?在您的代码示例中没有发生切片。OP试图使用-2008中发现的记录约束来提供对元素数据的约束,该元素数据是多维类型向量,所有这些都没有一个记录约束。了解为什么要花一些时间。@Mercury当您将VHDL文件添加到Vivado时,默认情况下它设置为使用VHDL 93,但不是2008。转到属性窗口,将文件类型从VHDL更改为VHDL 2008。我不知道为什么它在你的案例中打印了错误的错误消息。Vivado喜欢用错误的错误消息来迷惑用户。。。。无论如何,它应该报告您的功能仅在2008模式下受支持。@Paebbels谢谢您,解决了这个问题,也许可以将它作为子注释添加到您的响应中,以便我可以将其标记为已接受的答案。你刚刚帮我省去了几个小时的挫折。我已经开始熟悉Vivado的诡计了,我最喜欢的一个是错误接近。。。这肯定是我很长一段时间以来遇到的最无用的错误消息之一:这基本上就是我想要做的,除了让T_SLM成为记录中的一个元素之外,问题是一旦我将T_SLM打包到记录中,此行变量SLM:T_SLMROWS-1向下到0,列-1向下到0
; 最后看起来像这个变量slm:RECdatROWS-1向下到0,COLUMNS-1向下到0;其中dat是record REC中类型为T_SLM的元素,它最终抛出相同的错误,因为它与我的原始代码同义。或者我误解了你们想要演示的内容,这段代码将用于填充我编辑部分的前3个要点,但一旦我们将T_SLM引入到记录中,并直接使用录制的而不是T_SLM,我们就会遇到同样的问题,即无法在函数return中约束2d数组,这就是基本上,除了让T_SLM成为记录中的一个元素之外,我想做的是,问题是只要我将T_SLM打包到一个记录中,这一行变量SLM:T_SLMROWS-1 downto 0,COLUMNS-1 downto 0;最后看起来像这个变量slm:RECdatROWS-1向下到0,COLUMNS-1向下到0;其中dat是record REC中类型为T_SLM的元素,它最终抛出相同的错误,因为它与我的原始代码同义。或者我误解了你们想要演示的内容,这段代码将用于填充我编辑部分的前3个要点,但一旦我们将T_SLM引入记录并直接使用录制的而不是T_SLM,我们就会遇到同样的问题,即无法在函数return中约束2d数组。非常感谢对于全面的答复,我现在看到你的第一个评论包含了解决方案,这只是不太容易理解。作为一种跟进,我想问一下,是否有任何方法可以在文件comets本身中表示使用VHDL-2008,这样,如果我在其他地方使用此文件,我就不必在IDE中再次指定它了?非常感谢您的全面回复,我现在看到您的第一条评论包含了解决方案,这是很难理解的。作为一种跟进,我想问,是否有任何方法可以在文件comets本身中表示使用VHDL-2008,这样,如果我在其他地方使用此文件,我就不必在IDE中再次指定它了?

package body TEST is

    function con(
     a : REC;
     b : REC)
        return REC is variable r : REC(
            data(a.data'length(1) + b.data'length(1) - 1 downto 0, a.data'length(2) - 1 downto 0));

        begin

            -- . . . do things

    end function con;

end package body TEST;

Sliced name is allowed only on single-dimensional arrays
user1155120 I don't think I fully understand what you are trying to say. Are you saying my code is not
a minimal reproducible example, because except for me forgetting to include the STD_LOGIC library
the code reproduces the problem when I paste it into Vivado, and it is about as minimal as I can get it.
Or are you saying that the code you linked as this works works for you, because at least in my
Vivado it still throws the same error ? – Mercury 4 hours ago