上节介绍了数据对象的含义,并介绍了数据对象中变量的声明与使用范围。本节介绍使用最广泛的一种数据对象–信号(signal)。信号的使用范围最广,如果在Architecture的声明区域内定义,可以在Architecture的整个范围内使用,即全局可见。当然随着声明的区域不同,信号也有一定的可见范围。在VHDL语言规范中,信号可以综合成组合电路的连线类型,用于不同逻辑电路之间值的转递,也可以综合成时序电路的触发器模型,这一特性与system verilog中的logic数据对象类似。在Verilog语言中有wire与reg两种类型与之对应,见Verilog 变量声明与数据类型。在 VHDL中信号及其相关的操作,如信号赋值语句 ,决断函数(resolved function) ,延时语句等很好地描述了硬件系统的许多基本特征。
1. 信号声明
信号定义的语句格式与变量非常相似 ,信号定义也可以设置初始值 ,格式如下:
SIGNAL 信号名 数据类型:= 初始值;
或 SIGNAL 信号名 数据类型;
同样 信号初始值的设置不是必需的, 而且初始值仅在 VHDL 的行为仿真中有效, 与变量相比信号的硬件特征更为明显 ,它具有全局性特征 。例如 :在程序包中定义的信号对于所有调用此程序包的设计实体都是可见。 在实体中定义的信号在其对应的结构体中都是可见的, 实际上在entity中声明的端口除了具有方向外其特性与signal一致,是隐含的signal类型,而实体可以通过配置与多个构造体相关联,因此实体中声明的端口可以在多个构造体内可见。信号定义如下实例:
SIGNAL temp : STD_LOGIC := ‘0’ ; — 声明了单值信号temp, STD_LOGIC类型,初始值为字符’0’;
SIGNAL flaga, flagb : BIT ; — 声明了两个单值信号flaga,flagb,BIT类型,无初始值;
SIGNAL data : STD_LOGIC_VECTOR(15 DOWNTO 0 ) ; — 声明了矢量信号data, STD_LOGIC_VECTOR, 无初始值;
SIGNAL a : INTEGER RANGE 0 TO 15; –声明了整形信号a, 范围从0到15;
信号的使用和定义范围是实体(端口), 结构体和程序包(package), 在进程和子程序中不允许声明信号。 信号可以有多个驱动源, 但必须将此信号的数据类型定义为决断性数据类型。见std_logic与std_ulogic的区别。
2. 信号赋值
信号赋值为”<=”, 左边为信号名,右边为赋值表达式。信号采用如下格式:
信号名 <= 表达式;
例:
sum <= ci XOR a XOR b;
co <= (a AND b) OR (ci AND (a XOR b));
co_tmp[0]<= co;
表达式可以为是一个逻辑,算数或字符串等运算表达式,也可以是其它的数据对象,如其它信号,变量或常数等。在信号的赋值语句中还可以插入延时,成为延时赋值语句,如:
b <= a after 20 ns; –将a的值延迟20 ns赋值给 b;
延时赋值语句中的延时部分,只在仿真时有效,综合时自动忽略。
3. 信号的使用
-
连线
信号最常用的方式是等效成连线,如:
co <= (a AND b) OR (ci AND (a XOR b));
co_tmp[0]<= co and d;
上面的等效电路如图1所示,co可以看成一段连线,起到信号传递的作用。

图1
- 元件之间的信号传递
由于可以把已设计的实体文件例化成元件 在构造体中使用,元件之间的信号交互除了与本实体的端口交互外,信号是相互传递信息的惟一途径。将1位全加器例化到4位全加器的设计实例中,使用了信号为元件之间信息交互。
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); --signal co_tmp used for signal propagate among different components
--SIGNAL d1,d2,d3,d4,d5 : INTEGER RANGE 0 TO 255;
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));
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
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;
- 等效成触发器
在进程中,如果敏感量是时钟属性,则信号会等效成触发器模型。如:
PROCESS (clk)
VARIABLE cnt : INTEGER RANGE 0 TO 255;
BEGIN
IF (clk'EVENT AND clk = '1') THEN
IF clear = '0' THEN
cnt := 0;
ELSE
cnt := cnt + 1;
END IF;
END IF;
qc <= cnt;
END PROCESS;
关于时序电路的设计,以及process 的使用将在process章节中讲解。