加入星計劃,您可以享受以下權益:

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

VHDL語法學習筆記:一文掌握VHDL語法

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

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

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

VHDL語法學習筆記

一、VHDL簡介

1.1 VHDL 的歷史

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

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

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

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

1.2 VHDL 的特點

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

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

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

1.行為描述

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

2.仿真模擬

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

3.大規(guī)模設計

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

4.門級網(wǎng)表

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

5.獨立性

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

二、VHDL 程序基本結構

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

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

圖 1 所示為 VHDL 程序設計單元之間的關系。

圖 1 VHDL 程序設計單元關系圖

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

2.1 實體的申明方法

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

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

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

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

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

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

實體描述的格式如下:

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

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

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

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

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

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

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

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

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

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

表 1 端口方向關鍵字說明表

2.2 結構體的描述方法

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

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

結構體的格式如下:

  ARCHITECTURE 結構體名 OF 實體名 IS  [定義語句]  BEGIN  [并行處理語句]  END 結構體名;

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

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

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

對應以上原理圖的結構體描述如下:

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;

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

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

1).PROCESS 語句結構

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

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

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

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

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

PROCESS 語句的格式如下:

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

一般情況下進程名可以被省略。進程申明關鍵字 PROCESS 后面括號內的信號是此進程的敏感信號,這些信號的變化會激活過程的執(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

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

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 語句結構

BLOCK 語句的格式如下:

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

BLOCK 放在結構體的并行語句組中,每一個 BLOCK 相當于一個子電路原理圖。和 PROCESS語句不同,BLOCK 內的語句是并發(fā)執(zhí)行的。只要 BLOCK 右邊的條件滿足,BLOCK 內的語句就被執(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 語句內的程序,即將 a 和 b 兩個信號的異或結果賦給 s 信號,同時將 a 和 b 信號的與結果賦給 c 信號。

3).子程序結構

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

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

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)的時候將會介紹函數(shù)、過程定義的例子,在此不再舉例說明。

2.3 程序包和程序包體

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

程序包的結構如圖 4 所示。

圖 4 VHDL 程序包結構圖

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

下面介紹一個包含與非函數(shù)的程序包的實現(xiàn)以及調用方法。實現(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ù)的調用方法。假設要得到如下的邏輯關系式:

可以用下面的代碼描述:

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

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

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

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

2.4 配置的申明方法

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

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

配置的基本格式如下:

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

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

CONFIGURATION 配置名 OF 實體名 IS    FOR 所選的構造體名    END FOR;END 配置名;

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

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

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

2.5 VHDL 程序的庫

庫(Library)是經編譯后的數(shù)據(jù)的集合,它存放包集合申明、實體申明、構造體申明和配置定義。它的功能類似于 UNIX 和 MS-DOS 操作系統(tǒng)中的目錄,在 VHDL 中,庫的說明總是放在設計單元的最前面,這樣在設計單元內的語句就可以使用庫中的數(shù)據(jù)了。由此可見,使用庫的好處是使設計者可以共享已經編譯過的設計結果。在 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 的標準配置,因此設計者如要調用“STANDARD”中的數(shù)據(jù)可以不按標準格式說明。STD 庫中還包含有“TEXTIO”包集合,在測試時使用。使用“TEXTIO”包集合中的數(shù)據(jù)時,應先說明庫和包集合名:

LIBRARY STD;USE STD.TEXTIO.ALL;

3).ASIC 矢量庫

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

4).WORK 庫

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

5).用戶定義庫

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

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

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

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

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

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

-- 第一個實體的庫申明LIBRARY IEEE;USE IEEE.STD_LOGIC_1644.ALL;
-- 第一個實體申明ENTITY ent1 isEND ent1;
-- 第一個實體的結構體ARCHITECTURE arch1 of ent1 isEND arch1;-- 第一個實體的配置CONFIGURATION cfg1 of ent1 isEND cfg1;
-- 第二個實體的庫申明LIBRARY IEEE;USE IEEE.STD_LOGIC_1644.ALL;
-- 第二個實體申明ENTITY ent2 isEND ent2;
-- 第二個實體的結構體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ù)類型表示不可以綜合的類型或對象。

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

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

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

1).信號(Signal)

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

SIGNAL signal_name : signal_type [ :=initial_value ] ;

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

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

2).變量(Variable)

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

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

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

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

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

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

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

3).常量

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

CONSTANT PI: REAL:= 3.1416;

定義常量的格式如下:

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

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

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

? 在實體說明部分的常量被那個實體中任何結構體引用。

? 在結構體中的常量能被其結構體內部任何語句采用,包括為進程語句采用。

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

? 在數(shù)組和一些線性運算中經常用常量表,VHDL 的設計描述用常量表特別適于實現(xiàn) ROM 網(wǎng)絡的電路與函數(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 個元素對應邏輯電路狀態(tài) 000,第 2 個為狀態(tài) 001,第 3 個為狀態(tài) 010……后一個邏輯狀態(tài)為前一個元素邏輯狀態(tài)加 1。所以,上面的例子中,sun對應邏輯狀態(tài) 000,mon 對應邏輯狀態(tài) 001,……,sat 對應邏輯狀態(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ù)類型時(如枚舉類型),則應在指定數(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ù)組內的一個元素,格式如下:

數(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ù)類型中的元素應使用“.”,而不是數(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)、關系運算(Relational)、算術運算(Arithmetic)和移位運算(Shift),下面分別對它們進行介紹。

1).邏輯運算符

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

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

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

表 6 VHDL 邏輯運算符

2).關系運算符

關系運算符兩邊必須為相同的類型,其結果為 boolean 類型。

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

表 7 VHDL 關系運算符

3).算術運算符

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

表 8 VHDL 算術運算符

4).移位運算符

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

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

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

表 9 VHDL 移位運算符

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

sel <= a & b;

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

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

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

四、 VHDL 語言的描述語句

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

4.1 VHDL 順序語句描述方法

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

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

1).WAIT 語句

WAIT 語句允許把一個順序執(zhí)行的進程或子程序掛起,掛起的進程或子程序恢復的條件由 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).斷言語句

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

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

斷言語句的格式如下:

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

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

此外還有兩個可選的付句,REPORT 付句允許設計者指定輸出文字表達式的值,如果不指定 REPORT 語句,默認值是 ASSERTION VIOLATION,SEVERITY 付句允許設計者指定斷言語句的嚴重級別,如果沒指定 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 語句用關鍵字 IF 開頭和用關鍵字 END IF 結尾,END IF 分開拼寫。有兩個可選付句(ELSIF付句和 ELSE 付句),ELSIF 付句可重復并允許有多個 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í)行跟著的下一句并控制轉到跟在 END IF 之后的語句,否則轉到 ELSIF語句部分并檢查 day 是否為 Saturday;當變量 day 等于 saturday,執(zhí)行跟著的下一句并再次控制轉到跟在 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)語句

當需要重復操作時用循環(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ù)預先的設定進行迭代,所指定的范圍并不一定必須為整數(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ù)或過程中存在同名變量時,它們會被分別處理并由它們的內含尋址。

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

6).NEXT 語句

如果必須在這次迭代或循環(huán)中停下正在執(zhí)行的語句,而轉向下一個迭代時,用 NEXT 語句。執(zhí)行 NEXT 語句時,模塊處理停在當前點并轉到循環(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)。“WHEN 條件”項用于表明 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ā)信號賦值;

? 條件信號賦值;

? 選擇信號賦值。

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

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

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

下面是一個信號賦值的例子,其中 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 個條件都不滿足時自動選用此表達式,如果有條件滿足,則條件對應的表達式會計算賦值給目的信號量。條件信號代入語句也是并發(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 語言的預定義屬性

在 VHDL 中,屬性是指關于設計實體、結構體、類型、信號等項目的制定特征,利用屬性可以使得 VHDL 代碼更加簡明扼要、易于理解。

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

5.1 值類預定義屬性

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

? 'RIGHTOF(value)表示立即返回一值到輸入值的右邊。函數(shù)類型屬性主要用于從可枚舉數(shù)或物理類型的數(shù)轉換到整數(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ù)信號屬性用來返回有關信號行為功能的信息,例如報告究竟一個信號是否正好有值的變化,報告從上次事件中跳變過了多少時間以及該信號原來的值是什么。

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

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

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

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

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

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

5.3 信號類預定義屬性

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

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

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

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

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

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

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

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

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

數(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 屬性相類似,只是它按逆序返回一范圍而已。 比如假設'RANGE 屬性是返回 0 到 15,那么'REVERSE_RANGE 屬性返回 15 下降到 0。

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風險等級 參考價格 更多信息
EP2C5F256C7N 1 Altera Corporation Field Programmable Gate Array, 288 CLBs, 450MHz, 4608-Cell, CMOS, PBGA256, LEAD FREE, FBGA-256
$25.72 查看
10M08SCU169C8G 1 Intel Corporation Field Programmable Gate Array, PBGA169, 11 X 11 MM, 0.80 MM PITCH, ROHS COMPLIANT, UBGA-169

ECAD模型

下載ECAD模型
$11.16 查看
XC6SLX25-2FGG484I 1 AMD Xilinx Field Programmable Gate Array, 1879 CLBs, 667MHz, 24051-Cell, CMOS, PBGA484, 23 X 23 MM, 1 MM PITCH, LEAD FREE, FBGA-484

ECAD模型

下載ECAD模型
$90.44 查看

相關推薦

電子產業(yè)圖譜

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