Recursion 递归';类型';VHDL中的声明

Recursion 递归';类型';VHDL中的声明,recursion,vhdl,Recursion,Vhdl,我想知道这或类似的事情是否可能: package my_package is constant my_constant:integer:=4; type array_type1 is array(my_constant-1 downto 0)of integer; constant constant_array1:array_type1:=(62,47,28,76); --And here is the experimental part: for i in 0 to my_

我想知道这或类似的事情是否可能:

package my_package is
  constant my_constant:integer:=4;
  type array_type1 is array(my_constant-1 downto 0)of integer;
  constant constant_array1:array_type1:=(62,47,28,76);
  --And here is the experimental part:
  for i in 0 to my_constnat-1 loop
    type array_type2 is array(my_constant-1 downto 0)of string(1 to constant_array1(i));
  end loop;
  constant constant_array2:array_type2:=(
    "Hello my name is Doron and I'm the developer of this project.",--62 characters.
    "Another sentence, with 47 characters at total.",
    "So it's range is '1 to 47'.",
    "And the range of this sentence is: '1 to <last-number-in-constant_array1>'."
  );
end my_package;
包我的包是
常量my_常量:整数:=4;
类型array_type1是整数数组(my_常量-1到0);
常量数组1:数组类型1:=(62,47,28,76);
--这是实验部分:
对于0中的i到我的_constnat-1循环
类型数组_type2是字符串(1到常量数组1(i))的数组(my_constant-1到0);
端环;
常量数组2:数组类型2:=(
“你好,我叫多伦,我是这个项目的开发者。”,--62个字符。
“另一句话,总共47个字符。”,
“所以它的范围是‘1到47’。”,
“这句话的范围是:‘1到’
);
结束我的包;
我的最终目的是创建一个字符串数组,而每个字符串都有不同的长度。希望此数组将在项目中的不同文件中使用,只需声明:

使用work.my_package.all

但我得到了以下错误:

Error(10500):文本“for”附近的txt utilities.vhd(16)处的VHDL语法错误;应为“end”或声明语句


感谢您的帮助。

来自IEEE标准1076-2008:

5.3.2阵列类型
5.3.2.1概述

数组对象是由具有相同子类型的元素组成的复合对象

子类型提供了一个约束。在作为数组约束的数组类型上下文中(请参见6.3子类型声明5.3.2数组类型),这是一个范围

因此,作为数组元素的数组必须具有与任何其他元素相同的范围,并且您的方法无法工作(正如Paebbels指出的)

至少有一种索引字符串的替代方法

如果类型标记是基类型,则函数可以返回其返回类型的任何子类型的任何值

这可以通过以下方式证明:

package my_package is
    constant my_constant:   integer := 4;
    function my_string (index: natural) return string;
end package;

package body  my_package is
    function my_string (index: natural) return string is
        begin
            assert index < my_constant 
                report "my_string(" & integer'image(index) &") provides a range of elements greater than my_constant"
                severity ERROR;
            case index is
                when 0 =>
                    return "Hello my name is Doron and I'm the developer of this project.";
                when 1 =>
                    return "Another sentence, with 47 characters at total.";
                when 2 => 
                    return  "So it's range is '1 to 47'.";
                when 3 => 
                    return "And the range of this sentence is: '1 to <last-number-in-constant_array1>'.";
                when others => 
                    return "<ERROR>";
            end case;
        end function;
end package body;

use work.my_package.all;

entity foo is
end entity;

architecture fum of foo is
    constant my_string0: string (my_string(0)'range) := my_string(0);
begin 
    process
    begin
        report my_string0;
        report "my_string0'length = " &integer'image(my_string0'length);
        for i in 1 to my_constant loop  -- this will provide a call out of range
            report my_string(i);
            report "my_string(" &integer'image(i) &") length = " &integer'image(my_string(i)'length);
        end loop;
        wait;
    end process;
end architecture;

当运行时,这将产生与第一个示例基本相同的输出,尽管不同报告语句的标准输出中有不同的行号和字符指针。

来自IEEE Std 1076-2008:

5.3.2阵列类型
5.3.2.1概述

数组对象是由具有相同子类型的元素组成的复合对象

子类型提供了一个约束。在作为数组约束的数组类型上下文中(请参见6.3子类型声明5.3.2数组类型),这是一个范围

因此,作为数组元素的数组必须具有与任何其他元素相同的范围,并且您的方法无法工作(正如Paebbels指出的)

至少有一种索引字符串的替代方法

如果类型标记是基类型,则函数可以返回其返回类型的任何子类型的任何值

这可以通过以下方式证明:

package my_package is
    constant my_constant:   integer := 4;
    function my_string (index: natural) return string;
end package;

package body  my_package is
    function my_string (index: natural) return string is
        begin
            assert index < my_constant 
                report "my_string(" & integer'image(index) &") provides a range of elements greater than my_constant"
                severity ERROR;
            case index is
                when 0 =>
                    return "Hello my name is Doron and I'm the developer of this project.";
                when 1 =>
                    return "Another sentence, with 47 characters at total.";
                when 2 => 
                    return  "So it's range is '1 to 47'.";
                when 3 => 
                    return "And the range of this sentence is: '1 to <last-number-in-constant_array1>'.";
                when others => 
                    return "<ERROR>";
            end case;
        end function;
end package body;

use work.my_package.all;

entity foo is
end entity;

architecture fum of foo is
    constant my_string0: string (my_string(0)'range) := my_string(0);
begin 
    process
    begin
        report my_string0;
        report "my_string0'length = " &integer'image(my_string0'length);
        for i in 1 to my_constant loop  -- this will provide a call out of range
            report my_string(i);
            report "my_string(" &integer'image(i) &") length = " &integer'image(my_string(i)'length);
        end loop;
        wait;
    end process;
end architecture;

当运行时,这会产生与第一个示例基本相同的输出,尽管不同报告语句的标准输出中有不同的行号和字符指针。

一种可能性是将所有字符串存储在一个“超级字符串”中,并用一些神奇的字符或字符串将它们分开(在下面的示例中)。然后可以使用from(我是作者之一)将长字符串拆分为其组件

另一个选项是使用冻结字典类型,它是一个具有键/值对的字符串

"key1 : value1, key2 : value2"
这允许您通过键而不是使用索引来获取字符串。下面是VUnit测试台,显示/验证了这一点。如果您想了解这些软件包的更多信息,可以查看它们的测试台和


一种可能性是将所有字符串存储在一个“超级字符串”中,并用一些神奇的字符或字符串将它们分开(在下面的示例中)。然后可以使用from(我是作者之一)将长字符串拆分为其组件

另一个选项是使用冻结字典类型,它是一个具有键/值对的字符串

"key1 : value1, key2 : value2"
这允许您通过键而不是使用索引来获取字符串。下面是VUnit测试台,显示/验证了这一点。如果您想了解这些软件包的更多信息,可以查看它们的测试台和


正如其他人所说,没有一个简单的解决方案允许创建一个不规则数组的数组(具有大小不同的第二维度)

奥托,有很多创造性的解决方案。我在OSVVM中所做的就是使用指向字符串的指针数组。以下是作为OSVVM一部分的MessagePkg的简化版本。有关比下面的代码具有更多功能的完整示例,请参阅

要打印邮件,您可以执行以下操作:

 for i in 1 to Message.GetCount loop 
   write(OUTPUT, message.get(i) & LF) ;
 end loop ; 

在OSVVM中,常量MAX_消息由一个变量替换,超过该变量时,内部存储器将自动调整大小。在OSVVM中,MessagePkg.vhd由CoveragePkg.vhd使用

正如其他人所说,没有一个简单的解决方案允许创建一个不规则数组的数组(具有大小不同的第二维度)

奥托,有很多创造性的解决方案。我在OSVVM中所做的就是使用指向字符串的指针数组。以下是作为OSVVM一部分的MessagePkg的简化版本。有关比下面的代码具有更多功能的完整示例,请参阅

要打印邮件,您可以执行以下操作:

 for i in 1 to Message.GetCount loop 
   write(OUTPUT, message.get(i) & LF) ;
 end loop ; 

在OSVVM中,常量MAX_消息由一个变量替换,超过该变量时,内部存储器将自动调整大小。在OSVVM中,MessagePkg.vhd由CoveragePkg.vhd使用

可能的重复将不起作用,因为包中不允许for循环。其次,每个iterarion覆盖
array\u type2
。要建议一个替代解决方案,您能否告诉它的预期用途,例如,它是用于模拟还是合成,以及如何使用
常量\u array2
shared variable Message : MessagePType ; 
. . .
Message.Set("MessagePkg is part of OSVVM.");
Message.Set("OSVVM is a library of packages that provide next generation");
Message.Set("verification capabilty");
Message.Set("While the library implements constrained random and functional coverage, just like other languages");
Message.Set("It also implements a portable intelligent testbench capability that works in different simulators - something that Accellera is still working on");
 for i in 1 to Message.GetCount loop 
   write(OUTPUT, message.get(i) & LF) ;
 end loop ;