VHDL的并行行为
在VHDL中,结构体的内部没有规定语句的次序,执行的次序仅由对语句中的敏感信号发生的事件决定,且语句是同时执行产生其并行性。
并行幅值语句 选择信号赋值语句 复杂赋值语句
并行赋值语句
< 对象> <= < 表达式>
每当表达式的信号值变化时执行该语句。每个表达式至少有一个敏感信号,每当敏感信号改变其值时,这个信号赋值语句就执行。
在所有的并行语句中,两个以上的并行赋值语句在字面上的顺序并不表明它们的执行顺序,例如下面的两个结构体在功能上是等价的。
例14:
ENTITY exe IS PORT(a1,a2:IN BIT; b1,b2:OUT BIT); END exe; |
实体 | |
ARCHITECTURE exe_arc1 OF exe IS BEGIN b1 <= a1 AND a2; b2 <= NOT a1 OR a2; END exe_arc1; |
结构体1 | |
ARCHITECTURE exe_arc2 OF exe IS BEGIN b2 <= NOT a1 OR a2; b1 <= a1 AND a2; END exe_arc2; |
结构体2 |
选择信号赋值语句 回页首
它们的每一个赋值语句都需要给出一个表达式,同时给出与该表达式的每个可能值相关联的信号,选择信号赋值语句的一般形式如下:
WITH < 表达式> SELECT
<对象> <= < 信号1> WHEN < 分支1> ,
< 信号2> WHEN < 分支2> ,
┇
< 信号n> WHEN < 分支n> ;
用一个典型的四路数据选择器的VHDL程序说明WITH一般形式的用法,实体产生的符号如图8-6所示。
例15:
ENTITY sels IS ARCHITECTURE sels_arc OF sels IS |
|
此例是一个六输入端口和一个输出端口的模块,四个输入是逻辑类型,两个输入是整数类型,程序对s敏感,判断s值后将d0、d1、d2或d3送到输出out1。 注:选择信号S提供四种选择,因此应是两位二进制代码,因此用粗线表示。 |
例16:
仍以四路数据选择器为例,图8-7示出此例的四输入数据选择器的符号,四输入数据选择器的第二个VHDL程序如下: | |
LIBRARY ieee; |
|
ARCHITECTURE mux4_arc OF mux4 IS SIGNAL sel :INTEGER ; BEGIN Q <=I0 AFTER 10 ns WHEN sel= 0 ELSE I1 AFTER 10 ns WHEN sel= 1 ELSE I2 AFTER 10 ns WHEN sel= 2 ELSE I3 AFTER 10 ns ; sel <=0 WHEN A= ‘0’ AND B= ‘0’ ELSE 1 WHEN A= ‘1’ AND B= ‘0’ ELSE 2 WHEN A= ‘0’ AND B= ‘1’ ELSE 3 ; END mux4_arc; |
AB=00,Q=I0; AB=10,Q=I1; AB=01,Q=I2; AB=11,Q=I3。 |
从程序的先后顺序看上去,四输入数据选择器的程序,好象不能工作,因为要用到的选择信号sel的值是以后计算出来的,事实上得出这种印像是来自计算sel在使用sel之后。但是,此程序是能够工作的,这就是因为VHDL语言的并行行为的特点,第一句和第二句是并行的。而第二句对信号A和B是敏感的,每当A和B的值变化时,将执行第二句来更新信号sel,第一句的程序对信号sel敏感,每当信号sel的值发生变化时,就执行第一句程序。 |
VHDL的并行行为
在VHDL中,结构体的内部没有规定语句的次序,执行的次序仅由对语句中的敏感信号发生的事件决定,且语句是同时执行产生其并行性。
并行幅值语句 选择信号赋值语句 复杂赋值语句
并行赋值语句
< 对象> <= < 表达式>
每当表达式的信号值变化时执行该语句。每个表达式至少有一个敏感信号,每当敏感信号改变其值时,这个信号赋值语句就执行。
在所有的并行语句中,两个以上的并行赋值语句在字面上的顺序并不表明它们的执行顺序,例如下面的两个结构体在功能上是等价的。
例14:
ENTITY exe IS PORT(a1,a2:IN BIT; b1,b2:OUT BIT); END exe; |
实体 | |
ARCHITECTURE exe_arc1 OF exe IS BEGIN b1 <= a1 AND a2; b2 <= NOT a1 OR a2; END exe_arc1; |
结构体1 | |
ARCHITECTURE exe_arc2 OF exe IS BEGIN b2 <= NOT a1 OR a2; b1 <= a1 AND a2; END exe_arc2; |
结构体2 |
选择信号赋值语句
它们的每一个赋值语句都需要给出一个表达式,同时给出与该表达式的每个可能值相关联的信号,选择信号赋值语句的一般形式如下:
WITH < 表达式> SELECT
<对象> <= < 信号1> WHEN < 分支1> ,
< 信号2> WHEN < 分支2> ,
┇
< 信号n> WHEN < 分支n> ;
用一个典型的四路数据选择器的VHDL程序说明WITH一般形式的用法,实体产生的符号如图8-6所示。
例15:
ENTITY sels IS ARCHITECTURE sels_arc OF sels IS |
|
此例是一个六输入端口和一个输出端口的模块,四个输入是逻辑类型,两个输入是整数类型,程序对s敏感,判断s值后将d0、d1、d2或d3送到输出out1。 注:选择信号S提供四种选择,因此应是两位二进制代码,因此用粗线表示。 |
例16:
仍以四路数据选择器为例,图8-7示出此例的四输入数据选择器的符号,四输入数据选择器的第二个VHDL程序如下: | |
LIBRARY ieee; |
|
ARCHITECTURE mux4_arc OF mux4 IS SIGNAL sel :INTEGER ; BEGIN Q <=I0 AFTER 10 ns WHEN sel= 0 ELSE I1 AFTER 10 ns WHEN sel= 1 ELSE I2 AFTER 10 ns WHEN sel= 2 ELSE I3 AFTER 10 ns ; sel <=0 WHEN A= ‘0’ AND B= ‘0’ ELSE 1 WHEN A= ‘1’ AND B= ‘0’ ELSE 2 WHEN A= ‘0’ AND B= ‘1’ ELSE 3 ; END mux4_arc; |
AB=00,Q=I0; AB=10,Q=I1; AB=01,Q=I2; AB=11,Q=I3。 |
从程序的先后顺序看上去,四输入数据选择器的程序,好象不能工作,因为要用到的选择信号sel的值是以后计算出来的,事实上得出这种印像是来自计算sel在使用sel之后。但是,此程序是能够工作的,这就是因为VHDL语言的并行行为的特点,第一句和第二句是并行的。而第二句对信号A和B是敏感的,每当A和B的值变化时,将执行第二句来更新信号sel,第一句的程序对信号sel敏感,每当信号sel的值发生变化时,就执行第一句程序。 |
VHDL的进程行为
VHDL除了并行行为之外,还有顺序行为。顺序行为执行的顺序是一个接在另一个之后执行。顺序行为的语句存在于VHDL程序中的进程行为之中,而进程行为本身之间是并行行为语句。
进程行为语句的一般形式如下:
< 进程标号> :PROCESS < 敏感信号表>
< 进程说明区>
BEGIN
< 语句部分>
WAIT ON < 敏感信号表> ;
WAIT UNTIL < 条件表达式> ;
WAIT FOR < 时间表达式> ;
END PROCESS;
进程标号——该进程的标号,它是可选项。
进程行为语句的关键字——PROCESS、BEGIN、WAIT ON、WAIT UNTIL、WAIT FOR和END PROCESS,其中PROCESS、BEGIN和END PROCESS关键字不能省略,其余关键字可根据程序特定需要决定去留。
敏感信号表——可以是一个或多个信号,每当其中一个或多个信号值改变时,进入进程,执行进程中的语句。敏感信号表部分也可省略,但进程语句要有其它形式的敏感信号激励;
敏感信号的其它形式——WAIT UNTIL和WAIT FOR,当满足WAIT UNTIL和WAIT FOR后面的条件表达式或时间表达式时可激活进程。
进程行为的说明区——定义该进程所需要的局部数据环境,它包括子程序说明、属性说明和变量说明等。在这里只给出变量说明的一个例子,变量说明的一般形式为:
VARIABLE < 定义变量表> :< 类型说明:= 初始值> ;
变量可以在一个进程或子程序的说明区中被说明,下例进程说明区中说明了变量count,并为count赋值。
例18:
PROCESS 这个进程行为语句涉及到两个新问题,第一是在说明区说明了变量count为整数而且初始值为0。第二是最后一句“WAIT FOR 1000 ns;”,它是等待激活的语句。这个程序在PROCESS后无敏感信号,这样进程也许被无限期地挂起,但用了“WAIT FOR 1000 ns;”语句,使进程行为语句可以被激活。整个程序分析是这样的:当进程被激活后,要使 count加1,然后被挂起,等到1000ns以后再次激活进程语句,执行count加1。 |
程序的执行
VHDL语言的每个结构体中可以有多进程行为语句,程序的执行顺序:
进程语句内部,程序是顺序执行的;
进程之间,程序是并行执行的。
进程的激活方式
每个进程语句敏感表中的一个或多个信号的值发生变化时,就要执行语句部分的特定行为,这个行为就是进程语句内部的顺序执行语句,得到的结果可以加在输出信号上,也可被其它进程读取。每当进程的某个敏感信号接受了新值时,所定义的顺序行为语句就要依次地执行一次,当进程的最后一句执行完后,进程就被挂起,敏感信号再次发生变化时,再从第一句依次执行。
1.由敏感信号激活
整个实体模块中的每个进程行为语句可以在敏感信号发生变化的时候被激活,所有被激活的进程是并行执行的,下面以一个3—8线通用译码器程序为例子,说明进程语句是如何进行工作的。
例19:
LIBRARY ieee; 每当在进程敏感表中的输入信号sel的值发生变化时,进程中的顺序语句就被执行。此例中进程语句内部首先通过转换函数CONV_INTEGER,将sel无符号数值转换到整数值sel1,然后CASE语句根据敏感表中的信号sel1的值,使8个输出端口之一为高电平,这是一句判别语句,直到满足条件为止。另外,此例不像上例需等待1000ns以后再激活进程,而是只要sel的值一发生改变就使进程激活,从第一句执行直到满足条件后再被挂起。 |
2. 由敏感条件激活
例20:
ENTITY reg IS 此例中用到了另一个等待进程语句WAIT UNTIL,从程序中可以看出结构体中有两个进程,两个进程语句的行为是并行的,第一个进程表示D触发器是高电平有效,因为进程语句中的信号d传到q1要等到clk为高电平,才能激活进程,完成数据的传输。第二个进程语句中,信号传到q2要等到clk为低电平才能完成,也就是clk低电平时,才能激活第二个进程行为语句。 |
VHDL的顺序行为
顺序语句在进程语句内部,顺序行为语句可分为两大类:一是条件控制类,二是循环控制类。
IF语句 CASE 语句 FOR语句 WHILE..LOOP语句 EXIT语句 断言语句
IF语句
IF语句的一般形式为: IF < 条件> THEN |
IF语句的一般形式是以关键字IF开头和关键字END IF结尾,END IF应分开写并且分开读。 |
例21:用VHDL设计一家用告警系统的控制逻辑,它有来自传感器的三个输入信号smoke、door、water和准备传输到告警设备的三个输出触发信号fire_alarm、burg_alarm、water_alarm以及使能信号en和alarm_en。VHDL程序描述如下:
LIBRARY ieee;
|
CASE 语句
CASE语句的一般形式:
CASE < 表达式> IS
WHEN < 值> => < 语句> ;
WHEN < 值> | < 值> => < 语句> ;
WHEN < 离散范围> => < 语句> ;
WHEN OTHERS => < 语句> ;
END CASE;
CASE语句是VHDL提供的另一种形式的控制语句,每当单个表达式的值在多个起作用的项中选择时,用此语句是较合适的,它根据所给表达式的值或域,选择“=>”后面的执行语句。
用CASE语句应该注意三个问题: 一是关键字WHEN的数量不作限制,但不容许两个语句用一个值; 二是CASE语句中WHEN后面的所有值合起来是表达式的值域; 三是WHEN的次序可以任意排定,但OTHERS必须在最后面,而且一个CASE 语句仅有一个OTHERS行。 |
FOR语句
FOR循环语句的一般形式为:
< 循环标号> :FOR < 循环变量> IN < 范围> LOOP
< 语句> ;
END LOOP < 循环标号> ;
下面举一两位二进制数乘方电路来说明循环FOR语句的用法:
例22:
FOR I IN 1 TO 3 LOOP 此例中循环语句变量为I,循环范围为“1 TO 3”,语句部分是乘方。
WHILE..LOOP循环语句的一般形式为: < 循环标号> :WHILE < 条件> LOOP 循环的条件是布尔表达式,在每次执行循环前检查条件为真时执行循环,为假时结束循环。 |
例23:
WHILE ( X< 10) LOOP 例题中语句部分执行的操作是加1,而表达式是X< 10。当X< 10为真时,执行语句部分X:= X+1,直到X等于10,表达式为假结束循环。 |
EXIT语句
上述两例是在不满足条件表达式或完成了循环的范围时退出循环,另一种退出循环是有严重错误发生时,EXIT语句允许提前退出正在执行的循环语句,去执行紧跟在循环语句后面的语句,下例解释这种情况。
例24:
在进程语句内部,假定int的值总是大于零。如果int的值是负或为0,则会得到一个错误的条件并且不能完成计算。此时,IF语句中的条件表达式为真,执行EXIT语句终止循环,去执行循环语句外面的另一条赋值语句Y <= q。循环语句还可以嵌套在另一个循环语句内部,使用EXIT语句,可以跳到较外的一个循环语句,也可以跳到循环最外部的程序,跳到哪里,视EXIT后面的标号而定,如: EXIT < 标号> ; |
断言语句
用断言语句对描述中的模型添加限制条件,报告一条文本的字符串。断言语句检查一个布尔表达式为真或为假,当条件为真,该语句任何事都不做;如果为假,断言语句将设计者规定的字符串输出到标准的输出终端,另外,还可以规定输出的严重级别,级别共分四种:注意(note)、告警(warning)、出错(error)和失败(failure)。按严重级别分类断言语句是设计者分析自己设计的电路的好办法,而且按断言语句的报告找到描述语言出错的位置。断言语句不构造硬件,主要用于模块的预期处理,所以和综合设计的硬件系统无关。
断言语句的一般形式如下:
ASSERT < 条件>
REPORT < 输出信息>
SEVERITY < 严重级别> ;
当条件为假时,系统的输出设备上将输出REPORT后面设计者规定的字符串信息和SEVERITY后面的严重级别。断言语句是非常有用的,它类似于C和Pascal语言中的陷井,当一些重要的限制未得到满足,或者发现不能处理的错误时,就会终止模拟分析过程,提供错误条件的性质和有用信息。下面讨论用VHDL语言设计RS触发器和断言语句在程序中的作用。
VHDL的顺序行为
顺序语句在进程语句内部,顺序行为语句可分为两大类:一是条件控制类,二是循环控制类。
IF语句 CASE 语句 FOR语句 WHILE..LOOP语句 EXIT语句 断言语句
IF语句
IF语句的一般形式为: IF < 条件> THEN |
IF语句的一般形式是以关键字IF开头和关键字END IF结尾,END IF应分开写并且分开读。 |
例21:用VHDL设计一家用告警系统的控制逻辑,它有来自传感器的三个输入信号smoke、door、water和准备传输到告警设备的三个输出触发信号fire_alarm、burg_alarm、water_alarm以及使能信号en和alarm_en。VHDL程序描述如下:
LIBRARY ieee;
|
CASE 语句
CASE语句的一般形式:
CASE < 表达式> IS
WHEN < 值> => < 语句> ;
WHEN < 值> | < 值> => < 语句> ;
WHEN < 离散范围> => < 语句> ;
WHEN OTHERS => < 语句> ;
END CASE;
CASE语句是VHDL提供的另一种形式的控制语句,每当单个表达式的值在多个起作用的项中选择时,用此语句是较合适的,它根据所给表达式的值或域,选择“=>”后面的执行语句。
用CASE语句应该注意三个问题: 一是关键字WHEN的数量不作限制,但不容许两个语句用一个值; 二是CASE语句中WHEN后面的所有值合起来是表达式的值域; 三是WHEN的次序可以任意排定,但OTHERS必须在最后面,而且一个CASE 语句仅有一个OTHERS行。 |
FOR语句
FOR循环语句的一般形式为:
< 循环标号> :FOR < 循环变量> IN < 范围> LOOP
< 语句> ;
END LOOP < 循环标号> ;
下面举一两位二进制数乘方电路来说明循环FOR语句的用法:
例22:
FOR I IN 1 TO 3 LOOP 此例中循环语句变量为I,循环范围为“1 TO 3”,语句部分是乘方。
WHILE..LOOP循环语句的一般形式为: < 循环标号> :WHILE < 条件> LOOP 循环的条件是布尔表达式,在每次执行循环前检查条件为真时执行循环,为假时结束循环。 |
例23:
WHILE ( X< 10) LOOP 例题中语句部分执行的操作是加1,而表达式是X< 10。当X< 10为真时,执行语句部分X:= X+1,直到X等于10,表达式为假结束循环。 |
EXIT语句
上述两例是在不满足条件表达式或完成了循环的范围时退出循环,另一种退出循环是有严重错误发生时,EXIT语句允许提前退出正在执行的循环语句,去执行紧跟在循环语句后面的语句,下例解释这种情况。
例24:
在进程语句内部,假定int的值总是大于零。如果int的值是负或为0,则会得到一个错误的条件并且不能完成计算。此时,IF语句中的条件表达式为真,执行EXIT语句终止循环,去执行循环语句外面的另一条赋值语句Y <= q。循环语句还可以嵌套在另一个循环语句内部,使用EXIT语句,可以跳到较外的一个循环语句,也可以跳到循环最外部的程序,跳到哪里,视EXIT后面的标号而定,如: EXIT < 标号> ; |
断言语句
用断言语句对描述中的模型添加限制条件,报告一条文本的字符串。断言语句检查一个布尔表达式为真或为假,当条件为真,该语句任何事都不做;如果为假,断言语句将设计者规定的字符串输出到标准的输出终端,另外,还可以规定输出的严重级别,级别共分四种:注意(note)、告警(warning)、出错(error)和失败(failure)。按严重级别分类断言语句是设计者分析自己设计的电路的好办法,而且按断言语句的报告找到描述语言出错的位置。断言语句不构造硬件,主要用于模块的预期处理,所以和综合设计的硬件系统无关。
断言语句的一般形式如下:
ASSERT < 条件>
REPORT < 输出信息>
SEVERITY < 严重级别> ;
当条件为假时,系统的输出设备上将输出REPORT后面设计者规定的字符串信息和SEVERITY后面的严重级别。断言语句是非常有用的,它类似于C和Pascal语言中的陷井,当一些重要的限制未得到满足,或者发现不能处理的错误时,就会终止模拟分析过程,提供错误条件的性质和有用信息。下面讨论用VHDL语言设计RS触发器和断言语句在程序中的作用