深入理解FPGA电子系统设计:基于Quartus Prime与VHDL的Altera FPGA设计
上QQ阅读APP看书,第一时间看更新

2.4 顺序语句

从仿真的角度看,顺序语句的执行顺序与它们的书写顺序是基本一致的,顺序语句只能出现在进程(process)、函数(function)和过程(procedure)中。顺序语句包括信号赋值语句、变量赋值语句、流程控制语句、等待语句、子程序调用语句、返回语句、空操作语句等。

从数据对象赋值的角度,可以把赋值语句分为信号赋值语句和变量赋值语句两种。信号赋值语句在2.3节中已有介绍,需要注意的是,信号赋值语句在进程外部使用时,是并行语句形式;在进程内部使用则是顺序语句形式。下面仅介绍变量赋值语句。

1. 变量赋值语句

变量的说明和赋值只能在进程、函数和过程中,且变量是局部量,变量值无法传递到进程和子程序的外部。变量赋值语句的格式为

     目的变量: = 表达式;

该语句的意思是将表达式的值赋值给目的变量,两者的类型应保持一致。

例如:

2. if语句

常见的流程控制语句有if语句、case语句、loop语句、next语句、exit语句等,下面将分别对此做介绍。

if语句只能用在进程中,根据所指定的条件来确定执行哪些语句,因此if语句可以实现多选择控制。if语句的书写格式如下:

if语句中条件为布尔表达式,如果满足条件,则执行关键词then后面的顺序语句;如果所有条件都不满足,则执行else后面的顺序语句,end if结束操作。

【例2.6】用if语句设计四选一数据选择器。

为保证综合性能,建议一个进程中只放一条if语句。且为避免冗长的路径延迟,不建议使用过长的if嵌套结构。

3. case语句

case语句与if语句功能相似,也是根据条件表达式的取值执行不同的语句。但是又有区别,确切地说,if语句实现的是优先权电路,而case语句实现的是平衡电路。case语句常用于描述总线、译码器和平衡编码器的结构。case语句的一般格式如下:

表达式可以是一个整数类型或枚举类型的值,也可以是由这些数据类型的值构成的数组,条件句中的选择值必在表达式的取值范围内,且覆盖表达式所有可能的取值,否则,必须使用when others来替代未列出的取值,同时要注意选择值之间不允许有重叠,case语句执行时必须选中,且只能选中所列条件语句中的一条。

选择值的写法非常灵活,例如选择表达式s的取值为0到9的整型数,通过s的不同取值,决定整型数y的“0”、“1”、“2”、“3”不同取值,用case语句设计如下:

对于上例中的4选1数据选择器,我们可以将进程中的if语句用case语句替代如下:

与if语句相比,case语句的可读性要稍好,但是case语句占用资源多于if语句。

4. loop语句

loop语句能使程序进行有规则的循环,循环的次数受迭代算法的控制,常用来描述迭代电路的行为。loop语句有如下三种形式。

1)for-loop语句

格式如下:

for-loop语句中循环变量的值在每次循环中都发生变化,in后面跟随的离散范围表示循环变量在循环过程中依次取值的范围。EDA综合工具对for-loop语句支持较好,建议使用。

【例2.7】使用for循环变量语句描述8位奇偶校验电路。

2)while-loop语句

格式如下:

对于for-loop来说,其循环变量是不可以通过for-loop内部的程序改变的,而while-loop语句的循环条件是可以在程序中改变的,while-loop语句在构造之初,就是为了仿真而设计的,因此一般EDA工具不支持while-loop语句的描述。

3)无条件loop语句

如果语句中没有exit语句,则无条件loop语句将无限循环,不会停止。exit语句可以使它结束循环。例如:

5. next语句

next语句为loop的内部循环控制语句,控制循环提前进入下一轮循环,即跳过该语句后面的语句执行指定标号的下一轮循环。next语句的格式如下:

     next [loop标号][when条件];

由格式可知,next语句有三种终止循环的形式:

6. exit语句

exit语句也为loop的内部循环控制语句,控制跳出循环。exit语句的格式如下:

     exit [loop标号][when条件];

由格式可知,exit语句也有三种跳出循环的形式:

7. wait语句

在进程中或过程中,当执行到wait语句时,运行程序将被挂起,直到满足语句设置的结束挂起条件后,重新开始执行进程或过程中的程序。wait语句的格式有如下三种:

1)敏感信号等待语句

格式为:

wait on语句通常用在进程中,用以取代进程的敏感信号表。例如对于如下进程:

若用wait语句来取代,可以写成如下形式:

在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 时间表达式;

若时间表达式表示的等待时间达到,则启动程序执行。例如:

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语句做如下修改:

9. return语句

返回语句(return)用来中止子程序的运行。

1)过程返回语句

过程的返回语句格式如下:

     return;

当执行了这个语句时,控制返回到该过程的调用点。

2)函数返回语句

函数的返回语句格式如下:

     return返回值;

返回语句将返回值作为函数的输出值回送。例如: