VHDL设计中变量和信号探讨

2014-02-25 10:52刘琳吴维林
电脑知识与技术 2014年1期

刘琳 吴维林

摘要:随着航天产品中越来越广泛使用FPGA器件,熟练掌握VHDL硬件语言对于电路设计显得至关重要。变量和信号是VHDL语言中最为常用和最重要的两种数据对象,该文针对变量和信号的重要区别和使用技巧展开了探讨,并结合实际FPGA测试中的实例进行了详细的阐述和仿真验证。

关键词:FPGA;VHDL;变量和信号

中图分类号:TP31 文献标识码:A 文章编号:1009-3044(2014)01-0219-04

1 概述

随着EDA技术的发展,越来越多的航天产品中开始使用FPGA器件, FPGA设计中使用的硬件语言VHDL语言由于发展的较早,语法严格,非常适合大规模系统的设计,被航天产品设计师广泛应用。

变量和信号是VHDL语言中最为常用和最重要的两种数据对象,在电路设计中正确应用变量和信号是成功完成电路设计的重要因素。在对航天型号FPGA产品的评测过程中发现,设计师在使用VHDL语言时会对变量和信号的使用把握不准确,导致一些不必要的问题发生。因此,深入研究VHDL中变量和信号的基本特性和应用特点十分重要,对于提高FPGA的设计效率有着重要的意义。

2 变量和信号的主要区别

信号、变量和常量是VHDL中常用的2类数据对象。变量非常接近软件高级语言中的变量、而信号则具备更多的硬件特征,能对应硬件电路中的实际连线,是VHDL语言所特有的。信号和变量的用法和区别主要体现在以下几个方面。

1)变量是一个局部量,只能在进程和子程序中声明和使用。信号是一个全局量,使用和定义范围是实体、结构体和程序包,它具有全局性特征。例如,在实体中定义的信号可以被该实体中所有的进程使用。因此,信号可以作为信息交流通道在不同进程之间传递信息。

2)变量和信号的赋值语句不同,前者为“:=”,后者为“<=”。

3)进程中的敏感列表中可以有信号,不能有变量。

4)变量的赋值不存在延时,是立即发生的,而信号赋值都是有延时的。在一个进程中,如果对同一个信号多次赋值,仅最后一次赋值是有效的,如果对一个变量进行多次赋值,那么每次赋值都是有效的,变量的值在再次赋值之前一直保持不变。

结合以下的几个例子我们可以体会到变量和信号在赋值时的不同之处。在程序1中,由于信号赋值有延时,即进程结束时赋新值,所以结果是a和b 的值互换;而程序2中,由于变量赋值是立即更新的,所以结果是a和b的值均为b。

程序1:

architecture xinhao_arch of xinhao is

signal a,b : std_logic; —信号

begin

process (a,b)

begin

a <= b;

b <= a;

end process;

end xinhao_arch ;

程序2:

architecture bianliang_arch of bianliang is

begin

process

variable a,b : std_logic;—变量

begin

a := b;

b := a;

end process;

end bianliang_arch ;

程序3和程序4是将输入信号din用信号赋值和变量赋值的方法分别赋值给输出信号dout。我们分别比较两种情況下的区别。

程序3:

entity xh is

port(

din : in std_logic;—输入信号

clk : in std_logic;—时钟信号

dout : out std_logic –输出信号

);

end xh;

architecture xh_a of xh is

signal da,db: std_logic;—信号

begin

process(clk)

begin

if rising_edge(clk) then

da <= din;

db <= da;

end if;

end process ;

dout <= db;

end xh_a;

在程序3中,由于信号的赋值不是即时的,输入端口din的值在赋给输出端口dout时经过了2个时钟延时,所以它由2个D触发器构成,如图1和图2。

程序4:

entity bl is

port(

din : in std_logic;

clk : in std_logic;

dout : out std_logic

);

end bl;

architecture bl_b of bl is

begin

process(clk)

variable da,db: std_logic;—变量

begin

if rising_edge(clk) then

da := din;

db := da;

dout <= db;

end if;

end process ;

end bl_b;

程序4中,由于变量的赋值是即时的,相当于把输入端口din的的值赋给输出端口dout,所以它由一个D触发器构成,如图3、图4。

3 变量和信号赋初值技巧

在FPGA设计中,复位时赋予各个信号初值是很有必要的,否则可能出现不定态。在给变量和信号定义的时候虽然可以赋初值,但应该注意的是,这个初始值只是对于行为级仿真来说有用 , 综合器在综合时会忽略这些信息。

在某型号FPGA产品测试时发现设计师使用多个变量信号,并对这些变量信号赋初始值,前仿真结果正确,但后仿真中观测的信号为不定值,无法顺利进行后仿真。程序部分代码如下:

process(clk)

variable en : std_logic := '0';

variable cnt : std_logic_vector(1 downto 0) := (others =>'0');

begin

if rising_edge(clk) then

cnt := cnt + (clk2 and en);

en := not clk2

end if;

end process;

波形见下图5

分析其原因:在定义变量en和cnt时直接给其赋初始值并不能生效,这是因为综合过程中综合器将略去所有变量的初始值,因此变量en和cnt在后仿真中为不确定态,从而使得后仿真无法顺利进行。

为了实现对变量en和cnt赋初值,需要对程序进行如下修改。修改后仿真波形见下图6,后仿真结果正确。

process(clk)

variable en : std_logic;

variable cnt : std_logic_vector(1 downto 0);

begin

if rising_edge(clk) then

if reset = '0' then — reset为全局复位信号

cnt := (others=>'0');

en := '0';

else

cnt := cnt + (clk2 and en);

en := not clk2;

end if;

end if;

end process;

由此可见,信号和变量应该避免在定义时初始化赋值。而改由在相应的位置(如复位处)进行初始化。因此,无论是在仿真还是综合时,都建议使用这样的方法(在复位处)进行初始化。

4 变量和信号使用特点

在实际编程中,我们要结合变量和信号有各自的区别和优缺点在不同的情况下进行选择使用,尤其注意以下几个几点:

1)变量可以用来实现一些复杂的算法,也可以进行建模。对于仿真来说,使用变量一般可以提高程序的仿真速度,缩短测试周期,但在有的仿真器中也存在无法直接观测变量波形和变化值,使得仿真过程复杂化。

2)变量赋值虽然是无延时的,但变量的操作综合后容易在硬件上产生较大的延时,这是因为对变量的操作往往被综合成为组合逻辑。而信号更接近于硬件,综合后一般对应成触发器,能很好的控制硬件上的延时。因此,从这个意义上讲使用信号能提高设计的速度。

3)变量由于其有效范围只是局限在它所在的进程之中,因此要将變量的值传输到进程之外的话必须要先传输给信号,利用信号的全局特性进行信息传递。因此,程序中如果大量使用变量就必须同时定义若干个相关信号,在多个进程之间传递大量的信息十分的不方便,也大大降低了程序的可读性。而信号不存在这样的缺点,因此在实际设计中应尽量使用信号进行内部信息传递。

5 结束语

通过上面的讨论可知,在FPGA设计中,要特别注意信号和变量的区别和使用特点,灵活掌握信号和变量的使用技巧,提高设计效率。

参考文献:

[1] 侯伯亨,顾新.VHDL硬件描述语言与数字逻辑电路设计[M].西安电子科技大学出版社,1999.

[2] 潘松,黄继业.EDA技术应用教程[M].科学出版社,2006.

[3] 金宝根.VHDL中常用数据对象的应用及注意事项[J].信息技术,2012(5).