(原創)VHDL中的signal和variable探討
本文通過一個實際的例子來對比signal和variable的不同。
HDL代碼實現功能:對clk進行計數,當計數值等於4時,輸出flag=‘1’;
注:使用的綜合工具爲Synplify Pro V8.1
1、採用variable的HDL代碼
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY test IS
PORT(clk,cnt_en : IN STD_LOGIC;
num : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
flag : OUT STD_LOGIC);
END test;
ARCHITECTURE behav OF test IS
BEGIN
PROCESS(clk,cnt_en)
VARIABLE cnt_num : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
IF(clk 'EVENT AND clk='1')THEN
IF(cnt_en = '1')THEN
cnt_num := cnt_num + "0001";
END IF;
IF(cnt_num = "0100")THEN
flag <= '1';
ELSE
flag <= '0';
END IF;
END IF;
num <= cnt_num;
END PROCESS;
END behav;
綜合後的RTL圖
仿真波形
2、採用Signal的VHDL
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY test IS
PORT(clk : IN STD_LOGIC;
cnt_en : IN STD_LOGIC;
num : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
flag : OUT STD_LOGIC
);
END test;
ARCHITECTURE behav OF test IS
SIGNAL cnt_num : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
counter:PROCESS(clk,cnt_en)
BEGIN
IF(clk 'EVENT AND clk='1')THEN
IF(cnt_en = '1')THEN
cnt_num <= cnt_num + "0001";
END IF;
END IF;
num <= cnt_num;
END PROCESS;
comparer:PROCESS(clk,cnt_num)
BEGIN
IF(clk 'EVENT AND clk='1')THEN
IF(cnt_num = "0100")THEN
flag <= '1';
ELSE
flag <= '0';
END IF;
END IF;
END PROCESS;
END behav;
綜合後的RTL圖
仿真波形
3、思考總結
很多書上對變量都有這樣的解釋:對變量的賦值是立即生效的,不存在延時,而任何信號賦值是存在延時的。以前就總是想不通,將vhdl語言映射到實際的硬件電路上,怎麼可能不存在延時。
從以上的仿真波形圖1中,可觀察到num=4時,確實立即給出了flag=‘1’,不存在任何延時,與設計意圖完全一致。而仿真波形2中,則可看到必須在clk的rising_edge檢測到num=4且經過一小段延時後得到flag=‘1’。
如果僅這樣去理解變量的零延遲,就會造成以上的疑惑。實際上我們僅需關注的是cnt_num何時爲4,在1中,當num=3後,cnt_num+1立即得到執行,只需在第4個clk的上升沿將結果通過寄存器鎖存至flag即可。而在2中,當num=3時,需要1個clk完成加1操作,且需要另一個clk鎖存flag至輸出,故在第5個clk的rising_edge後纔會得到flag=‘1’。
從以上的分析可知,vhdl代碼1中的cnt_num <= cnt_num + "0001"的結果可以立即在判斷語句IF(cnt_num = "0100")THEN中使用,而vhdl代碼2中的cnt_num <= cnt_num + "0001"的結果由於延時的存在在下一個clk的上升沿才能使用。從而造成了“對變量的賦值是立即生效的,不存在延時”的說法,實際上這只是系統行爲上的理解,實際上的延時還是存在的。
以上是個人的一點理解,不對的地方還望大家探討。