第四章 VHDL的主要描述语句

第四章 VHDL的主要描述语句

4.1   VHDL顺序语句

4.2   VHDL并行语句

VHDL语言进行设计时,按描述语句的执行顺序进行分类,可将VHDL语句分为顺序执行语句(Sequential)和并行执行语句(Parallel)。

4.1     VHDL顺序语句

    顺序语句是指完全按照程序中书写的顺序执行各语句,并且在结构层次中前面的语句执行结果会直接影响后面各语句的执行结果。顺序描述语句只能出现在进程或子程序中,用来定义进程或子程序的算法。顺序语句可以用来进行算术运算、逻辑运算、信号和变量的赋值、子程序调用等,还可以进行条件控制和迭代。

注意,这里的顺序是从仿真软件的运行和顺应VHDL语法的编程逻辑思路而言的,其相应的硬件逻辑工作方式未必如此。应该注意区分VHDL语言的软件行为与描述综合后的硬件行为的差异。

VHDL顺序语句主要包括:

·变量赋值语句(Variable Evaluate

·信号赋值语句(Signal Evaluate

·WAIT语句

·IF 语句

·CASE 语句

·LOOP 语句

·NEXT 语句

·EXIT 语句

·RETURN 语句

·NULL 语句

·过程调用语句(Procedure Call

·断言语句(Assert

·REPORT 语句

4.1.1 变量赋值语句

变量赋值语句语法格式为:

      变量赋值目标 := 赋值表达式

:

VARIABLE sBIT  := ‘0’

PROCESSs

VARIABLE countINTEGER  := ‘0’                --变量说明

BEGIN

     count := s+1                           --变量赋值

 END PROCESS;

4.1.2   信号赋值语句

VHDL语言中,用符号<=为信号赋值。

信号赋值语句的规范书写格式如下:

目的信号量 <= [TRANSPORT][INERTIAL]信号变量表达式;

其中[TRANSPORT]表示传输延迟[INERTIAL]表示惯性延迟。要求“<=”两边的信号变量类型和位长度应该一致。

:   s <=TRANSPORT  t  AFTER 10ns;      --传输延迟

      d <= INERTIAL 2 AFTER 3ns, 1 AFTER 8ns;       --惯性延迟

例:s <= a NORb AND c); --信号赋值由敏感信号引起

3个敏感量abc中任何一个发生变化,该语句都将被执行。

4.1.3  WAIT语句

   WAIT语句在进程中起到与敏感信号一样重要的作用,敏感信号触发进程的执行,WAIT语句同步进程的执行,同步条件由WAIT语句指明。进程在仿真运行中处于执行或挂起两种状态之一。当进程执行到等待语句时,就将被挂起并设置好再次执行的条件。WAIT语句可以设置4种不同的条件:无限等待、时间到、条件满足以及敏感信号量变化。这几类WAIT语句可以混合使用。现分别介绍如下:

1WAIT         --无限等待语句

这种形式的WAIT语句在关键字“WAIT”后面不带任何信息,是无限等待的情况。

2WAIT ON 信号表       --敏感信号等待语句

        这种形式的WAIT语句使进程暂停,直到敏感信号表中某个信号值发生变化。WAIT ON语句后面跟着的信号表,在敏感信号表中列出等待语句的敏感信号。当进程处于等待状态时,其中敏感信号发生任何变化都将结束挂起,再次启动进程。

[A]

PROCESS

BEGIN

y <= a AND b

WAIT ON ab--a,b为敏感信号,由WAIT列出

END PROCESS

[B]

PROCESSab--a,b为敏感信号,由PROCESS列出

BEGIN

y <= a AND b

END PROCESS

在例[A]中执行所有语句后,进程将在WAIT语句处被挂起,直到ab中任何一个信号发生变化,进程才重新开始。例[A]与例[B]是等价的。

需要注意的是,在使用WAIT ON语句的进程中,敏感信号量应写在进程中的WAIT ON语句后面;而在不使用WAIT ON语句的进程中,敏感信号量应在开头的关键词PROCESS后面的敏感信号表中列出。VHDL规定,已列出敏感信号表的进程不能使用任何形式的WAIT语句

3WAIT UNTIL 条件      --条件等待语句

这种形式的WAIT语句使进程暂停,直到预期的条件为真。WAIT UNTIL后面跟的是布尔表达式在布尔表达式中隐式地建立一个敏感信号量表,当表中任何一个信号量发生变化时,就立即对表达式进行一次测评。如果其结果使表达式返回一个值,则进程脱离挂起状态,继续执行下面的语句。即WAIT UNTIL语句需满足以下条件:

·在条件表达式中所含的信号发生了变化;

·此信号改变后,且满足WAIT UNTIL语句中表达式的条件。

这两个条件缺一不可,且必须按照上述顺序来完成。

WAIT UNTIL语句有以下三种表达方式:

          WAIT UNTIL 信号 = VALUE

          WAIT UNTIL 信号’EVENT AND信号 = VALUE

          WAIT UNTIL 信号’STABLE AND信号 = VALUE

例如:

     WAIT UNTIL clock = “1”

     WAIT UNTIL rising_edgeclk);

     WAIT UNTIL clk =‘1’AND clk’ EVENT

     WAIT UNTIL NOT clk’ STABLE AND clk= “1”

一般的,在一个进程中使用了WAIT语句后,综合器会综合产生时序逻辑电路时序逻辑电路的运行依赖WAIT UNTIL表达式的条件,同时还具有数据存储的功能。

4WAIT  FOR  时间表达式      --超时等待语句

例如:WAIT FOR 40 ns

在该语句中,时间表达式为常数40ns,当进程执行到该语句时,将等待40ns,经过40ns之后,进程执行WAIT FOR的后继语句。

例如:WAIT FORa*b+c))

在此语句中,(a*b+c))为时间表达式,WAIT FOR语句在执行时,首先计算表达式的值,然后将计算结果返回作为该语句的等待时间。

4.1.4  IF语句

       VHDL语言中,IF语句的作用是根据指定的条件来确定语句的执行顺序。IF语句可用于选择器、比较器、编码器、译码器、状态机等的设计,是VHDL语言中最常用的语句之一。IF语句按其书写格式可分为以下3种。

1.门闩控制语句

这类语句书写格式为:

      IF 条件  THEN

      顺序语句

       END IF

当程序执行到这种门闩控制型IF语句时,首先判断语句中所指定的条件是否成立。如果条件成立,则程序继续执行IF语句中所含的顺序处理语句;如果条件不成立,程序将跳过IF语句所包含的顺序处理语句,而向下执行IF的后继语句。

: 利用IF语句引入D触发器

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY dff  IS

    PORTclkdIN STD_LOGIC

                qOUT STD_LOGIC);
END dff

ARCHITECTURE rtl OF dff IS

BEGIN

              PROCESS (clk)

              BEGIN

             IF (clk’EVENT AND clk=’1’) THEN

              q <= d;

                   END IF;

              END PROCESS;

END rtl;

2.二选一控制语句

这种语句的书写格式为:

     TF 条件  THEN

         顺序语句

     ELSE

         顺序语句

     END IF

IF条件成立时,程序执行THENELSE之间的顺序语句部分;当IF语句的条件得不到满足时,程序执行ELSEEND IF之间的顺序处理语句。即依据IF所指定的条件是否满足,程序可以进行两条不同的执行路径。

:二选一电路结构体的描述

ARCHITECTURE rtl OF mux2 IS

BEGIN

        PROCESS (abs)

        BEGIN

       IF (s =’1’) THEN

          c <= a;

       ELSE

          c <= b;

       END IF;

       END PROCESS;

     END rtl;

3.多选择控制语句

这种语句的书写格式为:

IF 条件 THEN

         顺序语句

     ELSIF

         顺序语句

     ELSIF

         顺序语句

     

     ELSE

         顺序语句

     END IF

这种多选择控制的IF语句,实际上就是条件嵌套。它设置了多个条件,当满足所设置的多个条件之一时,就执行该条件后的顺序处理语句。当所有设置的条件都不满足时,程序执行ELSEEND IF之间的顺序处理语句。

: 利用多选控制语句设计的四选一多路选择器

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY mux4 IS

    PORTinputIN STD_LOGIC_VECTOR (3 DOWNTO 0)

              selIN STD_LOGIC_VECTOR (1 DOWNTO 0)

                yOUT STD_LOGIC);

END mux4

ARCHITECTURE rtl OF mux4 IS

BEGIN

   PROCESS (inputsel)

   BEGIN

       IF (sel=“00”) THEN

          y<= input0);

       ELSIFsel=“01”THEN

          y<= input1);

       ELSIFsel=“10”THEN

          y<= input2);

       ELSE

          y<= input3);

       END IF;

  END PROCESS;

END rtl;

4.1.5 CASE语句

CASE语句根据满足的条件直接选择多项顺序语句中的一项执行,它常用来描述总线行为、编码器、译码器等的结构

CASE语句的结构为:

CASE 表达式 IS

WHEN 条件选择值 => 顺序语句,

             

WHEN 条件选择值 => 顺序语句,

END CASE

其中WHEN条件选择值可以有四种表达方式;

1单个普通数值,形如WHEN 选择值 => 顺序语句;

2并列数值,形如WHEN // => 顺序语句;

3数值选择范围,形如WHEN TO => 顺序语句;

4WHEN OTHERS => 顺序语句;

当执行到CASE语句时,首先计算CASEIS之间的表达式的值,然后根据条件语句中与之相同的选择值,执行对应的顺序语句,最后结束CASE语句。

使用CASE语句需注意以下几点:

·CASE语句中每一条语句的选择值只能出现一次,即不能有相同选择值的条件语句出现。

·CASE语句执行中必须选中,且只能选中所列条件语句中的一条,即CASE语句至少包含一个条件语句。

·除非所有条件语句中的选择值能完全覆盖CASE语句中表达式的取值,否则最末一个条件语句中的选择必须用“OTHERS”表示,它代表已给出的所有条件语句中未能列出的其他可能的取值。关键词OTHERS只能出现一次,且只能作为最后一种条件取值。使用OTHERS是为了使条件语句中的所有选择值能覆盖表达式的所有取值,以免综合过程中插入不必要的锁存器。这一点对于定义为STD_LOGICSTD_LOGIC_VECTOR数据类型的值尤为重要,因为这些数据对象的取值除了10之外,还可能出现输入高阻态Z,不定态X等取值。

[1] CASE语句使用

CASE command IS

   WHEN “00”=> c <= a;                  --适合41数据选择器

   WHEN “01”=> c <= b;

   WHEN “10”=> c <= e;

   WHEN “11”=> c <= f;

   WHEN OTHERS => NULL;       --无效

END CASE;

[2] CASE语句使用

CASE  sel  IS

   WHEN 1TO 9 => c <= 1;

   WHEN 11/12 => c <= 2;

   WHEN OTHERS => c <= 3;

END CASE;

在例[2]中,第一个WHEN语句的意思是当sel 的值是从19  中任意一个数值时,信号c的值取1;第二个WHEN语句的意思是当sel 的值为1112两者之一时,信号 c 的取值为2;第三个WHEN语句的意思是当sel 的值不为前面两种情况时,信号c 的取值为3

[3] 3-8译码器。

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY decoder3_8 IS

    PORTabcg1g2ag2bIN STD_LOGIC

             yOUT STD_LOGIC_VECTOR (7 DOWNTO 0)

END decoder3_8

ARCHITECTURE rtl OF decoder3_8 IS

   SIGNAL indataSTD_LOGIC_VECTOR (2 DOWNTO 0)--说明

    BEGIN

   indata <=  c & b & a--合语句

   PROCESSindatag1g2ag2b

   BEGIN     

     IFg1=‘1’AND g2a=‘0’ AND g2b=‘0’THEN

        CASE indata IS

         WHEN “000”=> y <=“11111110”

         WHEN “001”=> y <=“11111101”

         WHEN “010”=> y <=“11111011”

         WHEN “011”=> y <=“11110111”

         WHEN “100”=> y <=“11101111”

         WHEN “101”=> y <=“11011111”

         WHEN “110”=> y <=“10111111”

         WHEN “111”=> y <=“01111111”

         WHEN OTHERS => y <= “XXXXXXXX”       - -X:不定

        END CASE

       ELSE                    --指不满足g1=‘1’AND g2a=‘0’ AND g2b=‘0’情况

         y <=“11111111”

       END IF

     END PROCESS

 END rtl

IF语句相比,CASE语句组的程序语句是没有先后顺序的,所有表达式的值都并行处理IF语句是有序的,先处理最起始、最优先的条件,后处理次优先的条件。

4.1.6  LOOP语句

LOOP语句就是循环语句,它可以使包含的一组顺序语句被循环执行,其执行的次数受迭代算法控制。在VHDL中常用来描述迭代电路的行为

1.单个LOOP语句

单个LOOP语句的书写格式如下:

     [标号:] LOOP

        顺序语句

     END LOOP[标号]

这种循环语句需引入其他控制语句(如EXIT)后才能确定,否则为无限循环。其中的标号是可选的。

例如:

loop1LOOP

      WAIT  UNTIL  clk=‘1’

      q <= d AFTER 2 ns

END LOOP loop1

2.FOR_LOOP语句

该语句语法格式为:

     [标号:] FOR 循环变量 IN  离散范围 LOOP

         顺序处理语句

         END LOOP[标号]

例: 8位奇偶校验电路

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY parity_check IS

    PORTaIN STD_LOGIC_VECTOR (7 DOWNTO 0)

             yOUT STD_LOGIC)

END parity_check

ARCHITECTURE rtl OF parity_check IS

BEGIN

   PROCESSa

        VARIABLE tmpSTD_LOGIC    

  BEGIN

     tmp=‘0’

     FOR i IN 0 TO 7 LOOP

       tmp= tmp XOR ai);

     END LOOP

     y <= tmp                       - -y=1a为奇数个‘1’y=0 a为偶数个‘1’

   END PROCESS

END rtl

3.WHILE_LOOP语句

这种语句的书写格式为:

[标号:] WHILE 条件 LOOP

          顺序处理语句

      END LOOP[标号]

        在该LOOP语句中,没有给出循环次数的范围,而是给出了循环执行顺序语句的条件;没有自动递增循环变量的功能,而是在顺序处理语句中增加了一条循环次数计算语句,用于循环语句的控制。循环控制条件为布尔表达式,当条件为时,则进行循环,如果条件为,则结束循环。

例:8位奇偶校验电路的WHILE_LOOP设计形式

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY parity_check IS

    PORTaIN STD_LOGIC_VECTOR (7 DOWNTO 0)

             yOUT STD_LOGIC)

END parity_check

ARCHITECTURE behav OF parity_check IS

BEGIN

   PROCESSa

        VARIABLE tmpSTD_LOGIC

  BEGIN

     tmp := ‘0’

     i := 0

     WHILE i < 8LOOP

     tmp := tmp XOR ai);

     i := i+1       --循环次数计算语句

     END LOOP

     y <= tmp

   END PROCESS

END behav

4.1.7 NEXT语句

NEXT语句的书写格式为:

      NEXT[标号][WHEN 条件]

        该语句主要用于LOOP语句内部的循环控制。当NEXT语句后不跟[标号]NEXT语句作用于当前最内层循环,即LOOP语句的起始位置进入下一个循环NEXT语句不跟[WHEN 条件]NEXT语句立即无条件跳出循环。

:NEXT语句应用举例

WHILE data >1 LOOP

    data :=  data+1

NEXT WHEN data=3            - -条件成立而无标号,跳出循环

    data := data* data

END LOOP

N1FOR i IN 10 DOWNTO 1 LOOP

    N2FOR j IN 0 TO i LOOP

    NEXT N1 WHEN  i=j     - -条件成立,跳到N1

        matrixij:= j*i+1 - -条件不成立,继续内层循环N2

    END LOOP N2

END LOOP N1

4.1.8  EXIT语句

EXIT语句的书写格式为:

    EXIT[LOOP标号][WHEN条件]

EXIT语句也是用来控制LOOP的内部循环,NEXT语句不同的是EXIT语句跳向LOOP终点,结束LOOP语句;而NEXT语句是跳向LOOP语句的起始点,结束本次循环,开始下一次循环。当EXIT语句中含有标号时,表明跳到标号处继续执行。[WHEN条件]时,如果条件为,跳出LOOP语句;如果条件为,则继续执行LOOP循环。

      EXIT语句不含标号和条件时,表明无条件结束LOOP语句的执行,因此,它为程序需要处理保护、出错和警告状态,提供了一种快捷、简便的调试方法。

[]两个元素位矢量ab进行比较,当发现ab不同时,跳出循环比较程序并报告比较结果。

SIGNAL abSTD_LOGIC_VECTOR (0 TO 1)

SIGNAL a_less_than_bBOOLEAN

 

a_less_than_b <= FALSE;

FOR i IN 1TO 0 LOOP

    IFai=‘1’AND bi=‘0’THEN  - - a1a0 b1b0比较大小

       a_less_than_b <= FALSE

       EXIT      --无条件跳出循环

    ELSEIFai=‘0’AND bi=‘1’THEN

       a_less_than_b <= TRUE

       EXIT

    ELSE

    NULL

    END IF

END LOOP

4.1.9 返回语句 RETURN

      RETURN语句是一段子程序结束后,返回主程序的控制语句。它只能用于函数与过程体内并用来结束当前最内层函数或过程体的执行。

RETURN语句的书写格式为:

RETURN

RETURN  表达式;

:在函数体中使用RETURN语句

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY example IS

    PORTabIN  INTEGER

             yOUT INTEGER)

END example

ARCHITECTURE rtl OF example IS

BEGIN

PROCESSab             --进程语句

    FUNCTION maximum --函数

            abINTEGERRETURN INTEGER IS            --return integer

        VARIABLE tmpINTEGER 

     BEGIN

        IFa > bTHEN

           tmp := a

        ELSE

           tmp := b

        END IF

    END maximum

  BEGIN

     y <= maximumab);          --调用函数

   END PROCESS

END rtl

上例是一个对两个输入整数取最大值的功能描述,在结构体的进程中定义了一个取最大值的函数。在函数体中正是通过RETURN语句将比较得到的最大值返回的,并结束该函数体的执行。

4.1.10 NULL语句

NULL语句是空操作语句,不完成任何操作,执行NULL语句只是让程序运行流程走到下一个语句。

NULL语句的书写格式为:

NULL

NULL语句常用于CASE语句中,利用NULL来表示所余的不用的条件下的操作行为,以满足CASE语句对条件值全部列举的要求。

例:采用NULL语句的四选一数据选择器。

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY mux4 IS

    PORTd0 IN STD_LOGIC_VECTOR (7 DOWNTO 1)

           d1 IN STD_LOGIC_VECTOR (7 DOWNTO 1)

           d2 IN STD_LOGIC_VECTOR (7 DOWNTO 1)

           d3 IN STD_LOGIC_VECTOR (7 DOWNTO 1)

           s0 IN STD_LOGIC

           s1 IN STD_LOGIC

            y OUT STD_LOGIC_VECTOR (7 DOWNTO 1) )

END mux4

ARCHITECTURE behave OF mux4 IS

BEGIN

    lablePROCESSd0d1d2d3s0s1

    VARIABLE tmpINTEGER

     BEGIN

        tmp := 0

        IFs0=‘1’THEN

             tmp := tmp+1

        END IF

        IFs1=‘1’THEN

             tmp := tmp+2

        END IF

       

              CASE tmp IS

              WHEN 0 => y <= d0

              WHEN 1 => y <= d1

              WHEN 2 => y <= d2

              WHEN 3 => y <= d3

              WHEN OTHERS => NULL--为了满足CASE语句全部选择项,空语句

          END CASE

       END PROCESS

END behave

上例是通过对用于选通8位总线的四选一多路选择器进行功能描述,具体说明NULL语句的使用。

4.1.11 过程调用语句(Procedure Call

与其他高级程序设计语言相似,VHDL提供了子程序的概念。其中在进程、函数和过程中,可以使用过程调用语句,此时它是一种顺序语句。一个过程被调用时将去执行它的过程体。过程调用语句的书写格式为:

过程名(实参表);

:

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

USE IEEE. STD_LOGIC_UNSIGNED.ALL;

ENTITY max IS

    PORTin1IN STD_LOGIC_VECTOR (7 DOWNTO 0)

           in2IN STD_LOGIC_VECTOR (7 DOWNTO 0)

           in3IN STD_LOGIC_VECTOR (7 DOWNTO 0)

           qOUT STD_LOGIC_VECTOR (7 DOWNTO 0) )

END max

ARCHITECTURE rtl OF max IS

     PROCEDURE maximumabIN STD_LOGIC_VECTOR

                           cOUT STD_LOGIC_VECTORIS

          VARIABLE tempSTD_LOGIC_VECTORa’RANGE);

      BEGIN

          IFa > bTHEN

             temp := a

          ELSE

             temp := b

          END IF

          c := temp

      END maximum

BEGIN

    PROCESSin1in2in3

              VARIABLE tmp1tmp2STD_LOGIC_VECTOR (7 DOWNTO 0)

    BEGIN

          maximumin1in2tmp1);    - -过程调用

          maximumtmp1in3tmp2);      

            q <= tmp2

    END PROCESS

END rtl

上例是一个取三个输入位矢量最大值的功能描述,它在结构体中的进程语句中使用了两个过程调用语句。

4.1.12断言语句(Assert

断言语句分为顺序断言语句和并行断言语句,顺序断言语句主要用于进程、函数和过程仿真、调试中的人机对话,它可以给出一个文字串作为警告和错误信息。断言语句的书写格式如下:

ASSERT 条件 [REPORT 报告信息] [SEVERITY 出错级别]

在执行过程中,断言语句对条件(布尔表达式)的真假进行判断,如果条件为“TURE”,则向下执行另外一条语句;如果条件为“FALSE”,则输出错误信息和错误严重程度的级别。REPORT后面跟着的是设计者写的字符串,通常是说明错误的原因,字符串要用双引号括起来。SEVERITY后面跟着的是错误严重程度的级别,他们分别是:

·NOTE(注意)

·WARNING(警告)

·ERROR(错误)

·FAILURE(失败)

REPORT子句缺省,则默认消息为Assertion violation;若SEVERITY子句缺省,则出错级别的默认值为ERROR”

: RS触发器的VHDL描述中断言语句的使用

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY rsff IS

    PORTs IN BIT

           r IN BIT

           q OUT BIT

           qb OUT BIT);

END rsff

ARCHITECTURE rtl OF rsff IS

BEGIN

     PROCESSsr

              VARIABLE  last_state BIT

     BEGIN

             ASSERTNOTs =‘1’AND r =‘1’))

                            REPORT “Both s and r equal to‘1’.”

                            SEVERITY  ERROR

        IFs =‘0’AND r =‘0’THEN

             last_state :=  last_state

        ELSIFs =‘0’AND r =‘1’THEN

             last_state := 0

         ELSE

             last_state := 1

         END IF

            q <= last_state

            qb <= notlast_state);

    END PROCESS

END rtl

上例中,如果 r s 都为‘1’时,表示一种不定状态。在进程中先是设定了一条断言语句,目的是:当判断 r s 都为‘1’时,输出终端将显示字符串“Both s and r equal to‘1’.”,同时可能终止模拟过程,并显示错误的严重程度。接下来用IF语句判别触发器的其他三种情况,最后将值送到触发器的两个输出端口上。

4.1.13  REPORT 语句

      REPORT语句不增加硬件任何功能,但提供顺序断言语句的短格式,在仿真时使用REPORT语句可以提高程序的可读性

REPORT语句的书写格式为:

REPORT 输出信息 [SEVERITY 出错级别]

: RS触发器的VHDL描述中REPORT语句的使用 (本例中,用REPORT语句代替上例进程中的断言语句。)

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY rsff IS

    PORTs IN BIT

           r IN BIT

           q OUT BIT

           qb OUT BIT);

END rsff

ARCHITECTURE rtl OF rsff IS

BEGIN

              PROCESSsr

                            VARIABLE last_state BIT

              BEGIN

                            IFs =‘1’AND r =‘1’THEN

                                     REPORT “Both s and r equal to‘1’.”

                            ELSIF s =‘0’AND r =‘0’THEN

                                     last_state= last_state

                         ELSIF s =‘0’AND r =‘1’THEN

                                    last_state := 0

                         ELSE

                                    last_state := 1

                         END IF

                       q <= last_state

         qb <= notlast_state);

              END PROCESS

END rtl

4.2  VHDL并行语句

VHDL中,并行语句在结构体中的执行是同时并发执行的,其书写次序与其执行顺序并无关联,并行语句的执行顺序是由他们的触发事件来决定的

我们知道,实际的硬件系统中很多操作都是并发的,因此在对系统进行模拟时就要把这些并发性体现出来,并行语句正是用来表示这种并发行为的。

在结构体语句中,并行语句的位置是:

ARCHITECTURE 结构体名 OF 实体名 IS

        说明语句

    BEGIN

        并行语句

    END 结构体名;

其中并行语句主要有以下几种:

·PROCESS                                        --进程语句

·BLOCK                                     --块语句

·CONCURRENT SIGNAL ASSIGNMENT      --并行信号代入语句

·CONDITIONAL SIGNAL ASSIGNMENT    - -条件信号代入语句

·SELECTIVE SIGNAL ASSIGNMENT          - -选择信号代入语句

·CONCURRENT PROCEDURE CALL          --并行过程调用语句

·ASSERT                                    - -并行断言语句

·GENERIC                                  - -参数传递语句

·COMPONENT_INSTANT                     --元件例化语句

·GENERATE                                 --生成语句

并行描述语句语句可以是结构性的,也可以是行为性的。下面对这些语句的应用加以介绍。

4.2.1 进程语句(PROCESS

进程语句是最主要的并行语句,它在VHDL程序设计中使用频率最高,也是最能体现硬件描述语言特点的一条语句。进程语句的内部是是顺序语句,而进程语句本身是一种并行语句。进程语句的综合是比较复杂的,主要涉及这样一些问题:综合后的进程是用组合逻辑电路还是用时序逻辑电路来实现?进程中的对象是否有必要用寄存器、触发器、锁存器或是RAM等存储器件来实现

进程语句结构中至少需要一个敏感信号量,否则除了初始化阶段,进程永远不会被再次激活。这个敏感量一般是一个同步控制信号,同步控制信号用在同步语句中,同步语句可以是敏感信号表、WAIT UNTIL语句或是WAIT ON语句。一般来说,只有一个同步点或者是具有多个同步点但都使用完全相同的同步控制信号的进程不需要记忆在哪一个同步点上被挂起时,不会形成存储器。如下例所示:

--综合后不需要存储器的VHDL进程

label1PROCESSabc

    

BEGIN

            --其中没有其他同步描述

AND PROCESS label1

--综合后需要存储器的VHDL进程

label2PROCESS

    

BEGIN

      WAIT UNTIL clk’EVENT AND clk=‘1’

           s <=‘0’

      WAIT UNTIL clk’EVENT AND clk=‘1’

           s <=‘1’

END PROCESS label2

--不会形成存储器的变量

label3PROCESSabc

       VARIABLE varBIT

BEGIN

      var  :=  a XOR b

      s <= var AND c

END PROCESS label3

--需要存储器的变量

label4PROCESS

        TYPE state_table IS (stopgo)

        VARIABLE statetable_ state

BEGIN

        WAIT UNTIL clk’EVENT AND clk=‘1’

CASE state IS                                   - - state在赋值之前先被读访问

              WHEN stop => state :=  go

              WHEN go => state :=  stop- -这两个语句是并发关系

              END CASE

AND PROCESS label4

--综合为触发器的进程

label5PROCESS

BEGIN

      WAIT UNTIL clk’EVENT AND clk=‘1’

            q <= d

END PROCESS label5

4.2.2 块语句(BLOCK

块(BLOCK)语句可以看作是结构体中的子模块,块语句把许多并行语句组合在一起形成一个子模块,而它本身也是一个并行语句

块语句的基本结构如下:

[块标号:] BLOCK [保护表达式]

[类属子句 [类属接口表;]]

[端口子句 [端口接口表;]]

[块说明部分]

BEGIN

<并行语句1>

<并行语句2>

   

END BLOCK [块标号]

: 利用块语句描述的全加器

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY add IS

    PORTAIN STD_LOGIC

           BIN STD_LOGIC

           CinIN STD_LOGIC

           CoOUT STD_LOGIC

           SOUT STD_LOGIC);

END add

ARCHITECTURE dataflow OF add IS

BEGIN

ex : BLOCK

         PORTa_AIN STD_LOGIC

                 a_BIN STD_LOGIC

                 a_CinIN STD_LOGIC

                 a_CoOUT STD_LOGIC 

                 a_SOUT STD_LOGIC);

         PORT MAPa_A=>Aa_B=>Ba_Cin=> Cin

                                  a_Co=> Coa_S=>S);

         SIGNAL tmp1tmp2STD_LOGIC

      BEGIN

         label1PROCESSa_Aa_B

         BEGIN

                                    tmp1<= a_A XOR a_B

         END PROCESS label1

              label2PROCESStmp1a_Cin

         BEGIN

                                   tmp2<= tmp1AND a_Cin

                         END PROCESS label2

         label3PROCESStmp1a_Cin

         BEGIN

                                    a_S <= tmp1XOR a_Cin

                        END PROCESS label3

         label4PROCESSa_Aa_Btmp2

         BEGIN

                                   a_Co <= tmp2 ORa_A AND a_B);

         END PROCESS label4

              END BLOCK ex

END dataflow

在上面的例子中,结构体内含有4个进程语句,这4个进程语句是并行关系,共同形成了一个块语句。

      在实际应用中,一个块语句中又可以包含多个子块语句,这样循环嵌套以形成一个大规模的硬件电路。

4.2.3 并行信号代入语句

信号代入语句有两种:一种是在结构体中的进程内使用,此时它作为一种顺序语句出现;另一种是在结构体的进程之外使用,此时它是一种并行语句,因此称之为并行信号代入语句。

并行信号代入语句的语法格式为:

          信号量 <=  敏感信号量表达式;

需要注意的是,一条信号代入语句与一个信号代入的进程语句是等价的,我们可以把一条信号代入语句改写成一个信号代入的进程语句。

:

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY and_gat IS

    PORTaIN STD_LOGIC

           bIN STD_LOGIC

           yOUT STD_LOGIC);

END and_gat

ARCHITECTURE behave OF and_gat IS

BEGIN

          y <= a AND b    --并行信号代入语句(在结构体进程之外)

AND behave

本例是一个2输入与门的VHDL描述,在结构体中使用了并行信号代入语句。下面是2输入与门的另一种VHDL描述,在描述的结构体中采用了与上述并行信号代入语句等价的进程语句。

:

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY and_gat IS

    PORTaIN STD_LOGIC

           bIN STD_LOGIC

           yOUT STD_LOGIC);

END and_gat

ARCHITECTURE behave OF and_gat IS

BEGIN

       PROCESS ab

       BEGIN

          y <= a AND b                    --进程语句( 顺序语句)

       END PROCESS

AND behave

通过对上述两个例子的分析可见:从并行信号代入语句描述来看,当代入符号“<=”右边的值发生任何变化时,信号代入语句的操作立即执行,将信号代入符号“<=”右边的表达式代入给左边的信号量;从进程语句的描述来看,当进程敏感信号表中的敏感信号量发生变化时,进程将被启动,顺序信号代入语句将被执行以完成信号的代入操作。

VHDL中提供了三种并行信号代入语句:

·并发信号代入语句

·条件信号代入语句

 ·选择信号代入语句

(1) 并发信号代入语句

信号代入语句在进程内部执行时,它是一种顺序语句;信号代入语句在结构体的进程之外出现时,它作为并发语句的形式出现。作为并发信号代入语句,在结构体中他们是并行执行的,他们的执行顺序与书写无关。

并发信号代入语句是靠事件驱动的。对于并发信号代入语句来说,只有代入符号“<=”右边的对象有事件发生时才会执行该语句。

在实际设计中,并发信号代入语句常用来进行加法器、乘法器、除法器和比较器等多种逻辑电路的描述。下面是一个用VHDL并发语句描述的全加器的例子。

:

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY add IS

    PORTAIN STD_LOGIC

           BIN STD_LOGIC

           CinIN STD_LOGIC

           CoOUT STD_LOGIC

           SOUT STD_LOGIC);

END add

ARCHITECTURE dataflow OF add IS

       SIGNAL tmp1tmp2STD_LOGIC

BEGIN

      tmp1 <= A XOR B

      tmp2 <= tmp1 AND Cin                       --4条并发信号代入语句

      S <= tmp1 XOR Cin

      Co <= tmp2 ORA AND B);

AND dataflow

在上例的结构体中有4条并发信号代入语句,他们的执行顺序与书写顺序是无关的,因此上面的4条并发信号代入语句可以任意颠倒书写顺序,不会对执行结果产生任何影响。上面提到的并发信号代入语句是事件驱动的,例如:

     tmp2 <= tmp1 AND Cin

     S <= tmp1 XOR Cin

两条语句,只要tmp1 Cin中的值有一个发生变化,即有事件发生,那么这两条语句就会立即并发执行。

(2)条件信号代入语句

条件信号代入语句也是一种并发描述语句,它是一种根据不同条件将不同的表达式代入目的信号的语句。条件信号代入语句的书写格式为:

目的信号 <= 表达式1  WHEN 条件1  ELSE

            表达式2  WHEN 条件2  ELSE

            表达式2  WHEN 条件3  ELSE

                

            表达式n-1  WHEN 条件  ELSE

            表达式;

条件信号代入语句执行时要先进行条件判断,如果条件满足,就将条件前面的那个表达式的值代入目的信号;如果不满足条件,就去判断下一个条件;最后一个表达式没有条件,也就是说在前面的条件都不满足时,就将该表达式的值代入目的信号。

下面的例子是用条件信号代入语句来描述的七段显示译码器

: 采用条件代入语句描述的七段显示译码器

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY se7 IS

    PORTinputIN STD_LOGIC_VECTOR (3 DOWNTO 0)

           outputOUT STD_LOGIC_VECTOR (6 DOWNTO 0));

END se7

ARCHITECTURE rtl OF se7 IS

BEGIN

   output <=‘0’‘1’‘1’‘1’‘1’‘1’‘1’) WHEN input =“0000”ELSE

            ‘0’‘0’‘0’‘0’‘1’‘1’‘0’WHEN input =“0001”ELSE

            ‘1’‘0’‘1’‘1’‘0’‘1’‘1’WHEN input =“0010”ELSE

                  ‘1’‘0’‘0’‘1’‘1’‘1’‘1’WHEN input =“0011”ELSE

                  ‘1’‘1’‘0’‘0’‘1’‘1’‘0’WHEN input =“0100”ELSE

                  ‘1’‘1’‘0’‘1’‘1’‘0’‘1’WHEN input =“0101”ELSE

                  ‘1’‘1’‘1’‘1’‘1’‘0’‘1’WHEN input =“0110”ELSE

                  ‘0’‘0’‘0’‘0’‘1’‘1’‘1’WHEN input =“0111”ELSE

                  ‘1’‘1’‘1’‘1’‘1’‘1’‘1’WHEN input =“1000”ELSE

                  ‘1’‘1’‘0’‘1’‘1’‘1’‘1’WHEN input =“1001”ELSE

                  ‘1’‘1’‘1’‘0’‘1’‘1’‘1’WHEN input =“1010”ELSE

                  ‘1’‘1’‘1’‘1’‘1’‘0’‘0’WHEN input =“1011”ELSE

                  ‘0’‘1’‘1’‘1’‘0’‘0’‘1’WHEN input =“1100”ELSE

                  ‘1’‘0’‘1’‘1’‘1’‘1’‘0’WHEN input =“1101”ELSE

                  ‘1’‘1’‘1’‘1’‘0’‘0’‘1’WHEN input =“1110”ELSE

                  ‘1’‘1’‘1’‘0’‘0’‘0’‘1’WHEN input =“1111”ELSE

                  ‘0’‘0’‘0’‘0’‘0’‘0’‘0’);       - -灭灯

END rtl;

在上例中,七段显示译码器有一个输入端口input和一个输出端口output。输入端口input是一个四位总线,表示30的四位逻辑向量,表示输入是一个四位二进制数。输出端口output也以总线形式表示,它表示607位逻辑向量,表示输出是一个七位二进制数,以驱动共阴极显示七段数码管

      在上例的结构体中,用一个条件代入语句来完成所有状态的显示译码。在保留字WHEN的前面是驱动显示数码管的七位位矢量,WHEN的后面是译码的条件。需要说明的是条件信号代入语句中的书写顺序不是固定的,位置是可以任意颠倒的,他们并不表示执行的先后顺序,实际上他们是并发执行的。

(3) 选择信号代入语句

选择信号代入语句的书写格式为:

WITH  表达式  SELECT

目的信号 <= 表达式1  WHEN  条件1

            表达式2  WHEN  条件2

            表达式3  WHEN  条件3

               

            表达式n  WHEN  条件n

VHDL在执行选择信号代入语句时,目的信号是根据表达式的当前值来进行表达式代入的。当表达式的值符合某个条件时,就把该条件前的表达式代入目的信号;当表达式的值不符合条件时,语句就继续向下判断,直到找到满足的条件为止。选择信号代入语句与case语句相类似,都是对表达式进行测试,当表达式的值不同时,将把不同的表达式代入目的信号。需要注意的是,选择信号代入语句与case语句一样,必须把表达式的值在条件中都列出来,否则编译将会出错。

下面的例子是一个采用选择信号代入语句描述的选通8位总线的四选一多路选择器。

:

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY mux4 IS

    PORTd0IN STD_LOGIC_VECTOR (7 DOWNTO 0)

           d1IN STD_LOGIC_VECTOR (7 DOWNTO 0)

           d2IN STD_LOGIC_VECTOR (7 DOWNTO 0)

           d3IN STD_LOGIC_VECTOR (7 DOWNTO 0)

           s0IN STD_LOGIC

           s1IN STD_LOGIC

           qOUT STD_LOGIC_VECTOR (7 DOWNTO 0));

END mux4

ARCHITECTURE rtl OF mux4 IS

      SIGNAL combSTD_LOGIC_VECTOR (1 DOWNTO 0);;

BEGIN

     comb <= s1 & s0      --&运算

     WITH comb SELECT                - -comb进行选择

          q <= d0  WHEN “00”

              d1  WHEN “01”

              d2  WHEN “10”

              d3  WHEN  OTHERS      - -上面4条语句是并行执行的

END rtl

4.2.4 并行过程调用语句

    过程调用语句在进程内部执行时,它是一种顺序语句;过程调用语句在结构体的进程之外出现时,它作为并发语句的形式出现。作为并行过程调用语句,在结构体中他们是并行执行的,其执行顺序与书写顺序无关。

并行过程调用语句的一般书写格式如下:

  PROCEDURE 过程名(参数1;参数2;┄)IS

     [定义语句]             --变量定义

  BEGIN

     [顺序处理语句]

 END 过程名;     --当中没有PROCEDURE

下例是一个取三个输入位矢量最大值的功能描述,在它的结构体中使用了两个并行过程调用语句。

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

USE IEEE. STD_LOGIC_UNSIGNED.ALL;

ENTITY max IS

    PORTin1IN STD_LOGIC_VECTOR (7 DOWNTO 0)

           in2IN STD_LOGIC_VECTOR (7 DOWNTO 0)

           in3IN STD_LOGIC_VECTOR (7 DOWNTO 0)

           qOUT STD_LOGIC_VECTOR (7 DOWNTO 0));

END max

ARCHITECTURE rtl OF max IS     

PROCEDURE maximunabIN STD_LOGIC_VECTOR

                  SIGNAL cOUT STD_LOGIC_VECTORIS

           VARIABLE tempSTD_LOGIC_VECTOR (a’RANGE)

BEGIN                                    - -temp矢量长度与a相同

           IF (a > b) THEN

             temp = a

           ELSE

             temp = b

           END IF

           c <= temp

 END maximun

 SIGNAL tmp1tmp2OUT STD_LOGIC_VECTOR(7 DOWNTO 0)--此处需要OUT??

BEGIN

    maximunin1in2tmp1);--调用

    maximuntmp1in3tmp2);

    q <= tmp2

END rtl

4.2.5并行断言语句

并行断言语句的书写格式为:

ASSERT 条件 [REPORT 报告信息] [SEVERITY 出错级别]

并行断言语句的书写格式与顺序断言语句的书写格式相同。顺序断言语句只能用在进程、函数和过程中,而并行断言语句用在结构体中。任何并行断言语句都对应着一个等价的被动进程语句,被动进程语句没有输出,因此并行断言语句的执行不会引起任何事件的发生,只是在断言条件为“false”时给出一条信息报告。 --等价的被动进程语句

:

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

USE IEEE. STD_LOGIC_UNSIGNED.ALL;

ENTITY example IS

END example

ARCHITECTURE behave OF example IS

       SIGNAL comb STD_LOGIC_VECTOR(1 DOWNTO 0)

BEGIN

      ASSERT  FALSE

      REPORT“This entity is a example to descript assert statement”

      SEVERITY NOTE

END behave

4.2.6 参数传递语句

参数传递语句(GENERIC)主要用来传递信息给设计实体的某个具体元件,如用来定义端口宽度、器件延迟时间等参数后并将这些参数传递给设计实体。使用参数传递语句易于使设计具有通用性,例如,在设计中有一些参数不能确定,为了简化设计和减少VHDL程序的书写,我们通常编写通用的VHDL程序。在设计程序中,这些参数是待定的,在模拟时,只要用GENERIC语句将待定参数初始化即可。

参数传递语句的书写格式为:

GENERIC(类属表);

:

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY and2 IS

    GENERICDELAYTIME= 10 ns);

    PORTaIN STD_LOGIC

           bIN STD_LOGIC

           cOUT STD_LOGIC);

END and2

ARCHITECTURE behave OF and2 IS

BEGIN

     c <= a AND b AFTERDELAY);

END behave

4.2.7 元件例化语句

元件例化就是将预先设计好的设计实体定义为一个元件,然后利用映射语句将此元件与当前设计实体中的指定端口相连,从而为当前设计实体引入了一个低一级的设计层次。在结构体中,描述只表示元件(或模块)和元件(或模块)之间的互连,就象网表一样。当引用库中不存在的元件时,必须首先进行元件的创建,然后将其放在工作库中,通过调用工作库来引用元件。在引用元件时,要先在结构体中说明部分进行元件的说明,然后在使用元件时进行元件例化。

元件例化语句也是一种并行语句,各个例化语句的执行顺序与例化语句的书写顺序无关,而是按照驱动的事件并行执行的。

在进行元件例化时,首先要进行例化元件的说明,元件说明部分使用COMPONENT语句COMPONENT语句用来说明在结构体中所要调用的模块。如果所调用的模块在元件库中并不存在时,设计人员必须首先进行元件的创建,然后将其放在工作库中通过调用工作库来引用该元件。

COMPONENT语句的一般书写格式如下:

        COMPONENT <引用元件名>

             [GENERIC <参数说明>]

              PORT <端口说明>

        END COMPONENT                            - -元件说明语句

在上面的书写结构中,保留字COMPONENT后面的引用元件名用来指定要在结构体中例化的元件,该元件必须已经存在于调用的工作库中;如果在结构体中要进行参数传递,在COMPONENT语句中,就要有传递参数的说明,传递参数的说明语句以保留字GENERIC开始;然后是端口说明,用来对引用元件的端口进行说明;最后以保留字END COMPONENT来结束 COMPONENT语句。

如果在结构体中要引用上例中所定义的带延迟的二输入与门,首先在结构体中要用COMPONENT语句对该元件进行说明,说明如下:

COMPONENT and2           --元件名

GENERICDELAYTIME);--参数说明

          PORTaIN STD_LOGIC

                 bIN STD_LOGIC

                 cOUT STD_LOGIC);--端口说明

END COMPONENT

COMPONENT语句对要引用的元件进行说明之后,就可以在结构体中对元件进行例化以使用该元件。

元件例化语句的书写格式为:

<标号名:> <元件名> [GENERIC MAP(参数映射)]

PORT MAP(端口映射);

标号名是此元件例化的唯一标志,在结构体中标号名应该是唯一的,否则编译时将会给出错误信息;接下来就是映射语句,映射语句就是把元件的参数和端口与实际连接的信号对应起来,以进行元件的引用。

VHDL提供了两种映射方法:位置映射和名称映射。

位置映射就是PORT MAP语句中实际信号的书写顺序与COMPONENT语句中端口说明中的信号书写顺序保持一致,如下例所示:

位置映射示例:

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY example IS

        PORTin1in2IN STD_LOGIC

outOUT STD_LOGIC);

END example

ARCHITECTURE structure OF example IS

      COMPONENT and2                              --元件说明

GENERICDELAYTIME);

          PORTaIN STD_LOGIC

                 bIN STD_LOGIC

                 cOUT STD_LOGIC);

END COMPONENT

BEGIN

      U1 : and2 GENERIC MAP10 ns- -参数映射 标号名U1元件名and2元件例化

           PORT MAPin1in2out);    - -端口映射

END structure

在上例中,元件U1 的端口 a 映射到信号in1,端口 b 映射到信号in2,端口c 映射到信号 out

名称映射就是在PORT MAP语句中将引用的元件的端口信号名称赋给结构体中要使用的例化元件的信号,如下例所示:

:名称映射

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY example IS

        PORTin1in2IN STD_LOGIC

                            outOUT STD_LOGIC);

END example

ARCHITECTURE structure OF example IS

      COMPONENT and2

                GENERICDELAYTIME);

          PORTaIN STD_LOGIC

                 bIN STD_LOGIC

                            cOUT STD_LOGIC);

              END COMPONENT

BEGIN

      U1and2 GENERIC MAP10 ns

           PORT MAPa => in1b=> in2c => out);--名称映射

END structure

注意:名称映射的书写顺序要求并不是很严格,只要把要映射的对应信号连接起来就可以了,顺序是可以颠倒的 .

4.2.9 生成语句

生成语句(GENERATE)是一种可以建立重复结构或者是在多个模块的表示形式之间进行选择的语句。由于生成语句可以用来产生多个相同的结构,因此使用生成语句就可以避免多段相同结构的VHDL程序的重复书写(相当于复制

生成语句有两种形式:FOR- GENERATE模式和IF- GENERATE模式

FOR- GENERATE 模式的生成语句

FOR- GENERATE 模式生成语句的书写格式为:

[标号:]FOR 循环变量  IN  离散范围 GENERATE

        <并行处理语句>

END GENERATE [标号]

其中循环变量的值在每次的循环中都将发生变化;离散范围用来指定循环变量的取值范围,循环变量的取值将从取值范围最左边的值开始并且递增到取值范围最右边的值,实际上也就限制了循环的次数;循环变量每取一个值就要执行一次GENERATE语句体中的并行处理语句;最后FOR- GENERATE模式生成语句以保留字END GENERATE [标号:];来结束GENERATE语句的循环。

      生成语句的典型应用是存储器阵列和寄存器。下面以四位移位寄存器为例,说明FOR- GENERATE模式生成语句的优点和使用方法。

     下图所示电路是由边沿D触发器组成的四位移位寄存器,其中第一个触发器的输入端用来接收四位移位寄存器的输入信号,其余的每一个触发器的输入端均与左面一个触发器的Q端相连。  

图用D触发器构成的四位移位寄存器

根据上面的电路原理图,写出四位移位寄存器的VHDL描述如下。

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY shift_reg IS

    PORTdiIN STD_LOGIC

           cpIN STD_LOGIC

           doOUT STD_LOGIC);

END shift_reg

ARCHITECTURE structure OF shift_reg IS

       COMPONENT dff                                              --元件说明

           PORTdIN STD_LOGIC

                 clkIN STD_LOGIC

                  qOUT STD_LOGIC);

              END COMPONENT

      SIGNAL qSTD_LOGIC_VECTOR(4 DOWNTO 0)

BEGIN

      dff1dff  PORT MAP (dicpq1)             --元件例化

      dff2dff  PORT MAP (q1),cpq2)

      dff3dff  PORT MAP (q2),cpq3)

      dff4dff  PORT MAP (q3),cpdo)

END structure

在上例的结构体中有四条元件例化语句,这四条语句的结构十分相似。我们对上例再做适当修改,使结构体中这四条元件例化语句具有相同的结构,如下例所示:

[]

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY shift_reg IS

    PORTdiIN STD_LOGIC

           cpIN STD_LOGIC

           doOUT STD_LOGIC);

END shift_reg

ARCHITECTURE structure OF shift_reg IS

COMPONENT dff

           PORTdIN STD_LOGIC

                 clkIN STD_LOGIC

                  qOUT STD_LOGIC);

END COMPONENT

      SIGNAL qSTD_LOGIC_VECTOR(4 DOWNTO 0)

BEGIN

      q0<= di

      dff1dff  PORT MAP (q0),cpq1)

      dff2dff  PORT MAP (q1),cpq2)

      dff3dff  PORT MAP (q2),cpq3)

      dff4dff  PORT MAP (q3),cpq4)

      do<= q4

END structure

这样便可以使用FOR- GENERATE模式生成语句对上例中的规则体进行描述,如例[]所示。

: FOR- GENERATE模式生成语句应用

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY shift_reg IS

    PORTdiIN STD_LOGIC

           cpIN STD_LOGIC

           doOUT STD_LOGIC);

END shift_reg

ARCHITECTURE structure OF shift_reg IS      

COMPONENT dff

           PORTdIN STD_LOGIC

                 clkIN STD_LOGIC

                  qOUT STD_LOGIC);

END COMPONENT

      SIGNAL qSTD_LOGIC_VECTOR(4 DOWNTO 0)

BEGIN

      q0<= di

      label1FOR  i  IN  0  TO  3  GENERATE

             dffxdff  PORT MAP (qi),cpqi+1)

      END GENERATE  label1

      do <=  q4

END structure

可以看出用FOR- GENERATE模式生成语句替代例[]中的四条元件例化语句,使VHDL程序变的更加简洁明了。在例[]的结构体中用了两条并发的信号代入语句和一条FOR- GENERATE模式生成语句,两条并发的信号代入语句用来将内部信号q和输入端口di、输出端口do连接起来,一条FOR- GENERATE模式生成语句用来产生具有相同结构的四个触发器

IF- GENERATE模式生成语句

IF- GENERATE模式生成语句的书写格式如下:

[标号:]IF 条件 GENERATE

        <并行处理语句>

END GENERATE [标号]

IF- GENERATE模式生成语句主要用来描述一个结构中的例外情况,例如,某些边界条件的特殊性。当执行到该语句时首先进行条件判断,如果条件为“TRUE”才会执行生成语句中的并行处理语句;如果条件为“FALSE”,则不执行该语句。

: IF- GENERATE模式生成语句应用

LIBRARY IEEE;

USE IEEE. STD_LOGIC_1164.ALL;

ENTITY shift_reg IS

    PORTdiIN STD_LOGIC

           cpIN STD_LOGIC

           doOUT STD_LOGIC);

END shift_reg

ARCHITECTURE structure OF shift_reg IS      

COMPONENT dff

           PORTdIN STD_LOGIC

                 clkIN STD_LOGIC

                  qOUT STD_LOGIC);

END COMPONENT

      SIGNAL qSTD_LOGIC_VECTOR(3 DOWNTO 1)

BEGIN

      label1

      FOR i IN 0 TO 3 GENERATE

            IFi=0GENERATE

               dffxdff PORT MAP (dicpqi+1)

            END GENERATE           

                  IFi=3GENERATE

               dffxdff PORT MAP (qi),cpdo)

            END GENERATE

            IF((i /=0ANDi /=3))GENERATE

             dffxdff PORT MAP (qi),cpqi+1)

            END GENERATE

      END GENERATE label1

END structure

在例[]的结构体中,FOR- GENERATE模式生成语句中使用了IF- GENERATE模式生成语句。IF- GENERATE模式生成语句首先进行条件i = 0i = 3的判断,即判断所产生的D触发器是移位寄存器的第一级还是最后一级;如果是第一级触发器,就将寄存器的输入信号di代入到PORT MAP语句中;如果是最后一级触发器,就将寄存器的输出信号do代入到PORT MAP语句中。这样就解决了硬件电路中输入输出端口具有不规则性所带来的问题。

 

 
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值