大俠好,歡迎來(lái)到FPGA技術(shù)江湖,江湖偌大,相見(jiàn)即是緣分。大俠可以關(guān)注FPGA技術(shù)江湖,在“闖蕩江湖”、"行俠仗義"欄里獲取其他感興趣的資源,或者一起煮酒言歡。
今天給大俠帶來(lái)FPGA 之 VHDL 語(yǔ)法學(xué)習(xí)筆記,話不多說(shuō),上貨。
VHDL語(yǔ)法學(xué)習(xí)筆記
一、VHDL簡(jiǎn)介
1.1 VHDL 的歷史
VHDL 的 英 文 全 名 是 Very-High-Speed Integrated Circuit Hardware DescriptionLanguage,誕生于 1982 年。
1987 年底,VHDL 被 IEEE 和美國(guó)國(guó)防部確認(rèn)為標(biāo)準(zhǔn)硬件描述語(yǔ)言。自 IEEE 公布了 VHDL 的標(biāo)準(zhǔn)版本 IEEE-1076(簡(jiǎn)稱 87 版)之后,各 EDA 公司相繼推出了自己的 VHDL 設(shè)計(jì)環(huán)境,或宣布自己的設(shè)計(jì)工具可以提供 VHDL 接口。此后 VHDL 在電子設(shè)計(jì)領(lǐng)域逐步取代了原有的各種非標(biāo)準(zhǔn)硬件描述語(yǔ)言。
1993 年,IEEE 對(duì) VHDL 進(jìn)行了修訂,從更高的抽象層次和系統(tǒng)描述能力上擴(kuò)展 VHDL 的內(nèi)容,并公布了新版本的 VHDL,即 IEEE 標(biāo)準(zhǔn)的 1076-1993版本(簡(jiǎn)稱 93 版)。
現(xiàn)在,VHDL 和 Verilog HDL 作為 IEEE 的工業(yè)標(biāo)準(zhǔn)硬件描述語(yǔ)言,在電子工程領(lǐng)域已成為事實(shí)上的通用硬件描述語(yǔ)言。
1.2 VHDL 的特點(diǎn)
VHDL 主要用于描述數(shù)字系統(tǒng)的結(jié)構(gòu)、行為、功能和接口。除了含有許多具有硬件特征的語(yǔ)句外,VHDL 在語(yǔ)言形式、描述風(fēng)格和句法上與一般的計(jì)算機(jī)高級(jí)語(yǔ)言十分相似。VHDL 的程序結(jié)構(gòu)特點(diǎn)是將一項(xiàng)工程設(shè)計(jì),或稱設(shè)計(jì)實(shí)體(可以是一個(gè)元件、一個(gè)電路模塊或一個(gè)系統(tǒng))分成外部和內(nèi)部?jī)刹糠帧?/p>
外部也可稱為可視部分,它描述了此模塊的端口,而內(nèi)部可稱為不可視部分,它涉及到實(shí)體的功能實(shí)現(xiàn)和算法完成。在對(duì)一個(gè)設(shè)計(jì)實(shí)體定義了外部端口后,一旦其內(nèi)部開(kāi)發(fā)完成,其他的設(shè)計(jì)就可以直接調(diào)用這個(gè)實(shí)體。這種將設(shè)計(jì)實(shí)體分成內(nèi)外部分的概念是VHDL 系統(tǒng)設(shè)計(jì)的基本點(diǎn)。
應(yīng)用 VHDL 進(jìn)行工程設(shè)計(jì)有以下的優(yōu)點(diǎn):
1.行為描述
與其他的硬件描述語(yǔ)言相比,VHDL 具有更強(qiáng)的行為描述能力,強(qiáng)大的行為描述能力是避開(kāi)具體的器件結(jié)構(gòu),從邏輯行為上描述和設(shè)計(jì)大規(guī)模電子系統(tǒng)的重要保證。
2.仿真模擬
VHDL 豐富的仿真語(yǔ)句和庫(kù)函數(shù),使得在任何系統(tǒng)的設(shè)計(jì)早期就能查驗(yàn)設(shè)計(jì)系統(tǒng)的功能可行性,隨時(shí)可對(duì)設(shè)計(jì)進(jìn)行仿真模擬。
3.大規(guī)模設(shè)計(jì)
一些大型的 FPGA 設(shè)計(jì)項(xiàng)目必須有多人甚至多個(gè)開(kāi)發(fā)組共同并行工作才能實(shí)現(xiàn)。VHDL 語(yǔ)句的行為描述能力和程序結(jié)構(gòu)決定了它具有支持大規(guī)模設(shè)計(jì)的分解和已有設(shè)計(jì)的再利用功能。
4.門(mén)級(jí)網(wǎng)表
對(duì)于用 VHDL 完成的一個(gè)確定的設(shè)計(jì),可以利用 EDA 工具進(jìn)行邏輯綜合和優(yōu)化,并自動(dòng)把VHDL 描述設(shè)計(jì)轉(zhuǎn)變成門(mén)級(jí)網(wǎng)表。
5.獨(dú)立性
VHDL 對(duì)設(shè)計(jì)的描述具有相對(duì)獨(dú)立性,設(shè)計(jì)者可以不懂硬件的結(jié)構(gòu),也不必對(duì)最終設(shè)計(jì)實(shí)現(xiàn)的目標(biāo)器件有很深入地了解。
二、VHDL 程序基本結(jié)構(gòu)
一般的 VHDL 程序可以由實(shí)體(Entity)、結(jié)構(gòu)體(Architecture)、配置(Configuration)、程序包和程序包體(Package)以及庫(kù)(Library)5 個(gè)部分組成,它們是 VHDL 程序的設(shè)計(jì)單元。
其中實(shí)體、配置和程序包屬于初級(jí)設(shè)計(jì)單元,主要的功能是進(jìn)行端口、行為、函數(shù)等的定義。結(jié)構(gòu)體和程序包體是次級(jí)設(shè)計(jì)單元,包含了所有行為以及函數(shù)的實(shí)現(xiàn)代碼。其中,程序包和程序包體又屬于公用設(shè)計(jì)單元,即它們是被其他程序模塊調(diào)用的。庫(kù)則是一批程序包的集合。
圖 1 所示為 VHDL 程序設(shè)計(jì)單元之間的關(guān)系。
圖 1 VHDL 程序設(shè)計(jì)單元關(guān)系圖
無(wú)論是復(fù)雜的還是簡(jiǎn)單的數(shù)字模塊,用 VHDL 來(lái)描述都至少需要包括兩個(gè)部分,即實(shí)體申明(Entity Declaration)和結(jié)構(gòu)體(Architecture)。其中實(shí)體申明用于說(shuō)明模塊的端口,而結(jié)構(gòu)體用于描述模塊的功能。本節(jié)下面將詳細(xì)介紹 VHDL 程序的各個(gè)設(shè)計(jì)單元。
2.1 實(shí)體的申明方法
實(shí)體是設(shè)計(jì)的基本模塊和設(shè)計(jì)的初級(jí)單元,在分層次設(shè)計(jì)中,頂層有頂級(jí)實(shí)體,含在頂級(jí)實(shí)體中的較低層次的描述為低級(jí)實(shí)體,通過(guò)配置可把頂層實(shí)體和底層實(shí)體連接起來(lái)??梢詫?shí)體理解為電路圖設(shè)計(jì)中的芯片符號(hào)(Symbol),符號(hào)規(guī)定了電路的符號(hào)名、接口和數(shù)據(jù)類型。由連線(或信號(hào))將符號(hào)互連建立設(shè)計(jì)所需的電路圖,互連線生成的網(wǎng)表,在設(shè)計(jì)實(shí)現(xiàn)之前一直是設(shè)計(jì)驗(yàn)證的仿真模型,并在設(shè)計(jì)驗(yàn)證后,由網(wǎng)表向布線工具提供所需的連接信息和層信息。
圖 2 所示是傳統(tǒng)設(shè)計(jì)中 R-S 觸發(fā)器的符號(hào)圖,用 VHDL 對(duì)其進(jìn)行描述的代碼如下:
ENTITY rsff IS
PORT (
Set, Reset : IN BIT;
Q, QB : BUFFER BIT );
END rsff;
圖 2 R-S 觸發(fā)器的 VHDL 實(shí)體描述和符號(hào)
實(shí)體語(yǔ)句用關(guān)鍵詞 ENTITY 開(kāi)頭,實(shí)體名 rsff 是描述的符號(hào)名,在結(jié)束實(shí)體語(yǔ)句的 END rsff之間,實(shí)體語(yǔ)句可以用關(guān)鍵詞 BEGIN 把實(shí)體語(yǔ)句分成兩部分:即 BEGIN 之前是實(shí)體說(shuō)明,BEGIN之后是實(shí)體語(yǔ)句。
在 ENTITY 語(yǔ)句的實(shí)體說(shuō)明部分,常用 PORT 付語(yǔ)描述實(shí)體對(duì)外界連接的端口(數(shù)目、方向和數(shù)據(jù)類型)。實(shí)體 rsff 有 4 個(gè)端口,Set/Reset 是輸入 IN 模式,Q/QB 是輸出BUFFER(緩沖)模式,都為 BIT 類型。實(shí)體說(shuō)明中還可說(shuō)明數(shù)據(jù)類型、子程序和常量等數(shù)據(jù)信息,實(shí)體語(yǔ)句常用于描述設(shè)計(jì)經(jīng)常用到的判斷和檢查信息。
實(shí)體描述的格式如下:
ENTITY 實(shí)體名 IS
[GENERIC(參數(shù)表);]
[PORT(端口表);]
[BEGIN
實(shí)體語(yǔ)句部分;]
END [ENTITY] [實(shí)體名];
其中,GENERIC 是用于說(shuō)明設(shè)計(jì)實(shí)體和其外部環(huán)境通信的對(duì)象,規(guī)定端口的大小、實(shí)體中子元件的數(shù)目、實(shí)體的延時(shí)特性等。只能用整數(shù)類型表示,如整型、時(shí)間型等,其他類型的數(shù)據(jù)不能邏輯綜合。格式如下:
GENERIC ([CONSTANT]屬性名稱:[IN]子類型標(biāo)識(shí)[:=靜態(tài)表達(dá)式],……);
PORT 關(guān)鍵字用于定義模塊的端口,它的格式如下:
PORT( [SIGNAL] 端口名稱:[方向]類型標(biāo)識(shí)[BUS] [:=靜態(tài)表達(dá)式],
[SIGNAL] 端口名稱:[方向] 類型標(biāo)識(shí)[BUS] [:=靜態(tài)表達(dá)式],
…
[SIGNAL] 端口名稱:[方向] 類型標(biāo)識(shí)[BUS] [:=靜態(tài)表達(dá)式]);
? SIGNAL:SIGNAL 是關(guān)鍵字,但是由于 PORT 之后必須是信號(hào)類,所以一般可以將 SIGNAL關(guān)鍵字省略。
? 端口名稱:是該端口的標(biāo)識(shí),通常由英文字母和數(shù)字組成,但是必須是英文字母打頭。
? 方向:定義了端口是輸入還是輸出,如 IN、OUT。表明端口方向的關(guān)鍵字如表1所示。
? 類型標(biāo)識(shí):說(shuō)明流過(guò)該端口的數(shù)據(jù)類型,常用的數(shù)據(jù)類型有 BIT(位)、BIT_VECTOR(位向量)、BOOLEAN(布爾型)和 INTEGER(整數(shù)型)4 種。
? BUS 關(guān)鍵字:在該端口和多個(gè)輸出端相連的情況下使用。
表 1 端口方向關(guān)鍵字說(shuō)明表
2.2 結(jié)構(gòu)體的描述方法
結(jié)構(gòu)體描述實(shí)體的行為功能,一個(gè)實(shí)體可以有多個(gè)結(jié)構(gòu)體。結(jié)構(gòu)體是一個(gè)基本設(shè)計(jì)單元,它具體地指明了所設(shè)計(jì)模塊的行為、元件及內(nèi)部的連接關(guān)系,也就是說(shuō)它定義了設(shè)計(jì)單元具體的功能。結(jié)構(gòu)體對(duì)其基本設(shè)計(jì)單元的輸入/輸出關(guān)系可以用 3 種方式進(jìn)行描述,即行為描述(基本設(shè)計(jì)單元的數(shù)學(xué)模型描述)、寄存器傳輸描述(數(shù)據(jù)流描述)和結(jié)構(gòu)描述(邏輯元件連接描述)。
不同的描述方式只體現(xiàn)在描述語(yǔ)句上,而結(jié)構(gòu)體的結(jié)構(gòu)是完全一樣的。由于結(jié)構(gòu)體是對(duì)實(shí)體功能的具體描述,因此它一定要跟在實(shí)體的后面。通常,先編譯實(shí)體之后才能對(duì)結(jié)構(gòu)體進(jìn)行編譯。如果實(shí)體需要重新編譯,那么相應(yīng)結(jié)構(gòu)體也應(yīng)重新進(jìn)行編譯。
結(jié)構(gòu)體的格式如下:
ARCHITECTURE 結(jié)構(gòu)體名 OF 實(shí)體名 IS
[定義語(yǔ)句]
BEGIN
[并行處理語(yǔ)句]
END 結(jié)構(gòu)體名;
定義語(yǔ)句用于對(duì)結(jié)構(gòu)體內(nèi)部所使用的信號(hào)、常數(shù)、數(shù)據(jù)類型和函數(shù)等進(jìn)行定義。信號(hào)定義和端口說(shuō)明的語(yǔ)句一樣,應(yīng)有信號(hào)名和數(shù)據(jù)類型的說(shuō)明,但因它是內(nèi)部連接用的信號(hào),故沒(méi)有也不需有方向的說(shuō)明。并行處理語(yǔ)句具體地描述了結(jié)構(gòu)體的行為及其連接關(guān)系,它們都是可以并行執(zhí)行的。
以上面介紹的 R-S 觸發(fā)器為例。假設(shè)已經(jīng)有一個(gè)實(shí)現(xiàn)了與非功能的模塊 nand2,用它實(shí)現(xiàn)R-S 觸發(fā)器的原理圖如圖 3 所示。
圖 3 R-S 觸發(fā)器的實(shí)現(xiàn)原理圖
對(duì)應(yīng)以上原理圖的結(jié)構(gòu)體描述如下:
library IEEE;
use IEEE.std_logic_1164.all;
ENTITY rsff is
PORT (
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)體的開(kāi)頭,結(jié)構(gòu)體名為 arch_rsff,表示描述 rsff 實(shí)體的結(jié)構(gòu)體 arch_rsff。ARCHITECTURE 和 BEGIN 之間是結(jié)構(gòu)體說(shuō)明區(qū), BEGIN和 END 之間是結(jié)構(gòu)體語(yǔ)句區(qū)。結(jié)構(gòu)體說(shuō)明區(qū)描述組件(COMPONENT)和局部信號(hào),結(jié)構(gòu)體語(yǔ)句中用的具體元件(上例是 nand2)均應(yīng)在結(jié)構(gòu)體說(shuō)明中說(shuō)明接口,以便將描述的信息通知給編輯器。
如果設(shè)計(jì)者希望將模塊分為若干個(gè)相對(duì)比較獨(dú)立的子模塊進(jìn)行描述,可以將一個(gè)結(jié)構(gòu)體用幾個(gè)子結(jié)構(gòu)來(lái)構(gòu)成。VHDL 結(jié)構(gòu)體描述常常用到 3 種語(yǔ)句結(jié)構(gòu):PROCESS 語(yǔ)句結(jié)構(gòu)、BLOCK 語(yǔ)句結(jié)構(gòu)和子程序結(jié)構(gòu)。
1).PROCESS 語(yǔ)句結(jié)構(gòu)
進(jìn)程語(yǔ)句是一種并發(fā)處理語(yǔ)句,在一個(gè)結(jié)構(gòu)體中多個(gè) PROCESS 語(yǔ)句可以同時(shí)并行運(yùn)行(相當(dāng)于多個(gè) CPU 同時(shí)運(yùn)作)。PROCESS 語(yǔ)句是 VHDL 語(yǔ)言中描述硬件系統(tǒng)并發(fā)行為的最基本語(yǔ)句。
PROCESS 語(yǔ)句歸納起來(lái)有如下幾個(gè)特點(diǎn):
? 它可以與其他進(jìn)程并發(fā)運(yùn)行,并可存取結(jié)構(gòu)體或?qū)嶓w號(hào)中所定義的信號(hào);? 進(jìn)程結(jié)構(gòu)中的所有語(yǔ)句都是按順序執(zhí)行的;
? 為啟動(dòng)進(jìn)程,在進(jìn)行結(jié)構(gòu)中必須包含一個(gè)顯式的敏感信號(hào)量表或包含一個(gè) WAIT 語(yǔ)句;
? 進(jìn)程之間的通信是通過(guò)信號(hào)量傳遞來(lái)實(shí)現(xiàn)的。
PROCESS 語(yǔ)句的格式如下:
[進(jìn)程名]:PROCESS(信號(hào) 1,信號(hào) 2,…)
BEGIN
…
END PROCESS;
一般情況下進(jìn)程名可以被省略。進(jìn)程申明關(guān)鍵字 PROCESS 后面括號(hào)內(nèi)的信號(hào)是此進(jìn)程的敏感信號(hào),這些信號(hào)的變化會(huì)激活過(guò)程的執(zhí)行。例如下面的代碼就表示過(guò)程 main_proc 在信號(hào)clk 和 reset 變化時(shí)執(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 is
BEGIN
main_proc:
PROCESS(clk, reset)
BEGIN
if (reset = '1') then
…
end if;
END PROCESS;
END
在進(jìn)程中也可以定義一些變量,這些變量是局部量,只能在進(jìn)程內(nèi)部使用,它們的賦值是立即生效的。局部變量定義的格式如下:
VARIABLE 變量名:數(shù)據(jù)類型 [約束條件] [:=表達(dá)式];
下面的代碼演示了定義一個(gè)局部變量并且使用它的方法:
library IEEE;
use IEEE.std_logic_1164.all;
ENTITY counter is
PORT (
a: in bit;
c: out bit
);
END ENTITY;
ARCHITECTURE arch of counter is
BEGIN
main_proc:
PROCESS(a)
VARIABLE item:array0(7 downto 0); --定義一個(gè)變量 item
BEGIN
item(7):=a;
c<=item(7);
END PROCESS;
END
2).BLOCK 語(yǔ)句結(jié)構(gòu)
BLOCK 語(yǔ)句的格式如下:
塊名:BLOCK(條件)
[參數(shù) GENERIC 說(shuō)明; [參數(shù)映射;] ]
[端口說(shuō)明; [端口映射;] ]
[塊說(shuō)明語(yǔ)句]
BEGIN
并發(fā)語(yǔ)句組;
END BLOCK 塊名;
BLOCK 放在結(jié)構(gòu)體的并行語(yǔ)句組中,每一個(gè) BLOCK 相當(dāng)于一個(gè)子電路原理圖。和 PROCESS語(yǔ)句不同,BLOCK 內(nèi)的語(yǔ)句是并發(fā)執(zhí)行的。只要 BLOCK 右邊的條件滿足,BLOCK 內(nèi)的語(yǔ)句就被執(zhí)行。如果省略條件,表示本 BLOCK 被無(wú)條件執(zhí)行。下面是一個(gè) BLOCK 語(yǔ)句的例子:
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 is
BEGIN
block_demo: BLOCK(clk='1')
BEGIN
s<=a xor b;
c<=a and b;
END BLOCK block_demo;
END;
上面的程序表示當(dāng) clk 信號(hào)變?yōu)?1 時(shí),并行執(zhí)行 BLOCK 語(yǔ)句內(nèi)的程序,即將 a 和 b 兩個(gè)信號(hào)的異或結(jié)果賦給 s 信號(hào),同時(shí)將 a 和 b 信號(hào)的與結(jié)果賦給 c 信號(hào)。
3).子程序結(jié)構(gòu)
所謂子程序結(jié)構(gòu)就是將一部分實(shí)現(xiàn)代碼放到公用的程序(即程序包 Package)文件中實(shí)現(xiàn)。程序包中的代碼以子程序的方式提供給 VHDL 程序調(diào)用,這樣代碼可以實(shí)現(xiàn)共享,同時(shí)還使得VHDL 程序的結(jié)構(gòu)明了。
子程序在調(diào)用時(shí)首先要進(jìn)行初始化,執(zhí)行結(jié)束后子程序就終止,再調(diào)用時(shí)要再進(jìn)行初始化。因此子程序內(nèi)部的值不能保持,子程序返回以后才能被再調(diào)用,它是一個(gè)非重入的程序。
VHDL 中有兩種類型的子程序—過(guò)程(Procedure)和函數(shù)(Function),下面分別介紹一下它們的格式。
? 過(guò)程過(guò)程的格式如下:
PROCEDURE 過(guò)程名(參數(shù) 1;參數(shù) 2;……) IS
定義語(yǔ)句;
BEGIN
順序語(yǔ)句組;
END 過(guò)程名;
每個(gè)參數(shù)的說(shuō)明格式如下:
參數(shù)名:方向 類型
方向一般為 3 種:IN、OUT、INOUT。如果方向?yàn)?IN 則可省略方向說(shuō)明。
? 函數(shù)
函數(shù)的格式如下:
FUNCTION 函數(shù)名(參數(shù) 1;參數(shù) 2;……) RETURN 數(shù)據(jù)類型 IS
定義語(yǔ)句;
BEGIN
順序語(yǔ)句組;
RETURN [返回變量名];
END 函數(shù)名;
在 VHDL 語(yǔ)言中,函數(shù)的所有參數(shù)都是輸入?yún)?shù),因此都是 IN 的方向,可以省略方向說(shuō)明。
在下面介紹程序包(PACKAGE)的時(shí)候?qū)?huì)介紹函數(shù)、過(guò)程定義的例子,在此不再舉例說(shuō)明。
2.3 程序包和程序包體
程序包說(shuō)明類似 C 語(yǔ)言中的 include 語(yǔ)句,用來(lái)羅列 VHDL 語(yǔ)言中所要用到的信號(hào)定義、常數(shù)定義、數(shù)據(jù)類型、元件語(yǔ)句、函數(shù)定義和過(guò)程定義等,它是一個(gè)可編譯的設(shè)計(jì)單元,也是庫(kù)結(jié)構(gòu)中的一個(gè)層次。
程序包的結(jié)構(gòu)如圖 4 所示。
圖 4 VHDL 程序包結(jié)構(gòu)圖
一個(gè)程序包由兩大部分組成:程序包申明和程序包體。程序包體是一個(gè)可選項(xiàng),也就是說(shuō),程序包可以僅僅由程序包標(biāo)題構(gòu)成。一般程序包標(biāo)題列出所有項(xiàng)的名稱,而程序包體具體給出各項(xiàng)的細(xì)節(jié)。
下面介紹一個(gè)包含與非函數(shù)的程序包的實(shí)現(xiàn)以及調(diào)用方法。實(shí)現(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ù)實(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,然后在程序包體中具體實(shí)現(xiàn)了此函數(shù)的功能。下面舉個(gè)例子來(lái)說(shuō)明程序包的使用方法,即函數(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 is
BEGIN
-- 調(diào)用 nand 函數(shù)
D = nand2(A1, B1) and nand2(A2, B2);
END;
自定義的程序包必須首先進(jìn)行編譯,然后才能夠編譯調(diào)用此程序包的 VHDL 程序。自定義的程序包屬于 WORK 庫(kù),所以申明調(diào)用的代碼是:
use WORK.自定義程序包名稱.all;
調(diào)用程序包中函數(shù)或者過(guò)程的方法和一般高級(jí)語(yǔ)言(如 C 語(yǔ)言)一樣直接調(diào)用就可以了。
2.4 配置的申明方法
一個(gè)實(shí)體可以包含多個(gè)結(jié)構(gòu)體,配置的作用就是根據(jù)需要選擇實(shí)體的結(jié)構(gòu)體。配置語(yǔ)句描述層與層之間的連接關(guān)系以及實(shí)體與結(jié)構(gòu)之間的連接關(guān)系。設(shè)計(jì)者可以利用這種配置語(yǔ)句來(lái)選擇不同的結(jié)構(gòu)體,使其與要設(shè)計(jì)的實(shí)體相對(duì)應(yīng)。在仿真某一個(gè)實(shí)體時(shí),可以利用配置來(lái)選擇不同的結(jié)構(gòu)體,進(jìn)行性能對(duì)比試驗(yàn)以得到性能最佳的結(jié)構(gòu)體。
例如,設(shè)計(jì)一個(gè)二輸入、四輸出的譯碼器。如果一種結(jié)構(gòu)中的基本單元采用反相器和三輸入與門(mén),而另一種結(jié)構(gòu)中的基本元件都采用與非門(mén)。它們各自的結(jié)構(gòu)體是不一樣的,并且都放在各自不同的庫(kù)中。那么現(xiàn)在要設(shè)計(jì)的譯碼器,就可以利用配置語(yǔ)句實(shí)現(xiàn)對(duì)兩種不同構(gòu)造的選擇。
配置的基本格式如下:
CONFIGURATION 配置名 OF 實(shí)體名 IS
[語(yǔ)句說(shuō)明]
END 配置名;
如果一個(gè)實(shí)體僅僅具有一個(gè)結(jié)構(gòu)體,也需要定義其配置,但是可以寫(xiě)成一種最為簡(jiǎn)潔的格式:
CONFIGURATION 配置名 OF 實(shí)體名 IS
FOR 所選的構(gòu)造體名
END FOR;
END 配置名;
如果一個(gè)模塊比較復(fù)雜,含有多個(gè)子模塊,使用低層次配置可以為每個(gè)子模塊選擇其結(jié)構(gòu)體,代碼如下:
CONFIGURATION 配置名 OF 實(shí)體名 IS
FOR 所選的構(gòu)造體名
FOR 標(biāo)號(hào) 1:元件名 1 USE CONFIGURATION WORK.配置體名 1;
END FOR;
FOR 標(biāo)號(hào) 2:元件名 2 USE ENTITY WORK.實(shí)體名 2(構(gòu)造體名 2);
END FOR;
…
END FOR;
END 配置名;
其中,低層次構(gòu)造體名可用 ALL 或 OTHERS,構(gòu)造體名 2 可以省略。
2.5 VHDL 程序的庫(kù)
庫(kù)(Library)是經(jīng)編譯后的數(shù)據(jù)的集合,它存放包集合申明、實(shí)體申明、構(gòu)造體申明和配置定義。它的功能類似于 UNIX 和 MS-DOS 操作系統(tǒng)中的目錄,在 VHDL 中,庫(kù)的說(shuō)明總是放在設(shè)計(jì)單元的最前面,這樣在設(shè)計(jì)單元內(nèi)的語(yǔ)句就可以使用庫(kù)中的數(shù)據(jù)了。由此可見(jiàn),使用庫(kù)的好處是使設(shè)計(jì)者可以共享已經(jīng)編譯過(guò)的設(shè)計(jì)結(jié)果。在 VHDL 中可以存在多個(gè)不同的庫(kù),但是庫(kù)和庫(kù)之間是獨(dú)立的,不能互相嵌套。
申明庫(kù)的格式如下:
LIBRARY 庫(kù)名;
在 VHDL 語(yǔ)言中存在的庫(kù)大致可以歸納為 5 種:IEEE 庫(kù)、STD 庫(kù)、ASIC 矢量庫(kù)、用戶定義庫(kù)和 WORK 庫(kù)。
1).IEEE 庫(kù)
在 IEEE 庫(kù)中的“STD_LOGIC_1164”包集合是 IEEE 正式認(rèn)可的標(biāo)準(zhǔn)包集合?,F(xiàn)在有些公司提供的包集合如“STD_LOGIC_ARITH”、“STD_LOGIC_UNSIGNED”等,盡管沒(méi)有得到 IEEE 的承認(rèn),但是仍匯集在 IEEE 庫(kù)中。
2).STD 庫(kù)
STD 庫(kù)是 VHDL 的標(biāo)準(zhǔn)庫(kù),在庫(kù)中存放有“STANDARD”包集合。由于它是 VHDL 的標(biāo)準(zhǔn)配置,因此設(shè)計(jì)者如要調(diào)用“STANDARD”中的數(shù)據(jù)可以不按標(biāo)準(zhǔn)格式說(shuō)明。STD 庫(kù)中還包含有“TEXTIO”包集合,在測(cè)試時(shí)使用。使用“TEXTIO”包集合中的數(shù)據(jù)時(shí),應(yīng)先說(shuō)明庫(kù)和包集合名:
LIBRARY STD;
USE STD.TEXTIO.ALL;
3).ASIC 矢量庫(kù)
在 VHDL 中,為了進(jìn)行門(mén)級(jí)仿真,各公司可提供面向 ASIC 的邏輯門(mén)庫(kù)。在該庫(kù)中存放著與邏輯門(mén)一一對(duì)應(yīng)的實(shí)體。
4).WORK 庫(kù)
WORK 庫(kù)是現(xiàn)行作業(yè)庫(kù)。設(shè)計(jì)者所描述的 VHDL 語(yǔ)句不需要任何說(shuō)明,都將存放在 WORK 庫(kù)中。在使用該庫(kù)時(shí)無(wú)需進(jìn)行任何說(shuō)明。
5).用戶定義庫(kù)
將用戶自身設(shè)計(jì)開(kāi)發(fā)的包、實(shí)體等匯集在一起定義成一個(gè)庫(kù),就是用戶定義庫(kù)或稱用戶庫(kù)。在使用用戶定義庫(kù)時(shí)同樣要首先說(shuō)明庫(kù)名。
以上各種庫(kù)中,除 WORK 庫(kù)外,其他 4 類庫(kù)在使用前都首先要進(jìn)行說(shuō)明,格式為:
USE 庫(kù)名.包集合名.項(xiàng)目名;
如果項(xiàng)目名為 ALL,則表示包集合中的所有項(xiàng)目都要使用,例如:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.ALL;
USE WORK.STD_ARITH.ALL;
…
庫(kù)說(shuō)明語(yǔ)句的作用范圍從一個(gè)實(shí)體說(shuō)明開(kāi)始到它所屬的構(gòu)造體、配置結(jié)束為止。當(dāng)一個(gè)源程序出現(xiàn)兩個(gè)或兩個(gè)以上的實(shí)體時(shí),兩條作為使用庫(kù)的說(shuō)明語(yǔ)句就在每個(gè)實(shí)體說(shuō)明語(yǔ)句前重復(fù)書(shū)寫(xiě)。例如,在一個(gè) VHDL 文件中定義兩個(gè)實(shí)體,庫(kù)的申明如下:
-- 第一個(gè)實(shí)體的庫(kù)申明
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1644.ALL;
-- 第一個(gè)實(shí)體申明
ENTITY ent1 is
…
END ent1;
-- 第一個(gè)實(shí)體的結(jié)構(gòu)體
ARCHITECTURE arch1 of ent1 is
…
END arch1;
-- 第一個(gè)實(shí)體的配置
CONFIGURATION cfg1 of ent1 is
…
END cfg1;
-- 第二個(gè)實(shí)體的庫(kù)申明
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1644.ALL;
-- 第二個(gè)實(shí)體申明
ENTITY ent2 is
…
END ent2;
-- 第二個(gè)實(shí)體的結(jié)構(gòu)體
ARCHITECTURE arch2 of ent2 is
三、VHDL 語(yǔ)言的數(shù)據(jù)類型和運(yùn)算符
VHDL 和其他高級(jí)語(yǔ)言一樣,具有多種數(shù)據(jù)類型。對(duì)大多數(shù)數(shù)據(jù)類型的定義兩者是一致的(例如整數(shù)型),但是也有一些數(shù)據(jù)類型是 VHDL 所獨(dú)有的。表 2 所示為 VHDL 支持的數(shù)據(jù)類型和它的數(shù)據(jù)對(duì)象。
表 2 VHDL 數(shù)據(jù)類型和數(shù)據(jù)對(duì)象表
注意:表?2 中帶*號(hào)的數(shù)據(jù)類型表示不可以綜合的類型或?qū)ο蟆?/p>
3.1 VHDL 語(yǔ)言的數(shù)據(jù)對(duì)象
VHDL 對(duì)象有 4 種,即信號(hào)(Signal)、變量(Variable)、常量(Constant)和文件(File)。
其中文件(File)是 VHDL’93 標(biāo)準(zhǔn)中新通過(guò)的,它是不可以綜合的。下面介紹一下常量、信號(hào)和變量的申明方法。
1).信號(hào)(Signal)
信號(hào)用于將元件的裝配端口連在一起形成模塊,它的作用相當(dāng)于連接元件的導(dǎo)線。信號(hào)是實(shí)體間動(dòng)態(tài)數(shù)據(jù)交換的手段,信號(hào)申明格式如下:
SIGNAL signal_name : signal_type [ :=initial_value ] ;
在關(guān)鍵字 SIGNAL 后跟一個(gè)或者多個(gè)信號(hào)名,每個(gè)信號(hào)名將建立一個(gè)新信號(hào),用冒號(hào)把信號(hào)名和信號(hào)的數(shù)據(jù)類型分隔開(kāi),信號(hào)數(shù)據(jù)類型規(guī)定信號(hào)包含的數(shù)據(jù)類型信息及初始化信號(hào)指定的初值。
實(shí)體說(shuō)明部分、結(jié)構(gòu)體說(shuō)明和程序包說(shuō)明都能聲明信號(hào),全局信號(hào)在程序包中聲明,它們被所屬的實(shí)體分享。
2).變量(Variable)
變量用于存儲(chǔ)進(jìn)程和子程序中的局部數(shù)據(jù),變量的賦值是立即執(zhí)行的,沒(méi)有延時(shí)。變量的申明格式如下:
VARIABLE variable_name ,variable_name : variable_type[:= value];
關(guān)鍵字 VARIABLE 后跟著一個(gè)或多個(gè)變量名,每個(gè)變量名對(duì)應(yīng)建立一個(gè)新變量。variable_type 字段定義了變量的數(shù)據(jù)類型,并且還可以指定一個(gè)可選的初值。此外,還需要注意的是只可以在進(jìn)程說(shuō)明部分和子程序說(shuō)明部分聲明變量。
和信號(hào)相比,變量有以下優(yōu)點(diǎn):
? 變量處理起來(lái)更快,因?yàn)樽兞抠x值是立即發(fā)生的,而信號(hào)卻必須為此事件作相應(yīng)的處理。
? 變量用很少的存儲(chǔ)器,相反為了做一個(gè)調(diào)度安排和處理信號(hào)屬性,需要存儲(chǔ)更多的信號(hào)信息。
? 變量比信號(hào)更容易實(shí)現(xiàn)同步處理。
3).常量
常量是為特定的數(shù)據(jù)類型值所賦予的名稱,如果需要在多個(gè)具體元件中存放一個(gè)固定值就使用常量。例如可以如下定義常量 PI(π ):
CONSTANT PI: REAL:= 3.1416;
定義常量的格式如下:
CONSTANT constant_name,constant_name: type_name[:= value];
一般情況下,VHDL 中的常量是在程序包申明中進(jìn)行申明,而在程序包體中指定具體的值。使用常量需要注意以下幾個(gè)問(wèn)題:
? 在程序包中說(shuō)明的常量被全局化。
? 在實(shí)體說(shuō)明部分的常量被那個(gè)實(shí)體中任何結(jié)構(gòu)體引用。
? 在結(jié)構(gòu)體中的常量能被其結(jié)構(gòu)體內(nèi)部任何語(yǔ)句采用,包括為進(jìn)程語(yǔ)句采用。
? 在進(jìn)程說(shuō)明中說(shuō)明的常量只能在進(jìn)程中使用。
? 在數(shù)組和一些線性運(yùn)算中經(jīng)常用常量表,VHDL 的設(shè)計(jì)描述用常量表特別適于實(shí)現(xiàn) ROM 網(wǎng)絡(luò)的電路與函數(shù)設(shè)計(jì)。
3.2 VHDL 語(yǔ)言的數(shù)據(jù)類型
VHDL 的數(shù)據(jù)類型根據(jù)使用目的和場(chǎng)合,可以分為標(biāo)準(zhǔn)數(shù)據(jù)類型和用戶定義的數(shù)據(jù)類型兩種。
1).標(biāo)準(zhǔn)數(shù)據(jù)類型
VHDL 中定義的標(biāo)準(zhǔn)數(shù)據(jù)類型如表 3 所示。
表 3 VHDL 中的標(biāo)準(zhǔn)數(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 標(biāo)準(zhǔn)邏輯(向量)取值表
2).用戶定義的數(shù)據(jù)類型
用戶定義數(shù)據(jù)類型的格式如下:
TYPE 數(shù)據(jù)類型名 {,數(shù)據(jù)類型名} 數(shù)據(jù)類型定義;
數(shù)據(jù)類型定義放在語(yǔ)句的定義部分中,定義范圍為從本定義行開(kāi)始到本語(yǔ)句作用的最后。
一般用戶定義的數(shù)據(jù)類型分為以下幾種。
? 枚舉類型(enumeration)
枚舉類型的格式如下:
TYPE 數(shù)據(jù)類型名 IS (元素,元素,……)
例如,將一星期七天作為一個(gè)枚舉,可以如下定義:
TYPE week IS (sun, mon, tue, wed, thu, fri, sat);
在枚舉類型中,元素是有序列性的,第 1 個(gè)元素對(duì)應(yīng)邏輯電路狀態(tài) 000,第 2 個(gè)為狀態(tài) 001,第 3 個(gè)為狀態(tài) 010……后一個(gè)邏輯狀態(tài)為前一個(gè)元素邏輯狀態(tài)加 1。所以,上面的例子中,sun對(duì)應(yīng)邏輯狀態(tài) 000,mon 對(duì)應(yīng)邏輯狀態(tài) 001,……,sat 對(duì)應(yīng)邏輯狀態(tài) 110。
? 整數(shù)類型、實(shí)數(shù)類型(INTEGER,REAL)
這里的整數(shù)類型和實(shí)數(shù)類型其實(shí)是前面所述的標(biāo)準(zhǔn)整數(shù)類型和實(shí)數(shù)類型的子類,定義的格式如下:
TYPE 數(shù)據(jù)類型名 IS 數(shù)據(jù)類型定義 約束范圍
例如:
TYPE current IS REAL RANGE -1E4 TO 1E4
定義了 current 類型實(shí)數(shù)的范圍是-104到 104。
? 數(shù)組(ARRAY)
數(shù)組定義的格式如下:
TYPE 數(shù)據(jù)類型名 IS ARRAY 范圍 OF 原數(shù)據(jù)類型名;
注意:如果 范圍 這一項(xiàng)沒(méi)有被指定,則使用整數(shù)數(shù)據(jù)類型。
下面通過(guò)例子說(shuō)明數(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ù)組類型,可以定義一個(gè)此類新的常數(shù),如下:
CONSTANT mem:tmem:= ( ('0', '0', '0', '0'),
('0', '0', '1', '0'),
('1', '1', '0', '0'));
當(dāng)范圍這一項(xiàng)需用整數(shù)類型以外的其他數(shù)據(jù)類型時(shí)(如枚舉類型),則應(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)的一個(gè)元素,格式如下:
數(shù)組名(下標(biāo))
例如,word(1)區(qū)的 word 數(shù)組序號(hào)為 1 的元素。
當(dāng)數(shù)組類型定義中的范圍用“(Natural Range <>)”或“(Positive Range <>)”代替時(shí),表示本數(shù)組類型為非限定的類型,下標(biāo)范圍在信號(hào)或變量定義時(shí)再具體指定。
例如下面的代碼中定義的 array0 就是非限定類型的數(shù)組。
library IEEE;
use IEEE.std_logic_1164.all;
entity tmyarray is
port(a:in std_logic;c:out std_logic);
end ;
architecture myarray of tmyarray is
type array0 is array (natural range <>) of std_logic;
begin
process(a)
variable item:array0(7 downto 0);--定義一個(gè)變量 item
begin
item(7):=a;
c<=item(7);
end process;
end;
??時(shí)間(TIME)
定義時(shí)間的格式如下:
TYPE 數(shù)據(jù)類型名 IS 范圍
UNITS 基本單位;
單位描述;
END UNITS
例如:
TYPE 數(shù)據(jù)類型名 IS 范圍
UNITS 基本單位;
單位描述;
END UNITS
TYPE 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ù)組的括號(hào)。
例如,定義一個(gè)窗口尺寸的記錄,如下:
TYPE window IS RECORD
length:INTEGER;
width:INTEGER;
END RECORD;
當(dāng)需要使用 window 類型記錄的元素時(shí),方法如下:
signal win: window;
win.length<=10;
? 用戶定義的子類型
用戶定義的子類型是用戶對(duì)已定義的數(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; --錯(cuò)誤
在 VHDL 中,數(shù)據(jù)類型的定義是相當(dāng)嚴(yán)格的,不同類型的數(shù)據(jù)是不能進(jìn)行運(yùn)算和直接代入的。為了實(shí)現(xiàn)正確的代入操作,必須將要代入的數(shù)據(jù)進(jìn)行類型變換。
變 換 函 數(shù) 通 常 由 VHDL 語(yǔ) 言 的 包 集 合 提 供 。 例 如 在 “ STD_LOGIC_1164 ”、“STD_LOGIC_ARITH”、STD_LOGIC_UNSIGNED”的包集合中提供了如表 2-5 所示的數(shù)據(jù)類型變換函數(shù)。
表 5 類型變換函數(shù)表
有些數(shù)據(jù),從數(shù)據(jù)本身是斷定不出其類型的,如“01010001”,如果沒(méi)有上下文,VHDL 編譯器就無(wú)法知道它是字串型還是位數(shù)組類型。這時(shí)就要進(jìn)行數(shù)據(jù)類型的限定。類型限定的格式如下:
類型名'(數(shù)據(jù))
例如:
a<=std_logic_vector'("01010001");
這樣,編譯器知道“01010001”肯定是矢量型,而不是別的類型。
3.3 VHDL 語(yǔ)言的運(yùn)算符
在 VHDL 語(yǔ)言中,常用的運(yùn)算符有邏輯運(yùn)算(Logic)、關(guān)系運(yùn)算(Relational)、算術(shù)運(yùn)算(Arithmetic)和移位運(yùn)算(Shift),下面分別對(duì)它們進(jìn)行介紹。
1).邏輯運(yùn)算符
邏輯運(yùn)算符可以對(duì) bit 和 boolean 類型的值進(jìn)行運(yùn)算,也可對(duì)這些類型的一維數(shù)組進(jìn)行運(yùn)算。對(duì)數(shù)組型的運(yùn)算,運(yùn)算施加于數(shù)組中的每個(gè)元素,結(jié)果與原來(lái)數(shù)組長(zhǎng)度相同。
邏輯判斷的運(yùn)算為“短路運(yùn)算”,也就是說(shuō),條件表達(dá)式的左邊成立時(shí),就不再進(jìn)行右邊的判斷。比如,IF (a=0) AND (b/a>2) THEN…這個(gè)判斷運(yùn)算,當(dāng) a=0 時(shí),后面的判斷不再繼續(xù),避免出現(xiàn)除數(shù)為 0 的運(yùn)算。
VHDL 的邏輯運(yùn)算符如表 6 所示。
表 6 VHDL 邏輯運(yùn)算符
2).關(guān)系運(yùn)算符
關(guān)系運(yùn)算符兩邊必須為相同的類型,其結(jié)果為 boolean 類型。
等號(hào)(=)和不等號(hào)(/=)兩邊可以為任意類型的運(yùn)算對(duì)象。其他關(guān)系運(yùn)算符的運(yùn)算對(duì)象必須為標(biāo)量類型或離散類型的一維數(shù)組。對(duì)于復(fù)雜的運(yùn)算對(duì)象,如數(shù)組,兩個(gè)值相等意味著兩個(gè)值的所有對(duì)應(yīng)元素相等。VHDL 的關(guān)系運(yùn)算符如表 7 所示。
表 7 VHDL 關(guān)系運(yùn)算符
3).算術(shù)運(yùn)算符
算術(shù)運(yùn)算符包括一些基本的算術(shù)運(yùn)算,使用算術(shù)運(yùn)算符需要注意的是乘方(**)運(yùn)算的右邊必須為整數(shù)。VHDL 的算術(shù)運(yùn)算符如表 8 所示。
表 8 VHDL 算術(shù)運(yùn)算符
4).移位運(yùn)算符
移位運(yùn)算符為二元運(yùn)算符,左邊必須為一維數(shù)組,且元素類型為 bit 或 boolean 類型。右邊運(yùn)算數(shù)為整數(shù),可以為負(fù)數(shù),相當(dāng)于反方向移位。一位移位與循環(huán)移位的語(yǔ)義示意如圖 5 所示。
圖 5 一位移位與循環(huán)移位示意圖
VHDL 的移位運(yùn)算符如表 9 所示。
表 9 VHDL 移位運(yùn)算符
除了上面介紹的,VHDL 中運(yùn)算符還包括正號(hào)“+”、負(fù)號(hào)“-” 以及“&”。其中,連接符號(hào)(&)用于一維數(shù)組,這個(gè)數(shù)組的元素個(gè)數(shù)可以為 1,運(yùn)算結(jié)果為右邊數(shù)組連接在左邊數(shù)組之后形成新數(shù)組,例如:
sel <= a & b;
假設(shè) a 信號(hào)為“0”,b 信號(hào)為“1”,那么得到的 sel 信號(hào)就是“01”。
所有的 VHDL 運(yùn)算符之間都有優(yōu)先級(jí)的關(guān)系,各運(yùn)算符優(yōu)先級(jí)從最高到最低,順序如表 10 所示(同一行優(yōu)先級(jí)相同)。
表 10 運(yùn)算符的優(yōu)先順序
四、 VHDL 語(yǔ)言的描述語(yǔ)句
使用 VHDL 進(jìn)行數(shù)字電路描述時(shí)候,如果按照?qǐng)?zhí)行順序?qū)?VHDL 的程序進(jìn)行分類,可以分為順序(sequential)描述語(yǔ)句和并行(concurrent)描述語(yǔ)句。順序語(yǔ)句描述的程序總是按照程序書(shū)寫(xiě)的順序執(zhí)行;而并行語(yǔ)句都是同時(shí)執(zhí)行的,和程序的書(shū)寫(xiě)順序無(wú)關(guān)。
4.1 VHDL 順序語(yǔ)句描述方法
VHDL 中的順序語(yǔ)句一般在進(jìn)程中出現(xiàn),或者以函數(shù)、過(guò)程的方式在進(jìn)程中被調(diào)用。順序語(yǔ)句所涉及到的系統(tǒng)行為有時(shí)序流、控制、條件和迭代等。
VHDL 中的順序語(yǔ)句有 WAIT 語(yǔ)句、斷言語(yǔ)句、IF 語(yǔ)句、CASE 語(yǔ)句、LOOP 語(yǔ)句、NEXT 語(yǔ)句、過(guò)程調(diào)用語(yǔ)句和 NULL 語(yǔ)句,下面就對(duì)它們進(jìn)行詳細(xì)介紹。
1).WAIT 語(yǔ)句
WAIT 語(yǔ)句允許把一個(gè)順序執(zhí)行的進(jìn)程或子程序掛起,掛起的進(jìn)程或子程序恢復(fù)的條件由 3種不同的方法指定。WAIT 語(yǔ)句可以有不同的格式,分別有不同的作用,例如 WAIT ON 表示等待到信號(hào)變化,WAIT UNTIL 表示等到一個(gè)表達(dá)式為真,而 WAIT FOR 表示等待一個(gè)固定的事件,如果僅僅寫(xiě)一個(gè) WAIT 的話就表示無(wú)限期的等待。
WAIT 語(yǔ)句能用于多種不同的目的,常用于為綜合工具指定時(shí)鐘輸入。另一用途是將進(jìn)程的執(zhí)行延時(shí)一段時(shí)間或者是為了動(dòng)態(tài)地修改進(jìn)程敏感表。
為了避免無(wú)休止的等待可以加一個(gè)超時(shí)付句,不管進(jìn)行到哪兒或是條件有沒(méi)有滿足都允許執(zhí)行超時(shí)處理。下面的代碼就演示了 WAIT UNTIL 語(yǔ)句的使用方法和超時(shí)處理的方法:
WAIT UNTIL (sendB = '1') FOR 1 ns;
ASSERT (sendB = '1')
REPORT "sendB timed out at '1'"
SEVERITY ERROR;
2).?dāng)嘌哉Z(yǔ)句
斷言語(yǔ)句的功能是為設(shè)計(jì)者報(bào)告一個(gè)文本字符串。斷言語(yǔ)句包含一個(gè)布爾表達(dá)式,表達(dá)式為真,該語(yǔ)句不做任何事;反之,它將輸出一用戶規(guī)定的字符串到標(biāo)準(zhǔn)輸出終端。
斷言語(yǔ)句規(guī)定輸出字符串的嚴(yán)重程度為 4 個(gè)級(jí)別(NOTE、WARNING、ERROR 和 FAILURE),它們的意思分別是注意、警告、錯(cuò)誤和失敗,嚴(yán)重層次遞增。
斷言語(yǔ)句的格式如下:
ASSERT_STATEMENT ::=
ASSERT CONDITION
[REPORT EXPRESSION]
[SEVERITY EXPRESSION];
其中,關(guān)鍵字 ASSERT 后跟 CONDITION 布爾值表達(dá)式,它的條件決定 REPORT 付句規(guī)定的文字表達(dá)式輸出不輸出,如果是假,文字表達(dá)式輸出,如果是真,該文字表達(dá)式不輸出。
此外還有兩個(gè)可選的付句,REPORT 付句允許設(shè)計(jì)者指定輸出文字表達(dá)式的值,如果不指定 REPORT 語(yǔ)句,默認(rèn)值是 ASSERTION VIOLATION,SEVERITY 付句允許設(shè)計(jì)者指定斷言語(yǔ)句的嚴(yán)重級(jí)別,如果沒(méi)指定 SEVERITY 付句,其默認(rèn)值是 ERROR。
下面是一個(gè)斷言語(yǔ)句的使用實(shí)例,它表示對(duì)輸入時(shí)鐘進(jìn)行檢查,如果其建立時(shí)間小于20ns,則輸出 ERROR 信號(hào):
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
-- 斷言語(yǔ)句
ASSERT (NOW - last_d_change >= 20 ns)
REPORT "setup violation"
SEVERITY WARNING;
END IF;
END IF;
END PROCESS;
3).IF 語(yǔ)句
IF 語(yǔ)句是根據(jù)所指定的條件來(lái)確定執(zhí)行哪些語(yǔ)句,其格式如下:
IF condition THEN
sequence_of_statements
ELSIF condition THEN
sequence_of_statements
ELSE
sequence_of_statement
END IF;
IF 語(yǔ)句用關(guān)鍵字 IF 開(kāi)頭和用關(guān)鍵字 END IF 結(jié)尾,END IF 分開(kāi)拼寫(xiě)。有兩個(gè)可選付句(ELSIF付句和 ELSE 付句),ELSIF 付句可重復(fù)并允許有多個(gè) ELSIF 付句,可選 ELSE 付句但只允許有一個(gè) ELSE 付句。付句中的條件是一布爾表達(dá)式,如條件為真值,則下一語(yǔ)句被執(zhí)行;如果條件不為真,那么接著執(zhí)行跟在 ELSE 付句后的順序語(yǔ)句。
下面舉一個(gè) IF 語(yǔ)句的使用例子,如下:
IF (day = sunday) THEN
weekend := TRUE;
ELSIF (day = saturday) THEN
weekend := TRUE;
ELSE
weekday := TRUE;
END IF;
以上代碼的意義如下:有兩個(gè)變量 weekend 和 weekday,每當(dāng) day 等于 saturday 或 sunday時(shí)變量 weekend 變?yōu)檎?,?zhí)行跟著的下一句并控制轉(zhuǎn)到跟在 END IF 之后的語(yǔ)句,否則轉(zhuǎn)到 ELSIF語(yǔ)句部分并檢查 day 是否為 Saturday;當(dāng)變量 day 等于 saturday,執(zhí)行跟著的下一句并再次控制轉(zhuǎn)到跟在 END IF 之后的語(yǔ)句;若 day 并不等于 sunday 或 saturday,執(zhí)行 ELSE 語(yǔ)句部分。
4).CASE 語(yǔ)句
當(dāng)單個(gè)表達(dá)式的值在多個(gè)起作用的項(xiàng)中選擇時(shí)用 CASE 語(yǔ)句。CASE 語(yǔ)句的格式如下:
CASE expression IS
WHEN choice1 =>
sequence_of_statements
WHEN choice2 | choice3 =>
sequence_of_statements
…
WHEN OTHERS =>
sequence_of_statements
END CASE;
下面是一個(gè)使用 CASE 語(yǔ)句執(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)語(yǔ)句
當(dāng)需要重復(fù)操作時(shí)用循環(huán)語(yǔ)句,或者實(shí)現(xiàn)的模塊需要很強(qiáng)的迭代能力時(shí)用循環(huán)語(yǔ)句:
[循環(huán)標(biāo)示 :] [循環(huán)條件] LOOP
順序處理語(yǔ)句
END LOOP[LOOP_label];
其中循環(huán)條件可以用 WHILE 語(yǔ)句或者 FOR 語(yǔ)句來(lái)描述。WHLIE 語(yǔ)句有一個(gè)循環(huán)控制的條件 condition,只要條件表達(dá)式為真,WHILE 循環(huán)語(yǔ)句就一直執(zhí)行下去,除非要退出循環(huán)。例如:
WHILE (day = weekday) LOOP
day := get_next_day(day);
END LOOP
FOR 循環(huán)是根據(jù)預(yù)先的設(shè)定進(jìn)行迭代,所指定的范圍并不一定必須為整數(shù)值,也可以表示成一個(gè)子類型的指示或者一個(gè)范圍語(yǔ)句,例如:
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 語(yǔ)句的指數(shù)值(i)由 FOR 語(yǔ)句局部地說(shuō)明,這和進(jìn)程、函數(shù)和過(guò)程中變量 I 不是一會(huì)事,它不需要顯式地說(shuō)明,由于 FOR LOOP 語(yǔ)句的虛擬性,循環(huán)指數(shù)要局部說(shuō)明之。這樣在進(jìn)程、函數(shù)或過(guò)程中存在同名變量時(shí),它們會(huì)被分別處理并由它們的內(nèi)含尋址。
此外,關(guān)于循環(huán)需要特別注意的是,在某些編程語(yǔ)言中循環(huán)指數(shù)的值可由賦予內(nèi)部循環(huán)值來(lái)改變,但是 VHDL 中是不允許對(duì)循環(huán)指數(shù)的任何賦值,這排除了在任何函數(shù)返回值中或在過(guò)程的輸出與雙向參量中存在循環(huán)指數(shù)。
6).NEXT 語(yǔ)句
如果必須在這次迭代或循環(huán)中停下正在執(zhí)行的語(yǔ)句,而轉(zhuǎn)向下一個(gè)迭代時(shí),用 NEXT 語(yǔ)句。執(zhí)行 NEXT 語(yǔ)句時(shí),模塊處理停在當(dāng)前點(diǎn)并轉(zhuǎn)到循環(huán)語(yǔ)句的開(kāi)始。隨著循環(huán)的第一個(gè)語(yǔ)句執(zhí)行,循環(huán)變量增加一個(gè)迭代值,直到迭代的限制值,循環(huán)停止。
下面是一個(gè) NEXT 語(yǔ)句使用的例子:
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 語(yǔ)句
EXIT 語(yǔ)句提供完全停下循環(huán)執(zhí)行的能力。執(zhí)行期間發(fā)生了明顯的錯(cuò)誤或者所有的進(jìn)程已執(zhí)行完畢就跳出循環(huán),EXIT 語(yǔ)句允許退出或跳出循環(huán)語(yǔ)句。執(zhí)行 EXIT 語(yǔ)句后 EXIT 語(yǔ)句后面的語(yǔ)句暫停執(zhí)行,去執(zhí)行循環(huán)語(yǔ)句后面的語(yǔ)句。
EXIT 語(yǔ)句的基本書(shū)寫(xiě)格式如下:
EXIT [循環(huán)標(biāo)號(hào)][WHEN 條件]
循環(huán)標(biāo)號(hào)一般在多重循環(huán)中用于標(biāo)明循環(huán)層次,如果 EXIT 語(yǔ)句后面添加循環(huán)標(biāo)號(hào),它將會(huì)退出循環(huán)標(biāo)號(hào)指定的循環(huán)。“WHEN 條件”項(xiàng)用于表明 EXIT 語(yǔ)句執(zhí)行的條件,此條件為真時(shí)才推出循環(huán)。
EXIT 語(yǔ)句的使用實(shí)例如下:
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 并行語(yǔ)句描述方法
VHDL 不僅僅提供了一系列的順序語(yǔ)句,同樣也提供了很多并行語(yǔ)句。在 VHDL 中,并行語(yǔ)句主要包括以下幾種:
? 進(jìn)程(PROCESS)語(yǔ)句;
? 塊(BLOCK)語(yǔ)句;
? 并發(fā)信號(hào)賦值;
? 條件信號(hào)賦值;
? 選擇信號(hào)賦值。
其中進(jìn)程語(yǔ)句和塊語(yǔ)句已經(jīng)在結(jié)構(gòu)體的描述方法中介紹過(guò)了,在此不再累贅,后面主要介紹余下的 3 種并行語(yǔ)句。
1).并發(fā)信號(hào)賦值
信號(hào)賦值就是使用信號(hào)賦值操作符“<=”修改一個(gè)信號(hào)的狀態(tài),如果此語(yǔ)句是在一個(gè)進(jìn)程中,那么它是一個(gè)順序語(yǔ)句,反之如果它是在進(jìn)程外面(和進(jìn)程并列關(guān)系),那么它就是一個(gè)并行賦值的語(yǔ)句。
下面是一個(gè)信號(hào)賦值的例子,其中 c1、c2 是順序賦值的,c2 在 c1 之后賦值;d1 和 d2是并行賦值的,它們同時(shí)被賦值:
ARCHITECTURE arch of demo is
BEGIN
-- 并行賦值
d1 <= din
d2 <= din
-- 進(jìn)程
PROCESS(din)
BEGIN
-- 順序賦值
c1 <= din
c2 <= din
END PROCESS;
END arch;
2).條件信號(hào)賦值
條件信號(hào)賦值的格式如下:
目的信號(hào) <= 表達(dá)式 1 WHEN 條件 1 ELSE
表達(dá)式 2 WHEN 條件 2 ELSE
表達(dá)式 3 WHEN 條件 3 ELSE
…
表達(dá)式 n;
最后一個(gè)表達(dá)式 n 表示以上 n-1 個(gè)條件都不滿足時(shí)自動(dòng)選用此表達(dá)式,如果有條件滿足,則條件對(duì)應(yīng)的表達(dá)式會(huì)計(jì)算賦值給目的信號(hào)量。條件信號(hào)代入語(yǔ)句也是并發(fā)描述語(yǔ)句,它可以根據(jù)不同條件將不同的多個(gè)表達(dá)式之一的值代入信號(hào)量。
下面通過(guò)一個(gè)四選一選擇器的實(shí)現(xiàn)方法來(lái)介紹條件信號(hào)代入語(yǔ)句的使用方法:
ENTITY mux4 IS
PORT (
din0, din1, din2, din3,sel0,sel1: in bit;
dout: out bit );
END mux4;
ARCHITECTURE arch of mux4 is
SIGNAL 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).選擇信號(hào)賦值
選擇信號(hào)賦值類似于 CASE 語(yǔ)句,它的格式如下:
WITH 表達(dá)式 SELECT
目的信號(hào)量 <= 表達(dá)式 1 WHEN 條件 1;
表達(dá)式 2 WHEN 條件 2;
表達(dá)式 3 WHEN 條件 3;
…
表達(dá)式 n WHEN 條件 n;
如果使用選擇信號(hào)賦值實(shí)現(xiàn)上面的四選一選擇器,代碼如下:
ENTITY mux4 IS
PORT (
din0, din1, din2, din3,sel0,sel1: in bit;
dout: out bit );
END mux4;
ARCHITECTURE arch of mux4 is
SIGNAL 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ǔ)言的預(yù)定義屬性
在 VHDL 中,屬性是指關(guān)于設(shè)計(jì)實(shí)體、結(jié)構(gòu)體、類型、信號(hào)等項(xiàng)目的制定特征,利用屬性可以使得 VHDL 代碼更加簡(jiǎn)明扼要、易于理解。
VHDL 提供了下面 5 類預(yù)定義屬性:值類屬性、函數(shù)類屬性、信號(hào)類屬性、數(shù)據(jù)類型類屬性和數(shù)據(jù)范圍類屬性。
5.1 值類預(yù)定義屬性
值類屬性返回有關(guān)數(shù)組類型、塊和常用數(shù)據(jù)類型的特定值,值類屬性還用于返回?cái)?shù)組的長(zhǎng)度或者類型的最低邊界,值類屬性分成 3 個(gè)子類。
1).值類型屬性:返回類型的邊界
值類型屬性用來(lái)返回類型的邊界,有 4 種預(yù)定義屬性:
? T'LEFT 用于返回類型或者子類型的左邊界;
? T'RIGHT 用于返回類型或者子類型的右邊界;
? T'High 用于返回類型或者子類型的上限值;
? T'Low 用于返回類型或者子類型的下限值。
用字符“'”指定屬性并后跟屬性名,“'”前的對(duì)象是所附屬性的對(duì)象,字首大寫(xiě)“T”指所附屬性的對(duì)象是類型(TYPE),“'”字符標(biāo)點(diǎn)符號(hào)(tick)是 VHDL 特有的標(biāo)號(hào)。
2).值類數(shù)組屬性:返回?cái)?shù)組長(zhǎng)度
值類數(shù)組屬性只有一個(gè),即 LENGTH,該屬性返回指定數(shù)組范圍的總長(zhǎng)度,它用于帶某種標(biāo)量類型的數(shù)組范圍和帶標(biāo)量類型范圍的多維數(shù)組。
3).值類塊屬性:返回塊的信息
用屬性'STRUCTURE 和'BEHAVIOR 返回有關(guān)在塊和結(jié)構(gòu)體中塊是如何建模的信息。在塊和結(jié)構(gòu)體中如不含元件具體裝配語(yǔ)句,則屬性'BEHAVIOR 將返回真值,如果塊或者結(jié)構(gòu)體中只含元件具體裝配語(yǔ)句或被動(dòng)進(jìn)程,則屬性'STRUCTUTE 將返回真值。
5.2 函數(shù)類預(yù)定義屬性
函數(shù)類屬性為設(shè)計(jì)者返回類型、數(shù)組和信號(hào)信息。用函數(shù)類屬性時(shí),函數(shù)調(diào)用由輸入變?cè)闹捣祷匾粋€(gè)值,返回值為可枚舉值的位置號(hào)碼、在一個(gè)△時(shí)間內(nèi)信號(hào)是否改變的指示或者一個(gè)數(shù)組的邊界。函數(shù)類屬性可細(xì)分為 3 個(gè)常見(jiàn)的類別。
1).函數(shù)類型屬性:返回類型值
函數(shù)類型屬性返回類型內(nèi)部值的位置號(hào)碼、返回特定類型輸入值的左和右邊的值,函數(shù)類型屬性分為 6 種:
? 'POS(value)返回傳入值的位置號(hào)碼;
? 'VAL(value)返回從該位置號(hào)碼傳入的值;
? 'SUCC(value)返回輸入值后類型中的下一個(gè)值;
? 'PRED(value)返回輸入值前類型中的原先的值;
? 'LEFTOF(value)表示立即返回一個(gè)值到輸入值的左邊;
? 'RIGHTOF(value)表示立即返回一值到輸入值的右邊。函數(shù)類型屬性主要用于從可枚舉數(shù)或物理類型的數(shù)轉(zhuǎn)換到整數(shù)類型。
2).函數(shù)數(shù)組屬性:返回?cái)?shù)組的邊界
函數(shù)數(shù)組類屬性返回?cái)?shù)組類型的邊界,分 4 類:
? 數(shù)組'LEFT(n)返回指數(shù)范圍 n 的左邊界;
? 數(shù)組'RIGHT(n)返回指數(shù)范圍 n 的右邊界;
? 數(shù)組'HIGH(n)返回指數(shù)范圍 n 的上限值;
? 數(shù)組'LOW(n)返回指數(shù)范圍 n 的下限值。值類數(shù)組屬性只有一個(gè)即 LENGTH,該屬性返回指定數(shù)組范圍的總長(zhǎng)度,它用于帶某種標(biāo)量類型的數(shù)組范圍和帶標(biāo)量類型范圍的多維數(shù)組。
3).函數(shù)信號(hào)屬性:返回信號(hào)歷史信息
函數(shù)信號(hào)屬性用來(lái)返回有關(guān)信號(hào)行為功能的信息,例如報(bào)告究竟一個(gè)信號(hào)是否正好有值的變化,報(bào)告從上次事件中跳變過(guò)了多少時(shí)間以及該信號(hào)原來(lái)的值是什么。
函數(shù)信號(hào)屬性有如下 5 類:
? S'EVENT,如果當(dāng)前的△時(shí)間期間發(fā)生了事件返回真,否則返回假(信號(hào)是否有值的變化);
? S'ACTIVE,如果在當(dāng)前的△時(shí)間期間做了事項(xiàng)處理返回真,否則返回假;
? S'LAST_EVENT,返回從信號(hào)原先事件的跳變至今所經(jīng)歷的時(shí)間;
? S'LAST_VALUE,返回在上一次事件之前 S 的原先值;
? S'LAST_ACTIVE,返回自信號(hào)原先一次的事項(xiàng)處理至今所經(jīng)歷的時(shí)間。
5.3 信號(hào)類預(yù)定義屬性
信號(hào)類屬性用于根據(jù)另一個(gè)信號(hào)創(chuàng)建一些專用的信號(hào),由類專用信號(hào)為設(shè)計(jì)者返回有關(guān)所附屬性的信號(hào)信息(在一指定時(shí)間范圍內(nèi)該信號(hào)是否已經(jīng)穩(wěn)定的信息、在信號(hào)上有無(wú)事項(xiàng)處理的信息和建立的信號(hào)的延遲形式)。
對(duì)這類信號(hào)是不能在子程序內(nèi)部使用的,返回的信息和由某種函數(shù)屬性所提供的功能非常類似,區(qū)別是這類專用信號(hào)用于正常信號(hào)能用的任何場(chǎng)合,包括在敏感表中。有如下的 4 類屬性:
? S'DELAYED[(time)] 建立和參考信號(hào)同類型的信號(hào),該信號(hào)后跟參考信號(hào)和延時(shí)可選時(shí)間表示式的時(shí)間。'DELAYED 屬性為信號(hào)建立延遲的版本并附在該信號(hào)上,它和傳輸延時(shí)信號(hào)賦值的功能相同,但簡(jiǎn)單。
? S'STABLE[(time)] 在選擇時(shí)間表達(dá)式指定的時(shí)間內(nèi)參考信號(hào)無(wú)事件發(fā)生時(shí),屬性建立為真值的布爾信號(hào)。
? S'QUIET[(time)] 參考信號(hào)或所選時(shí)間表達(dá)式指定時(shí)間內(nèi)沒(méi)事項(xiàng)處理時(shí),屬性建立一個(gè)為真值的布爾信號(hào)。
? S'TRANSACTION 信號(hào)上有事件發(fā)生或?yàn)槊總€(gè)事項(xiàng)處理而翻轉(zhuǎn)它的值時(shí),該屬性建立一個(gè) BIT 類型的信號(hào)。
5.4 數(shù)據(jù)類型類預(yù)定義屬性
數(shù)據(jù)類型類的屬性只有一個(gè) t'BASE 類型屬性,它必須由另一個(gè)值或函數(shù)類型屬性用該屬性。這個(gè)屬性將返回類型或者子類型的基本類型,這個(gè)屬性只能作另一屬性的前綴。
5.5 數(shù)據(jù)范圍類預(yù)定義屬性
數(shù)據(jù)范圍類屬性返回?cái)?shù)組類型的范圍值,并由所選的輸入?yún)?shù)返回指定的指數(shù)范圍,這種屬性標(biāo)記如下:a'RANGE[(n)];a'REVERSE_RANGE[(n)]。
屬性 RANGE 將返回由參數(shù) n 值指明的第 n 個(gè)范圍和按指定排序的范圍,'REVERSE_RANGE將返回按逆序的范圍,屬性'RANGE 和'REVERSE_RANGE 也用于控制循環(huán)語(yǔ)句的循環(huán)次數(shù)。
REVERSE_RANGE 屬性的用法和 RANGE 屬性相類似,只是它按逆序返回一范圍而已。 比如假設(shè)'RANGE 屬性是返回 0 到 15,那么'REVERSE_RANGE 屬性返回 15 下降到 0。