加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權(quán)保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 一、VHDL簡介
    • 二、VHDL 程序基本結(jié)構(gòu)
    • 三、VHDL 語言的數(shù)據(jù)類型和運算符
    • 四、 VHDL 語言的描述語句
    • 五、 VHDL 語言的預(yù)定義屬性
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

VHDL語法學(xué)習(xí)筆記:一文掌握VHDL語法

05/07 14:32
1.6萬
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

大俠好,歡迎來到FPGA技術(shù)江湖,江湖偌大,相見即是緣分。大俠可以關(guān)注FPGA技術(shù)江湖,在“闖蕩江湖”、"行俠仗義"欄里獲取其他感興趣的資源,或者一起煮酒言歡。

今天給大俠帶來FPGA 之 VHDL 語法學(xué)習(xí)筆記,話不多說,上貨。

VHDL語法學(xué)習(xí)筆記

一、VHDL簡介

1.1 VHDL 的歷史

VHDL 的 英 文 全 名 是 Very-High-Speed Integrated Circuit Hardware DescriptionLanguage,誕生于 1982 年。

1987 年底,VHDL 被 IEEE 和美國國防部確認為標準硬件描述語言。自 IEEE 公布了 VHDL 的標準版本 IEEE-1076(簡稱 87 版)之后,各 EDA 公司相繼推出了自己的 VHDL 設(shè)計環(huán)境,或宣布自己的設(shè)計工具可以提供 VHDL 接口。此后 VHDL 在電子設(shè)計領(lǐng)域逐步取代了原有的各種非標準硬件描述語言。

1993 年,IEEE 對 VHDL 進行了修訂,從更高的抽象層次和系統(tǒng)描述能力上擴展 VHDL 的內(nèi)容,并公布了新版本的 VHDL,即 IEEE 標準的 1076-1993版本(簡稱 93 版)。

現(xiàn)在,VHDL 和 Verilog HDL 作為 IEEE 的工業(yè)標準硬件描述語言,在電子工程領(lǐng)域已成為事實上的通用硬件描述語言。

1.2 VHDL 的特點

VHDL 主要用于描述數(shù)字系統(tǒng)的結(jié)構(gòu)、行為、功能和接口。除了含有許多具有硬件特征的語句外,VHDL 在語言形式、描述風格和句法上與一般的計算機高級語言十分相似。VHDL 的程序結(jié)構(gòu)特點是將一項工程設(shè)計,或稱設(shè)計實體(可以是一個元件、一個電路模塊或一個系統(tǒng))分成外部和內(nèi)部兩部分。

外部也可稱為可視部分,它描述了此模塊的端口,而內(nèi)部可稱為不可視部分,它涉及到實體的功能實現(xiàn)和算法完成。在對一個設(shè)計實體定義了外部端口后,一旦其內(nèi)部開發(fā)完成,其他的設(shè)計就可以直接調(diào)用這個實體。這種將設(shè)計實體分成內(nèi)外部分的概念是VHDL 系統(tǒng)設(shè)計的基本點。

應(yīng)用 VHDL 進行工程設(shè)計有以下的優(yōu)點:

1.行為描述

與其他的硬件描述語言相比,VHDL 具有更強的行為描述能力,強大的行為描述能力是避開具體的器件結(jié)構(gòu),從邏輯行為上描述和設(shè)計大規(guī)模電子系統(tǒng)的重要保證。

2.仿真模擬

VHDL 豐富的仿真語句和庫函數(shù),使得在任何系統(tǒng)的設(shè)計早期就能查驗設(shè)計系統(tǒng)的功能可行性,隨時可對設(shè)計進行仿真模擬。

3.大規(guī)模設(shè)計

一些大型的 FPGA 設(shè)計項目必須有多人甚至多個開發(fā)組共同并行工作才能實現(xiàn)。VHDL 語句的行為描述能力和程序結(jié)構(gòu)決定了它具有支持大規(guī)模設(shè)計的分解和已有設(shè)計的再利用功能。

4.門級網(wǎng)表

對于用 VHDL 完成的一個確定的設(shè)計,可以利用 EDA 工具進行邏輯綜合和優(yōu)化,并自動把VHDL 描述設(shè)計轉(zhuǎn)變成門級網(wǎng)表。

5.獨立性

VHDL 對設(shè)計的描述具有相對獨立性,設(shè)計者可以不懂硬件的結(jié)構(gòu),也不必對最終設(shè)計實現(xiàn)的目標器件有很深入地了解。

二、VHDL 程序基本結(jié)構(gòu)

一般的 VHDL 程序可以由實體(Entity)、結(jié)構(gòu)體(Architecture)、配置(Configuration)、程序包和程序包體(Package)以及庫(Library)5 個部分組成,它們是 VHDL 程序的設(shè)計單元。

其中實體、配置和程序包屬于初級設(shè)計單元,主要的功能是進行端口、行為、函數(shù)等的定義。結(jié)構(gòu)體和程序包體是次級設(shè)計單元,包含了所有行為以及函數(shù)的實現(xiàn)代碼。其中,程序包和程序包體又屬于公用設(shè)計單元,即它們是被其他程序模塊調(diào)用的。庫則是一批程序包的集合。

圖 1 所示為 VHDL 程序設(shè)計單元之間的關(guān)系。

圖 1 VHDL 程序設(shè)計單元關(guān)系圖

無論是復(fù)雜的還是簡單的數(shù)字模塊,用 VHDL 來描述都至少需要包括兩個部分,即實體申明(Entity Declaration)和結(jié)構(gòu)體(Architecture)。其中實體申明用于說明模塊的端口,而結(jié)構(gòu)體用于描述模塊的功能。本節(jié)下面將詳細介紹 VHDL 程序的各個設(shè)計單元。

2.1 實體的申明方法

實體是設(shè)計的基本模塊和設(shè)計的初級單元,在分層次設(shè)計中,頂層有頂級實體,含在頂級實體中的較低層次的描述為低級實體,通過配置可把頂層實體和底層實體連接起來??梢詫嶓w理解為電路圖設(shè)計中的芯片符號(Symbol),符號規(guī)定了電路的符號名、接口和數(shù)據(jù)類型。由連線(或信號)將符號互連建立設(shè)計所需的電路圖,互連線生成的網(wǎng)表,在設(shè)計實現(xiàn)之前一直是設(shè)計驗證的仿真模型,并在設(shè)計驗證后,由網(wǎng)表向布線工具提供所需的連接信息和層信息。

圖 2 所示是傳統(tǒng)設(shè)計中 R-S 觸發(fā)器的符號圖,用 VHDL 對其進行描述的代碼如下:

  ENTITY rsff IS  PORT (          Set, Reset : IN BIT;          Q, QB : BUFFER BIT );  END rsff;

圖 2 R-S 觸發(fā)器的 VHDL 實體描述和符號

實體語句用關(guān)鍵詞 ENTITY 開頭,實體名 rsff 是描述的符號名,在結(jié)束實體語句的 END rsff之間,實體語句可以用關(guān)鍵詞 BEGIN 把實體語句分成兩部分:即 BEGIN 之前是實體說明,BEGIN之后是實體語句。

在 ENTITY 語句的實體說明部分,常用 PORT 付語描述實體對外界連接的端口(數(shù)目、方向和數(shù)據(jù)類型)。實體 rsff 有 4 個端口,Set/Reset 是輸入 IN 模式,Q/QB 是輸出BUFFER(緩沖)模式,都為 BIT 類型。實體說明中還可說明數(shù)據(jù)類型、子程序和常量等數(shù)據(jù)信息,實體語句常用于描述設(shè)計經(jīng)常用到的判斷和檢查信息。

實體描述的格式如下:

  ENTITY 實體名 IS    [GENERIC(參數(shù)表);]    [PORT(端口表);]  [BEGIN    實體語句部分;]  END [ENTITY] [實體名];

其中,GENERIC 是用于說明設(shè)計實體和其外部環(huán)境通信的對象,規(guī)定端口的大小、實體中子元件的數(shù)目、實體的延時特性等。只能用整數(shù)類型表示,如整型、時間型等,其他類型的數(shù)據(jù)不能邏輯綜合。格式如下:

GENERIC ([CONSTANT]屬性名稱:[IN]子類型標識[:=靜態(tài)表達式],……);

PORT 關(guān)鍵字用于定義模塊的端口,它的格式如下:

  PORT( [SIGNAL] 端口名稱:[方向]類型標識[BUS] [:=靜態(tài)表達式],        [SIGNAL] 端口名稱:[方向] 類型標識[BUS] [:=靜態(tài)表達式],        [SIGNAL] 端口名稱:[方向] 類型標識[BUS] [:=靜態(tài)表達式]);

? SIGNAL:SIGNAL 是關(guān)鍵字,但是由于 PORT 之后必須是信號類,所以一般可以將 SIGNAL關(guān)鍵字省略。

? 端口名稱:是該端口的標識,通常由英文字母和數(shù)字組成,但是必須是英文字母打頭。

? 方向:定義了端口是輸入還是輸出,如 IN、OUT。表明端口方向的關(guān)鍵字如表1所示。

? 類型標識:說明流過該端口的數(shù)據(jù)類型,常用的數(shù)據(jù)類型有 BIT(位)、BIT_VECTOR(位向量)、BOOLEAN(布爾型)和 INTEGER(整數(shù)型)4 種。

? BUS 關(guān)鍵字:在該端口和多個輸出端相連的情況下使用。

表 1 端口方向關(guān)鍵字說明表

2.2 結(jié)構(gòu)體的描述方法

結(jié)構(gòu)體描述實體的行為功能,一個實體可以有多個結(jié)構(gòu)體。結(jié)構(gòu)體是一個基本設(shè)計單元,它具體地指明了所設(shè)計模塊的行為、元件及內(nèi)部的連接關(guān)系,也就是說它定義了設(shè)計單元具體的功能。結(jié)構(gòu)體對其基本設(shè)計單元的輸入/輸出關(guān)系可以用 3 種方式進行描述,即行為描述(基本設(shè)計單元的數(shù)學(xué)模型描述)、寄存器傳輸描述(數(shù)據(jù)流描述)和結(jié)構(gòu)描述(邏輯元件連接描述)。

不同的描述方式只體現(xiàn)在描述語句上,而結(jié)構(gòu)體的結(jié)構(gòu)是完全一樣的。由于結(jié)構(gòu)體是對實體功能的具體描述,因此它一定要跟在實體的后面。通常,先編譯實體之后才能對結(jié)構(gòu)體進行編譯。如果實體需要重新編譯,那么相應(yīng)結(jié)構(gòu)體也應(yīng)重新進行編譯。

結(jié)構(gòu)體的格式如下:

  ARCHITECTURE 結(jié)構(gòu)體名 OF 實體名 IS  [定義語句]  BEGIN  [并行處理語句]  END 結(jié)構(gòu)體名;

定義語句用于對結(jié)構(gòu)體內(nèi)部所使用的信號、常數(shù)、數(shù)據(jù)類型和函數(shù)等進行定義。信號定義和端口說明的語句一樣,應(yīng)有信號名和數(shù)據(jù)類型的說明,但因它是內(nèi)部連接用的信號,故沒有也不需有方向的說明。并行處理語句具體地描述了結(jié)構(gòu)體的行為及其連接關(guān)系,它們都是可以并行執(zhí)行的。

以上面介紹的 R-S 觸發(fā)器為例。假設(shè)已經(jīng)有一個實現(xiàn)了與非功能的模塊 nand2,用它實現(xiàn)R-S 觸發(fā)器的原理圖如圖 3 所示。

圖 3 R-S 觸發(fā)器的實現(xiàn)原理圖

對應(yīng)以上原理圖的結(jié)構(gòu)體描述如下:

library IEEE;use IEEE.std_logic_1164.all;
ENTITY rsff isPORT (      set, reset: in bit;      q, qb: buffer      );END ENTITY;
ARCHITECTURE arch_rsff OF rsff IS      COMPONENT nand2          PORT (                  a, b : IN BIT;                  c: OUT BIT);??????END?COMPONENT;?????BEGIN      U1: nand2      PORT MAP (set, qb, q);      U2: nand2      PORT MAP (reset, q, qb);END arch_rsff;

上面的代碼中,以關(guān)鍵字 ARCHITECTURE 作為結(jié)構(gòu)體的開頭,結(jié)構(gòu)體名為 arch_rsff,表示描述 rsff 實體的結(jié)構(gòu)體 arch_rsff。ARCHITECTURE 和 BEGIN 之間是結(jié)構(gòu)體說明區(qū), BEGIN和 END 之間是結(jié)構(gòu)體語句區(qū)。結(jié)構(gòu)體說明區(qū)描述組件(COMPONENT)和局部信號,結(jié)構(gòu)體語句中用的具體元件(上例是 nand2)均應(yīng)在結(jié)構(gòu)體說明中說明接口,以便將描述的信息通知給編輯器。

如果設(shè)計者希望將模塊分為若干個相對比較獨立的子模塊進行描述,可以將一個結(jié)構(gòu)體用幾個子結(jié)構(gòu)來構(gòu)成。VHDL 結(jié)構(gòu)體描述常常用到 3 種語句結(jié)構(gòu):PROCESS 語句結(jié)構(gòu)、BLOCK 語句結(jié)構(gòu)和子程序結(jié)構(gòu)。

1).PROCESS 語句結(jié)構(gòu)

進程語句是一種并發(fā)處理語句,在一個結(jié)構(gòu)體中多個 PROCESS 語句可以同時并行運行(相當于多個 CPU 同時運作)。PROCESS 語句是 VHDL 語言中描述硬件系統(tǒng)并發(fā)行為的最基本語句。

PROCESS 語句歸納起來有如下幾個特點:

? 它可以與其他進程并發(fā)運行,并可存取結(jié)構(gòu)體或?qū)嶓w號中所定義的信號;? 進程結(jié)構(gòu)中的所有語句都是按順序執(zhí)行的;

? 為啟動進程,在進行結(jié)構(gòu)中必須包含一個顯式的敏感信號量表或包含一個 WAIT 語句;

? 進程之間的通信是通過信號量傳遞來實現(xiàn)的。

PROCESS 語句的格式如下:

[進程名]:PROCESS(信號 1,信號 2,…)BEGINEND PROCESS;

一般情況下進程名可以被省略。進程申明關(guān)鍵字 PROCESS 后面括號內(nèi)的信號是此進程的敏感信號,這些信號的變化會激活過程的執(zhí)行。例如下面的代碼就表示過程 main_proc 在信號clk 和 reset 變化時執(zhí)行:

library IEEE;use IEEE.std_logic_1164.all;
ENTITY counter is    PORT (          clk, reset: in bit;          c: out bit          );END ENTITY;
ARCHITECTURE arch of counter isBEGIN    main_proc:    PROCESS(clk, reset)    BEGIN    if (reset = '1') then    end if;    END PROCESS;END

在進程中也可以定義一些變量,這些變量是局部量,只能在進程內(nèi)部使用,它們的賦值是立即生效的。局部變量定義的格式如下:

VARIABLE 變量名:數(shù)據(jù)類型 [約束條件] [:=表達式];

下面的代碼演示了定義一個局部變量并且使用它的方法:

library IEEE;use IEEE.std_logic_1164.all;
ENTITY counter is    PORT (          a: in bit;          c: out bit          );END ENTITY;
ARCHITECTURE arch of counter isBEGIN    main_proc:    PROCESS(a)    VARIABLE item:array0(7 downto 0); --定義一個變量 item    BEGIN        item(7):=a;        c<=item(7);    END PROCESS;END

2).BLOCK 語句結(jié)構(gòu)

BLOCK 語句的格式如下:

塊名:BLOCK(條件)    [參數(shù) GENERIC 說明; [參數(shù)映射;] ]    [端口說明; [端口映射;] ]    [塊說明語句]BEGIN    并發(fā)語句組;END BLOCK 塊名;

BLOCK 放在結(jié)構(gòu)體的并行語句組中,每一個 BLOCK 相當于一個子電路原理圖。和 PROCESS語句不同,BLOCK 內(nèi)的語句是并發(fā)執(zhí)行的。只要 BLOCK 右邊的條件滿足,BLOCK 內(nèi)的語句就被執(zhí)行。如果省略條件,表示本 BLOCK 被無條件執(zhí)行。下面是一個 BLOCK 語句的例子:

library IEEE;use IEEE.std_logic_1164.all;
ENTITY test is    PORT (          a, b: in bit;          s, c: out bit?????????);END ENTITY;
ARCHITECTURE arch of test isBEGIN    block_demo: BLOCK(clk='1')    BEGIN        s<=a xor b;        c<=a and b;    END BLOCK block_demo;END;

上面的程序表示當 clk 信號變?yōu)?1 時,并行執(zhí)行 BLOCK 語句內(nèi)的程序,即將 a 和 b 兩個信號的異或結(jié)果賦給 s 信號,同時將 a 和 b 信號的與結(jié)果賦給 c 信號。

3).子程序結(jié)構(gòu)

所謂子程序結(jié)構(gòu)就是將一部分實現(xiàn)代碼放到公用的程序(即程序包 Package)文件中實現(xiàn)。程序包中的代碼以子程序的方式提供給 VHDL 程序調(diào)用,這樣代碼可以實現(xiàn)共享,同時還使得VHDL 程序的結(jié)構(gòu)明了。

子程序在調(diào)用時首先要進行初始化,執(zhí)行結(jié)束后子程序就終止,再調(diào)用時要再進行初始化。因此子程序內(nèi)部的值不能保持,子程序返回以后才能被再調(diào)用,它是一個非重入的程序。

VHDL 中有兩種類型的子程序—過程(Procedure)和函數(shù)(Function),下面分別介紹一下它們的格式。

? 過程過程的格式如下:

PROCEDURE 過程名(參數(shù) 1;參數(shù) 2;……) IS    定義語句;BEGIN    順序語句組;END 過程名;

每個參數(shù)的說明格式如下:

參數(shù)名:方向 類型

方向一般為 3 種:IN、OUT、INOUT。如果方向為 IN 則可省略方向說明。

? 函數(shù)

函數(shù)的格式如下:

FUNCTION 函數(shù)名(參數(shù) 1;參數(shù) 2;……) RETURN 數(shù)據(jù)類型 IS    定義語句;BEGIN    順序語句組;    RETURN [返回變量名];END 函數(shù)名;

在 VHDL 語言中,函數(shù)的所有參數(shù)都是輸入?yún)?shù),因此都是 IN 的方向,可以省略方向說明。

在下面介紹程序包(PACKAGE)的時候?qū)榻B函數(shù)、過程定義的例子,在此不再舉例說明。

2.3 程序包和程序包體

程序包說明類似 C 語言中的 include 語句,用來羅列 VHDL 語言中所要用到的信號定義、常數(shù)定義、數(shù)據(jù)類型、元件語句、函數(shù)定義和過程定義等,它是一個可編譯的設(shè)計單元,也是庫結(jié)構(gòu)中的一個層次。

程序包的結(jié)構(gòu)如圖 4 所示。

圖 4 VHDL 程序包結(jié)構(gòu)圖

一個程序包由兩大部分組成:程序包申明和程序包體。程序包體是一個可選項,也就是說,程序包可以僅僅由程序包標題構(gòu)成。一般程序包標題列出所有項的名稱,而程序包體具體給出各項的細節(jié)。

下面介紹一個包含與非函數(shù)的程序包的實現(xiàn)以及調(diào)用方法。實現(xiàn)與非函數(shù)程序包的代碼如下:

LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;
-- 程序包申明PACKAGE package_demo is    -- 函數(shù)申明    FUNCTION nand2(a, b : in bit)    RETURN bit;END package_demo;
-- 程序包體PACKAGE BODY package_demo is    -- 函數(shù)實現(xiàn)    FUNCTION nand2(a, b : in bit)    RETURN bit IS    VARIABLE ret: bit;    BEGIN        ret = not(a and b);        return ret;    END nand2;END BODY;

上面的代碼在程序包申明中申明了函數(shù) nand2,然后在程序包體中具體實現(xiàn)了此函數(shù)的功能。下面舉個例子來說明程序包的使用方法,即函數(shù)的調(diào)用方法。假設(shè)要得到如下的邏輯關(guān)系式:

可以用下面的代碼描述:

library IEEE;use IEEE.std_logic_1164.all;use WORK.package_demo.all; -- 調(diào)用自定義的程序包
ENTITY test is    PORT (          A1, B1, A2, B2: in bit;          D: out bit          );END ENTITY;
ARCHITECTURE arch of test isBEGIN    -- 調(diào)用 nand 函數(shù)    D = nand2(A1, B1) and nand2(A2, B2);END;

自定義的程序包必須首先進行編譯,然后才能夠編譯調(diào)用此程序包的 VHDL 程序。自定義的程序包屬于 WORK 庫,所以申明調(diào)用的代碼是:

use WORK.自定義程序包名稱.all;

調(diào)用程序包中函數(shù)或者過程的方法和一般高級語言(如 C 語言)一樣直接調(diào)用就可以了。

2.4 配置的申明方法

一個實體可以包含多個結(jié)構(gòu)體,配置的作用就是根據(jù)需要選擇實體的結(jié)構(gòu)體。配置語句描述層與層之間的連接關(guān)系以及實體與結(jié)構(gòu)之間的連接關(guān)系。設(shè)計者可以利用這種配置語句來選擇不同的結(jié)構(gòu)體,使其與要設(shè)計的實體相對應(yīng)。在仿真某一個實體時,可以利用配置來選擇不同的結(jié)構(gòu)體,進行性能對比試驗以得到性能最佳的結(jié)構(gòu)體。

例如,設(shè)計一個二輸入、四輸出的譯碼器。如果一種結(jié)構(gòu)中的基本單元采用反相器和三輸入與門,而另一種結(jié)構(gòu)中的基本元件都采用與非門。它們各自的結(jié)構(gòu)體是不一樣的,并且都放在各自不同的庫中。那么現(xiàn)在要設(shè)計的譯碼器,就可以利用配置語句實現(xiàn)對兩種不同構(gòu)造的選擇。

配置的基本格式如下:

CONFIGURATION 配置名 OF 實體名 IS    [語句說明]END 配置名;

如果一個實體僅僅具有一個結(jié)構(gòu)體,也需要定義其配置,但是可以寫成一種最為簡潔的格式:

CONFIGURATION 配置名 OF 實體名 IS    FOR 所選的構(gòu)造體名    END FOR;END 配置名;

如果一個模塊比較復(fù)雜,含有多個子模塊,使用低層次配置可以為每個子模塊選擇其結(jié)構(gòu)體,代碼如下:

CONFIGURATION 配置名 OF 實體名 IS    FOR 所選的構(gòu)造體名        FOR 標號 1:元件名 1 USE CONFIGURATION WORK.配置體名 1;        END FOR;        FOR 標號 2:元件名 2 USE ENTITY WORK.實體名 2(構(gòu)造體名 2);        END FOR;    END FOR;END 配置名;

其中,低層次構(gòu)造體名可用 ALL 或 OTHERS,構(gòu)造體名 2 可以省略。

2.5 VHDL 程序的庫

庫(Library)是經(jīng)編譯后的數(shù)據(jù)的集合,它存放包集合申明、實體申明、構(gòu)造體申明和配置定義。它的功能類似于 UNIX 和 MS-DOS 操作系統(tǒng)中的目錄,在 VHDL 中,庫的說明總是放在設(shè)計單元的最前面,這樣在設(shè)計單元內(nèi)的語句就可以使用庫中的數(shù)據(jù)了。由此可見,使用庫的好處是使設(shè)計者可以共享已經(jīng)編譯過的設(shè)計結(jié)果。在 VHDL 中可以存在多個不同的庫,但是庫和庫之間是獨立的,不能互相嵌套。

申明庫的格式如下:

LIBRARY 庫名;

在 VHDL 語言中存在的庫大致可以歸納為 5 種:IEEE 庫、STD 庫、ASIC 矢量庫、用戶定義庫和 WORK 庫。

1).IEEE 庫

在 IEEE 庫中的“STD_LOGIC_1164”包集合是 IEEE 正式認可的標準包集合?,F(xiàn)在有些公司提供的包集合如“STD_LOGIC_ARITH”、“STD_LOGIC_UNSIGNED”等,盡管沒有得到 IEEE 的承認,但是仍匯集在 IEEE 庫中。

2).STD 庫

STD 庫是 VHDL 的標準庫,在庫中存放有“STANDARD”包集合。由于它是 VHDL 的標準配置,因此設(shè)計者如要調(diào)用“STANDARD”中的數(shù)據(jù)可以不按標準格式說明。STD 庫中還包含有“TEXTIO”包集合,在測試時使用。使用“TEXTIO”包集合中的數(shù)據(jù)時,應(yīng)先說明庫和包集合名:

LIBRARY STD;USE STD.TEXTIO.ALL;

3).ASIC 矢量庫

在 VHDL 中,為了進行門級仿真,各公司可提供面向 ASIC 的邏輯門庫。在該庫中存放著與邏輯門一一對應(yīng)的實體。

4).WORK 庫

WORK 庫是現(xiàn)行作業(yè)庫。設(shè)計者所描述的 VHDL 語句不需要任何說明,都將存放在 WORK 庫中。在使用該庫時無需進行任何說明。

5).用戶定義庫

將用戶自身設(shè)計開發(fā)的包、實體等匯集在一起定義成一個庫,就是用戶定義庫或稱用戶庫。在使用用戶定義庫時同樣要首先說明庫名。

以上各種庫中,除 WORK 庫外,其他 4 類庫在使用前都首先要進行說明,格式為:

USE 庫名.包集合名.項目名;

如果項目名為 ALL,則表示包集合中的所有項目都要使用,例如:

LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.ALL;USE WORK.STD_ARITH.ALL;

庫說明語句的作用范圍從一個實體說明開始到它所屬的構(gòu)造體、配置結(jié)束為止。當一個源程序出現(xiàn)兩個或兩個以上的實體時,兩條作為使用庫的說明語句就在每個實體說明語句前重復(fù)書寫。例如,在一個 VHDL 文件中定義兩個實體,庫的申明如下:

-- 第一個實體的庫申明LIBRARY IEEE;USE IEEE.STD_LOGIC_1644.ALL;
-- 第一個實體申明ENTITY ent1 isEND ent1;
-- 第一個實體的結(jié)構(gòu)體ARCHITECTURE arch1 of ent1 isEND arch1;-- 第一個實體的配置CONFIGURATION cfg1 of ent1 isEND cfg1;
-- 第二個實體的庫申明LIBRARY IEEE;USE IEEE.STD_LOGIC_1644.ALL;
-- 第二個實體申明ENTITY ent2 isEND ent2;
-- 第二個實體的結(jié)構(gòu)體ARCHITECTURE arch2 of ent2 is

三、VHDL 語言的數(shù)據(jù)類型和運算符

VHDL 和其他高級語言一樣,具有多種數(shù)據(jù)類型。對大多數(shù)數(shù)據(jù)類型的定義兩者是一致的(例如整數(shù)型),但是也有一些數(shù)據(jù)類型是 VHDL 所獨有的。表 2 所示為 VHDL 支持的數(shù)據(jù)類型和它的數(shù)據(jù)對象。

表 2 VHDL 數(shù)據(jù)類型和數(shù)據(jù)對象表

注意:表?2 中帶*號的數(shù)據(jù)類型表示不可以綜合的類型或?qū)ο蟆?/p>

3.1 VHDL 語言的數(shù)據(jù)對象

VHDL 對象有 4 種,即信號(Signal)、變量(Variable)、常量(Constant)和文件(File)。

其中文件(File)是 VHDL’93 標準中新通過的,它是不可以綜合的。下面介紹一下常量、信號和變量的申明方法。

1).信號(Signal)

信號用于將元件的裝配端口連在一起形成模塊,它的作用相當于連接元件的導(dǎo)線。信號是實體間動態(tài)數(shù)據(jù)交換的手段,信號申明格式如下:

SIGNAL signal_name : signal_type [ :=initial_value ] ;

在關(guān)鍵字 SIGNAL 后跟一個或者多個信號名,每個信號名將建立一個新信號,用冒號把信號名和信號的數(shù)據(jù)類型分隔開,信號數(shù)據(jù)類型規(guī)定信號包含的數(shù)據(jù)類型信息及初始化信號指定的初值。

實體說明部分、結(jié)構(gòu)體說明和程序包說明都能聲明信號,全局信號在程序包中聲明,它們被所屬的實體分享。

2).變量(Variable)

變量用于存儲進程和子程序中的局部數(shù)據(jù),變量的賦值是立即執(zhí)行的,沒有延時。變量的申明格式如下:

VARIABLE variable_name ,variable_name : variable_type[:= value];

關(guān)鍵字 VARIABLE 后跟著一個或多個變量名,每個變量名對應(yīng)建立一個新變量。variable_type 字段定義了變量的數(shù)據(jù)類型,并且還可以指定一個可選的初值。此外,還需要注意的是只可以在進程說明部分和子程序說明部分聲明變量。

和信號相比,變量有以下優(yōu)點:

? 變量處理起來更快,因為變量賦值是立即發(fā)生的,而信號卻必須為此事件作相應(yīng)的處理。

? 變量用很少的存儲器,相反為了做一個調(diào)度安排和處理信號屬性,需要存儲更多的信號信息。

? 變量比信號更容易實現(xiàn)同步處理。

3).常量

常量是為特定的數(shù)據(jù)類型值所賦予的名稱,如果需要在多個具體元件中存放一個固定值就使用常量。例如可以如下定義常量 PI(π ):

CONSTANT PI: REAL:= 3.1416;

定義常量的格式如下:

CONSTANT constant_name,constant_name: type_name[:= value];

一般情況下,VHDL 中的常量是在程序包申明中進行申明,而在程序包體中指定具體的值。使用常量需要注意以下幾個問題:

? 在程序包中說明的常量被全局化。

? 在實體說明部分的常量被那個實體中任何結(jié)構(gòu)體引用。

? 在結(jié)構(gòu)體中的常量能被其結(jié)構(gòu)體內(nèi)部任何語句采用,包括為進程語句采用。

? 在進程說明中說明的常量只能在進程中使用。

? 在數(shù)組和一些線性運算中經(jīng)常用常量表,VHDL 的設(shè)計描述用常量表特別適于實現(xiàn) ROM 網(wǎng)絡(luò)的電路與函數(shù)設(shè)計。

3.2 VHDL 語言的數(shù)據(jù)類型

VHDL 的數(shù)據(jù)類型根據(jù)使用目的和場合,可以分為標準數(shù)據(jù)類型和用戶定義的數(shù)據(jù)類型兩種。

1).標準數(shù)據(jù)類型

VHDL 中定義的標準數(shù)據(jù)類型如表 3 所示。

表 3 VHDL 中的標準數(shù)據(jù)類型

其中,在數(shù)據(jù)類型后面,可以加上約束區(qū)間,比如:

INTEGER RANGE 100 downto 1;BIT_VECTOR(3 downto 1) real range 2.0 to 30.0;

STD_LOGIC 和 STD_LOGIC_VECTOR 的邏輯數(shù)據(jù)取值可以有 9 種狀態(tài),如表 4 所示。

表 4 標準邏輯(向量)取值表

2).用戶定義的數(shù)據(jù)類型

用戶定義數(shù)據(jù)類型的格式如下:

TYPE 數(shù)據(jù)類型名 {,數(shù)據(jù)類型名} 數(shù)據(jù)類型定義;

數(shù)據(jù)類型定義放在語句的定義部分中,定義范圍為從本定義行開始到本語句作用的最后。

一般用戶定義的數(shù)據(jù)類型分為以下幾種。

? 枚舉類型(enumeration)

枚舉類型的格式如下:

TYPE 數(shù)據(jù)類型名 IS (元素,元素,……)

例如,將一星期七天作為一個枚舉,可以如下定義:

TYPE week IS (sun, mon, tue, wed, thu, fri, sat);

在枚舉類型中,元素是有序列性的,第 1 個元素對應(yīng)邏輯電路狀態(tài) 000,第 2 個為狀態(tài) 001,第 3 個為狀態(tài) 010……后一個邏輯狀態(tài)為前一個元素邏輯狀態(tài)加 1。所以,上面的例子中,sun對應(yīng)邏輯狀態(tài) 000,mon 對應(yīng)邏輯狀態(tài) 001,……,sat 對應(yīng)邏輯狀態(tài) 110。

? 整數(shù)類型、實數(shù)類型(INTEGER,REAL)

這里的整數(shù)類型和實數(shù)類型其實是前面所述的標準整數(shù)類型和實數(shù)類型的子類,定義的格式如下:

TYPE 數(shù)據(jù)類型名 IS 數(shù)據(jù)類型定義 約束范圍

例如:

TYPE current IS REAL RANGE -1E4 TO 1E4

定義了 current 類型實數(shù)的范圍是-104到 104。

? 數(shù)組(ARRAY)

數(shù)組定義的格式如下:

TYPE 數(shù)據(jù)類型名 IS ARRAY 范圍 OF 原數(shù)據(jù)類型名;

注意:如果 范圍 這一項沒有被指定,則使用整數(shù)數(shù)據(jù)類型。

下面通過例子說明數(shù)組的定義方法。

TYPE word IS ARRAY (1 TO 8) OF STD_LOGIC;TYPE tmem IS ARRAY (0 TO 2, 3 DOWNTO 0) OF STD_LOGIC;

以上定義了 tmem 一種數(shù)組類型,可以定義一個此類新的常數(shù),如下:

CONSTANT mem:tmem:= ( ('0', '0', '0', '0'),                      ('0', '0', '1', '0'),                      ('1', '1', '0', '0'));

當范圍這一項需用整數(shù)類型以外的其他數(shù)據(jù)類型時(如枚舉類型),則應(yīng)在指定數(shù)據(jù)范圍前加數(shù)據(jù)類型名。例如:

TYPE week IS (sun, mon, tue, wed, thu, fri, sat);TYPE workdate IS ARRAY (week mon TO fri) OF STD_LOGIC;

如果要取得數(shù)組內(nèi)的一個元素,格式如下:

數(shù)組名(下標)

例如,word(1)區(qū)的 word 數(shù)組序號為 1 的元素。

當數(shù)組類型定義中的范圍用“(Natural Range <>)”或“(Positive Range <>)”代替時,表示本數(shù)組類型為非限定的類型,下標范圍在信號或變量定義時再具體指定。

例如下面的代碼中定義的 array0 就是非限定類型的數(shù)組。

library IEEE;use IEEE.std_logic_1164.all;entity tmyarray isport(a:in std_logic;c:out std_logic);end ;architecture myarray of tmyarray istype array0 is array (natural range <>) of std_logic;begin    process(a)        variable item:array0(7 downto 0);--定義一個變量 item    begin        item(7):=a;        c<=item(7);    end process;end;

??時間(TIME)

定義時間的格式如下:

TYPE 數(shù)據(jù)類型名 IS 范圍    UNITS  基本單位;           單位描述;    END UNITS

例如:

TYPE 數(shù)據(jù)類型名 IS 范圍    UNITS 基本單位;          單位描述;    END UNITSTYPE time IS RANGE -1E18 TO 1E18    UNITS fs;          ps=1000fs;          ns=1000ps;          us=1000ns;          ms=1000us;          sec=1000ms;          min=60sec;          hr=60min;    END UNITS;

? 記錄(Record)

記錄的定義格式是:

TYPE 數(shù)據(jù)類型名 IS RECORD    元素名:數(shù)據(jù)類型名;    元素名:數(shù)據(jù)類型名;    元素名:數(shù)據(jù)類型名;END RECORD;

注意:引用記錄數(shù)據(jù)類型中的元素應(yīng)使用“.”,而不是數(shù)組的括號。

 

例如,定義一個窗口尺寸的記錄,如下:

TYPE window IS RECORD    length:INTEGER;    width:INTEGER;END RECORD;

 

當需要使用 window 類型記錄的元素時,方法如下:

signal win: window;win.length<=10;

 

? 用戶定義的子類型

用戶定義的子類型是用戶對已定義的數(shù)據(jù)類型做一些范圍限制而形成的一種數(shù)據(jù)類型。子類型的名稱通常采用用戶較容易理解的名字。子類型的定義格式為:

SUBTYPE 子類型名 IS 數(shù)據(jù)類型名[范圍];

例如:

SUBTYPE digit IS INTEGER RANGE 0 TO 9;SUBTYPE abus IS STD_LOGIC_VECTOR(7 DOWNTO 0);signal a: STD_LOGIC_VECTOR (7 downto 0);signal b: STD_LOGIC_VECTOR (15 downto 0);signal c: abus;a<=c; --正確b<=c; --錯誤

在 VHDL 中,數(shù)據(jù)類型的定義是相當嚴格的,不同類型的數(shù)據(jù)是不能進行運算和直接代入的。為了實現(xiàn)正確的代入操作,必須將要代入的數(shù)據(jù)進行類型變換。

變 換 函 數(shù) 通 常 由 VHDL 語 言 的 包 集 合 提 供 。 例 如 在 “ STD_LOGIC_1164 ”、“STD_LOGIC_ARITH”、STD_LOGIC_UNSIGNED”的包集合中提供了如表 2-5 所示的數(shù)據(jù)類型變換函數(shù)。

表 5 類型變換函數(shù)表

有些數(shù)據(jù),從數(shù)據(jù)本身是斷定不出其類型的,如“01010001”,如果沒有上下文,VHDL 編譯器就無法知道它是字串型還是位數(shù)組類型。這時就要進行數(shù)據(jù)類型的限定。類型限定的格式如下:

類型名'(數(shù)據(jù))

例如:

a<=std_logic_vector'("01010001");

這樣,編譯器知道“01010001”肯定是矢量型,而不是別的類型。

3.3 VHDL 語言的運算符

在 VHDL 語言中,常用的運算符有邏輯運算(Logic)、關(guān)系運算(Relational)、算術(shù)運算(Arithmetic)和移位運算(Shift),下面分別對它們進行介紹。

1).邏輯運算符

邏輯運算符可以對 bit 和 boolean 類型的值進行運算,也可對這些類型的一維數(shù)組進行運算。對數(shù)組型的運算,運算施加于數(shù)組中的每個元素,結(jié)果與原來數(shù)組長度相同。

邏輯判斷的運算為“短路運算”,也就是說,條件表達式的左邊成立時,就不再進行右邊的判斷。比如,IF (a=0) AND (b/a>2) THEN…這個判斷運算,當 a=0 時,后面的判斷不再繼續(xù),避免出現(xiàn)除數(shù)為 0 的運算。

VHDL 的邏輯運算符如表 6 所示。

表 6 VHDL 邏輯運算符

2).關(guān)系運算符

關(guān)系運算符兩邊必須為相同的類型,其結(jié)果為 boolean 類型。

等號(=)和不等號(/=)兩邊可以為任意類型的運算對象。其他關(guān)系運算符的運算對象必須為標量類型或離散類型的一維數(shù)組。對于復(fù)雜的運算對象,如數(shù)組,兩個值相等意味著兩個值的所有對應(yīng)元素相等。VHDL 的關(guān)系運算符如表 7 所示。

表 7 VHDL 關(guān)系運算符

3).算術(shù)運算符

算術(shù)運算符包括一些基本的算術(shù)運算,使用算術(shù)運算符需要注意的是乘方(**)運算的右邊必須為整數(shù)。VHDL 的算術(shù)運算符如表 8 所示。

表 8 VHDL 算術(shù)運算符

4).移位運算符

移位運算符為二元運算符,左邊必須為一維數(shù)組,且元素類型為 bit 或 boolean 類型。右邊運算數(shù)為整數(shù),可以為負數(shù),相當于反方向移位。一位移位與循環(huán)移位的語義示意如圖 5 所示。

圖 5 一位移位與循環(huán)移位示意圖

VHDL 的移位運算符如表 9 所示。

表 9 VHDL 移位運算符

除了上面介紹的,VHDL 中運算符還包括正號“+”、負號“-” 以及“&”。其中,連接符號(&)用于一維數(shù)組,這個數(shù)組的元素個數(shù)可以為 1,運算結(jié)果為右邊數(shù)組連接在左邊數(shù)組之后形成新數(shù)組,例如:

sel <= a & b;

假設(shè) a 信號為“0”,b 信號為“1”,那么得到的 sel 信號就是“01”。

所有的 VHDL 運算符之間都有優(yōu)先級的關(guān)系,各運算符優(yōu)先級從最高到最低,順序如表 10 所示(同一行優(yōu)先級相同)。

表 10 運算符的優(yōu)先順序

四、 VHDL 語言的描述語句

使用 VHDL 進行數(shù)字電路描述時候,如果按照執(zhí)行順序?qū)?VHDL 的程序進行分類,可以分為順序(sequential)描述語句和并行(concurrent)描述語句。順序語句描述的程序總是按照程序書寫的順序執(zhí)行;而并行語句都是同時執(zhí)行的,和程序的書寫順序無關(guān)。

4.1 VHDL 順序語句描述方法

VHDL 中的順序語句一般在進程中出現(xiàn),或者以函數(shù)、過程的方式在進程中被調(diào)用。順序語句所涉及到的系統(tǒng)行為有時序流、控制、條件和迭代等。

VHDL 中的順序語句有 WAIT 語句、斷言語句、IF 語句、CASE 語句、LOOP 語句、NEXT 語句、過程調(diào)用語句和 NULL 語句,下面就對它們進行詳細介紹。

1).WAIT 語句

WAIT 語句允許把一個順序執(zhí)行的進程或子程序掛起,掛起的進程或子程序恢復(fù)的條件由 3種不同的方法指定。WAIT 語句可以有不同的格式,分別有不同的作用,例如 WAIT ON 表示等待到信號變化,WAIT UNTIL 表示等到一個表達式為真,而 WAIT FOR 表示等待一個固定的事件,如果僅僅寫一個 WAIT 的話就表示無限期的等待。

WAIT 語句能用于多種不同的目的,常用于為綜合工具指定時鐘輸入。另一用途是將進程的執(zhí)行延時一段時間或者是為了動態(tài)地修改進程敏感表。

為了避免無休止的等待可以加一個超時付句,不管進行到哪兒或是條件有沒有滿足都允許執(zhí)行超時處理。下面的代碼就演示了 WAIT UNTIL 語句的使用方法和超時處理的方法:

WAIT  UNTIL (sendB = '1') FOR 1 ns;      ASSERT (sendB = '1')      REPORT "sendB timed out at '1'"      SEVERITY ERROR;

2).斷言語句

斷言語句的功能是為設(shè)計者報告一個文本字符串。斷言語句包含一個布爾表達式,表達式為真,該語句不做任何事;反之,它將輸出一用戶規(guī)定的字符串到標準輸出終端。

斷言語句規(guī)定輸出字符串的嚴重程度為 4 個級別(NOTE、WARNING、ERROR 和 FAILURE),它們的意思分別是注意、警告、錯誤和失敗,嚴重層次遞增。

斷言語句的格式如下:

ASSERT_STATEMENT ::=    ASSERT CONDITION    [REPORT EXPRESSION]    [SEVERITY EXPRESSION];

其中,關(guān)鍵字 ASSERT 后跟 CONDITION 布爾值表達式,它的條件決定 REPORT 付句規(guī)定的文字表達式輸出不輸出,如果是假,文字表達式輸出,如果是真,該文字表達式不輸出。

此外還有兩個可選的付句,REPORT 付句允許設(shè)計者指定輸出文字表達式的值,如果不指定 REPORT 語句,默認值是 ASSERTION VIOLATION,SEVERITY 付句允許設(shè)計者指定斷言語句的嚴重級別,如果沒指定 SEVERITY 付句,其默認值是 ERROR。

下面是一個斷言語句的使用實例,它表示對輸入時鐘進行檢查,如果其建立時間小于20ns,則輸出 ERROR 信號:

PROCESS (clk,din)    VARIABLE last_d_change :TIME := 0 ns;    VARIABLE last_d_value :std_logic := 'X';    VARIABLE last_clk_value :std_logic := 'X';    BEGIN    IF (last_d_value /= din) THEN -- /= is not equal        last_d_change := NOW;        last_d_value := din;    END IF;        IF (last_clk_value /= clk) THEN        last_clk_value := clk;                IF (clk = '1') THEN            -- 斷言語句            ASSERT (NOW - last_d_change >= 20 ns)            REPORT "setup violation"            SEVERITY WARNING;        END IF;            END IF;    END PROCESS;

3).IF 語句

IF 語句是根據(jù)所指定的條件來確定執(zhí)行哪些語句,其格式如下:

IF condition THEN    sequence_of_statementsELSIF condition THEN    sequence_of_statementsELSE    sequence_of_statementEND IF;    

IF 語句用關(guān)鍵字 IF 開頭和用關(guān)鍵字 END IF 結(jié)尾,END IF 分開拼寫。有兩個可選付句(ELSIF付句和 ELSE 付句),ELSIF 付句可重復(fù)并允許有多個 ELSIF 付句,可選 ELSE 付句但只允許有一個 ELSE 付句。付句中的條件是一布爾表達式,如條件為真值,則下一語句被執(zhí)行;如果條件不為真,那么接著執(zhí)行跟在 ELSE 付句后的順序語句。

下面舉一個 IF 語句的使用例子,如下:

IF (day = sunday) THEN    weekend := TRUE;ELSIF (day = saturday) THEN    weekend := TRUE;ELSE    weekday := TRUE;END IF;

以上代碼的意義如下:有兩個變量 weekend 和 weekday,每當 day 等于 saturday 或 sunday時變量 weekend 變?yōu)檎妫瑘?zhí)行跟著的下一句并控制轉(zhuǎn)到跟在 END IF 之后的語句,否則轉(zhuǎn)到 ELSIF語句部分并檢查 day 是否為 Saturday;當變量 day 等于 saturday,執(zhí)行跟著的下一句并再次控制轉(zhuǎn)到跟在 END IF 之后的語句;若 day 并不等于 sunday 或 saturday,執(zhí)行 ELSE 語句部分。

4).CASE 語句

當單個表達式的值在多個起作用的項中選擇時用 CASE 語句。CASE 語句的格式如下:

CASE expression IS    WHEN choice1 =>        sequence_of_statements    WHEN choice2 | choice3 =>        sequence_of_statements    WHEN OTHERS =>        sequence_of_statementsEND CASE;

下面是一個使用 CASE 語句執(zhí)行處理器指令的例子:

CASE instruction IS    WHEN load_accum =>        accum <= data;    WHEN store_out =>        data_out <= accum;    WHEN load|store =>        process_IO(addr);    WHEN OTHERS =>        process_error(instruction);END CASE

?5).循環(huán)語句

當需要重復(fù)操作時用循環(huán)語句,或者實現(xiàn)的模塊需要很強的迭代能力時用循環(huán)語句:

[循環(huán)標示 :] [循環(huán)條件] LOOP    順序處理語句END LOOP[LOOP_label];

其中循環(huán)條件可以用 WHILE 語句或者 FOR 語句來描述。WHLIE 語句有一個循環(huán)控制的條件 condition,只要條件表達式為真,WHILE 循環(huán)語句就一直執(zhí)行下去,除非要退出循環(huán)。例如:

WHILE (day = weekday) LOOP    day := get_next_day(day);END LOOP

FOR 循環(huán)是根據(jù)預(yù)先的設(shè)定進行迭代,所指定的范圍并不一定必須為整數(shù)值,也可以表示成一個子類型的指示或者一個范圍語句,例如:

PROCESS (clk)    TYPE day_of_week IS (sun,mon,tue,wed,thur,fri,sat);BEGIN    FOR i IN day_of_week LOOP        IF i = sat THEN            son <= mow_lawn;        ELSEIF i = sun THEN            church <= family;        ELSE            dad <= go_to_work;        END IF;    END LOOP;END PROCESS;

FOR LOOP 語句的指數(shù)值(i)由 FOR 語句局部地說明,這和進程、函數(shù)和過程中變量 I 不是一會事,它不需要顯式地說明,由于 FOR LOOP 語句的虛擬性,循環(huán)指數(shù)要局部說明之。這樣在進程、函數(shù)或過程中存在同名變量時,它們會被分別處理并由它們的內(nèi)含尋址。

此外,關(guān)于循環(huán)需要特別注意的是,在某些編程語言中循環(huán)指數(shù)的值可由賦予內(nèi)部循環(huán)值來改變,但是 VHDL 中是不允許對循環(huán)指數(shù)的任何賦值,這排除了在任何函數(shù)返回值中或在過程的輸出與雙向參量中存在循環(huán)指數(shù)。

6).NEXT 語句

如果必須在這次迭代或循環(huán)中停下正在執(zhí)行的語句,而轉(zhuǎn)向下一個迭代時,用 NEXT 語句。執(zhí)行 NEXT 語句時,模塊處理停在當前點并轉(zhuǎn)到循環(huán)語句的開始。隨著循環(huán)的第一個語句執(zhí)行,循環(huán)變量增加一個迭代值,直到迭代的限制值,循環(huán)停止。

下面是一個 NEXT 語句使用的例子:

PROCESS(A,B)    CONSTANT max_limit :INTEGER := 255;    TYPE d_type IS ARRAY (0 to max_limit) OF BOOLEAN ;    VARIABLE done : d_type;BEGIN    FOR i IN 0 TO max_limit LOOP    IF (done(i) = TRUE ) THEN        NEXT;    ELSE        done (i) := TRUE;    END IF;    q(i) <= a(i) AND b(i);    END LOOP;END PROCESS;

7).EXIT 語句

EXIT 語句提供完全停下循環(huán)執(zhí)行的能力。執(zhí)行期間發(fā)生了明顯的錯誤或者所有的進程已執(zhí)行完畢就跳出循環(huán),EXIT 語句允許退出或跳出循環(huán)語句。執(zhí)行 EXIT 語句后 EXIT 語句后面的語句暫停執(zhí)行,去執(zhí)行循環(huán)語句后面的語句。

EXIT 語句的基本書寫格式如下:

EXIT [循環(huán)標號][WHEN 條件]

循環(huán)標號一般在多重循環(huán)中用于標明循環(huán)層次,如果 EXIT 語句后面添加循環(huán)標號,它將會退出循環(huán)標號指定的循環(huán)?!癢HEN 條件”項用于表明 EXIT 語句執(zhí)行的條件,此條件為真時才推出循環(huán)。

EXIT 語句的使用實例如下:

PROCESS (a)BEGIN    first_loop:FOR i IN 0 TO 100 LOOP        second_loop:FOR j IN 1 TO 10 LOOP            ......            EXIT second_loop;            ......            EXIT first_loop;        END LOOP;    END LOOP;END PROCESS;

4.2 VHDL 并行語句描述方法

VHDL 不僅僅提供了一系列的順序語句,同樣也提供了很多并行語句。在 VHDL 中,并行語句主要包括以下幾種:

? 進程(PROCESS)語句;

? 塊(BLOCK)語句;

? 并發(fā)信號賦值;

? 條件信號賦值;

? 選擇信號賦值。

其中進程語句和塊語句已經(jīng)在結(jié)構(gòu)體的描述方法中介紹過了,在此不再累贅,后面主要介紹余下的 3 種并行語句。

1).并發(fā)信號賦值

信號賦值就是使用信號賦值操作符“<=”修改一個信號的狀態(tài),如果此語句是在一個進程中,那么它是一個順序語句,反之如果它是在進程外面(和進程并列關(guān)系),那么它就是一個并行賦值的語句。

下面是一個信號賦值的例子,其中 c1、c2 是順序賦值的,c2 在 c1 之后賦值;d1 和 d2是并行賦值的,它們同時被賦值:

ARCHITECTURE arch of demo isBEGIN-- 并行賦值d1 <= dind2 <= din-- 進程PROCESS(din)BEGIN-- 順序賦值c1 <= dinc2 <= dinEND PROCESS;END arch;

2).條件信號賦值

條件信號賦值的格式如下:

目的信號 <=  表達式 1 WHEN 條件 1 ELSE            表達式 2 WHEN 條件 2 ELSE            表達式 3 WHEN 條件 3 ELSE            表達式 n;

最后一個表達式 n 表示以上 n-1 個條件都不滿足時自動選用此表達式,如果有條件滿足,則條件對應(yīng)的表達式會計算賦值給目的信號量。條件信號代入語句也是并發(fā)描述語句,它可以根據(jù)不同條件將不同的多個表達式之一的值代入信號量。

下面通過一個四選一選擇器的實現(xiàn)方法來介紹條件信號代入語句的使用方法:

ENTITY mux4 ISPORT (      din0, din1, din2, din3,sel0,sel1: in bit;      dout: out bit );END mux4;
ARCHITECTURE arch of mux4 isSIGNAL sel : bit_vector(1 downto 0);BEGIN    sel <= sel1 & sel0;    dout <= din0 WHEN sel = “00” ELSE            din1 WHEN sel = “01” ELSE            din2 WHEN sel = “10” ELSE            din3 WHEN sel = “11” ELSE            ‘X’;END mux4;

3).選擇信號賦值

選擇信號賦值類似于 CASE 語句,它的格式如下:

WITH 表達式 SELECT目的信號量 <=  表達式 1 WHEN 條件 1;              表達式 2 WHEN 條件 2;              表達式 3 WHEN 條件 3;              表達式 n WHEN 條件 n;

如果使用選擇信號賦值實現(xiàn)上面的四選一選擇器,代碼如下:

ENTITY mux4 ISPORT (      din0, din1, din2, din3,sel0,sel1: in bit;      dout: out bit );END mux4;ARCHITECTURE arch of mux4 isSIGNAL sel : bit_vector(1 downto 0);BEGIN    sel <= sel1 & sel0;    WITH sel SELECT    dout <= din1 when “00”,    dout <= din1 when “01”,    dout <= din2 when “10”,    dout <= din3 when “1”,    ‘X” WHEN OTHERS;    END mux4;

五、 VHDL 語言的預(yù)定義屬性

在 VHDL 中,屬性是指關(guān)于設(shè)計實體、結(jié)構(gòu)體、類型、信號等項目的制定特征,利用屬性可以使得 VHDL 代碼更加簡明扼要、易于理解。

VHDL 提供了下面 5 類預(yù)定義屬性:值類屬性、函數(shù)類屬性、信號類屬性、數(shù)據(jù)類型類屬性和數(shù)據(jù)范圍類屬性。

5.1 值類預(yù)定義屬性

值類屬性返回有關(guān)數(shù)組類型、塊和常用數(shù)據(jù)類型的特定值,值類屬性還用于返回數(shù)組的長度或者類型的最低邊界,值類屬性分成 3 個子類。

1).值類型屬性:返回類型的邊界

值類型屬性用來返回類型的邊界,有 4 種預(yù)定義屬性:

? T'LEFT 用于返回類型或者子類型的左邊界;

? T'RIGHT 用于返回類型或者子類型的右邊界;

? T'High 用于返回類型或者子類型的上限值;

? T'Low 用于返回類型或者子類型的下限值。

用字符“'”指定屬性并后跟屬性名,“'”前的對象是所附屬性的對象,字首大寫“T”指所附屬性的對象是類型(TYPE),“'”字符標點符號(tick)是 VHDL 特有的標號。

2).值類數(shù)組屬性:返回數(shù)組長度

值類數(shù)組屬性只有一個,即 LENGTH,該屬性返回指定數(shù)組范圍的總長度,它用于帶某種標量類型的數(shù)組范圍和帶標量類型范圍的多維數(shù)組。

3).值類塊屬性:返回塊的信息

用屬性'STRUCTURE 和'BEHAVIOR 返回有關(guān)在塊和結(jié)構(gòu)體中塊是如何建模的信息。在塊和結(jié)構(gòu)體中如不含元件具體裝配語句,則屬性'BEHAVIOR 將返回真值,如果塊或者結(jié)構(gòu)體中只含元件具體裝配語句或被動進程,則屬性'STRUCTUTE 將返回真值。

5.2 函數(shù)類預(yù)定義屬性

函數(shù)類屬性為設(shè)計者返回類型、數(shù)組和信號信息。用函數(shù)類屬性時,函數(shù)調(diào)用由輸入變元的值返回一個值,返回值為可枚舉值的位置號碼、在一個△時間內(nèi)信號是否改變的指示或者一個數(shù)組的邊界。函數(shù)類屬性可細分為 3 個常見的類別。

1).函數(shù)類型屬性:返回類型值

函數(shù)類型屬性返回類型內(nèi)部值的位置號碼、返回特定類型輸入值的左和右邊的值,函數(shù)類型屬性分為 6 種:

? 'POS(value)返回傳入值的位置號碼;

? 'VAL(value)返回從該位置號碼傳入的值;

? 'SUCC(value)返回輸入值后類型中的下一個值;

? 'PRED(value)返回輸入值前類型中的原先的值;

? 'LEFTOF(value)表示立即返回一個值到輸入值的左邊;

? 'RIGHTOF(value)表示立即返回一值到輸入值的右邊。函數(shù)類型屬性主要用于從可枚舉數(shù)或物理類型的數(shù)轉(zhuǎn)換到整數(shù)類型。

2).函數(shù)數(shù)組屬性:返回數(shù)組的邊界

函數(shù)數(shù)組類屬性返回數(shù)組類型的邊界,分 4 類:

? 數(shù)組'LEFT(n)返回指數(shù)范圍 n 的左邊界;

? 數(shù)組'RIGHT(n)返回指數(shù)范圍 n 的右邊界;

? 數(shù)組'HIGH(n)返回指數(shù)范圍 n 的上限值;

? 數(shù)組'LOW(n)返回指數(shù)范圍 n 的下限值。值類數(shù)組屬性只有一個即 LENGTH,該屬性返回指定數(shù)組范圍的總長度,它用于帶某種標量類型的數(shù)組范圍和帶標量類型范圍的多維數(shù)組。

3).函數(shù)信號屬性:返回信號歷史信息

函數(shù)信號屬性用來返回有關(guān)信號行為功能的信息,例如報告究竟一個信號是否正好有值的變化,報告從上次事件中跳變過了多少時間以及該信號原來的值是什么。

函數(shù)信號屬性有如下 5 類:

? S'EVENT,如果當前的△時間期間發(fā)生了事件返回真,否則返回假(信號是否有值的變化);

? S'ACTIVE,如果在當前的△時間期間做了事項處理返回真,否則返回假;

? S'LAST_EVENT,返回從信號原先事件的跳變至今所經(jīng)歷的時間;

? S'LAST_VALUE,返回在上一次事件之前 S 的原先值;

? S'LAST_ACTIVE,返回自信號原先一次的事項處理至今所經(jīng)歷的時間。

5.3 信號類預(yù)定義屬性

信號類屬性用于根據(jù)另一個信號創(chuàng)建一些專用的信號,由類專用信號為設(shè)計者返回有關(guān)所附屬性的信號信息(在一指定時間范圍內(nèi)該信號是否已經(jīng)穩(wěn)定的信息、在信號上有無事項處理的信息和建立的信號的延遲形式)。

對這類信號是不能在子程序內(nèi)部使用的,返回的信息和由某種函數(shù)屬性所提供的功能非常類似,區(qū)別是這類專用信號用于正常信號能用的任何場合,包括在敏感表中。有如下的 4 類屬性:

? S'DELAYED[(time)] 建立和參考信號同類型的信號,該信號后跟參考信號和延時可選時間表示式的時間。'DELAYED 屬性為信號建立延遲的版本并附在該信號上,它和傳輸延時信號賦值的功能相同,但簡單。

? S'STABLE[(time)] 在選擇時間表達式指定的時間內(nèi)參考信號無事件發(fā)生時,屬性建立為真值的布爾信號。

? S'QUIET[(time)] 參考信號或所選時間表達式指定時間內(nèi)沒事項處理時,屬性建立一個為真值的布爾信號。

? S'TRANSACTION 信號上有事件發(fā)生或為每個事項處理而翻轉(zhuǎn)它的值時,該屬性建立一個 BIT 類型的信號。

5.4 數(shù)據(jù)類型類預(yù)定義屬性

數(shù)據(jù)類型類的屬性只有一個 t'BASE 類型屬性,它必須由另一個值或函數(shù)類型屬性用該屬性。這個屬性將返回類型或者子類型的基本類型,這個屬性只能作另一屬性的前綴。

5.5 數(shù)據(jù)范圍類預(yù)定義屬性

數(shù)據(jù)范圍類屬性返回數(shù)組類型的范圍值,并由所選的輸入?yún)?shù)返回指定的指數(shù)范圍,這種屬性標記如下:a'RANGE[(n)];a'REVERSE_RANGE[(n)]。

屬性 RANGE 將返回由參數(shù) n 值指明的第 n 個范圍和按指定排序的范圍,'REVERSE_RANGE將返回按逆序的范圍,屬性'RANGE 和'REVERSE_RANGE 也用于控制循環(huán)語句的循環(huán)次數(shù)。

REVERSE_RANGE 屬性的用法和 RANGE 屬性相類似,只是它按逆序返回一范圍而已。 比如假設(shè)'RANGE 屬性是返回 0 到 15,那么'REVERSE_RANGE 屬性返回 15 下降到 0。

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

任何技術(shù)的學(xué)習(xí)就好比一個江湖,對于每一位俠客都需要不斷的歷練,從初入江湖的小白到歸隱山林的隱世高人,需要不斷的自我感悟自己修煉,讓我們一起仗劍闖FPGA乃至更大的江湖。