在用VHDL语言描述系统硬件行为时,按语句执行顺序对其进行分类,可以分为顺序(Sequential)描述语句和并发(Concurrent)描述语句。例如,进程语句(Process Statement)是并发语句。在一个构造体内可以有几个进程语句同时存在,各进程语句是并发执行的。但是,在进程内部所有语句应是顺序描述语句,也就是说按书写的顺序自上至下,一个语句一个语句地执行的。例如,IF语句、LOOP语句等都属于此类顺序描述语句。灵活运用这两类语句就可以正确地描述系统的并发行为和顺序行为。
现在来讲述并发描述语句吧~
在VHDL语言中能进行并发处理的语句有:进程( PROCESS)语句,并发信号代入(Concurrent Signal Assignment)语句,条件信号代入(Conditional Signal Assignment)语句,选择信号代入(Selective Signal Assignment)语句,并发过程调用(Concurrent Procedure Call)语句和块(BLOCK)语句。由于硬件描述语言所描述的实际系统,其许多操作是并发的,所以在对系统进行仿真时,这些系统中的元件在定义的仿真时刻应该是并发工作的。并发语句就是用来表示这种并发行为的。并发描述可以是结构性的也可以是行为性的。在并发语句中最关键的语句是进程。
一、进程语句
PROCESS语句是并发处理语句,在一个构造体中多个PROCESS语句可以同时并发运行。因此,PROCESS语句是VHDL语言中描述硬件系统并发行为的最基本的语句。PROCESS语句归纳起来有如下几个特点:
1.可以与其它进程并发运行,并可存取构造体或实体中所定义的信号;
2.进程结构中的所有语句都是顺序执行的;
3.要启动进程,在进程结构中必须包含一个显式的敏感信号量表;
4.进程之间的通信是通过信号量传递来实现的。
并发信号代入语句、条件信号代入语句等并发执行语句,实质上是一种进程的缩写形式,它们仍可以归属于进程语句。
二、并发信号代入语句
代入语句(信号代入语句)可以在进程内部使用,此时它作为顺序语句形式出现;代入语句(并发信号代入语句)也可以在构造体的进程之外使用,此时它作为并发语句形式出现。一个并发信号代入语句实际上是一个进程的编写。例如:
ARCHITECTURE behav OF a_var IS
BEGIN
Output <= a(i);
END behav;
可以等效于
ARCHITECTURE behave OF a_ var IS
BEGIN
PROCESS(a,i)
BEGIN
Output <= a(i);
END PROCESS;
END behav;
由信号代入语句的功能可以知道,当代入符号“<=”右边的信号值发生任何变化时,代入操作就会立即发生,新的值将赋予代入符号“<=”左边的信号。从进程语句描述来看,在PROCESS语句的括号中列出了敏感信号量表,例中是a和i。由PROCESS语句的功能可知,在仿真时进程一直在监视敏感信号量表中的敏感信号量a和i。一旦任何一个敏感信号量发生新的变化,进程将得到启动,代入语句将被执行,新的值将从Output信号量输出。
由上面叙述可知,并发信号代入语句和进程语句在这种情况下确实是等效的。
并发信号代入语句在仿真时刻同时运行,它表征了各个独立器件的各自的独立操作。例如:
a <= b + c;
d <= e * f;
第一个语句描述了一个加法器的行为,而第二个语句描述了一个乘法器的行为。在实际硬件系统中,加法器和乘法器是独立并行工作的。现在第一个语句和第二个语句都是并发信号代入语句,在仿真时刻,两个语句是并发处理的,从而真实地模拟了实际硬件系统中的加法器和乘法器的工作。
并发信号代入语句可以仿真加法器、乘法器、除法器、比较器及各种逻辑电路的输出。因此,在代入符号“<=”的右边可以用算术运算表达式,也可以用逻辑运算表达式,还可以用关系操作表达式来表示。
三、条件信号代入语句
条件信号代入语句也是并发描述语句,它可以根据不同条件将不同的多个表达式之一的值代入信号量,其书写格式为:
目的信号量< = 表达式 1 WHEN 条件1 ELSE
表达式2 WHEN 条件2 ELSE
表达式3 WHEN 条件3 ELSE
┇ ELSE
表达式n;
在每个表达式后面都跟有用“WHEN”所指定的条件,如果满足该条件,则该表达式的值代入目的信号量;如果不满足条件,则再判别下一个表达式所指定的条件。最后一个表达式可以不跟条件表达式。它表明,在上述表达式所指明的条件都不满足时,则将该表达式的值代入目标信号量。
例1就是利用条件信号代入语句来描述的四选一逻辑电路。
【例1】
ENTITY mux4 IS --实体
PORT(i0,i1,i2,i3,a,b:IN STD_LOGIC; --端口
q:OUT STD_LOGIC);
END mux4;
ARCHITECTURE rtl OF mux4 IS --结构体
SIGNAL sel:STD_LOGIC_VECTOR(1 DOWNTO 0);
BEGIN
sel <= b & a;
q <= i0 WHEN sel==“00”ELSE
i1 WHEN sel==“01”ELSE
i2 WHEN sel==“10”ELSE
i3 WHEN sel==“01”ELSE
‘X’;
END rtl;
条件信号代入语句与前述的IF语句的不同之处就在于,后者只能在进程内部使用(因为它们是顺序语句),而且与IF语句相比,条件信号代入语句中的ELSE是一定要有的,而IF语句则可以有也可以没有。另外,与IF语句不同的是,条件信号代入语句不能进行嵌套,因此,受制于没有自身值代入的描述,不能生成锁存电路。用条件信号代入语句所描述的电路,与逻辑电路的工作情况比较贴近,这样,往往要求设计者具有较多的硬件电路知识,从而使一般设计者难于掌握。一般来说,只有当用进程语句、IF语句和CASE语句难于描述时,才使用条件信号代入语句。
四、选择信号代入语句
选择信号代入语句类似于CASE语句,它对表达式进行测试,当表达式取值不同时,将使不同的值代入目的信号量。选择信号代入语句的书写格式如下:
WITH 表达式 SELECT
目的信号量<= 表达式1 WHEN 条件1,
表达式2 WHEN 条件2,
┇
表达式n WHEN 条件n;
下面仍以四选一电路为例说明一下该语句的使用方法,具体如例2所示。
【例2】
LIBRARY IEEE;
USE IEEE.STD_ LOGIC_1164.ALL;
ENTITY mux IS
PORT(i0,i1,i2,i3,a,b:IN STD_LOGIC;
q:OUT STD_LOGIC);
END mux;
ARCHITECTURE behav OF mux IS
SIGNAL sel:INTEGER;
BEGIN
WITH sel SELECT
q <= i0 WHEN 0,
i1 WHEN 1,
i2 WHEN 2,
i3 WHEN 3,
‘X’WHEN OTHERS;
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 WHEN a=‘1’AND b=‘1’ELSE
4;
END behav;
上例中的选择信号代入语句,根据sel的当前不同值来完成i0,i1,i2,i3及剩余情况的选择功能。选择信号代入语句在进程外使用。当被选择的信号发生变化时,该语句就会启动执行。由此可见,选择信号的并发代入,可以在进程外实现CASE语句进程的功能。例如,四选一电路用CASE语句进程所描述的程序如例3所示。
例3:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164. ALL;
ENTITY mux4 IS
PORT(input: IN STD_LOGIC_VECTOR(1 DOWNTO 0);
i0,i1,i2,i3:IN STD_LOGIC;
q:OUT STD_LOGIC);.
END inllX4 alal;
ARCHITECTURE rtl OF mux4 IS
BEGIN
PROCESS(input)
BEGIN
CASE input IS
WHEN “00” => q <= i0;
WHEN “01” => q <= i1;
WHEN “10” => q <= i2;
WHEN “11” => q <= i3;
WHEN OTHERS => q <=‘X’;
END CASE;
END PROCESS;
END rtl;
对照例2和例3可以看到,两者功能是完全一样的,所不同的仅仅是描述方法有区别而已。
4.1.5 并发过程调用语句
并发过程调用语句可以出现在构造体中,而且是一种可以在进程之外执行的过程调用语句。有关过程的结构及书写方法不再详述,这里仅就调用时应注意的几个问题作一说明。
1.并发过程调用语句是一个完整的语句,在它的前面可以加标号;
2.并发过程调用语句应带有IN,OUT或者INOUT的参数,它们应列于过程名后跟的括号内;
3.并发过程调用可以有多个返回值,但这些返回值必须通过过程中所定义的输出参数带回。
在构造体中采用并发过程调用语句的实例如下所示:
ARCHITECTURE …
BEGIN
vector_to_int(z,x.flag,q);
┇
END;
例中的vector_to_int并发过程调用是对位矢量z进行数制转换,使之变成十进制的整数。x.flag是标志位,当标志位为“真”表明转换失败,为“假”表明转换成功。
这种并发过程调用语句实际上是一个过程调用进程的简写。过程调用语句可以出现在进程语句中,如果该进程的作用就是进行过程调用,完成该过程的操作功能,那么两者是完全等效的。由此可知,上例的并发过程调用语句和下面的过程调用进程是完全等效的,因为两者都是为了完成位矢量至整数的转换。
ARCHITECTURE …
BEGIN
PROCESS(z,q)
BEGIN
vector_to_int(z,x.flag,q);
┇
END PROCESS:
END;
在构造体中的并发过程调用语句也由过程信号敏感量的变化而得到启动,例如上例的位矢量z的变化将使vector_to_int语句得到启动,并执行之。执行结果将拷贝到x.flag和q中,构造体中的其它语句就可以使用该结果。