如何定义一个 VHDL 组件和封装?
How to define a VHDL component and package?
下面我有以下两个VHDL文件。文件 x.vhd 带有 component x 需要引用(包含)在文件 top.vhd 作为一个包。
-- x.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
package x_pkg is
component my_x
port(clk_clk : in std_logic := '0';
reset_reset_n : in std_logic := '0';
end component my_x;
end package x_pkg;
-----------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity x is
port (
clk_clk : in std_logic := '0'; -- clk.clk
reset_reset_n : in std_logic := '0'; -- reset.reset_n
);
end entity x;
architecture rtl of x is
需要在以下顶级文件中引用此包:
-- top.vhd
library ieee;
use ieee.std_logic_1164.all;
library altera;
use altera.altera_syn_attributes.all;
use work.x_pkg.all;
entity EyeTracker_Top is
port
(
Nios_Clk : in std_logic;
Nios_Reset_n : in std_logic;
);
end EyeTracker_Top;
architecture struct of EyeTracker_Top is
begin
M1 : my_x port map(Nios_Clk, Nios_Reset_n); -- Here I get the error message!
编译后出现如下错误信息:
***错误(12006):节点实例"M1"实例化未定义的实体"my_x"
这里有什么问题?我猜包参考有问题...
谢谢!
您正在实例化组件 my_x
。组件只是一个声明,一种空shell。每个组件实例都必须在某个时候绑定到实际的 entity/architecture 对。此绑定必须通过显式配置完成。有几种方法可以做到这一点。一种是添加:
for all: my_x use work.x(rtl);
在您的体系结构的声明区域中(在 architecture
和 begin
之间)。当然,实体 x
及其架构 rtl
必须在您使用的库中编译为 work
才能详细说明您的顶层。
您收到的错误消息很难理解,因为您的工具试图应用基于名称的默认配置策略:对于未绑定的组件实例,它会搜索与组件同名的实体。因为找到了none,报错了一个missing entity,其实是组件绑定问题,也就是缺少配置。更好的工具会告诉您组件 my_x
的 M1
实例未绑定。
最后一点:如果所有这些组件对您的需求来说太复杂了,只需摆脱它并直接实例化您的实体:
M1: entity work.x(rtl) port map(Nios_Clk, Nios_Reset_n);
并且您将不需要组件声明和配置。
基本上有两种方法:
- 具有组件实例化和配置的自顶向下设计,
- 具有实体实例化的自下而上设计,没有组件也没有配置。
了解两者之间的差异、优缺点并不容易。在那里,一本好的 VHDL 书可能比 Whosebug 上的问题和答案更好。
下面我有以下两个VHDL文件。文件 x.vhd 带有 component x 需要引用(包含)在文件 top.vhd 作为一个包。
-- x.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
package x_pkg is
component my_x
port(clk_clk : in std_logic := '0';
reset_reset_n : in std_logic := '0';
end component my_x;
end package x_pkg;
-----------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity x is
port (
clk_clk : in std_logic := '0'; -- clk.clk
reset_reset_n : in std_logic := '0'; -- reset.reset_n
);
end entity x;
architecture rtl of x is
需要在以下顶级文件中引用此包:
-- top.vhd
library ieee;
use ieee.std_logic_1164.all;
library altera;
use altera.altera_syn_attributes.all;
use work.x_pkg.all;
entity EyeTracker_Top is
port
(
Nios_Clk : in std_logic;
Nios_Reset_n : in std_logic;
);
end EyeTracker_Top;
architecture struct of EyeTracker_Top is
begin
M1 : my_x port map(Nios_Clk, Nios_Reset_n); -- Here I get the error message!
编译后出现如下错误信息:
***错误(12006):节点实例"M1"实例化未定义的实体"my_x"
这里有什么问题?我猜包参考有问题...
谢谢!
您正在实例化组件 my_x
。组件只是一个声明,一种空shell。每个组件实例都必须在某个时候绑定到实际的 entity/architecture 对。此绑定必须通过显式配置完成。有几种方法可以做到这一点。一种是添加:
for all: my_x use work.x(rtl);
在您的体系结构的声明区域中(在 architecture
和 begin
之间)。当然,实体 x
及其架构 rtl
必须在您使用的库中编译为 work
才能详细说明您的顶层。
您收到的错误消息很难理解,因为您的工具试图应用基于名称的默认配置策略:对于未绑定的组件实例,它会搜索与组件同名的实体。因为找到了none,报错了一个missing entity,其实是组件绑定问题,也就是缺少配置。更好的工具会告诉您组件 my_x
的 M1
实例未绑定。
最后一点:如果所有这些组件对您的需求来说太复杂了,只需摆脱它并直接实例化您的实体:
M1: entity work.x(rtl) port map(Nios_Clk, Nios_Reset_n);
并且您将不需要组件声明和配置。
基本上有两种方法:
- 具有组件实例化和配置的自顶向下设计,
- 具有实体实例化的自下而上设计,没有组件也没有配置。
了解两者之间的差异、优缺点并不容易。在那里,一本好的 VHDL 书可能比 Whosebug 上的问题和答案更好。