VHDL语言一个优良的特点是任何由VHDL语言描述的电路都可以作为一个元件为另外一个设计使用,这个使用过程成为例化。通过例化可以使设计电路重用与设计层次化。代码重用加速设计进程,层次化使设计代码更清晰。本节着重讨论实体电路例化及层次化设计。下面以4位全加器设计为例,将已经设计过的一位全加器作为元件例化,形成4位全加器,构成层次化设计。
1.元件声明
完整的VHDL设计(entity+ architecture)可以作为元件例化。下面将一位全加器的代码重列如下:
entity full_addition1 is
generic(
WIDTH_IN: integer:=1;
WIDTH_OUT: integer:=1
);
port
(
ci : in bit;
a : in bit;
b : in bit;
sum : out bit;
co : out bit
);
end full_addition1;
ARCHITECTURE arch_fadd1 of full_addition1 is
begin
sum <= ci XOR a XOR b;
co <= (a AND b) OR (ci AND (a XOR b));
end arch_fadd1;
- 元件声明格式
若希望已设计的代码可以重用,首先需要作元件声明。注意将设计例化,需要entity和architecture两个部分都具备的完整设计。元件声明由component 关键字引导后跟元件名,元件名应该与将要声明为元件的设计程序的实体名一致。元件声明须在architecture 的声明区内完成。
元件声明格式如下:
component component_name – – component_name is the entity name of another entity ,元件名应与被例化的实体名一致
generic(
parameter_name1 : type_1 ; – – same as entity generic part excerpt that the comma is used in stead of semicolon.
– -这一部分几乎与实体的generic部分相同,
parameter_name2 : type_2 ; – -但需注意每行以分号“;”结束。因此可以将被例化的源文件复制修改即可。元件声明部分,参数不能设初值。
…
parameter_namen : type_n
); – – – 以分号“;”结束
port (
port_name1 : direction type_1; – -same as entity port part excerpt that the comma is used in stead of semicolon. 这一部分几乎与实体的generic部分相同,但需注意每行以分号”;”结束。
port_name2 : direction type_2,;- -但需注意每行以分号”;”结束。因此可以将被例化的源文件复制修改即可。元件声明部分,参数不能设初值。
….
port_namen : direction type_n — direction — in ,out ,inout , buffer etc.
);
end component;
元件声明 除了 “ component component_name ….end component;” 外 ,内部的generic和port 部分几乎与被例化的实体格式一致,除了这里每行以逗号结束,而且不能设置初值。
例1: 将一位全加器在新设计的四位全加器内声明
entity full_addition4 is
generic(
WIDTH_IN: integer:=4;
WIDTH_OUT: integer:=4
);
port
(
ci : in bit;
a : in bit_vector(WIDTH_IN-1 downto 0);
b : in bit_vector(WIDTH_IN-1 downto 0);
sum : out bit_vector(WIDTH_OUT-1 downto 0);
co : out bit
);
end full_addition1;
ARCHITECTURE arch_fadd1 of full_addition1 is
component full_addition1
generic(
WIDTH_IN : integer;
WIDTH_OUT: integer
);
port (
ci : in bit;
a : in bit;
b : in bit;
sum : out bit;
co : out bit
);
end component;
begin
-- sum <= ci XOR a XOR b;
-- co <= (a AND b) OR (ci AND (a XOR b));
end arch_fadd1;
2. 元件的例化格式
元件声明后就可以在行为描述区例化及使用。
- 元件例化及使用方式如下:
(1) 将本设计实体的输入端口或本地信号作为元件的输入。
(2)将元件的输出作为本设计实体的输出或参与本地的信号运算。
(3)一个元件可以多次例化并使用。
- 元件的使用格式
component_instance_name : component_name —元件例化名:元件名 ,
generic map( – – generic map
parameter_name1 => value1, —参数传递值,可以为常数,也可为generic声明的参数,注意以逗号”,”结束
parameter_name2 => value2,
…..
parameter_namen => valuen
) – – 没有分号”;”
port map ( – – port map
port_name1 => signal_name_1 , – -注意以逗号”,”结束, signal_name 可以为本地信号,或本实体的端口,
– – 映射时注意输入、 输出方向
port_name2 => signal_name_2 ,
….
port_namen => signal_name_n
);
元件例化注意事项:
(1) 例化名在前,元件名在后,中间冒号”:”隔开;注意这种例化名与元件的顺序与Verilog和system verilog的例化方式的区别。
(2)generic map引导参数部分例化
(3)参数例化部分以逗号”,”结束一条描述指令。注意与元件声明时的区别,元件声明时以分号”;”结束每一个参数的映射。
(4)generic 的结束只有”)”,没有分号”;”
(5) port map引导端口例化
(6)每行以逗号结束
(7)无论参数映射还是端口映射,都采用”=>”进行映射。左边为元件内部名称,右边为本实体中端口或信号名称。
3. 完成4为全加器设计
----------------------------------------------------------------------------------
-- Company: Fraser Innovation Inc
-- Engineer: tim Zhuang
--
-- Create Date: 2022/05/21 00:09:20
-- Design Name:
-- Module Name: top_logic - Behavioral
-- Project Name: full addition
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
--library IEEE;
--use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity full_addition4 is
generic(
WIDTH_IN: integer:=4;
WIDTH_OUT: integer:=4
);
port
(
ci : in bit;
a : in bit_vector(WIDTH_IN-1 downto 0);
b : in bit_vector(WIDTH_IN-1 downto 0);
sum : out bit_vector(WIDTH_OUT-1 downto 0);
co : out bit
);
end full_addition4;
ARCHITECTURE arch_fadd4 of full_addition4 is
signal co_tmp : bit_vector(WIDTH_IN-1 downto 0); --声明中间变量,由于要与例化的元件输出相接,因此不能赋初值
component full_addition1 --元件声明
generic(
WIDTH_IN : integer; --参数只有类型,不赋初值; 以分号结束
WIDTH_OUT : integer
); --分号结束
port (
ci : in bit; --端口指明方向,只有类型,不赋初值; 以分号结束
a : in bit;
b : in bit;
sum : out bit;
co : out bit
); --分号结束
end component;
begin
full_addition1_inst0 : full_addition1 - -例化第一个元件,例化后的元件名为full_addition1_inst0, 模板元件名为full_addition1。
- -中间以":" 隔开
generic map(
WIDTH_IN => 1,
WIDTH_OUT => 1
) - - 没有分号
port map(
ci => ci,
a => a(0), - - 以逗号结束
b => b(0),
sum => sum(0),
co =>co_tmp(0)
);
full_addition1_inst1 :full_addition1 - -例化第二个元件,例化后的元件名为full_addition1_inst1, 模板元件名为full_addition1。
- -中间以":" 隔开
generic map(
WIDTH_IN => 1,
WIDTH_OUT => 1
)
port map(
ci => co_tmp(0),
a => a(1),
b => b(1),
sum => sum(1),
co =>co_tmp(1)
);
full_addition1_inst2 : full_addition1
generic map(
WIDTH_IN => 1,
WIDTH_OUT => 1
)
port map(
ci => co_tmp(1),
a => a(2),
b => b(2),
sum => sum(2),
co =>co_tmp(2)
);
full_addition1_inst3 : full_addition1
generic map(
WIDTH_IN => 1,
WIDTH_OUT => 1
)
port map(
ci => co_tmp(2),
a => a(3),
b => b(3),
sum => sum(3),
co =>co_tmp(3)
);
co<=co_tmp(3);
end arch_fadd4;
注意:在VHDL语言中,矢量的每个分量的引用采用小括号加索引值的方式实现的。如a(3)单独使用a{bit_vector(3 downto 0)}的第4个bit。其他使用方式,如a(3 downto 2), a(2 downto 1) 等。