原创 (原创)VHDL中的signal和variable探讨

2009-2-13 22:49 5351 3 3 分类: FPGA/CPLD

本文通过一个实际的例子来对比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的上升沿才能使用。从而造成了“对变量的赋值是立即生效的,不存在延时”的说法,实际上这只是系统行为上的理解,实际上的延时还是存在的。
     以上是个人的一点理解,不对的地方还望大家探讨。

文章评论0条评论)

登录后参与讨论
我要评论
0
3
关闭 站长推荐上一条 /2 下一条