第三章VHDL的语句VHDL中的语句按其执行顺序可分为顺序描述语句和.docx
- 文档编号:6275395
- 上传时间:2023-01-05
- 格式:DOCX
- 页数:42
- 大小:34.98KB
第三章VHDL的语句VHDL中的语句按其执行顺序可分为顺序描述语句和.docx
《第三章VHDL的语句VHDL中的语句按其执行顺序可分为顺序描述语句和.docx》由会员分享,可在线阅读,更多相关《第三章VHDL的语句VHDL中的语句按其执行顺序可分为顺序描述语句和.docx(42页珍藏版)》请在冰豆网上搜索。
第三章VHDL的语句VHDL中的语句按其执行顺序可分为顺序描述语句和
第三章VHDL的语句
VHDL中的语句按其执行顺序可分为顺序描述语句和并行描述语句两大类。
顺序描述语句的执行顺序是按语句的书写顺序依次执行的,常用于实现模块的算法部分;并行描述语句的执行顺序与书写顺序无关,所有语句是并发执行的,常用于表示模块间的连接关系。
本章将详细介绍这两类VHDL语句。
3.1VHDL语言的顺序描述语句
顺序语句是建模进程、过程和函数功能的基本语句单元,它只能在进程、过程和函数中使用,其执行顺序按照书写顺序来执行,同时前面语句的执行结果会对后面语句的执行结果产生影响。
顺序描述语句按照控制方式分为条件控制语句和迭代控制语句,其中,条件控制语句有IF语句和CASE语句,迭代控制语句有循环语句和顺序断言语句。
下面对顺序描述语句进行详细介绍。
3.1.1信号赋值语句与变量赋值语句
采用VHDL描述硬件电路的过程中,数据的传递和端口界面数据的读写都是通过赋值语句来实现的,赋值语句就是将一个数值或表达式传递给某一个数据对象的语句。
VHDL提供了两类赋值语句:
信号赋值语句和变量赋值语句。
信号虽然只能在VHDL程序的并行部分进行说明,但是它在程序的顺序部分和并行部分都可使用。
信号赋值语句的语法如下:
待赋值信号<=表达式;
变量的说明和赋值操作都只能在程序的顺序部分进行。
变量赋值语句的语法如下:
待赋值变量:
=表达式;
注意:
不论是信号还是变量,赋值符号两边必须具备相同的数据类型和位长。
在前一章我们讲过信号与变量的区别,这里有必要重申一下:
信号赋值的执行和信号值的更新之间是有一定延迟的,只有经过延迟后信号才能得到新值,否则保持原值;而变量赋值的语句执行后立即得到新值,没有延迟。
上面讲到,信号赋值会有延迟,其实,VHDL允许为信号赋值选择“延迟机制”,即:
传输延迟或惯性延迟,其中,传输延迟用于表示无论输入脉冲宽度多窄都能在输出端无失真复现的延迟模型;惯性延迟用于表示输入脉冲传播时间受电路“惯性”影响的延迟模型。
VHDL默认的延迟模型是惯性延迟。
由于信号的赋值有延迟,任何对信号的赋值都暂存于该信号的驱动器中,什么时候把新值代入信号,有待同步事件发生或延迟达到由保留字after指定的时间,例如:
a<=0after5ns,1after10ns;
after指定的延迟时间应从执行信号赋值语句的模拟时刻起开始计算,如上例,假设在100ns时执行该语句,那么把0值代入a的时刻是105ns,而把1值代入a的时刻是110ns。
信号赋值语句本身的执行是不耗费时间的。
3.1.2if语句
IF语句是具有条件控制功能的语句,它根据给出的条件及其条件是否成立的结果来确定执行语句的顺序,其格式由三种:
第一种
IF条件THEN顺序语句
ENDIF
第二种
IF语句二选择控制,其书写格式为:
IF条件THEN
顺序处理语句;
ELSE
顺序处理语句;
ENDIF;
第三种
IF语句的多选择控制又称IF语句的嵌套,其书写格式为:
IF条件THEN
顺序处理语句;
ELSE
顺序处理语句;
……
ELSEIF条件THEN
顺序处理语句;
ELSE
顺序处理语句;
ENDIF;
下例是用if语句实现三态单向总线:
LIBRARYieee;
USEieee.std_logic_1164.all;――程序包使用说明
ENTITYbufsIS――ENTITY(实体)
PORT(din:
INstd_LOGIC_vector(7downto0);
dout:
OUTstd_LOGIC_vector(7downto0)bus;――PORT(端口定义)
en:
INstd_LOGIC);
ENDbufs;
ARCHITECTUREbufs1OFbufsIS――ARCHITECTURE(结构体)
BEGIN
process(en,din)--process(进程)en与din为进程敏感信号,控制进程的挂起和执行
begin
if(en='1')then
dout<=din;
else
dout<="ZZZZZZZZ";
endif;
endprocess;
endbufs1;
下例是用if语句实现四选一多路选择器:
LIBRARYieee;
USEieee.std_logic_1164.all;
entitymux4is
port(input:
instd_logic_vector(3downto0);
a,b:
instd_logic;
y:
outstd_logic);
endmux4;
architecturebe_mux4OFmux4is
signalsel:
std_logic_vector(1downto0);
begin
sel<=b&a;
process(input,sel)
begin
if(sel="00")then
y<=input(0);
elsif(sel="01")then
y<=input
(1);
elsif(sel="10")then
y<=input
(2);
else
y<=input(3);
endif;
endprocess;
endbe_mux4;
通过以上两例,希望读者对if语句的使用有所了解。
3.1.3case语句
CASE语句是另外一种条件控制语句,它是根据表达式的值来从不同的顺序处理语句中选取其中的一组语句来进行操作,常用来描写总线行为、编码器和译码器的结构。
与IF语句相比可读性好,非常简洁。
其书写格式为:
CASE表达式IS
WHEN条件表达式1=>顺序处理语句1;
WHEN条件表达式2=>顺序处理语句2;
………………….
WHEN条件表达式n-1=>顺序处理语句n-1;
WHENOTHERS=>顺序处理语句n;
ENDCASE;
条件句中的“=>”不是操作符,只相当于“THEN”作用。
下面是用case语句实现的译码器:
3-8译码器:
LIBRARYieee;
USEieee.std_logic_1164.all;
entitydecoder38is
port(a,b,c,g1,g2a,g2b:
instd_logic;
y:
outstd_logic_vector(7downto0));
enddecoder38;
architecturebehave38OFdecoder38is
signalindata:
std_logic_vector(2downto0);
begin
indata<=c&b&a;
process(indata,g1,g2a,g2b)
begin
if(g1='1'andg2a='0'andg2b='0')then
caseindatais
when"000"=>y<="11111110";
when"001"=>y<="11111101";
when"010"=>y<="11111011";
when"011"=>y<="11110111";
when"100"=>y<="11101111";
when"101"=>y<="11011111";
when"110"=>y<="10111111";
when"111"=>y<="01111111";
whenothers=>y<="XXXXXXXX";
endcase;
else
y<="11111111";
endif;
endprocess;
endbehave38;
七段显示译码器:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYDecL7SIS
PORT(A:
INSTD_LOGIC_VECTOR(3DOWNTO0);
LED7S:
OUTSTD_LOGIC_VECTOR(6DOWNTO0));
END;
ARCHITECTUREoneOFDecL7SIS
BEGIN
PROCESS(A)
BEGIN
CASEA(3DOWNTO0)IS
WHEN"0000"=>LED7S<="1111110";--X“3F”0
WHEN"0001"=>LED7S<="0110000";--X“06”1
WHEN"0010"=>LED7S<="1101101";--X“5B”2
WHEN"0011"=>LED7S<="1111001";--X“4F”3
WHEN"0100"=>LED7S<="0110011";--X“66”4
WHEN"0101"=>LED7S<="1011011";--X“6D”5
WHEN"0110"=>LED7S<="1011111";--X“7D”6
WHEN"0111"=>LED7S<="1110000";--X“07”7
WHEN"1000"=>LED7S<="1111111";--X“7F”8
WHEN"1001"=>LED7S<="1111011";--X“6F”9
WHEN"1010"=>LED7S<="1110111";--X“77”10
WHEN"1011"=>LED7S<="0011111";--X“7C”11
WHEN"1100"=>LED7S<="1001110";--X“39”12
WHEN"1101"=>LED7S<="0111101";--X“5E”13
WHEN"1110"=>LED7S<="1001111";--X“79”14
WHEN"1111"=>LED7S<="1000111";--X“71”15
WHENOTHERS=>NULL;
ENDCASE;
ENDPROCESS;
END;
case子句的WHEN子句有五种不同的书写格式,上面的两例中只用到了两种,设计人员可根据需要具体来选择使用哪一种:
(1)WHEN值=>顺序处理语句
(2)WHEN值|值|…|值=>顺序处理语句
(3)WHEN值TO值=>顺序处理语句
(4)WHEN值DOWNTO值=>顺序处理语句
(5)WHENOTHERS=>顺序处理语句
在VHDL中,采用case语句要注意以下几个方面:
1.条件表达式的所有可能值都必须在WHEN子句中列举出来。
2.WHEN子句的取值必须在条件表达式的取值范围之内。
3.不同的WHEN子句中不允许出现相同的表达式的取值。
4.WHEN子句可以任意颠倒顺序。
5.WHEN子句可以采用保留字others来表示所有具有相同操作的取值。
6.含有保留字others的WHEN子句只能在case语句中出现一次且只能放在最后。
3.1.4loop语句
Loop语句也叫循环语句,它是一种可用来实现迭代控制的语句。
它非常适用于进行位片逻辑或者迭代电路的功能描述。
在采用VHDL描述硬件电路的过程中,设计人员经常会遇到某些操作重复进行或操作重复进行到某个条件满足为止的情况,这时就可采用loop语句来进行有规则的循环操作。
Loop语句与高级语言的循环语句十分类似,使用loop语句将会使程序显得简单明了,并且可省掉大量的重复书写而节省了开发时间。
VHDL语言提供了两种形式的loop语句:
FOR模式的loop语句和WHILE模式的loop语句。
其中,FOR模式主要用于规定迭代次数的重复情况;WHILE模式则主要用于连续执行操作直至控制条件被判为“ture”的情况。
下面分别进行介绍。
(1)FOR模式的loop语句
在VHDL中,FOR模式的loop语句的语法如下:
[循环标号:
]FOR循环变量IN离散区间LOOP
顺序处理语句;
……………………..;
ENDLOOP[循环标号];
其中,循环标号是用来表示loop语句的唯一标识符,它是一个可选项;循环变量是一个属于loop语句的局部、临时的变量,它无需进行变量说明就可在语句中使用,同时这个变量只能作为赋值源,循环变量的值在每次的循环中都将发生变化;离散区间用来指定循环变量的取值范围,循环变量的取值将从取值范围的最左边的值开始递增到取值范围的最右边的值,也即指定了loop语句的循环次数,循环变量每取一个值就要执行依次循环体中的顺序处理语句,这正式loop语句的特殊之处。
下面给出了一个应用FOR模式的loop语句的例子,此例功能是将位矢量转换为整数:
LIBRARYIEEE;
USEIEEEstd_logic_1164.ALL;
ENTITYvector_to_integerIS
PORT(data_in:
INstd_logic_vector(7DOWNTO0);
flag:
OUTboolean;
data_out:
OUTinteger);
ENDvector_to_integer;
ARCHITECTUREbehaveOFvector_to_integerIS
BEGIN
PROCESS(data_in)
VARIABLEtemp:
integer:
=0;
BEGIN
flag<=false;
LOOP1:
FORiIN7DOWNTO0LOOP
temp:
=tmep*2;
IF(data_in(7-i)='1')THEN
temp:
=temp+1;
flag<=true;
ELSE
flag<=false;
ENDIF;
ENDLOOPLOOP1;
data_out<=temp;
ENDPROCESS;
ENDbehave;
其中,进程中的变量temp是一个局部变量,只能在进程中定义,循环变量i由FOR模式的loop语句局部的进行说明,它并不需要在进程、过程和函数中进行显示说明,循环变量i的具体取值为7-0,这也表示要循环八次才能将位矢量转化为整数。
Loop语句中的顺序处理语句由变量赋值语句和IF语句组成,用以逐位的将矢量转化为整数。
注意:
loop语句中隐式定义的变量i只能作为赋值源,即信号和变量的值不能赋给该变量;另外,由于标识符i已经被隐式说明,因此,loop语句中不允许出现与之相同的变量或信号标识符。
(2)WHILE模式的loop语句
在VHDL中,WHILE模式的loop语句的语法如下:
[循环标号:
]WHILE条件表达式LOOP
顺序处理语句;
………………;
ENDLOOP[循环标号];
其中,循环标号是用来表示loop语句的唯一标识符,它是一个可选项;“WHILE”后面跟一个布尔表达式,它的返回值为boolean类型,如果此返回值为“true”时,将会执行一次循环体中的顺序处理语句,执行完毕后回到该循环的开始,并再次检查条件表达式的值,如果返回值仍为“true”,接着执行一次循环体中的顺序处理语句,执行完毕后在回到该循环的开始,只要条件表达式的返回值为“true”,就会这么周而复始的执行,一旦检查到条件表达式的返回值为“false”时,那么程序将会结束循环并转而执行loop语句后面的语句从而跳出loop语句。
下面是应用WHILE模式的loop语句的例子,此例功能还是将位矢量转换为整数,大家可以比较一下此例与上例的区别:
LIBRARYIEEE;
USEIEEE.std_logic_1164.ALL;
ENTITYvector_to_integerIS
PORT(data_in:
INstd_logic_vector(7DOWNTO0);
flag:
OUTboolean;
data_out:
OUTinteger);
ENDvector_to_integer;
ARCHITECTUREbehaveOFvector_to_integerIS
BEGIN
PROCESS(data_in)
VARIABLEtemp:
integer:
=0;
VARIABLEi:
integer:
=0;
BEGIN
flag<=false;
LOOP1:
WHILE(i<8)LOOP
temp:
=tmep*2;
IF(data_in(i)='1')THEN
temp:
=temp+1;
i:
=i+1;
flag<=true;
ELSE
flag<=true;
ENDIF;
ENDLOOPLOOP1;
data_out<=temp;
ENDPROCESS;
ENDbehave;
从上例可以看出,WHILE模式的loop语句中的条件表达式的控制变量i需要事先定义,要进行显示的说明,同时变量i的递增操作也需要在循环处理语句中进行,这是与FOR模式的loop语句完全不同的,需要引起读者注意。
目前,一般的综合工具都可以对FOR模式的loop语句进行逻辑综合,但对WHILE模式的loop语句,仅有一些高级的综合工具才能对其进行逻辑综合,所以希望大家要使用loop语句时,尽量使用FOR模式的loop语句。
3.1.5null语句
VHDL中的null语句表示一种只占位置的空操作符,它不进行任何操作,其功能是使程序流程运行到下一个语句,null语句的语法十分简单,如下所示:
NULL;
Null语句经常用在case语句中,用来表示case语句中所剩余的条件选择值下的操作行为,从而满足case语句对条件选择值全部列举的要求。
下面举个例子具体说明null语句的用法:
LIBRARYieee;
USEieee.std_logic_1164.all;
entitymux4is
port(input:
instd_logic_vector(3downto0);
a,b:
instd_logic;
y:
outstd_logic);
endmux4;
architecturebe_mux4OFmux4is
signalsel:
std_logic_vector(1downto0);
begin
sel<=b&a;
process(input,sel)
begin
CASEselIS
WHEN"00"=>y<=input(0);
WHEN"01"=>y<=input
(1);
WHEN"10"=>y<=input
(2);
WHEN"11"=>y<=input(3);
WHENOTHERS=>NULL;
ENDCASE
endprocess;
endbe_mux4;
3.1.6return
在VHDL中,return语句只能在过程体和函数中使用,具体用来结束当前最内层过程体或是函数的执行,从而返回到主程序。
Return语句的语法结构有两种:
RETURN;(只能用在过程体中)
RETURN表达式;(只能用在函数中)
第一种结构用在过程体中,它表示无条件地结束过程体,不含有返回表达式;第二种结构用在函数中,它的表达式用来提供函数的返回值,并且结束函数的执行。
下面来看看具体的例子:
FUNCTIONmax(a,b:
integer)RETURNintegeris
VARIABLEtemp:
integer;
BEGIN
IF(a
temp:
=b;
ELSE
temp:
=a;
ENDIF
RETURN(temp);
ENDmax;
该函数的功能就是返回两个整数中的最大值。
一般的综合工具要求函数中只能有一个return语句,同时要求它只能用在函数的末尾。
目前也有一些高级综合工具可以支持函数中具有多个return语句,但是只有一个return语句被执行。
3.1.7跳出循环的语句
前面介绍的loop语句是一种自然跳出的循环语句,即只有完成了离散区间限定次数的操作或条件表达式的返回值为false时,loop语句才会跳出循环转而执行其它的语句,但是在某些情况下,我们需要人为的跳出本次或整个循环语句。
为此,VHDL提供了两种人为跳出循环语句:
一种是跳出本次循环的NEXT语句;另一种是跳出整个循环的EXIT语句。
3.1.7.1next语句
next语句是一种能控制循环语句执行的语句,它经常用在loop语句的内部,可以有条件或是无条件的结束循环并开始下一次的循环。
当next语句被执行时,循环语句中剩余的语句执行操作被终止,语句将跳到由循环标号所指定的新位置继续执行,或回到本层循环语句的入口处重新开始一次新的循环。
Next语句的语法如下:
NEXT[循环标号][WHEN条件表达式];
其中,循环标号是可选项,用来标明结束本次循环后下一次循环的起始位置,当next语句中没有循环标号时,语句将跳出循环回到本层循环语句的入口处重新开始一次新的循环;WHEN条件表达式也是可选项,保留字WHEN后面的条件表达式用来标明跳出本次循环的条件,当next语句中没有WHEN条件表达式时,将会无条件跳出本次循环。
下面是具体实例:
LIBRARYIEEE;
USEIEEEstd_logic_1164.ALL;
ENTITYcomparatorIS
PORT(x:
INstd_logic_vector(7DOWNTO0);
y:
INstd_logic_vector(7DOWNTO0);
eq:
OUTstd_logic);
ENDcomparator;
ARCHITECTUREbehaveOFcomparatorIS
BEGIN
PROCESS(x,y)
VARIABLEtemp:
std_logic;
BEGIN
temp:
='1';
LOOP1:
FORiIN0TO7LOOP
NEXTWHENtemp:
='0';
temp:
=tempAND(x(i)xnory(i));
ENDLOOPLOOP1;
eq<=temp;
ENDPROCESS;
ENDbehave;
上例可以看出,当x和y有不同的位时,temp:
='0'便为真,next后的语句便不会执行,跳出本次循环,如果i值没到7,会接着执行循环语句,接着遇到next语句跳出,直到i值为7,整个循环结束,eq=’0’代表x,y不同;当当x和y有相同时,不会执行next语句,整个程序执行完后,eq=’1’。
下面再看一例:
LIBRARYIEEE;
USEIEEEstd_logic_1164.ALL;
ENTITYlogic_andIS
PORT(x:
INstd_logic_vector(7DOWNTO0);
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第三 VHDL 语句 中的 执行 顺序 分为 描述