![深入理解FPGA电子系统设计:基于Quartus Prime与VHDL的Altera FPGA设计](https://wfqqreader-1252317822.image.myqcloud.com/cover/453/34061453/b_34061453.jpg)
2.4 顺序语句
从仿真的角度看,顺序语句的执行顺序与它们的书写顺序是基本一致的,顺序语句只能出现在进程(process)、函数(function)和过程(procedure)中。顺序语句包括信号赋值语句、变量赋值语句、流程控制语句、等待语句、子程序调用语句、返回语句、空操作语句等。
从数据对象赋值的角度,可以把赋值语句分为信号赋值语句和变量赋值语句两种。信号赋值语句在2.3节中已有介绍,需要注意的是,信号赋值语句在进程外部使用时,是并行语句形式;在进程内部使用则是顺序语句形式。下面仅介绍变量赋值语句。
1. 变量赋值语句
变量的说明和赋值只能在进程、函数和过程中,且变量是局部量,变量值无法传递到进程和子程序的外部。变量赋值语句的格式为
目的变量: = 表达式;
该语句的意思是将表达式的值赋值给目的变量,两者的类型应保持一致。
例如:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P59_28091.jpg?sign=1738831960-lIoWBPHub9YUIny9ebkYsH4DwSj0NSEf-0-59126c5985104720f777fdb1c764bace)
2. if语句
常见的流程控制语句有if语句、case语句、loop语句、next语句、exit语句等,下面将分别对此做介绍。
if语句只能用在进程中,根据所指定的条件来确定执行哪些语句,因此if语句可以实现多选择控制。if语句的书写格式如下:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P60_5628.jpg?sign=1738831960-nCR8NXAwpvGcICXhu4G3463HFS0nLiEY-0-4c9cce438515c4f811b08587e2f2f9e8)
if语句中条件为布尔表达式,如果满足条件,则执行关键词then后面的顺序语句;如果所有条件都不满足,则执行else后面的顺序语句,end if结束操作。
【例2.6】用if语句设计四选一数据选择器。
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P60_28095.jpg?sign=1738831960-Wyf7b8xEAWfPTGseXtA1JPgBUGLykPEB-0-7b24e8ce3b73e36fa15e3bf901a32845)
为保证综合性能,建议一个进程中只放一条if语句。且为避免冗长的路径延迟,不建议使用过长的if嵌套结构。
3. case语句
case语句与if语句功能相似,也是根据条件表达式的取值执行不同的语句。但是又有区别,确切地说,if语句实现的是优先权电路,而case语句实现的是平衡电路。case语句常用于描述总线、译码器和平衡编码器的结构。case语句的一般格式如下:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P60_28096.jpg?sign=1738831960-XiUPhdAJb8x7qfeRRWnIohjOPSzagJ05-0-73f0e459517d75f2cf1fffdd8fabe172)
表达式可以是一个整数类型或枚举类型的值,也可以是由这些数据类型的值构成的数组,条件句中的选择值必在表达式的取值范围内,且覆盖表达式所有可能的取值,否则,必须使用when others来替代未列出的取值,同时要注意选择值之间不允许有重叠,case语句执行时必须选中,且只能选中所列条件语句中的一条。
选择值的写法非常灵活,例如选择表达式s的取值为0到9的整型数,通过s的不同取值,决定整型数y的“0”、“1”、“2”、“3”不同取值,用case语句设计如下:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P61_28098.jpg?sign=1738831960-U9NT3F13S2rDyAb1s1HAm9cty7hh2lyo-0-2c320daf5ae8ea11248a7483262b7a24)
对于上例中的4选1数据选择器,我们可以将进程中的if语句用case语句替代如下:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P61_28099.jpg?sign=1738831960-EJ6L23qhOl502lZ21Xu1dlyYMbczc3Yi-0-f90ef5597ebe4495a1a5b38919a0d009)
与if语句相比,case语句的可读性要稍好,但是case语句占用资源多于if语句。
4. loop语句
loop语句能使程序进行有规则的循环,循环的次数受迭代算法的控制,常用来描述迭代电路的行为。loop语句有如下三种形式。
1)for-loop语句
格式如下:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P61_28100.jpg?sign=1738831960-tyvAwUwUZPLF5EhqCXauzqTNbKE19G66-0-11f534e52def18a402fab017137c357f)
for-loop语句中循环变量的值在每次循环中都发生变化,in后面跟随的离散范围表示循环变量在循环过程中依次取值的范围。EDA综合工具对for-loop语句支持较好,建议使用。
【例2.7】使用for循环变量语句描述8位奇偶校验电路。
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P62_28104.jpg?sign=1738831960-ts1vFNl9QJGWtu5ld5adAE4pvFc9abnl-0-a9aa032553648260659fd0308deb38c8)
2)while-loop语句
格式如下:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P62_28106.jpg?sign=1738831960-DS98BWerh2nXQWYALQufbGFILnz35Lzp-0-7da171268e77392c89e405bdc9b2ea38)
对于for-loop来说,其循环变量是不可以通过for-loop内部的程序改变的,而while-loop语句的循环条件是可以在程序中改变的,while-loop语句在构造之初,就是为了仿真而设计的,因此一般EDA工具不支持while-loop语句的描述。
3)无条件loop语句
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P62_28107.jpg?sign=1738831960-Cok6I0xA1WiVMg17OTaFYxVKMnx1J2GK-0-89c30373c319aaf43d2f1a3b5d59595d)
如果语句中没有exit语句,则无条件loop语句将无限循环,不会停止。exit语句可以使它结束循环。例如:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P62_28108.jpg?sign=1738831960-ps30JfvUfFHjfdxdF1I721wIxbS0ju75-0-f7870fc3c17d0ae9e91f428d29666dbb)
5. next语句
next语句为loop的内部循环控制语句,控制循环提前进入下一轮循环,即跳过该语句后面的语句执行指定标号的下一轮循环。next语句的格式如下:
next [loop标号][when条件];
由格式可知,next语句有三种终止循环的形式:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P62_28109.jpg?sign=1738831960-rDvGoZ5JYy2ZIRd2UmwTjlyLHvRFAZAa-0-19ef467e0658b2b0ae1ff4ae0d2ac738)
6. exit语句
exit语句也为loop的内部循环控制语句,控制跳出循环。exit语句的格式如下:
exit [loop标号][when条件];
由格式可知,exit语句也有三种跳出循环的形式:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P62_28111.jpg?sign=1738831960-0e5MvOXJEvcuqpHuVoAE5pRqG6MfIGNS-0-6e1621bf8245639114980d33772da309)
7. wait语句
在进程中或过程中,当执行到wait语句时,运行程序将被挂起,直到满足语句设置的结束挂起条件后,重新开始执行进程或过程中的程序。wait语句的格式有如下三种:
1)敏感信号等待语句
格式为:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P63_28119.jpg?sign=1738831960-XQwLtmQ2ciW4jIJnlroejMEyuofxGa3w-0-15b6fcc5f56bdc1206c4435b712a415f)
wait on语句通常用在进程中,用以取代进程的敏感信号表。例如对于如下进程:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P63_28120.jpg?sign=1738831960-XpGdjOSES4dbEQQOFadg8UWGxJo3z5Xr-0-693f649bc46639281bf1228d2439eb60)
若用wait语句来取代,可以写成如下形式:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P63_28122.jpg?sign=1738831960-vTYc0frGIGSSFZ3LJODqodRX4pKaUxR7-0-f5bfbefe520433179644f79f7295d70d)
在VHDL程序仿真时,若进程含有敏感信号表,则每个带敏感信号表的进程都会先执行一遍,然后回到进程的初始处等待敏感信号的变化;若进程含有wait语句,则此进程先执行到首个wait语句处,再等待满足wait语句的条件。所以上述两段程序的仿真结果是一致的,综合后的电路也是相同的。
注意:一个进程中不可以既有敏感信号表,又有wait语句。
2)条件等待语句
格式为:
wait until 条件表达式;
表示若条件表达式满足,则启动程序执行。例如:
wait until clock='1'; wait until rising_edge (clock); wait until clock='1'and clock'event;
这三条wait语句生成的硬件电路结构是相同的。
3)等待时间到语句
格式为:
wait for 时间表达式;
若时间表达式表示的等待时间达到,则启动程序执行。例如:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P63_28123.jpg?sign=1738831960-74ywtiOdDdzbrSHnMoxE3PanhFXKP3Ph-0-80f2a6185cfe6fc9c02ba13a5377b5b3)
4)无限等待语句
格式为:
wait
进程中若存在一条无限等待语句,则进程将进入无限等待状态。此语句通常在仿真中使用。
另外,VHDL支持多条件的wait语句,例如:
wait on a, buntil Enable= '1'for 5 ns;
该wait语句有三个等待条件:①a或b发生变化;②条件Enable变为高电平;③时间经过5ns。只要一个条件满足,则该wait语句所在的进程就被启动。
8. null语句
null语句表示无任何动作。执行该语句只是为了使程序执行走到下一个语句。
格式为
null;
例如对于case语句中介绍的4选1数据选择器的设计,可以用null语句做如下修改:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P64_28132.jpg?sign=1738831960-ra12nS1DXECyMk0xnGM9lpJt9ZkIiOhT-0-72754be7d88273968f59c6c593239162)
9. return语句
返回语句(return)用来中止子程序的运行。
1)过程返回语句
过程的返回语句格式如下:
return;
当执行了这个语句时,控制返回到该过程的调用点。
2)函数返回语句
函数的返回语句格式如下:
return返回值;
返回语句将返回值作为函数的输出值回送。例如:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P64_28133.jpg?sign=1738831960-D8Pr5lRPdZEosbK3fQcGysTzub4bLIFm-0-788050d394950deda98da879b3577e9c)