信号与变量区别

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; 

2.变量

等效的逻辑图是这样的: 
 

显然,综合器将信号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. 

大意是说输入
从未使用,如果是顶层程序或者属于一个子模块并且该子模块有这个端口时,会被保留,其余情况下端口会被忽略掉. 

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.总结

在一个进程中,如果对一个信号多次复制,那么,只有最后一个值才是有效的。如果对变量多次赋值,那么每次赋值都是有效的,

并且,变量的值在再次赋值之前一直保持不变。信号跟硬件有点类似,并且是在进程结束的时候才更新;变量是立即更新的,因此

可以影响程序的功能,但变量的好处是仿真速度更快。

基于以下几点原因,我们建议,编程时还是应以信号为主,尽量减少变量的使用。
(1)变量赋值无延时是针对进程运行而言的,只是一个理想值,对于变量的操作往往被综合成为组合逻辑的形式,而硬件上的组合逻辑必然存在输入到输出延时。当进程内关于变量的操作越多,其组合逻辑就会变得越大越复杂。假设在一个进程内,有关于变量的3个 级连操作,其输出延时 分别为5ns,6ns,7ns,则其最快的时钟只能达到18ns。相反,采用信号编程,在时钟控制下,往往综合成触发器的形式,特别是对于FPGA芯片而言,具有丰富的触发器结构,易形成流水作业,其时钟频率只受控于延时最大的那一级,而不会与变量一样层层累积。假设某个设计为3级流水作业,其每一级延时分别为10ns,11ns,12ns,则其最快时钟可达12ns。因此,采用信号反而更能提高设计的速度。
(2)由于变量不具备信息的相关性,只有当前值,因此也无法在仿真时观察其波形和状态改变情况,无法对设计的运行情况有效验证,而测试验证工作量往往会占到整个设计70%~80%的工作量,采用信号则不会存在这类问题。
(3)变量有效范围只能局限在单个进程或子程序中,要想将其值带出与其余进程、子模块之间相互作用,必须借助信号,这在一定程度上会造成代码不够简洁,可读性下降等缺点。

4.实际应用

使用变量

process(INTClk ,GPIO8)
begin
 if (GPIO8 = '1') then
INTState <= X"0";
   counter <= X"00000000";
 elsif (INTClk'event and INTClk = '1') then
  counter <= counter + 1;
case INTState is
when X"0" => IRQ7 <= '1';
if counter > X"72BF00" then--  (94ms)
counter <= X"00000000";
INTState <= X"1";
else
INTState <= X"0";
end if;
when X"1" => IRQ7 <= '0';
if counter > X"3A" then 
coun ter <= X"00000000";
INTState <= X"0";
else
INTState <= X"1";
end if;  
when others => null;
end case;
 end if;
end process;

注意:counter<=counter+1;的位置顺序一定要放counter复位前。

使用变量

process(INTClk ,GPIO8)
variable counter : std_logic_vector(31 downto 0);
begin
 if (GPIO8 = '1') then
INTState <= X"0";
   counter := X"00000000";
 elsif (INTClk'event and INTClk = '1') then
case INTState is
when X"0" => IRQ6 <= '1';
--if counter > X"70F760" then--7403360
if counter > X"50" then--7403360
INTState <= X"1";
counter := X"00000000";
else
INTState <= X"0";
end if;
when X"1" => IRQ6 <= '0';
--if counter > X"E380" then --58240
if counter > X"10" then --58240
counter := X"00000000";
INTState <= X"0";
else
INTState <= X"1";
end if;  
when others => null;
end case;
        counter := counter + 1;
 end if;
end process;


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值