如何在VHDL中实例化通用设计的参数化版本?

如何在VHDL中实例化通用设计的参数化版本?,vhdl,Vhdl,我正在努力理解VHDL中的泛型编程,我已经编写了一些简单的代码来做到这一点。我的目标是能够编写一个通用设计(在某种意义上,通用是指没有指定实体的输入/输出大小),然后在顶级模块中实例化它,并在实例化时指定设计约束。这样,我可以根据用户的需要编写一个设计来满足许多不同的参数约束。否则,我需要为每个文件编写一个单独的设计,其中每个文件中只做了一些修改。这种灵活性的一个明显的用例是创建一个库 这两个文件说明了我试图实现的目标: -- array_adder.vhd -- -- Computes an

我正在努力理解VHDL中的泛型编程,我已经编写了一些简单的代码来做到这一点。我的目标是能够编写一个通用设计(在某种意义上,通用是指没有指定实体的输入/输出大小),然后在顶级模块中实例化它,并在实例化时指定设计约束。这样,我可以根据用户的需要编写一个设计来满足许多不同的参数约束。否则,我需要为每个文件编写一个单独的设计,其中每个文件中只做了一些修改。这种灵活性的一个明显的用例是创建一个库

这两个文件说明了我试图实现的目标:

-- array_adder.vhd
-- 
-- Computes and outputs the pointwise addition of two arrays.
library ieee;
use ieee.numeric_std.all;

package array_adder_pkg is
    generic (array_size     : integer;
             precision_size : integer
    );
    type array_type is array (0 to array_size-1) of signed(precision_size-1 downto 0);

    component array_adder is
        port (a   : in  array_type;
              b   : in  array_type;
              c   : out array_type
        );
    end component;
end package;
-----main code:-----------------------------------------------------------------
library ieee;
use ieee.numeric_std.all;
--------------------------------------------------------------------------------
entity array_adder is
    port (a : in  array_type;
          b : in  array_type;
          c : out array_type
    );
end entity;
--------------------------------------------------------------------------------
architecture fpga of array_adder is
begin
    comp: for i in 0 to array_size-1 generate
        c(i) <= a(i) + b(i);
    end generate;
end architecture;
由于
array\u adder
不知道
array\u类型是什么,所以第一个集合无法编译。在ModelSim 10.4b中,我得到了
(vcom-1136)未知标识符“array\u type”。
这并不奇怪,因为我从未实例化
array\u adder\u pkg

因此,我尝试在
array\u adder.vhd
中实例化一个默认包,它基本上是相同的,但我将包含它以使其完整<代码>顶级。vhd保持不变

-- array_adder2.vhd
-- 
-- Computes and outputs the pointwise addition of two arrays.
library ieee;
use ieee.numeric_std.all;

package array_adder_pkg is
    generic (array_size     : integer;
             precision_size : integer
    );
    type array_type is array (0 to array_size-1) of signed(precision_size-1 downto 0);

    component array_adder is
        port (a   : in  array_type;
              b   : in  array_type;
              c   : out array_type
        );
    end component;
end package;
-----main code:-----------------------------------------------------------------
package default_array_adder_pkg is new work.array_adder_pkg
    generic map (array_size     => 3,
                 precision_size => 7
    );
use work.default_array_adder_pkg.all;

library ieee;
use ieee.numeric_std.all;
--------------------------------------------------------------------------------
entity array_adder is
    port (a : in  array_type;
          b : in  array_type;
          c : out array_type
    );
end entity;
--------------------------------------------------------------------------------
architecture fpga of array_adder is
begin
    comp: for i in 0 to array_size-1 generate
        c(i) <= a(i) + b(i);
    end generate;
end architecture;
--数组_adder2.vhd
-- 
--计算并输出两个数组的逐点加法。
图书馆ieee;
使用ieee.numeric_std.all;
封装阵列_加法器_包装为
通用(数组大小:整数;
精度大小:整数
);
类型array\u type是有符号(精度\u size-1向下到0)的数组(0到数组\u size-1);
元件阵列加法器
端口(a:阵列_类型;
b:阵列_型;
c:输出数组类型
);
端部元件;
端包装;
-----主要代码:-----------------------------------------------------------------
包默认值\u数组\u加法器\u包装是新的工作。数组\u加法器\u包装
通用映射(数组大小=>3,
精度大小=>7
);
使用work.default_array_adder_pkg.all;
图书馆ieee;
使用ieee.numeric_std.all;
--------------------------------------------------------------------------------
实体数组加法器是
端口(a:阵列_类型;
b:阵列_型;
c:输出数组类型
);
终端实体;
--------------------------------------------------------------------------------
介绍了阵列加法器的fpga结构
开始
comp:0中的i要生成数组_size-1

c(i)您几乎做到了,但需要为包中的组件分配默认值

然后VHDL-2008允许使用无约束数组,这在这里可以帮助您

请参见此示例:

library ieee;
use ieee.numeric_std.all;

package array_pkg is
    type signed_array is array (natural range <>) of signed;
end package;


use work.array_pkg.signed_array;

package array_adder_pkg is
    generic(
        array_size     : positive;
        precision_size : positive
    );

    subtype array_type is signed_array(0 to array_size-1)(precision_size-1 downto 0);

    component array_adder is
        generic(
            array_size     : positive := array_size;
            precision_size : positive := precision_size
        );
        port (
            a : in  signed_array(0 to array_size-1)(precision_size-1 downto 0);
            b : in  signed_array(0 to array_size-1)(precision_size-1 downto 0);
            c : out signed_array(0 to array_size-1)(precision_size-1 downto 0)
        );
    end component;
end package;


use work.array_pkg.signed_array;

entity array_adder is
    generic(
        array_size     : positive;
        precision_size : positive
    );
    port (
        a : in  signed_array(0 to array_size-1)(precision_size-1 downto 0);
        b : in  signed_array(0 to array_size-1)(precision_size-1 downto 0);
        c : out signed_array(0 to array_size-1)(precision_size-1 downto 0)
    );
end entity;

library ieee;

architecture fpga of array_adder is
    use ieee.numeric_std.all;
begin
    comp: for i in 0 to array_size-1 generate
        c(i) <= a(i) + b(i);
    end generate;
end architecture;


entity top_level is end entity;

package small_pkg is new work.array_adder_pkg
    generic map (array_size     => 3,
                 precision_size => 5
    );
package large_pkg is new work.array_adder_pkg
    generic map (array_size     => 3,
                 precision_size => 9
    );

library ieee;

architecture fpga of top_level is
    use ieee.numeric_std.all;

    signal small_ina : work.small_pkg.array_type :=
                (to_signed(1, work.small_pkg.precision_size),
                 to_signed(2, work.small_pkg.precision_size),
                 to_signed(3, work.small_pkg.precision_size));
    signal small_inb : work.small_pkg.array_type :=
                (to_signed(4, work.small_pkg.precision_size),
                 to_signed(5, work.small_pkg.precision_size),
                 to_signed(6, work.small_pkg.precision_size));
    signal small_out : work.small_pkg.array_type;

    signal large_ina : work.large_pkg.array_type :=
                (to_signed(100, work.large_pkg.precision_size),
                 to_signed(110, work.large_pkg.precision_size),
                 to_signed(120, work.large_pkg.precision_size));
    signal large_inb : work.large_pkg.array_type :=
                (to_signed(50, work.large_pkg.precision_size),
                 to_signed(30, work.large_pkg.precision_size),
                 to_signed(80, work.large_pkg.precision_size));
    signal large_out : work.large_pkg.array_type;
begin
    small_array_adder: work.small_pkg.array_adder
        port map (a => small_ina,
                  b => small_inb,
                  c => small_out);

    large_array_adder: work.large_pkg.array_adder
        port map (a => large_ina,
                  b => large_inb,
                  c => large_out);
end architecture;

太宽了。你能问一个关于某个问题的具体问题吗?所显示的所有代码示例都有问题,不一定是同一组。例如,如果use子句为small_-pkg和large_-pkg进行声明,那么类型array_-type的声明都不应该直接可见。(IEEE标准1076-2008 12.4使用条款,第8段案例c))。更好地匹配错误消息和代码。看起来array_加法器使用的是不同的array_类型声明,每个声明都是唯一的,并且都必须使用相同的声明。modelsim错误非常明显。。。对于
large\u pkg
您可以将
array\u size
设置为15。。。但是,只能用3个元素初始化数组。。而不是15。。。您是否希望modelsim随机填写这些空白?Modelsim无法读懂您的心思…泛型和实例化包是2008年的功能,正如5.3.2.1无界数组定义一样,它允许您推迟在数组元素子类型指示中提供约束,直到声明该类型的对象并提供(一个)无约束索引。这将允许您通过提供大型/小型唯一泛型(其中大型数组和小型数组加法器是实例化的)来完全取消对泛型包的实例化。具有必需元素子类型约束的无约束数组定义在-1993和-2002中可用。
library ieee;
use ieee.numeric_std.all;

package array_pkg is
    type signed_array is array (natural range <>) of signed;
end package;


use work.array_pkg.signed_array;

package array_adder_pkg is
    generic(
        array_size     : positive;
        precision_size : positive
    );

    subtype array_type is signed_array(0 to array_size-1)(precision_size-1 downto 0);

    component array_adder is
        generic(
            array_size     : positive := array_size;
            precision_size : positive := precision_size
        );
        port (
            a : in  signed_array(0 to array_size-1)(precision_size-1 downto 0);
            b : in  signed_array(0 to array_size-1)(precision_size-1 downto 0);
            c : out signed_array(0 to array_size-1)(precision_size-1 downto 0)
        );
    end component;
end package;


use work.array_pkg.signed_array;

entity array_adder is
    generic(
        array_size     : positive;
        precision_size : positive
    );
    port (
        a : in  signed_array(0 to array_size-1)(precision_size-1 downto 0);
        b : in  signed_array(0 to array_size-1)(precision_size-1 downto 0);
        c : out signed_array(0 to array_size-1)(precision_size-1 downto 0)
    );
end entity;

library ieee;

architecture fpga of array_adder is
    use ieee.numeric_std.all;
begin
    comp: for i in 0 to array_size-1 generate
        c(i) <= a(i) + b(i);
    end generate;
end architecture;


entity top_level is end entity;

package small_pkg is new work.array_adder_pkg
    generic map (array_size     => 3,
                 precision_size => 5
    );
package large_pkg is new work.array_adder_pkg
    generic map (array_size     => 3,
                 precision_size => 9
    );

library ieee;

architecture fpga of top_level is
    use ieee.numeric_std.all;

    signal small_ina : work.small_pkg.array_type :=
                (to_signed(1, work.small_pkg.precision_size),
                 to_signed(2, work.small_pkg.precision_size),
                 to_signed(3, work.small_pkg.precision_size));
    signal small_inb : work.small_pkg.array_type :=
                (to_signed(4, work.small_pkg.precision_size),
                 to_signed(5, work.small_pkg.precision_size),
                 to_signed(6, work.small_pkg.precision_size));
    signal small_out : work.small_pkg.array_type;

    signal large_ina : work.large_pkg.array_type :=
                (to_signed(100, work.large_pkg.precision_size),
                 to_signed(110, work.large_pkg.precision_size),
                 to_signed(120, work.large_pkg.precision_size));
    signal large_inb : work.large_pkg.array_type :=
                (to_signed(50, work.large_pkg.precision_size),
                 to_signed(30, work.large_pkg.precision_size),
                 to_signed(80, work.large_pkg.precision_size));
    signal large_out : work.large_pkg.array_type;
begin
    small_array_adder: work.small_pkg.array_adder
        port map (a => small_ina,
                  b => small_inb,
                  c => small_out);

    large_array_adder: work.large_pkg.array_adder
        port map (a => large_ina,
                  b => large_inb,
                  c => large_out);
end architecture;
entity top_level is end entity;

library ieee;

architecture fpga of top_level is
    use ieee.numeric_std.all;

    package small_pkg is new work.array_adder_pkg
        generic map (array_size     => 3,
                     precision_size => 5
        );
    package large_pkg is new work.array_adder_pkg
        generic map (array_size     => 3,
                     precision_size => 9
        );

    signal small_ina : small_pkg.array_type :=
                (to_signed(1, small_pkg.precision_size),
                 to_signed(2, small_pkg.precision_size),
                 to_signed(3, small_pkg.precision_size));
    signal small_inb : small_pkg.array_type :=
                (to_signed(4, small_pkg.precision_size),
                 to_signed(5, small_pkg.precision_size),
                 to_signed(6, small_pkg.precision_size));
    signal small_out : small_pkg.array_type;

    signal large_ina : large_pkg.array_type :=
                (to_signed(100, large_pkg.precision_size),
                 to_signed(110, large_pkg.precision_size),
                 to_signed(120, large_pkg.precision_size));
    signal large_inb : large_pkg.array_type :=
                (to_signed(50, large_pkg.precision_size),
                 to_signed(30, large_pkg.precision_size),
                 to_signed(80, large_pkg.precision_size));
    signal large_out : large_pkg.array_type;
begin
    small_array_adder: small_pkg.array_adder
        port map (a => small_ina,
                  b => small_inb,
                  c => small_out);

    large_array_adder: large_pkg.array_adder
        port map (a => large_ina,
                  b => large_inb,
                  c => large_out);
end architecture;