![深入理解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=1738855757-9S5h6OoEmWzC6rVCH2pawnkedFkFJP9w-0-37b7a20e2a6d0e4c647342020c85819f)
2. if语句
常见的流程控制语句有if语句、case语句、loop语句、next语句、exit语句等,下面将分别对此做介绍。
if语句只能用在进程中,根据所指定的条件来确定执行哪些语句,因此if语句可以实现多选择控制。if语句的书写格式如下:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P60_5628.jpg?sign=1738855757-bM6fK2EypZqa9uG8NRJhjPeO9LiuHbSJ-0-e97f27a856fe3451e4dcace1b5f667e0)
if语句中条件为布尔表达式,如果满足条件,则执行关键词then后面的顺序语句;如果所有条件都不满足,则执行else后面的顺序语句,end if结束操作。
【例2.6】用if语句设计四选一数据选择器。
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P60_28095.jpg?sign=1738855757-uhrWX84048wzQNWVgcErmzvDuFrjMc18-0-622fdcf47c2ad6920e25203cecfd165e)
为保证综合性能,建议一个进程中只放一条if语句。且为避免冗长的路径延迟,不建议使用过长的if嵌套结构。
3. case语句
case语句与if语句功能相似,也是根据条件表达式的取值执行不同的语句。但是又有区别,确切地说,if语句实现的是优先权电路,而case语句实现的是平衡电路。case语句常用于描述总线、译码器和平衡编码器的结构。case语句的一般格式如下:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P60_28096.jpg?sign=1738855757-74p4sjS0zC51S2A9woUaC6lsf4gmg4xb-0-639fa3f82ef221ef68134eef260fcfce)
表达式可以是一个整数类型或枚举类型的值,也可以是由这些数据类型的值构成的数组,条件句中的选择值必在表达式的取值范围内,且覆盖表达式所有可能的取值,否则,必须使用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=1738855757-wNSBYQz1us6dFmEbsc2hj96rjipWcWU2-0-f7eb63177f923f5ade5f288488acc19b)
对于上例中的4选1数据选择器,我们可以将进程中的if语句用case语句替代如下:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P61_28099.jpg?sign=1738855757-AWGJKolDE7zucgEMgXRGBFlP4UNoACCF-0-1f8ae11402f3f2b8e3c2e589bc569943)
与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=1738855757-yN4bdJRiFzjuQqDiac6GzFzHpZdIkvhm-0-2d8d5a3b2c178145e9fcea514c1c4492)
for-loop语句中循环变量的值在每次循环中都发生变化,in后面跟随的离散范围表示循环变量在循环过程中依次取值的范围。EDA综合工具对for-loop语句支持较好,建议使用。
【例2.7】使用for循环变量语句描述8位奇偶校验电路。
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P62_28104.jpg?sign=1738855757-wfr8JCIg1cD5dBzqYTHmDQdFLmKbHONK-0-44e08fae1babe81426225b6046a2dc4d)
2)while-loop语句
格式如下:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P62_28106.jpg?sign=1738855757-zNvRKpKICGCCVuYfgTIUiHBntRA1HERI-0-149d171977797ad19009ba55726afbb4)
对于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=1738855757-UqfNbI66E7C6Zp58v0ZonzgFWI54nNxF-0-82012839101bc2237eeaf8846c554b7d)
如果语句中没有exit语句,则无条件loop语句将无限循环,不会停止。exit语句可以使它结束循环。例如:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P62_28108.jpg?sign=1738855757-cmP2FyWjC0Qqrbc16uI66GbDIEUmf6qp-0-7188b2cccff0e548ae7d92b55c3178d3)
5. next语句
next语句为loop的内部循环控制语句,控制循环提前进入下一轮循环,即跳过该语句后面的语句执行指定标号的下一轮循环。next语句的格式如下:
next [loop标号][when条件];
由格式可知,next语句有三种终止循环的形式:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P62_28109.jpg?sign=1738855757-zGZZD9r5gxpCuqp98FVTvhQ7kRfjCuaL-0-7bbe88f2cc1d0c279cef942e1796f94d)
6. exit语句
exit语句也为loop的内部循环控制语句,控制跳出循环。exit语句的格式如下:
exit [loop标号][when条件];
由格式可知,exit语句也有三种跳出循环的形式:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P62_28111.jpg?sign=1738855757-B9mL9pJh1coixyo9UyIDtJa8vMNahLvr-0-90ec87f09f13dd53a78072683b7bd8b7)
7. wait语句
在进程中或过程中,当执行到wait语句时,运行程序将被挂起,直到满足语句设置的结束挂起条件后,重新开始执行进程或过程中的程序。wait语句的格式有如下三种:
1)敏感信号等待语句
格式为:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P63_28119.jpg?sign=1738855757-G0QC7hmwEKlmAtaU05bwpIK4r6ua1Qb7-0-94279e241864d5e4191103b9b59f96d3)
wait on语句通常用在进程中,用以取代进程的敏感信号表。例如对于如下进程:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P63_28120.jpg?sign=1738855757-ewDS4AVoTEQgBeDlhi0pu0amRdgGyKVJ-0-c5d7d42c721d2597ef60507b79deaf53)
若用wait语句来取代,可以写成如下形式:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P63_28122.jpg?sign=1738855757-09GcRhev1JLzUNEuPkxqSxyW9CGA5b23-0-547164ac55f3d229cf728419f372e094)
在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=1738855757-ee3gnqJtS1ywD0JjNEsvSPAz9lklIt7T-0-11ad45bbdd8e33d444e82563fe5f9cdb)
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=1738855757-KkzVwVb7ukFoIx8fD9Ztit1pbtgoZ3BY-0-2b2dc7ca072c35bb1ce2e8bfc050e14f)
9. return语句
返回语句(return)用来中止子程序的运行。
1)过程返回语句
过程的返回语句格式如下:
return;
当执行了这个语句时,控制返回到该过程的调用点。
2)函数返回语句
函数的返回语句格式如下:
return返回值;
返回语句将返回值作为函数的输出值回送。例如:
![](https://epubservercos.yuewen.com/A3A866/18225431901802806/epubprivate/OEBPS/Images/Figure-P64_28133.jpg?sign=1738855757-P11Gn44jxhYoxlSW7Rqxa4lPlht9PJfs-0-a287da5970e765f717e82c631157f94c)