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