VHDL的并行行为


 

VHDL的并行行为

在VHDL中,结构体的内部没有规定语句的次序,执行的次序仅由对语句中的敏感信号发生的事件决定,且语句是同时执行产生其并行性。   

并行幅值语句   选择信号赋值语句   复杂赋值语句

  • 并行赋值语句

< 对象>  <=  < 表达式>

每当表达式的信号值变化时执行该语句。每个表达式至少有一个敏感信号,每当敏感信号改变其值时,这个信号赋值语句就执行。

在所有的并行语句中,两个以上的并行赋值语句在字面上的顺序并不表明它们的执行顺序,例如下面的两个结构体在功能上是等价的。

例14:

  ENTITY   exe  IS
          PORT(a1,a2:IN BIT;  b1,b2:OUT BIT);
        END exe;
wpe2.gif (916 
    bytes) 实体
   ARCHITECTURE  exe_arc1  OF  exe  IS
           BEGIN
                b1 <=   a1 AND a2;
             b2 <=   NOT a1 OR a2;
       END  exe_arc1;
wpe2.gif (916 
    bytes) 结构体1
   ARCHITECTURE  exe_arc2  OF  exe  IS
  BEGIN
   b2 <=  NOT a1 OR a2;
    b1 <=  a1 AND a2;
  END  exe_arc2;
wpe3.gif (916 
    bytes) 结构体2

选择信号赋值语句                               回页首

    它们的每一个赋值语句都需要给出一个表达式,同时给出与该表达式的每个可能值相关联的信号,选择信号赋值语句的一般形式如下:

WITH  < 表达式>  SELECT
      <对象>  <=  < 信号1>  WHEN  < 分支1> ,
                 < 信号2>  WHEN  < 分支2> ,
              ┇
                 < 信号n>  WHEN  < 分支n> ;

用一个典型的四路数据选择器的VHDL程序说明WITH一般形式的用法,实体产生的符号如图8-6所示。

例15:四选一数据选择器

ENTITY  sels  IS                                 
 PORT(d0,d1,d2,d3:IN BIT;
       s   :INTEGER   RANGE  0 TO 3;
             out1  :OUT BIT);
 END  sels;

ARCHITECTURE  sels_arc  OF  sels  IS
BEGIN
  WITH  s  SELECT
    out1 <=  d0  WHEN  0,
     d1  WHEN  1,
     d2  WHEN  2,
     d3  WHEN  3;
END sels_arc;

wpe4.gif (1592 bytes)

此例是一个六输入端口和一个输出端口的模块,四个输入是逻辑类型,两个输入是整数类型,程序对s敏感,判断s值后将d0、d1、d2或d3送到输出out1。

注:选择信号S提供四种选择,因此应是两位代码,因此用粗线表示。


  • 复杂赋值语句

例16:

  仍以四路数据选择器为例,图8-7示出此例的四输入数据选择器的符号,四输入数据选择器的第二个VHDL程序如下:

LIBRARY  ieee;
USE  ieee.std_log_1164.all;
ENTITY  mux4  IS
 PORT(I0,I1,I2,I3,A,B:IN std_logic;
        Q          :OUT std_logic);
END  mux4;     

wpe7.gif (1587 bytes)

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;
 

wpe9.gif (947
    bytes)

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;
wpe2.gif (916 
    bytes) 实体
   ARCHITECTURE  exe_arc1  OF  exe  IS
           BEGIN
                b1 <=   a1 AND a2;
             b2 <=   NOT a1 OR a2;
       END  exe_arc1;
wpe2.gif (916 
    bytes) 结构体1
   ARCHITECTURE  exe_arc2  OF  exe  IS
  BEGIN
   b2 <=  NOT a1 OR a2;
    b1 <=  a1 AND a2;
  END  exe_arc2;
wpe3.gif (916 
    bytes) 结构体2

选择信号赋值语句                              

    它们的每一个赋值语句都需要给出一个表达式,同时给出与该表达式的每个可能值相关联的信号,选择信号赋值语句的一般形式如下:

WITH  < 表达式>  SELECT
      <对象>  <=  < 信号1>  WHEN  < 分支1> ,
                 < 信号2>  WHEN  < 分支2> ,
              ┇
                 < 信号n>  WHEN  < 分支n> ;

用一个典型的四路数据选择器的VHDL程序说明WITH一般形式的用法,实体产生的符号如图8-6所示。

例15:四选一数据选择器

ENTITY  sels  IS                                 
 PORT(d0,d1,d2,d3:IN BIT;
       s   :INTEGER   RANGE  0 TO 3;
             out1  :OUT BIT);
 END  sels;

ARCHITECTURE  sels_arc  OF  sels  IS
BEGIN
  WITH  s  SELECT
    out1 <=  d0  WHEN  0,
     d1  WHEN  1,
     d2  WHEN  2,
     d3  WHEN  3;
END sels_arc;

wpe4.gif (1592 bytes)

此例是一个六输入端口和一个输出端口的模块,四个输入是逻辑类型,两个输入是整数类型,程序对s敏感,判断s值后将d0、d1、d2或d3送到输出out1。

注:选择信号S提供四种选择,因此应是两位二进制代码,因此用粗线表示。


  • 复杂赋值语句

例16:

  仍以四路数据选择器为例,图8-7示出此例的四输入数据选择器的符号,四输入数据选择器的第二个VHDL程序如下:

LIBRARY  ieee;
USE  ieee.std_logic_1164.all;
ENTITY  mux4  IS
 PORT(I0,I1,I2,I3,A,B:IN std_logic;
        Q          :OUT std_logic);
END  mux4;     

wpe7.gif (1587 bytes)

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;
 

wpe9.gif (947
    bytes)

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
    VARIABLE  count:INTEGER:= 0;
    BEGIN
    count:= count+1;
    WAIT FOR  1000 ns;
    END PROCESS;

这个进程行为语句涉及到两个新问题,第一是在说明区说明了变量count为整数而且初始值为0。第二是最后一句“WAIT FOR 1000 ns;”,它是等待激活的语句。这个程序在PROCESS后无敏感信号,这样进程也许被无限期地挂起,但用了“WAIT FOR 1000 ns;”语句,使进程行为语句可以被激活。整个程序分析是这样的:当进程被激活后,要使 count加1,然后被挂起,等到1000ns以后再次激活进程语句,执行count加1。


  • 程序的执行

VHDL语言的每个结构体中可以有多进程行为语句,程序的执行顺序:

进程语句内部,程序是顺序执行的;

进程之间,程序是并行执行的。

  • 进程的激活方式

每个进程语句敏感表中的一个或多个信号的值发生变化时,就要执行语句部分的特定行为,这个行为就是进程语句内部的顺序执行语句,得到的结果可以加在输出信号上,也可被其它进程读取。每当进程的某个敏感信号接受了新值时,所定义的顺序行为语句就要依次地执行一次,当进程的最后一句执行完后,进程就被挂起,敏感信号再次发生变化时,再从第一句依次执行。

1.由敏感信号激活

整个实体模块中的每个进程行为语句可以在敏感信号发生变化的时候被激活,所有被激活的进程是并行执行的,下面以一个3—8线通用译码器程序为例子,说明进程语句是如何进行工作的。

  例19:

LIBRARY  ieee;
USE  ieee.std_logic_1164.all;
USE  ieee.std_logic_arith.all;
ENTITY  decoder   IS
      PORT(sel : IN UNSIGNED(2  DOWNTO  0);
             dout : OUT UNSIGNED(7  DOWNTO  0));
END  decoder;
ARCHITECTURE  decoder_arc  OF  decoder  IS
  SIGNAL  sel1 :INTEGER;
    BEGIN
        PROCESS(sel)
         BEGIN
           sel1 <= CONV_INTEGER(sel);
           CASE  sel1  IS
             WHEN  0  =>  dout <= (‘0’,’0’,’0’,’0’,’0’,’0’,’0’,’1’) AFTER  5 ns;
             WHEN  1  =>  dout <= (‘0’,’0’,’0’,’0’,’0’,’0’,’1’,’0’) AFTER  5 ns;
             WHEN  2  =>  dout <= (‘0’,’0’,’0’,’0’,’0’,’1’,’0’,’0’) AFTER  5 ns;
             WHEN  3  =>  dout <= (‘0’,’0’,’0’,’0’,’1’,’0’,’0’,’0’) AFTER  5 ns;
             WHEN  4  =>  dout <= (‘0’,’0’,’0’,’1’,’0’,’0’,’0’,’0’) AFTER  5 ns;
             WHEN  5  =>  dout <= (‘0’,’0’,’1’,’0’,’0’,’0’,’0’,’0’) AFTER  5 ns;
             WHEN  6  =>  dout <= (‘0’,’1’,’0’,’0’,’0’,’0’,’0’,’0’) AFTER  5 ns;
             WHEN OTHERS => dout <= (‘1’,’0’,’0’,’0’,’0’,’0’,’0’,’0’) AFTER 5 ns;
           END  CASE;
        END  PROCESS;
END  decoder_arc;

每当在进程敏感表中的输入信号sel的值发生变化时,进程中的顺序语句就被执行。此例中进程语句内部首先通过转换函数CONV_INTEGER,将sel无符号数值转换到整数值sel1,然后CASE语句根据敏感表中的信号sel1的值,使8个输出端口之一为高,这是一句判别语句,直到满足条件为止。另外,此例不像上例需等待1000ns以后再激活进程,而是只要sel的值一发生改变就使进程激活,从第一句执行直到满足条件后再被挂起。

2. 由敏感条件激活

  例20:

ENTITY  reg   IS
     PORT(d,clk:IN BIT;
              q1,q2:OUT  BIT);
END  reg;
ARCHITECTURE  reg_arc  OF  reg  IS
     BEGIN
        PROCESS
          BEGIN
            WAIT  UNTIL  clk= ‘1’;
               q1 <=  d;
          END  PROCESS;
        PROCESS
          BEGIN
            WAIT  UNTIL  clk= ‘0’;
               q2 <=  d;
          END  PROCESS;
END  reg_arc;

此例中用到了另一个等待进程语句WAIT UNTIL,从程序中可以看出结构体中有两个进程,两个进程语句的行为是并行的,第一个进程表示D是高电平有效,因为进程语句中的信号d传到q1要等到clk为高电平,才能激活进程,完成数据的传输。第二个进程语句中,信号传到q2要等到clk为低电平才能完成,也就是clk低电平时,才能激活第二个进程行为语句。

 

VHDL的顺序行为


  顺序语句在进程语句内部,顺序行为语句可分为两大类:一是条件控制类,二是循环控制类。   

IF语句 CASE 语句   FOR语句   WHILE..LOOP语句   EXIT语句 断言语句

IF语句

IF语句的一般形式为:

IF  < 条件>  THEN
  < 语句> ;
ELSIF < 条件>  THEN
  < 语句> ;
ELSIF < 条件>  THEN
  < 语句> ;
ELSE
  < 语句> ;
END IF;

  IF语句的一般形式是以关键字IF开头和关键字END IF结尾,END IF应分开写并且分开读。
  关键字ELEIF和ELSE是可选句,ELSIF可以多次使用,而ELSE仅可使用一次。
  < 条件>部分是一个布尔表达式,即是一种算出是真或是假的表达式,当条件为真时去执行接下来的语句部分;如果条件为假就去执行接下来可选的顺序语句ELSIF或ELSE。

例21:用VHDL设计一家用告警系统的控制逻辑,它有来自的三个输入信号smoke、door、water和准备传输到告警设备的三个输出触发信号fire_alarm、burg_alarm、water_alarm以及使能信号en和alarm_en。VHDL程序描述如下:

LIBRARY  ieee;
    USE ieee.std_logic_1164.all;
    ENTITY  alarm  IS
         PORT(smoke,door,water:IN std_logic;
                     en,alarm_en :IN std_logic;
                    fire_alarm,burg_alarm,water_alarm:OUT std_logic);
    END  alarm;
   ARCHITECTURE  alarm_arc  OF  alarm  IS
        BEGIN
             PROCESS(smoke,door,water,en,alarm_en)
                BEGIN
                   IF ((smoke= ‘1’) AND (en= ‘0’))  THEN
                       fire_alarm <=  ‘1’;
                  ELSE
                      fire_alarm <=  ‘0’;
                  END IF;
                  IF ((door= ‘1’) AND ((en= ‘0’) AND (alarm_en= ‘0’)))  THEN
                     burg_alarm <=  ‘1’;
                  ELSE
                     burg_alarm <=  ‘0’;
                 END IF;
                 IF ((water= ‘1’) AND (en= ‘0’)) THEN
                      water_alarm <=  ‘1’;
                 ELSE
                     water_alarm <=  ‘0’;
                END IF;
            END  PROCESS;
 END  alarm_arc;

程序中用了三个分开的IF语句描述其功能,它们都没有ELSIF关键字,可以看出每个IF语句描述了一个输出端口。第一个IF语句是检测有没有烟雾报警情况,有烟雾火警灾情发生立即产生报警信号,触发fire_alarm。第二和第三IF语句检测不同的报警信号,和第一句相仿。

此模块的输入端口有两个使能信号,en使所有的输入都能到达输出,而用alarm_en端口,只对防盗告警系统使能。需要指出的是这种功能很容易用逻辑方程描述,如前面的并行行为程序的例子。但是有时IF语句的形式是更可读、更容易理解。图8-11给出了报警控制逻辑图。

 


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
                         a(i):= i*i;
                    END  LOOP;

此例中循环语句变量为I,循环范围为“1  TO  3”,语句部分是乘方。

  • WHILE..LOOP语句

WHILE..LOOP循环语句的一般形式为:

< 循环标号> :WHILE  < 条件>  LOOP
                                                < 语句> ;
                END  LOOP  < 循环标号> ;

循环的条件是布尔表达式,在每次执行循环前检查条件为真时执行循环,为假时结束循环。

例23:

WHILE  ( X< 10)  LOOP
                            X:= X+1;
                   END  LOOP;

例题中语句部分执行的操作是加1,而表达式是X< 10。当X< 10为真时,执行语句部分X:= X+1,直到X等于10,表达式为假结束循环。


EXIT语句   

上述两例是在不满足条件表达式或完成了循环的范围时退出循环,另一种退出循环是有严重错误发生时,EXIT语句允许提前退出正在执行的循环语句,去执行紧跟在循环语句后面的语句,下例解释这种情况。

例24:

PROCESS (a)
           VARIABLE  int:INTEGER;
        BEGIN
            int:= a;
            FOR I IN 0 TO 255   LOOP
            IF (int <=  0) THEN
            EXIT;
            ELSE
               int:= int-1;
                  q(i) <= 3.1416/REAL(int*i);
            END IF;
          END  LOOP;
          Y <=  q;
       END  PROCESS;
              ┇

在进程语句内部,假定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
  < 语句> ;
ELSIF < 条件>  THEN
  < 语句> ;
ELSIF < 条件>  THEN
  < 语句> ;
ELSE
  < 语句> ;
END IF;

  IF语句的一般形式是以关键字IF开头和关键字END IF结尾,END IF应分开写并且分开读。
  关键字ELEIF和ELSE是可选句,ELSIF可以多次使用,而ELSE仅可使用一次。
  < 条件>部分是一个布尔表达式,即是一种算出是真或是假的表达式,当条件为真时去执行接下来的语句部分;如果条件为假就去执行接下来可选的顺序语句ELSIF或ELSE。

例21:用VHDL设计一家用告警系统的控制逻辑,它有来自传感器的三个输入信号smoke、door、water和准备传输到告警设备的三个输出触发信号fire_alarm、burg_alarm、water_alarm以及使能信号en和alarm_en。VHDL程序描述如下:

LIBRARY  ieee;
    USE ieee.std_logic_1164.all;
    ENTITY  alarm  IS
         PORT(smoke,door,water:IN std_logic;
                     en,alarm_en :IN std_logic;
                    fire_alarm,burg_alarm,water_alarm:OUT std_logic);
    END  alarm;
   ARCHITECTURE  alarm_arc  OF  alarm  IS
        BEGIN
             PROCESS(smoke,door,water,en,alarm_en)
                BEGIN
                   IF ((smoke= ‘1’) AND (en= ‘0’))  THEN
                       fire_alarm <=  ‘1’;
                  ELSE
                      fire_alarm <=  ‘0’;
                  END IF;
                  IF ((door= ‘1’) AND ((en= ‘0’) AND (alarm_en= ‘0’)))  THEN
                     burg_alarm <=  ‘1’;
                  ELSE
                     burg_alarm <=  ‘0’;
                 END IF;
                 IF ((water= ‘1’) AND (en= ‘0’)) THEN
                      water_alarm <=  ‘1’;
                 ELSE
                     water_alarm <=  ‘0’;
                END IF;
            END  PROCESS;
 END  alarm_arc;

程序中用了三个分开的IF语句描述其功能,它们都没有ELSIF关键字,可以看出每个IF语句描述了一个输出端口。第一个IF语句是检测有没有烟雾报警情况,有烟雾火警灾情发生立即产生报警信号,触发fire_alarm。第二和第三IF语句检测不同的报警信号,和第一句相仿。

此模块的输入端口有两个使能信号,en使所有的输入都能到达输出,而用alarm_en端口,只对防盗告警系统使能。需要指出的是这种功能很容易用逻辑方程描述,如前面的并行行为程序的例子。但是有时IF语句的形式是更可读、更容易理解。图8-11给出了报警控制逻辑电路图。

 


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
                         a(i):= i*i;
                    END  LOOP;

此例中循环语句变量为I,循环范围为“1  TO  3”,语句部分是乘方。

  • WHILE..LOOP语句

WHILE..LOOP循环语句的一般形式为:

< 循环标号> :WHILE  < 条件>  LOOP
                                                < 语句> ;
                END  LOOP  < 循环标号> ;

循环的条件是布尔表达式,在每次执行循环前检查条件为真时执行循环,为假时结束循环。

例23:

WHILE  ( X< 10)  LOOP
                            X:= X+1;
                   END  LOOP;

例题中语句部分执行的操作是加1,而表达式是X< 10。当X< 10为真时,执行语句部分X:= X+1,直到X等于10,表达式为假结束循环。


EXIT语句                

上述两例是在不满足条件表达式或完成了循环的范围时退出循环,另一种退出循环是有严重错误发生时,EXIT语句允许提前退出正在执行的循环语句,去执行紧跟在循环语句后面的语句,下例解释这种情况。

例24:

PROCESS (a)
           VARIABLE  int:INTEGER;
        BEGIN
            int:= a;
            FOR I IN 0 TO 255   LOOP
            IF (int <=  0) THEN
            EXIT;
            ELSE
               int:= int-1;
                  q(i) <= 3.1416/REAL(int*i);
            END IF;
          END  LOOP;
          Y <=  q;
       END  PROCESS;
              ┇

在进程语句内部,假定int的值总是大于零。如果int的值是负或为0,则会得到一个错误的条件并且不能完成计算。此时,IF语句中的条件表达式为真,执行EXIT语句终止循环,去执行循环语句外面的另一条赋值语句Y <=  q。循环语句还可以嵌套在另一个循环语句内部,使用EXIT语句,可以跳到较外的一个循环语句,也可以跳到循环最外部的程序,跳到哪里,视EXIT后面的标号而定,如:

EXIT  < 标号> ;


断言语句           

用断言语句对描述中的模型添加限制条件,报告一条文本的字符串。断言语句检查一个布尔表达式为真或为假,当条件为真,该语句任何事都不做;如果为假,断言语句将设计者规定的字符串输出到标准的输出终端,另外,还可以规定输出的严重级别,级别共分四种:注意(note)、告警(warning)、出错(error)和失败(failure)。按严重级别分类断言语句是设计者分析自己设计的电路的好办法,而且按断言语句的报告找到描述语言出错的位置。断言语句不构造硬件,主要用于模块的预期处理,所以和综合设计的硬件系统无关。

断言语句的一般形式如下:

ASSERT  < 条件>

REPORT  < 输出信息>

SEVERITY  < 严重级别> ;

当条件为假时,系统的输出设备上将输出REPORT后面设计者规定的字符串信息和SEVERITY后面的严重级别。断言语句是非常有用的,它类似于C和Pascal语言中的陷井,当一些重要的限制未得到满足,或者发现不能处理的错误时,就会终止模拟分析过程,提供错误条件的性质和有用信息。下面讨论用VHDL语言设计RS触发器和断言语句在程序中的作用