关于变量(Variable)和信号(Signal),很多书都有介绍,基本上都是说信号会有延时,而变量是立即赋值的,但是对于两者到底有什么区别,说的不是很透彻。以至于我对两者的理解也一直很模糊,只能在实践中慢慢体会。下面介绍个例子,希望可以给朋友们一点启发:
1.信号
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity xor_sig is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
C : in STD_LOGIC;
X : out STD_LOGIC;
Y : out STD_LOGIC);
end xor_sig;
architecture Behavioral of xor_sig is
signal D: STD_LOGIC;
begin
SIG:process (A,B,C)
begin
D <= A; -- ignored !!
X <= C xor D;
D <= B; -- overrides !!
Y <= C xor D;
end process;
end Behavioral;
这段程序的本意是:X <= A xor C; Y <= B xor C。事实上,在利用ISE 10.1综合以后得到的结果如下图:
等效的逻辑图是这样的:
显然,综合器将信号A给忽略了,这跟我们希望的是不一致的。仔细观察综合过程发现,在综合时会产生一条WARNING:
Input is never used. This port will be preserved and left unconnected if it belongs to a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved.
大意是说输入从未使用,如果是顶层程序或者属于一个子模块并且该子模块有这个端口时,会被保留,其余情况下端口[url=]会被忽略掉。
2.变量
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity xor_sig is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
C : in STD_LOGIC;
X : out STD_LOGIC;
Y : out STD_LOGIC);
end xor_sig;
architecture Behavioral of xor_sig is
begin
VAR:process (A,B,C)
variable D: STD_LOGIC;
begin
D := A;
X <= C xor D;
D := B;
Y <= C xor D;
end process;
end Behavioral;
这段程序的本意与上面是一样的:X <= A xor C; Y <= B xor C。在利用ISE 10.1综合以后得到的结果如下图:
等效的逻辑图是这样的:
可以看出,采用变量时,程序综合的结果与我们希望的是一致的。
3.总结
在一个进程中,如果对一个信号多次赋值,那么,只有最后一个值才是有效的。如果对变量多次赋值,那么每次赋值都是有效的,并且,变量的值在再次赋值之前一直保持不变。
信号跟硬件有点类似,并且是在进程结束的时候才更新;变量是立即更新的,因此可以影响程序的功能,但变量的好处是仿真速度更快。
因此,通常情况下,推荐使用信号,可以保证程序的正确性。