VHDL中的信号与变量仿真.docx

上传人:b****5 文档编号:5362234 上传时间:2022-12-15 格式:DOCX 页数:19 大小:490.71KB
下载 相关 举报
VHDL中的信号与变量仿真.docx_第1页
第1页 / 共19页
VHDL中的信号与变量仿真.docx_第2页
第2页 / 共19页
VHDL中的信号与变量仿真.docx_第3页
第3页 / 共19页
VHDL中的信号与变量仿真.docx_第4页
第4页 / 共19页
VHDL中的信号与变量仿真.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

VHDL中的信号与变量仿真.docx

《VHDL中的信号与变量仿真.docx》由会员分享,可在线阅读,更多相关《VHDL中的信号与变量仿真.docx(19页珍藏版)》请在冰豆网上搜索。

VHDL中的信号与变量仿真.docx

VHDL中的信号与变量仿真

从仿真语义的角度看VHDL中的信号与变量

摘要

变量和信号是VHDL语言中最为常用和最重要的两种数据对象,然而两者在实际的应用中却常常难以区分。

把握二者的特点和区别,并在电路设计中正确应用是成功完成电路设计的重要因素。

本文先是系统地对两者的相似之处和区别加以论述,然后则重从仿真语义的角度分析、概括两者的区别,并通过若干相似实例程序的仿真波形图、RTL电路显示这一区别。

关键词:

VHDL变量信号赋值延时

1VHDL中变量、信号的语法规则概述

在VHDL中,数据对象有三类:

变量(VARIABLE)、常量(CONSTANT)和信号(SIGNAL)。

数据对象类似于一种容器,它接受不同数据类型的赋值。

其中的变量、常量和高级程序设计语言如C语言中的变量、常量相类似。

而信号的表现较为特殊,它具有更多的硬件特性,是硬件描述语言所特有的数据对象。

然而,在VHDL的编程中,变量、信号在某些方面既有相同或相似之处,又有着质的区别,在实际应用中很容易混淆。

从硬件电路系统来看,“变量”和“信号”相当于电路系统中的门与门间的连线以及连线上的信号值;从行为仿真和VHDL语句功能上看,“变量”和“信号”具有明显的区别,其差异主要表现在接受和保持保证的方式及信息保持和传递的区域大小上。

例如,信号可以设置传输延迟量,而变量则不能;变量只能作为局部的信息载体。

变量的设置有时只是一种过渡,最后的信息传输和界面间的通信都要靠信号来完成。

1.1变量

在VHDL语法规则中,变量是一个局部变量,只能在进程和子程序中使用。

变量的赋值是一种理想化的数据传输,是立即发生的,不存在任何的延时行为。

其主要作用是在进程中作为临时的数据存储单元,即用于数据的暂存。

变量定义的一般表述如下:

VARIABLE变量名:

数据类型:

=初始值;

例如,要想定义一个名称为A的变量,其数据类型为标准逻辑位类型,初始值为1,其定义表述如下:

VARIABLEA:

STD_LOGIC:

=’1’;

虽然变量定义时可以定义初始值,但是综合器并不支持设置初始值。

故定义变量时多从仿真的角度出发,定义表述如下:

VARIABLE变量名:

数据类型;

然后,在需要的时候再对该变量进行赋值,变量赋值的表述如下:

目标变量名:

=表达式;

赋值语句右方的“表达式”必须是一个与“目标变量名”具有相同数据类型的数值,这个表达式可以是一个运算表达式,也可以是一个数值。

而且,新的变量值的获得是立即发生的。

1.2信号

信号是描述硬件系统的基本数据对象,它的性质类似于连接线。

信号可以作为设计实体中并行语句模块间的信息交流通道。

信号定义的语句格式如下:

SIGNAL信号名:

数据类型:

=初始值;

信号的赋值语句格式一般如下:

目标信号名<=表达式AFTER时间量;

同变量一样,信号的初始值的设置也不是必需的,而且初始值仅在VHDL的行为仿真中有效。

而与变量相比,信号的硬件特征更为明显,它具有全局的特性。

信号的使用、定义范围是实体、结构体和程序包,在进程和子程序的顺序语句中不允许定义信号。

另外,在进程中只能将信号列入敏感表,而不能将变量列入敏感表。

这里的“表达式”可以是一个运算表达式,也可以是数据对象(变量、信号或常量)。

数据信息的传入可以设置延时量,如AFTER3ns。

因此,目标信号获得传入的数据并不是即时的。

即使是零延时(不做任何显式的延时设置,即等效于AFTER0ns),也要经历一个特定的延时,即δ延时。

因此,符号“<=”两边的数值并不总是一致的,这与实际器件的传播延迟特性是相吻合的,因此这与变量的赋值过程有很大的差别。

信号的赋值可以出现在一个进程中,也可以直接出现在结构体的并行语句结构中,但他们运行的含义不一样。

前者属于顺序信号赋值,这时的信号赋值操作要视进程是否已经被启动,并且允许对同一目标信号进行多次赋值;后者属于并行信号赋值,其赋值操作是各自独立并行地发生的,且不允许对同一目标信号进行多次赋值。

2变量与信号的相同之处

●初始值的功效相同。

变量和信号定义的初始值都不是必需的,即使设置了,经综合后的硬件电路也不支持。

●变量与信号都具有能够接受赋值这一重要的共性。

在不完整的条件语句中,单独的变量赋值语句和信号赋值语句都能产生相同的时序电路,但此时变量已经不是简单的数据临时储存结构。

下面分别用利用变量和信号的VHDL描述构成一个D触发器。

程序清单1D触发器(变量)

LIBRARYIEEE;

UseIEEE.STD_LOGIC_1164.ALL;

entityD_variableis

port

--Inputports

CLK:

inSTD_LOGIC;

D:

inSTD_LOGIC;

--Outputports

Q:

outSTD_LOGIC

);

endD_variable;

architectureEXPofD_variableis

BEGIN

PROCESS(CLK)

VARIABLETemp_QV:

STD_LOGIC;

begin

ifCLK'EVENTANDCLK='1'then

Temp_QV:

=D;

endif;

Q<=Temp_QV;

ENDPROCESS;

--Q<=Temp_Q;

endEXP;

此代码在QUARTUSII中综合的时间戳如图1:

图1变量的VHDL描述构成D触发器在quartus综合的时间戳

工作时序如图2:

图2变量的VHDL描述构成D触发器的工作时序

生成的RTL电路如图3:

图3变量的VHDL描述构成D触发器的RTL电路

此代码在SynplifyPro9.0.1中综合的报告信息、时间戳如图4:

图4变量的VHDL描述构成D触发器在Synplify综合的时间戳

Synplify生成的RTL电路如图5:

图5变量的VHDL描述构成D触发器在Synplify中产生的RTL电路

程序清单2D触发器(信号)

LIBRARYIEEE;

UseIEEE.STD_LOGIC_1164.ALL;

entityD_signalis

port

--Inputports

CLK:

inSTD_LOGIC;

D:

inSTD_LOGIC;

--Outputports

Q:

outSTD_LOGIC

);

endD_signal;

architectureEXPofD_signalis

SIGNALTemp_QS:

STD_LOGIC;

BEGIN

PROCESS(CLK)

begin

ifCLK'EVENTANDCLK='1'then

Temp_QS<=D;

endif;

ENDPROCESS;

Q<=Temp_QS;

endEXP;

此代码在QUARTUSII中综合的时间戳如图6:

图6信号的VHDL描述构成D触发器在quartus综合的时间戳

工作时序如图7:

图7变量的VHDL描述构成D触发器的工作时序图

生成的RTL电路如图8:

图8变量的VHDL描述构成D触发器的RTL电路

由以上两个实例可以看出,虽然分别使用了变量和信号进行D触发器的描述,但他们综合后的结果却是一样的,工作时序一样,RTL电路也一样。

由此,可以说明,在不完整的条件语句中,单独的变量赋值语句和信号赋值语句都能产生相同的时序电路,但此时变量已经不是简单的数据临时储存结构。

3变量与信号的区别

3.1变量与信号在语句功能上的不同

从行为仿真和VHDL语句功能上看,信号和变量具有比较明显的区别,其主要差异表现在接受和保持信号的方式和信息保持与转递区域大小上。

3.1.1根本作用的区别

也就是说从硬件电路上看两者的区别:

●变量相当于进程中局部数据存储单元。

●信号相当于电路中的信号连线。

3.1.2定义位置不同

●变量声明在子程序、进程内部。

●信号声明在子程序、进程等外部。

3.1.3适用范围不同

●变量仅限于在定义了变量的进程和子程序中使用。

●信号的使用和定义范围是实体、结构体和程序包。

3.1.4语句功能区别小结

表1变量与信号赋值语句功能的比较

变量(VARIABLE)

信号(SIGNAL)

基本用法

用于作为进程中局部数据存储单元

用于作为电路中的信号连线

适用范围

只能在其所定义的进程中使用

在整个结构体内的任何地方都能适用

行为特性

立即赋值

在进程的最后才对信号赋值

3.2变量与信号在仿真功能上的不同

3.2.1延时行为特性不同

●变量的赋值是一种理想化的数据传输,是立即发生的,不存在任何延时行为。

●信号在VHDL中可以设置延时量,对信号赋值是按仿真时间进行的,到了进程的最后才进行赋值,这与实际硬件的传播延迟特性十分吻合。

下面通过两个实例仔细讨论一下变量与信号在延时行为特性上的不同。

程序清单3

LIBRARYIEEE;

UseIEEE.STD_LOGIC_1164.ALL;

entityD_3Vis

port

--Inputports

CLK:

inSTD_LOGIC;

D:

inSTD_LOGIC;

--Outputports

Q:

outSTD_LOGIC

);

endD_3V;

architectureEXPofD_3Vis

BEGIN

PROCESS(CLK)

VARIABLEA,B:

STD_LOGIC;

begin

ifCLK'EVENTANDCLK='1'then

A:

=D;

B:

=A;

Q<=B;

endif;

ENDPROCESS;

endEXP;

在quartusii中综合时的时间戳如图9:

图9

工作时序如图10:

图10

生成的RTL电路如图11:

图11

程序清单4

LIBRARYIEEE;

UseIEEE.STD_LOGIC_1164.ALL;

entityD_3Sis

port

--Inputports

CLK:

inSTD_LOGIC;

D:

inSTD_LOGIC;

--Outputports

Q:

outSTD_LOGIC

);

endD_3S;

architectureEXPofD_3Sis

SIGNALA,B:

STD_LOGIC;

BEGIN

PROCESS(CLK)

begin

ifCLK'EVENTANDCLK='1'then

A<=D;

B<=A;

Q<=B;

endif;

ENDPROCESS;

endEXP;

在quartusii中综合时的时间戳如图12:

图12

工作时序如图13:

图13

生成的RTL电路如图14:

图14

通过比较以上两例可以看出,变量和信号在上述VHDL描述中出现的结果截然不同,不论是工作时序图还是生成的RTL电路。

使用程序3仍然产生一个D触发器,而使用程序4却产生了三个串联的D触发器。

对于程序3,由于A、B都是变量,他们都具有临时保存数据的特性,而且他们的赋值更新是立即发生的,因而有了明显的顺序性。

当三条语句:

A:

=D;

B:

=A;

Q<=B;

顺序执行时,变量A和B便有了传递数据的功能。

语句执行的时候,先把输入D的值传递给A,再通过A传递给B,最后,在一个δ时刻之后,再由B传递给Q。

在上述语句执行的过程中,A和B只是作为输入D的数据的暂时存储单元。

Q最终被更新的数值是上一个时钟周期的输入D。

故,虽然程序3相比程序1而言,中间多了一个变量B,但是,他们的最终实现却是一样的,综合后产生单个的D触发器。

通过前面对信号这种数据对象的分析,我们可以看到信号行为特性的三个主要特性:

●信号的赋值需要有一个δ的延时。

比如程序4中的表达式:

A<=D,当语句执行到此句时,D向A的赋值是在一个δ的延时之后发生的,此时的A并没有立即得到更新,也就是说A并没有获得D的数值,而只是刚刚启动了一个延时为δ的模拟定时器,只有在延时为δ后,A才能被更新,获得D的赋值。

●在进程中,所有的赋值操作,当然也包括变量赋值,都必须在一个δ延时中完成,但变量的赋值操作在δ延时前就已经按顺序完成。

一方面,在进程中的所有信号赋值语句在进程启动的一瞬间就立即顺序起到那个各自的延时为δ的定时器,准备在定时器结束后分别执行赋值操作。

但是,在另一方面,这种顺序启动的间隔几乎为0,而在顺序执行到ENDPROCESS语句时,δ延时才会结束。

因此,这时在进程中的所有信号赋值操作几乎在同一时刻完成赋值。

即在进程中的顺序赋值操作是以近乎并行的方式“同时”完成,并且是在执行到ENDPROCESS语句的时候才会发生。

因此也不难理解,执行赋值操作和完成赋值是两个不同的概念,而对于类似C语言这样的高级软件语言,执行一条语句的赋值和完成一条语句的赋值是没事什么区别的,但是对于VHDL这样的硬件描述语言其情况就大不相同了。

“执行赋值操作”只是一个过程而已,它具有顺序的特征;而“完成赋值操作”则是一种结果,它的发生具有硬件描述语言最本质的并行特征。

●当进程中存在同一个信号有多个赋值源,也就是对同一个信号进行多次赋值操作时,实际完成赋值,即赋值对象的数值发生更新的信号是最接近ENDPROCESS语句的信号。

而对于程序4,由于三个赋值语句:

A<=D;

B<=A;

Q<=B;

都必须在遇到ENDPROCESS后的δ时刻内执行,所以他们具有了近乎并行执行的特性,即语句:

A<=D中的A和语句:

B<=A中的A并非是同一个时刻的数值,B<=A与Q<=B中的B也不是同一个时刻的B,他们都相差一个δ时间。

故,在同一个时刻中,D不可能直接将数值传递到Q,是Q得到更新。

在实际的应用中,A被更新的值是上一个时钟周期的D,也就是当前时钟上升沿以前的数值,B被更新的数值是上一个时钟周期的A,而Q被更新的数值也同样是上一个时钟周期的B。

因此,本程序的综合结果将会是三个串联的D触发器。

3.2.2信息作用区域不同

●变量只能作为局部的信息载体,如只能在定义的进程中传递。

●信号则可作为模块间的信息载体,如在结构体中进行信息传递。

信号用于内部信号,而非外部信号(外部信号对应为IN,OUT,INOUT,BUFFER),其在元件之间起互联作用,可以赋值给外部信号。

3.2.3进程中的表现不同

●在进程中不能将变量列入敏感表。

●信号可以被列入敏感表。

这是因为信号能把进程外的信息带入进程内部,或将进程内的信息带出进程。

3.2.4保持信息方式不同

在一定程度上说变量的设置仅仅是一种过渡,是进程中的临时数据存储单元,最后的信息传输和界面间通信都需信号来完成。

●变量是虚的,仅仅是为了书写方便而引入的一个名称。

●信号是实际的,是外输入,或者是内部的一个存储元件。

3.2.5硬件特征不同

信号比变量具有更多的硬件特征,如实体中的信号,在其对应结构体中可视,具体体现在综合后的硬件电路结构上,信号比变量对应更多的硬件结构。

例如,我们要用VHDL语言描述设计一个最大数输出电路,该电路的输入数据位四组四个二进制数,输出为最大的一组数据。

现在,我们分别用变量和信号进行描述,看看他们分别都达到什么样的效果。

利用变量进行描述的源程序如程序清单5:

程序清单5

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

entityMax_Vis

port(Clk,reset:

instd_logic;

din0,din1,din2,din3:

instd_logic_vector(3downto0);

result:

outstd_logic_vector(3downto0)

);

endMax_V;

architectureEXPofMax_Vis

begin

process(Clk)

variabletemp:

std_logic_vector(3downto0);

begin

if(Clk'eventandClk='1')then

if(reset='1')then

result<="0000";

temp:

="0000";

else

temp:

=din0;

if(temp

temp:

=din1;

endif;

if(temp

temp:

=din2;

endif;

if(temp

temp:

=din3;

endif;

result<=temp;

endif;

endif;

endprocess;

endEXP;

在quartusii中综合时的时间戳如图15:

图15

工作时序如图16:

图16

可见,利用变量进行描述,达到了预期的设计要求。

生成的RTL电路如图17:

图17

利用变量进行描述的源程序如程序清单6:

程序清单6

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

entityMax_Sis

port(Clk,reset:

instd_logic;

din0,din1,din2,din3:

instd_logic_vector(3downto0);

result:

outstd_logic_vector(3downto0)

);

endMax_S;

architectureEXPofMax_Sis

signaltemp:

std_logic_vector(3downto0);

begin

process(Clk)

begin

if(Clk'eventandClk='1')then

if(reset='1')then

result<="0000";

temp<="0000";

else

temp<=din0;

if(temp

temp<=din1;

endif;

if(temp

temp<=din2;

endif;

if(temp

temp<=din3;

endif;

result<=temp;

endif;

endif;

endprocess;

endEXP;

在quartusii中综合时的时间戳如图18:

图18

工作时序如图19:

图19

可见,利用信号进行描述,没有达到预期的设计要求。

生成的RTL电路如图20:

图20

通过这两个实例的综合仿真结果,我们进一步分析两者的区别。

在程序6使用信号进行描述时,仿真波形出现了中间值temp的波形,而程序5则使用变量进行描述,仿真波形没有中间值temp的波形。

图16中的波形,输出result在每个Clk时钟的上升沿(在reset为低电平时)都能找到当前最大的输入值并输出该最大值。

而图19中的波形,总是最大值和中间值temp在有效的上升沿交替输出。

最大值和中间值之所以会交替出现,是因为在进程中的信号的赋值是在进程结束的时候更新的。

由于信号不能被立即更新,只能在δ延时后才能更新这一重要特性,使得上述工作时序混乱,最终也得不到预期的效果。

而变量和信号在延时上的不同之处直接导致了他们在硬件电路上的不同。

从图17和图20的差别可以看出,变量在综合后对应的电路连线相对信号在综合后产生的电路连线而言较简洁。

这也验证了变量的主要作用是在进程中作为临时的数据存储单元,即用于数据的暂存,信号的性质类似于连接线这一说法。

4总结

通过以上若干实验可以发现,从行为仿真和VHDL语句功能上看,信号与变量有着明显的区别,主要体现为接受和保持保证的方式以及信息保持和传递的区域大小上。

例如信号的有效域为整个结构体,可以存在于多个进程中,变量的使用范围只能在进程和子程序中使用;信号可以设置传输延迟量,而变量则不能;变量只能作为局部的信息载体,而信号可以作为模块间的信息载体;在进程中只能将信号列人敏感信号表,而不能将变量列人敏感信号表;信号的赋值只有在进程挂起时才发生代人,也就是在进程中给同一个信号赋值多次,只有最后一个值生效,而变量的赋值则是立即发生的;从波形仿真的结果可以看出,信号可以形成波形,而变量没有波形,只有当前值。

在实际的应用中,信号的行为更接近于硬件的实际情况,因此应更多地使用信号进行电路内部的数据传递,只有在描述一些用信号很难描述的算法时才会用到变量。

5参考资料

1、《EDA技术实用教程(第三版)》,潘松、黄继业编著,科学出版社

2、VHDL中的信号与变量比较,张文,内江师范学院物理学与电子信息工程系

3、VHDL语言中信号与变量赋值语句的应用,柳莹、蒋本珊,北京理工大学计算机系

4、VHDL程序设计中的变量与信号,张霞,华中科技大学

5、

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 院校资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1