《Xilinx FPGA設(shè)計基礎(chǔ)》課件第3章_第1頁
《Xilinx FPGA設(shè)計基礎(chǔ)》課件第3章_第2頁
《Xilinx FPGA設(shè)計基礎(chǔ)》課件第3章_第3頁
《Xilinx FPGA設(shè)計基礎(chǔ)》課件第3章_第4頁
《Xilinx FPGA設(shè)計基礎(chǔ)》課件第3章_第5頁
已閱讀5頁,還剩326頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第3章VHDL硬件描述語言3.1VHDL的歷史和概況

3.2VHDL基本設(shè)計思想

3.3VHDL語言設(shè)計的基本單元

3.4VHDL語言的對象和數(shù)據(jù)類型3.5VHDL語言運算操作符3.6VHDL語言的描述語句3.7VHDL的層次結(jié)構(gòu)設(shè)計3.8有限狀態(tài)機(FSM)

3.1VHDL的歷史和概況

VHDL是VHSIC硬件描述語言(VHSICHardwareDescriptionLanguage)的縮寫,而VHSIC又是超高速集成電路(VeryHigh-SpeedIntegratedCircuit)的縮寫。從這個縮寫我們大致可以看出VHDL語言的起源和目的。

VHDL是1980年在美國國防部的指導(dǎo)下開發(fā)的,于1983年完成。1987年被美國國防部和IEEE確定為標準的硬件描述語言,形成的標準為IEEE1076。當(dāng)初開發(fā)這種語言是出于美國國防部采購電子設(shè)備的需要。美國軍隊的裝備是向私人企業(yè)采購的,如果武器大量裝備部隊,而其中某個供應(yīng)商在幾年后倒閉了,那這種武器的維修保養(yǎng)和再生產(chǎn)就會出現(xiàn)大問題。而這些電子設(shè)備,尤其是超高速集成電路的內(nèi)部結(jié)構(gòu)很復(fù)雜,如果出現(xiàn)了這種問題要找其他公司生產(chǎn)代用品就非常困難。因此,美國國防部希望供應(yīng)商能留下其產(chǎn)品的信息,以保證其一旦破產(chǎn)能由其他廠商迅速生產(chǎn)出代用品。由于涉及商業(yè)機密和知識產(chǎn)權(quán)的問題,供應(yīng)商不會提供最初的設(shè)計文檔,于是美國國防部就提出了一種折中的方法,即硬件描述語言,也就是VHDL。供應(yīng)商要用VHDL把自己生產(chǎn)的集成電路芯片的行為描述出來,例如從芯片的哪個管腳輸入什么樣的信號,過多長時間能輸出什么樣的信號等。這樣,如果需要其他廠商生產(chǎn)代用品,只需要按照VHDL文檔,設(shè)計行為與其相同的芯片即可。

VHDL當(dāng)初是為了描述芯片的行為,而并不是為了設(shè)計硬件而開發(fā)的,因此IEEE1076-1987標準在模型描述方面非常詳盡,但在綜合方面它只定義了一些很寬泛的參數(shù),在工程實現(xiàn)中有很大的難度。1993年,IEEE修訂了VHDL標準,新標準相對于87版本有了很大的改進。93版本的VHDL是目前應(yīng)用最廣泛的版本,很多廠商的綜合工具都支持這一標準。IEEE規(guī)定其標準必須每五年修訂一次,因此VHDL還有很多后續(xù)版本,如2000版,但這些版本并沒有修訂多少內(nèi)容。 3.2VHDL基本設(shè)計思想

從VHDL的字面含義可以看出,VHDL語言著重于描述。通過描述芯片的輸入/輸出、結(jié)構(gòu)和行為等,使工程師能從概念上對芯片有一個完整的了解。描述的目的是要傳遞信息,通常意義下的描述是一個非常靈活的過程,例如口述、打手勢、書面陳述等,但每個人的表達方式和理解方式不同,這些方法都無法或很難準確無誤地傳遞要表達的信息。因此,工程化的描述都采用規(guī)范的語言形式,用嚴格的語法結(jié)構(gòu)限定描述的內(nèi)容,VHDL也不例外。

VHDL只是給工程師提供了一個描述規(guī)范,用這種規(guī)范進行描述可以使眾多工程師之間傳遞信息更加簡潔、準確。學(xué)習(xí)VHDL就是學(xué)習(xí)如何利用這些規(guī)范進行描述,因此,我們在學(xué)習(xí)VHDL之前,要在思維中假想一個現(xiàn)成的芯片,學(xué)習(xí)的過程中,對照芯片不斷完善對芯片的描述。

VHDL不僅可以對芯片的接口和行為參數(shù)做詳盡的描述,而且可以作為一門編程語言對可編程邏輯器件進行編程配置。目前,可編程邏輯器件的EDA工具都支持以VHDL代碼作為工程設(shè)計的輸入。

VHDL語言語法簡單,結(jié)構(gòu)明晰,可以滿足工程設(shè)計中的各種需求。

1)用編程的方式描述設(shè)計的功能

在2.2節(jié)的實驗中,我們已經(jīng)初步接觸了VHDL語言程序。VHDL程序的設(shè)計方法與其他編程語言的設(shè)計方法很相似,工程師可以用編程的思想完成FPGA的電路設(shè)計。這對于熟悉Pascal或C語言的工程師來說相當(dāng)方便。

2)?VHDL支持工程設(shè)計的結(jié)構(gòu)化描述

一般在硬件電路設(shè)計中,采用自底向上的設(shè)計方式,即先設(shè)計構(gòu)成系統(tǒng)的各個組成模塊,明確模塊的端口和時序,然后設(shè)計模塊之間的互聯(lián)關(guān)系,組成整個系統(tǒng)。

VHDL不僅支持自底向上的設(shè)計方式,而且支持如圖3.1所示的自頂向下的設(shè)計輸入模式,這種輸入模式更符合一般設(shè)計者對工程的認知過程。首先根據(jù)工程設(shè)計需要完成的功能、芯片的輸入/輸出信號的定義等信息,對設(shè)計的頂層模塊進行描述。然后,將頂層模塊的功能實現(xiàn)劃分為幾個二級功能模塊,對二級模塊的端口和互聯(lián)關(guān)系進行描述。如此,由頂向下逐步將系統(tǒng)模塊劃分為底層的模塊實現(xiàn)。圖3.1自頂向下的設(shè)計輸入方式

3)?VHDL支持多層次抽象描述

FPGA電路設(shè)計一般抽象為四個層次,即行為層次(Behavioral)、寄存器傳輸層次(RTL,RegisterTransferLevel)、邏輯門層次(Logic)和布圖層次(Layout),如圖3.2所示。

行為層次主要關(guān)注模塊的功能描述和仿真驗證,寄存器傳輸層次要關(guān)注模塊的可綜合電路的實現(xiàn),邏輯門層次考慮如何用門級電路實現(xiàn)給定功能,布圖層次考慮如何將電路適配到FPGA的資源中。

抽象層次越高,設(shè)計和仿真用的時間越少,但對電路細節(jié)的描述也越少;抽象層次越低,與器件相關(guān)的細節(jié)描述越多,但設(shè)計和仿真難度越大,花費時間越長。圖3.2FPGA設(shè)計的抽象層次通常做基于FPGA的工程設(shè)計,工程師只需要用VHDL語言設(shè)計RTL以上的層次實現(xiàn),電路的FPGA底層實現(xiàn)通過綜合工具和實現(xiàn)工具完成。

4)用仿真工具對設(shè)計進行仿真

仿真是驗證工程設(shè)計的必要步驟,VHDL語言有專用的仿真工具,可以對FPGA設(shè)計的各個層次做仿真驗證,包括行為層次和寄存器傳輸層次的功能仿真,邏輯門層次的綜合后的仿真和布圖層次的布局布線后的仿真。每個層次的仿真有其各自的特點,靈活使用各層次的仿真,可以使工程驗證得心應(yīng)手。

另外,需要注意,VHDL語言在建模方面有很多描述語句,但并不是所有的描述語句都是可以綜合的,可綜合語句只是VHDL建模語句的一個子集,它們的關(guān)系如圖3.3所示。圖3.3建模語句與可綜合語句的關(guān)系行為層次的VHDL描述是用于仿真的,全部的建模語言都可以使用;寄存器傳輸層次的VHDL描述只能用可綜合的語句。一般的工程設(shè)計文件都要用寄存器傳輸層次的描述,而測試平臺文件則用行為級的描述。 3.3VHDL語言設(shè)計的基本單元

VHDL是由設(shè)計單元組成的,基本的設(shè)計單元包括:

●實體Entity;

●構(gòu)造體Architecture;

●配置Configuration;

●包集合Package;

●庫Library。

芯片中的一個模塊可以是芯片的頂層模塊,即芯片本身,也可以是芯片內(nèi)的任意模塊。讀者在學(xué)習(xí)本節(jié)內(nèi)容的過程中可以參照2.2節(jié)實驗中的內(nèi)容,以加深對VHDL設(shè)計單元的理解。3.3.1實體

設(shè)計一個模塊,首先要給模塊起一個名字作為這個模塊的標識,稱為實體名稱。這個名字通常與模塊的功能有密切關(guān)系,例如2.2節(jié)實驗中的AND_OR。

模塊命名后,就要確定這個模塊的外部接口參數(shù),即模塊有哪些輸入信號,有哪些輸出信號,信號的名稱和類型是什么,在確定了這些參數(shù)之后,我們就完成了對實體的描述。

實體描述了模塊的外部接口和接口的相關(guān)參數(shù)。

在VHDL中實體描述的結(jié)構(gòu)如圖3.4所示。圖3.4實體描述結(jié)構(gòu)圖中,“entity實體名稱is”標識實體說明的開始,“end實體名稱”標識實體說明的結(jié)束,“entity”是實體聲明的關(guān)鍵字。

端口聲明是實體說明的主要部分,用于說明模塊實體與外部接口的信號傳遞關(guān)系。模塊的端口聲明與芯片的管腳說明類似,只有定義了端口,模塊才能通過端口信號與外部互相傳遞信息。

實體中所有的端口信號都要在“port();”語句的括號內(nèi)聲明。端口的聲明包含三個部分:端口名稱、端口模式和數(shù)據(jù)類型。相同端口模式和數(shù)據(jù)類型的端口信號可以作為一組信號聯(lián)合聲明,信號之間用逗號“,”隔開,不同組的信號聲明之間用分號“;”隔開,但是要注意聲明最后一組信號后不需要再加分號,端口聲明的結(jié)構(gòu)如下:

1.端口名稱

一般一個模塊實體包含不止一個端口,為了區(qū)別不同的端口,給端口命名時通常不會采用上面例子中的方式,而會將端口的含義包含在名稱中。例如,常用的端口名稱“clk”表示時鐘信號等。

2.端口模式

端口模式用于定義模塊端口的數(shù)據(jù)傳輸模式。VHDL的端口模式有五種,如表3.1所示。表3.1端口模式說明

in模式的端口只能用作實體的輸入端口,外部信號只能通過端口輸入,而實體內(nèi)部的信號不能通過端口輸出,如圖3.5(a)所示。

與此相反,out模式的端口只能用作實體的輸出端口,實體內(nèi)部的信號可以通過端口輸出,但是外部信號不能通過端口輸入,如圖3.5(b)所示。圖3.5實體端口類型(a)?in端口;(b)?out端口;(c)?inout端口;(d)?buffer端口

inout端口是雙向端口,既可以用作內(nèi)部信號的輸出端口,也可以用作外部信號的輸入端口,但是輸入和輸出是分時復(fù)用的,輸入的信號值是外部信號驅(qū)動的值,而不是內(nèi)部輸出時驅(qū)動的值,如圖3.5(c)所示。

buffer是緩沖輸出端口,使用buffer輸出的信號值在實體內(nèi)部仍可以對其他信號進行賦值。buffer與inout有明顯的不同,buffer不能用作信號的輸入。當(dāng)一個實體的端口用buffer模式時,只能與其他實體的buffer類型的端口相連。

linkage類型的端口不指定信號傳輸方向,可以與任意類型的端口相連。

3.?dāng)?shù)據(jù)類型

IEEE1706/93VHDL語言參考手冊規(guī)定,EDA綜合工具支持的端口數(shù)據(jù)類型為布爾型(boolean)、位型(bit)、位矢量型(bit_vector)和整數(shù)型(integer)。

由IEEEstd_logic_1164所約定的、并由EDA工具支持和提供的數(shù)據(jù)類型為標準邏輯類型(StandardLogic)。標準邏輯類型也分為布爾型、位型、位矢量型和整數(shù)型。為了使EDA工具的仿真、綜合軟件能夠處理這些邏輯類型,這些庫必須用USE語句聲明。

我們會在后續(xù)內(nèi)容中對數(shù)據(jù)類型做詳細介紹。

一個典型的實體聲明如圖3.6所示。圖3.6實體聲明實例圖3.6實例中,一開始將“IEEE”庫包含進來,并聲明用“IEEE.STD_LOGIC_1164”包中的全部內(nèi)容。端口的類型選用了STD_LOGIC和STD_LOGIC_VECTOR,STD_LOGIC類似于位型,說明這些端口信號只能取邏輯“0”或邏輯“1”;STD_LOGIC_VECTOR類似于位矢量型,說明這些端口的信號值可以取一組二進制位值,位矢量的長度在后面的括號中說明,(7downto0)說明該端口是一個8位的端口,比特位由左至右為從高到低的次序。

4.參數(shù)聲明

實體的聲明過程中還可以加入?yún)?shù)聲明,參數(shù)聲明類似于C++語言中的類屬參數(shù)聲明,在實體內(nèi)部可以將聲明的參數(shù)作為常數(shù)使用。參數(shù)聲明必須放在端口聲明之前,聲明的參數(shù)必須在generic();語句的括號內(nèi)。參數(shù)聲明包含三部分,參數(shù)名稱、參數(shù)類型和參數(shù)默認值,其中參數(shù)的默認值是可選的。參數(shù)聲明時,多個參數(shù)之間用分號“;”隔開。參數(shù)聲明的結(jié)構(gòu)如下:

包含參數(shù)聲明的實體聲明結(jié)構(gòu)如圖3.7所示。圖3.7帶參數(shù)的實體描述結(jié)構(gòu)例如圖3.8的實例中,SETVALUE和COUNTOUT的端口位矢量長度可以設(shè)置為參數(shù)。圖3.8帶參數(shù)的實體聲明實例3.3.2構(gòu)造體

通過實體聲明可以了解模塊的外部特征,但無法得知模塊內(nèi)部的功能實現(xiàn)。通常用構(gòu)造體對實體的內(nèi)部實現(xiàn)做更加詳細的描述。構(gòu)造體是一個從屬單元,不能獨立存在于模塊中,必須與實體聲明聯(lián)合使用。而一個實體聲明可以有多個構(gòu)造體。

構(gòu)造體描述了模塊的內(nèi)部功能、行為或結(jié)構(gòu)實現(xiàn)。

在VHDL中構(gòu)造體描述的結(jié)構(gòu)如圖3.9所示。圖3.9構(gòu)造體描述結(jié)構(gòu)

1.實體名稱

構(gòu)造體中的實體名稱必須與實體聲明中的實體名稱一致。

2.構(gòu)造體名稱

構(gòu)造體名稱是構(gòu)造體的標識,在命名時通常與構(gòu)造體的描述方式相關(guān)。構(gòu)造體在描述模塊的內(nèi)部實現(xiàn)時通常有三種方式,行為描述、數(shù)據(jù)流描述和結(jié)構(gòu)描述,不同的描述方式只在于其風(fēng)格不同,而功能實現(xiàn)是統(tǒng)一的。在比較復(fù)雜的構(gòu)造體描述中,通常不止用一種描述方式,而會靈活地搭配三種方式進行描述。

1)行為描述

行為描述是抽象層最高的描述。主要使用電路的行為特性來描述設(shè)計,通過EDA工具的綜合和優(yōu)化,實現(xiàn)實體的功能。采用這種描述方法設(shè)計的電路非常易于維護。在VHDL中通常用process的方式進行行為描述。

例如,2.2節(jié)實驗1中的模塊AND_OR,采用行為描述方式的代碼如圖3.10所示。圖3.10AND_OR的行為描述代碼

2)數(shù)據(jù)流描述

數(shù)據(jù)流的描述方式主要使用VHDL語言中的標準布爾函數(shù),將信號之間的布爾代數(shù)關(guān)系用布爾方程式來表示。采用數(shù)據(jù)流描述方式的AND_OR模塊代碼如圖3.11所示。圖3.11AND_OR的數(shù)據(jù)流描述代碼

3)結(jié)構(gòu)描述

結(jié)構(gòu)描述主要通過下層模塊的聲明和調(diào)用及端口映射將下層模塊相連,構(gòu)成電路的結(jié)構(gòu)性描述。AND_OR模塊的結(jié)構(gòu)描述代碼如圖3.12所示。圖3.12AND_OR的結(jié)構(gòu)描述代碼

3.聲明語句

聲明語句在構(gòu)造體的關(guān)鍵字“begin”之前,可用于聲明下列描述語句:

●?“use”語句;

●?子程序(subprogram)聲明;

●?子程序體(subprogrambody);

●?類型(type)聲明;

●?子類型(subtype)聲明;

●?常量(constant)聲明;

●?信號(signal)聲明;

●?元件(component)聲明;

●?并發(fā)(concurrent)語句。最典型的聲明語句如AND_OR的三種描述中都用到的SIG1和SIG2信號的聲明。在這里只將全部的聲明語句提出,后續(xù)的章節(jié)中將詳細介紹每一種聲明語句。

4.并發(fā)語句

構(gòu)造體中的每一個并發(fā)語句都定義了一個運算單元,這個單元包括三個部分:

●讀取信號值;

●用讀取的信號值進行運算;

●將運算的結(jié)果賦值給另外一個信號。構(gòu)造體中的所有并發(fā)語句都是同時進行運算的,與語句的書寫順序沒有任何關(guān)系。并發(fā)語句有五種類型:

●塊(block)語句;

●元件(component)例化;

●過程(procedure)調(diào)用;

●進程(process);

●信號(signal)賦值。

我們可以在AND_OR的結(jié)構(gòu)體描述實例中找到用到的并發(fā)語句,這里也只將全部的并發(fā)語句提出,在后續(xù)的章節(jié)中將詳細介紹這些并發(fā)語句。3.3.3配置

上述構(gòu)造體內(nèi)容中提到,一個實體聲明可以有多個構(gòu)造體,但這個實體被上層模塊調(diào)用,并在最終形成電路時,只能使用一種結(jié)構(gòu)體作為實體功能實現(xiàn)的描述。這時就需要使用配置結(jié)構(gòu)將實體與對應(yīng)的結(jié)構(gòu)體連接起來。配置不是所有VHDL代碼必備的一部分,它不是從屬單元,可以獨立存在。通常在使用時都會將配置單獨寫入一個文件中。

注意:雖然使用配置可以使VHDL代碼更加靈活,但目前很多綜合工具都不支持配置。

配置用于描述設(shè)計的層次之間的互聯(lián)關(guān)系,以及實體與結(jié)構(gòu)體之間的連接關(guān)系。

在VHDL中配置描述的結(jié)構(gòu)如圖3.13所示。圖3.13配置描述結(jié)構(gòu)配置描述以“configuration配置名稱of實體名稱is”開始,以“end配置名稱”結(jié)束,“configuration”是構(gòu)造體聲明的關(guān)鍵字。

1.實體名稱

配置中的實體名稱必須與實體聲明中的實體名稱一致。

2.配置名稱

配置名稱是配置的標識。一個實體的配置可以在這個實體被上層模塊調(diào)用時,作為上層模塊中的配置語句使用。

3.配置語句

根據(jù)使用情況不同,配置語句有簡有繁。最簡單的配置語句的結(jié)構(gòu)如下:庫包含3.3.4包集合

VHDL工程設(shè)計包含很多元素,不僅包含之前所涉及的實體、結(jié)構(gòu)體以及配置,還包含一些常量定義、數(shù)據(jù)類型定義、子類型定義、子程序和函數(shù)等元素,這些元素會在源文件設(shè)計中反復(fù)用到。

類似于C語言中,我們經(jīng)常將用戶定義的類型、常量、函數(shù)聲明等單獨寫入一個頭文件中,然后在C源文件中用include語句包含進來一樣。VHDL語言中,也將這些內(nèi)容組織在一起,但不形成文件,而形成包集合。

包集合用于存儲在工程設(shè)計中需要反復(fù)用到的常量定義、數(shù)據(jù)類型定義、子類型定義、子程序和函數(shù)聲明等。在上述的代碼中,都會以“l(fā)ibraryIEEE”和“use……”開頭,其中“use……”部分代碼的含義就是對用到的包集合進行聲明。

包集合由包集合聲明和包集合體兩部分構(gòu)成,包集合的描述結(jié)構(gòu)如圖3.14所示。圖3.14包集合描述結(jié)構(gòu)

1.包集合名稱

包集合名稱是包集合的標識,在使用包集合時,可以作為參數(shù)使用。

2.包集合聲明語句

包集合聲明語句中包含了工程設(shè)計中常用的信息,這些信息包括數(shù)據(jù)類型聲明、信號聲明、子程序聲明和元件聲明。在聲明語句中,對子程序和元件只做聲明,具體的實現(xiàn)在包集合體描述語句中進行描述。包集合聲明語句中聲明的這些定義對外界是可見的。

注意,包集合中聲明的信號在不同的實體中是不能共享的,如果多個實體都使用了包集合中的同一個信號,則每個實體內(nèi)都會有一個獨立的該信號的復(fù)制信號。

3.包集合體描述語句

包集合體描述語句包含了子函數(shù)(Function)和過程(Prodecure)等的具體實現(xiàn),這些子函數(shù)或過程是在包集合聲明語句中已經(jīng)聲明的。

一個簡單的包集合實例如下:3.3.5庫

所有的VHDL設(shè)計元素經(jīng)過編譯后最終都會包含在庫中,庫和包集合構(gòu)成了VHDL工程數(shù)據(jù)的管理結(jié)構(gòu),這個管理結(jié)構(gòu)類似于操作系統(tǒng)中文件夾和子文件夾的結(jié)構(gòu),如圖3.15所示。圖3.15庫和包集合構(gòu)成的管理結(jié)構(gòu)庫中包含了編譯后的數(shù)據(jù)的集合,這些數(shù)據(jù)包括實體定義、構(gòu)造體定義、配置定義和包集合定義。

我們在之前的示例代碼中經(jīng)常以“l(fā)ibraryIEEE;”開頭,這個語句的含義就是將IEEE庫包含到設(shè)計文件中。庫的描述結(jié)構(gòu)為:

library庫名稱;

將庫文件包含到設(shè)計文件中后,設(shè)計單元內(nèi)的語句就可以使用庫中的數(shù)據(jù),這一點和C語言中庫的概念是一致的。

VHDL設(shè)計中可以存在多個不同的庫,這些庫大致可以歸為5類:IEEE庫、STD庫、ASIC庫、WORK庫和用戶自定義庫?!?IEEE庫:包含了“STD_LOGIC_1164”、“STD_LOGIC_ARITH”和“STD_LOGIC_UNSIGNED”等包集合,這些包集合定義了一些工程設(shè)計中常用的數(shù)據(jù)類型等的定義。

●?STD庫:VHDL的標準庫,庫中有標準的“STANDARD”包集合。

●?ASIC庫:各公司為了使用VHDL語言進行門級仿真而提供的ASIC邏輯門庫。

●?WORK庫:類似于項目管理文件夾,項目中設(shè)計的所有單元都存放于這個庫中。

●??用戶自定義庫:用戶自行開發(fā)的庫,用于包含多個實體中共用的包集合和實體等。

VHDL語言中,庫與庫之間是相互獨立的,不能互相嵌套。其中WORK庫和STD庫是工程設(shè)計中的每個設(shè)計單元都要用到的庫,因此設(shè)計過程中可以不用標準格式說明。

通常在工程設(shè)計中庫和包集合是聯(lián)合使用的,如在之前的VHDL代碼實例中經(jīng)常用到的開頭:

libraryIEEE;

useIEEE.STD_LOGIC_1164.all;

這個開頭中“l(fā)ibraryIEEE”聲明將IEEE庫包含進來,“useIEEE.STD_LOGIC_1164.all”表示使用IEEE庫中STD_LOGIC_1164包集合的所有(all)定義。另外一個簡單的實例如圖3.16所示。圖3.16library和package使用實例

3.4VHDL語言的對象和數(shù)據(jù)類型

3.4.1VHDL語言的對象類型

在VHDL語言中,可以被賦值的都稱為對象(Object)。對象有很多種,常用的有端口(Port)、常量(Constant)、信號(Signal)、變量(Variable)。

這里,首先給出一個簡單的例子,讀者可以對照例子中的代碼理解這些對象。

1.端口(Port)

端口定義了實體的信號傳遞接口,在3.3.1節(jié)介紹實體的定義時,已經(jīng)對端口做了介紹。在端口的定義中,數(shù)據(jù)類型是必不可少的一部分。

常用的端口類型有輸入(Input)、輸出(Output)、雙向(Inout)和緩沖輸出(Buffer)四種,其中Input、Inout和Buffer端口可以對其他對象賦值,Output、Inout和Buffer可以被其他對象賦值。

2.常量(Constant)

常量是一個固定的值。常量在被創(chuàng)建時就被賦值為一個固定的值,并且常量的值在使用過程中只能對其他對象賦值,不能被修改。常量使代碼更容易閱讀和維護。常量可以在結(jié)構(gòu)體、包集合、實體、塊語句、過程語句和子函數(shù)中聲明,在結(jié)構(gòu)體中聲明的常量是本地常量,只能在結(jié)構(gòu)體內(nèi)部使用。

常量聲明的結(jié)構(gòu)為:

constant常量名稱:數(shù)據(jù)類型:=常量表達式

例如:

constantCPU_ADDR_MSB:integer:=32;

constantMASK:std_logic_vector:="00001111"

3.變量(Variable)

變量是用于存儲信息的一種對象。變量在被創(chuàng)建時也可以賦初始值,但與常量相反,變量在使用過程中既可以對其他對象賦值,也可以被修改。

變量是一個局部量,不能在結(jié)構(gòu)體中聲明,而只能在進程語句(Process)、函數(shù)語句(Function)和過程語句(Procedure)中聲明。

變量聲明的結(jié)構(gòu)為:

variable變量名稱:數(shù)據(jù)類型[:=初始值表達式]

例如:

variableCOUNT:INTEGER;

variableV:STD_LOGIC_VECTOR(3downto0):="0101";

variableW:INTEGER

range0to7:=7;在VHDL中,變量在綜合后可以是一個連線(Wire),也可以是一個寄存器(register),綜合的結(jié)果取決于變量在時序電路中是否用于保存信號值。這一靈活性也使得變量在使用過程中經(jīng)常引發(fā)錯誤,例如功能仿真的結(jié)果與綜合后的結(jié)果不一致的情況,所以在使用變量時要格外小心。

變量用“:=”符號進行賦值操作,例如:

V:="0111";

W:=5;

COUNT:=W+16;

另外,雖然變量可以賦初始值,但是在綜合時,綜合器會將初始值忽略掉,因此在使用過程中也要特別注意。

4.信號(Signal)

信號是電路底層硬件單元連接的抽象。在VHDL中,信號可以用于在結(jié)構(gòu)體中的不同并發(fā)語句之間傳遞信息,也可以通過端口與其他實體傳遞信息。從某種意義上講,端口也是信號的一種,但是被限定了輸入/輸出特性,因此也可以通過創(chuàng)建端口來創(chuàng)建一個信號,而端口的賦值方式也與信號相同。

信號可以在實體(Entity)、結(jié)構(gòu)體(Architecture)和塊語句(Block)中聲明,不能在進程(Process)語句、函數(shù)語句(Function)和過程語句(Procedure)中聲明,但可以在進程(Process)、函數(shù)(Function)和過程(Procedure)中使用。信號的聲明結(jié)構(gòu)與變量類似:

signal信號名稱:數(shù)據(jù)類型[:=初始值表達式];

例如:

signalA,B:BIT;

signalLBUS:INTEGER:?=

8;

與變量相同,信號在聲明結(jié)構(gòu)中被賦予的初始值,在綜合時也會被忽略。

信號采用“<=”符號進行賦值操作,例如:

A<='0';

LBUS<=16;由于信號本身是底層硬件單元連接的抽象,因此,類似于信號在連線上有傳輸時延,信號在數(shù)值傳遞的過程中也可以加入延時,例如兩個信號A和B,B的值經(jīng)過5ns的延時后傳遞到A,賦值語句可以寫為:

A<=Bafter5ns;

但必須明白,像“after5ns”這樣的語句,在底層電路是根本無法實現(xiàn)的,因此,延時語句只在行為建模時起作用,而在綜合時也會被完全忽略。

從變量和信號的聲明和定義看,很容易將這兩種對象混淆,但實際上,這兩種對象有明顯的區(qū)別,這些區(qū)別在以后的工程實踐中可以慢慢體會。

1)聲明和使用位置不同

變量只能在進程語句(Process)、函數(shù)語句(Function)和過程語句(Procedure)內(nèi)聲明,也只能在這些語句內(nèi)部使用,因此是一個局部對象。

信號可以在實體(Entity)、結(jié)構(gòu)體(Architecture)和塊語句(Block)中聲明,在進程(Process)、函數(shù)(Function)和過程(Procedure)中使用,因此可以在不同的進程之間傳遞信息,是一個全局對象。

2)賦值符號和延遲不同

變量用“:=”賦值,信號用“<=”賦值。

變量被賦值時,可以被看做是賦值符號右側(cè)表達式的代名詞,在使用變量時,可以直接用其所代的表達式替代。如果賦值的過程被分為獲取數(shù)據(jù)值、數(shù)值計算、用計算的結(jié)

果進行賦值三個步驟,那么變量在賦值的過程中,第三步“用計算的結(jié)果進行賦值”這個操作是即時的,沒有延時。而信號是物理單元的抽象,因此第三個步驟的操作是有時延的。3.4.2VHDL語言的數(shù)據(jù)類型

VHDL對類型的要求很嚴格,如上所述,所有的端口、常量、變量和信號在聲明時都要顯式地定義其對應(yīng)的數(shù)據(jù)類型。不同類型之間的數(shù)據(jù)不能直接賦值,數(shù)據(jù)類型相同,而位長不同時也不能直接代入。因此,熟練掌握各種數(shù)據(jù)類型對于用VHDL語言編程至關(guān)重要。

VHDL中定義了很多種數(shù)據(jù)類型,這些數(shù)據(jù)類型大致可以分為五種:

●標量類型(ScalarType)

●復(fù)合類型(CompositeType)

●存取類型(AccessType)

●文件類型(FilesType)

●用戶定義的子類型(SubTypes)

1.標量類型

標量類型是VHDL中最基本的類型,用于描述一個單值數(shù)據(jù)對象。屬于標量類型的數(shù)據(jù)類型有以下幾種:

●位型(BIT)

●布爾型(BOOLEAN)

●整型(INTEGER)

●實型(REAL)

●物理型

●符號型(CHARACTER)

●標準邏輯類型(STD_LOGIC)

●枚舉類型(ENUMERATE)

●錯誤等級(SEVERITY_LEVEL)

1)位(BIT)

BIT型是數(shù)字邏輯中最基本的邏輯形式,BIT型在STD庫中有明確定義,其定義如下:

typeBITis('0','1');

從上面的定義可以看出,BIT類型的數(shù)據(jù)只能取'0'和'1'兩個值,是二值系統(tǒng)中的最基本單元,分別表示低電平和高電平。

一個位型數(shù)據(jù)的實例如下:

signalX,Y,Z:BIT;

X<='0';

Y<='1';

Z<=XandY;

2)布爾(BOOLEAN)

BOOLEAN型相對于BIT型抽象層次更高,BOOLEAN型的定義如下:

typeBOOLEANis(FALSE,TRUE);

從定義上看,BOOLEAN類型類似于BIT類型,一個BOOLEAN量也具有兩種狀態(tài),F(xiàn)ALSE或者TRUE。但它和位型不同,它沒有數(shù)值的含義,也不能進行算術(shù)運算,只能作為關(guān)系運算的結(jié)果,在判斷語句中判斷使用,例如:

ifSEL='1'…

ifF>=G…

這些語句都將產(chǎn)生BOOLEAN型的結(jié)果。一個BOOLEAN型數(shù)據(jù)的實例如下:

signalCOND:BOOLEAN;

ifCONDthen

3)整型(INTEGER)

VHDL中的INTEGER數(shù)據(jù)與C語言中的整型數(shù)據(jù)定義相同。VHDL中INTEGER數(shù)據(jù)的表示范圍為-(231-1)~231-1,即-2147483647~2147483647。INTEGER型的定義如下:

typeINTEGERisrange-2147483647to2147483647雖然INTEGER類型的數(shù)據(jù)在底層電路中也是用一系列二進制位表示的,但是在使用INTEGER類型時,不能直接對數(shù)據(jù)的比特位進行操作,而必須使用轉(zhuǎn)換函數(shù)將INTEGER數(shù)據(jù)轉(zhuǎn)換為位矢量類型。不過,目前一些公司的綜合器已經(jīng)不受這個約束的限制。

一個INTEGER類型數(shù)據(jù)的實例如下:

signalINT_S:INTEGER;

signalA:INTEGERrange0to7;

signalB:INTEGERrange15downto0;

A<=5;

B<=12;通常INTEGER類型的數(shù)據(jù)在定義時,都要用“range”語句給出數(shù)據(jù)的取值范圍,數(shù)據(jù)在后續(xù)使用過程中不能超出此范圍?!皉ange”定義的范圍必須在-2147483647~2147483647范圍內(nèi)。

4)實型(REAL)

VHDL語言中,實型REAL也叫浮點型Floating,REAL數(shù)據(jù)是通常的數(shù)值運算中浮點型的抽象,它的數(shù)值范圍為-1038~1038。在VHDL中沒有定義REAL數(shù)據(jù)的精度,但這個精度至少可以達到6個比特位。使用REAL類型數(shù)據(jù)時要注意,很多公司的綜合工具都不支持REAL類型的數(shù)據(jù)。在VHDL中,通常采用用戶自定義的方式來定義一個REAL類型的數(shù)據(jù),例如:

typeCAPACITYisrange-25.0to25.0;

signalSIG_1:CAPACITY:=3.0;

SIG_1<=5.6;

其中,CAPACITY是用戶自定義的一種REAL型的數(shù)據(jù)類型。

5)物理型

物理型數(shù)據(jù)用于表示一些物理量,如重量、長度、時間或電壓值等等,用戶可以根據(jù)工程需要定義一些物理數(shù)據(jù)類型。完整的物理型數(shù)據(jù)包含數(shù)值和單位兩部分,在定義一個物理型數(shù)據(jù)類型時,必須先給出一個基準單位,其他的單位也必須是基準單位的倍數(shù)。VHDL中只定義了一種物理類型TIME。TIME類型用于對延時等時間參數(shù)建模,VHDL中TIME類型的定義如下:

VHDL-93除了上述的字符外,還預(yù)定義了一些其他字符,共支持256個字符,這些字符中不能打印的字符用標識符給出。

7)標準邏輯類型(STD_LOGIC)

在IEEE標準庫的STD_LOGIC_1164包集合中,定義了STD_LOGIC數(shù)據(jù)類型,與BIT類型相似,STD_LOGIC也是表示單個數(shù)字信號邏輯的。STD_LOGIC類型的定義如下:上述的定義中,首先定義了STD_ULOGIC類型,STD_LOGIC類型是經(jīng)過RESOLVED函數(shù)處理過的STD_ULOGIC類型,但STD_LOGIC和STD_ULOGIC可以取值的數(shù)值集合是相同的,這里我們不對這兩種類型做詳細介紹,可以簡單地認為兩種類型是一致的。

從類型的定義可以看出,STD_LOGIC表現(xiàn)的狀態(tài)就是實際的數(shù)字電路在輸入/輸出時所呈現(xiàn)的狀態(tài),它比BIT型所描述的邏輯狀態(tài)更完整。不過,定義中的Don’tcare表示不重要的邏輯,是什么狀態(tài)都無所謂,這在真實邏輯中是不存在的。

8)枚舉類型(ENUMERATE)

在VHDL中,也支持類似于其他編程語言中常用的枚舉類型。使用枚舉類型可以使工程師在更高的抽象層次上進行建模,也可以使程序代碼簡便易懂,這一點在狀態(tài)機和復(fù)雜系統(tǒng)的描述中尤其有用。

枚舉類型的描述結(jié)構(gòu)為:

type類型名稱is(元素,元素,…);

事實上,在上述其他數(shù)據(jù)類型的介紹中已經(jīng)多次使用的枚舉類型,BIT型、BOOL型、CHARACTER型和STD_LOGIC型都是用這種結(jié)構(gòu)定義的。

9)錯誤等級(SEVERITY_LEVEL)

錯誤等級用于表征系統(tǒng)的運行狀態(tài),有四種狀態(tài)可用:NOTE(注意)、WARNING(警告)、ERROR(錯誤)和FAILURE(失敗)。

錯誤等級的描述結(jié)構(gòu)為:

type

SEVERITY_LEVEL

is(NOTE,WARNING,ERROR,FAILURE);

錯誤等級也是在標準庫中用枚舉類型的方式預(yù)定義的,在系統(tǒng)仿真過程中可以用這四種狀態(tài)來提示系統(tǒng)當(dāng)前的運行狀態(tài)。

SEVERITY_LEVEL通常與ASSERT語句配合使用,讀者可以參照圖3.33的實例了解SEVERITY_LEVEL類型數(shù)據(jù)的使用方法。

2.復(fù)合類型

復(fù)合型的數(shù)據(jù)是指由多個單值數(shù)據(jù)組合而成的數(shù)據(jù),復(fù)合型數(shù)據(jù)以向量、數(shù)組或記錄的形式存在。屬于復(fù)合類型的數(shù)據(jù)有以下幾種:

●位矢量型(BIT_VECTOR)

●標準邏輯矢量型(STG_LOGIC_VECTOR)

●字符串型(STRING)

●數(shù)組型(ARRAY)

●記錄型(RECORD)

1)位矢量型(BIT_VECTOR)

位矢量型是由多個位型數(shù)據(jù)組合起來的一組位數(shù)據(jù),在VHDL的標準STD包集合中,BIT_VECTOR的定義如下:

typeBIT_VECTORisARRAY(NATURALrange<>)ofBIT;

這里我們不需要關(guān)心NATURALrange<>的含義。

位矢量在定義和使用時,用雙引號括起來,例如:

signalA_WORD:bit_vector(7downto0):="01011100";

A_WORD<=X?"AC";其中,X"A"的前綴X表示后面的數(shù)是十六進制數(shù),"A"表示十六進制數(shù)的值。BIT_VECTOR可以用"_"符號來分隔數(shù)值位,例如上面例子中,A也可以這樣賦值:

A_WORD<="0101_1100";

這種賦值方法與上例中的賦值方法得到的效果是相同的。

2)標準邏輯矢量型(STD_LOGIC_VECTOR)

標準邏輯矢量型是由多個標準邏輯數(shù)據(jù)組合起來的,在STD_LOGIC_1164包集合中,STD_LOGIC_VECTOR的定義如下:

type

STD_LOGIC_VECTOR

is

ARRAY(NATURAL

range<>)of

STD_LOGIC;

STD_LOGIC_VECTOR的定義和使用方式與BIT_VECTOR的方式相同,也要用雙引號括起來,例如:

signalB_DATA:STD_LOGIC_VECTOR(3downto0):="0011";

B_DATA<="1100";

3)字符串型(STRING)

字符串類型是由多個字符類型的數(shù)據(jù)組合起來的,在VHDL的標準STD包集合中,STRING的定義如下:

type

STRING

is

ARRAY?(POSITIVE

range<>)ofCHARACTER;

字符串型數(shù)據(jù)在定義和使用時也要用雙引號括起來,例如:

variableMY_STRING:STRING?(1to11);

MY_STRING:="Test_string"

字符串類型常用于程序的提示或說明,使用字符串時要注意,字符串類型的數(shù)據(jù)對大小寫是敏感的,“xxxx”和“XXXX”是不同的。

4)數(shù)組型(ARRAY)

數(shù)組型是由多個相同類型的數(shù)據(jù)組成的集合,組成集合的數(shù)據(jù)類型可以是任意的。VHDL支持多維數(shù)組,但有一些綜合器只支持一維數(shù)組。數(shù)組中的數(shù)據(jù)可以通過索引值獲取,索引值是INTEGER類型的,它的范圍取決于數(shù)組中元素的個數(shù)和順序。圖3.17數(shù)組賦值示意圖數(shù)組也可以采用一種便捷的方式進行賦值,即聯(lián)合賦值。聯(lián)合賦值不僅在數(shù)組中可以使用,多個標量對象在賦值時也可以采用這種方式。下面舉一個簡單的例子說明這種賦值方式:

signalH_BYTE,L_BYTE:STD_LOGIC_VECTOR(0to7);

signalQ_OUT:STD_LOGIC_VECTOR(31downto0);

signalA,B,C,D:STD_LOGIC;

signalWORD:STD_LOGIC_VECTOR(3downto0);

(A,B,C,D)<=WORD;

WORD<=(2=>'1',3=>D,others=>'0');

Q_OUT<=(others=>'0');

WORD<=(A,B,C,D);

H_BYTE<=(7|6|0|1=>'1',2to5=>'0');

使用聯(lián)合賦值時,出現(xiàn)在賦值符號左側(cè)的聯(lián)合體只能由標量類型組成,如上述例子中對A,B,C,D聯(lián)合賦值的情況,賦值符號兩側(cè)的元素個數(shù)必須相等,上例中“others”表示對所有未賦值的位賦予給定的默認值。

在工程應(yīng)用中,大型的數(shù)組(即索引值范圍比較大的數(shù)組)一般用變量或常量定義,用信號定義時,會影響仿真速度。圖3.18TX_PACKET的組成結(jié)構(gòu)

3.文件類型(File)

VHDL中的文件類型是由某種類型的數(shù)據(jù)組成的數(shù)據(jù)流,可以在仿真中讀入和寫出,類似于C語言中的文件類型。目前常用的文件類型只有TEXT類型,IEEE的TEXTIO包集合中包含了TEXT文件常用的一些讀寫函數(shù),方便設(shè)計者在開發(fā)時調(diào)用。

VHDL-87和VHDL-93中文件的描述結(jié)構(gòu)不同,例如:

4.用戶定義的子類型

除了上述VHDL中預(yù)定義的標準類型外,用戶可以根據(jù)工程設(shè)計的需要,修改已定義數(shù)據(jù)類型的范圍限定,形成新的數(shù)據(jù)類型,這種類型稱為子類型(subtype)。子類型的定義結(jié)構(gòu)如下:

subtype子類型名稱is已定義類型名稱;

例如:

subtypeMY_INTisintegerrange0to255;

subtypeSMALL_INTisMY_INTrange5to30;

再如:

typeMY_STATEis(

LOAD,JUMP,ADD,SUB,DIV,MULT,STORA,STORB);3.4.3不同數(shù)據(jù)類型之間的轉(zhuǎn)換

以上給出了多種VHDL中常用的數(shù)據(jù)類型,用這些數(shù)據(jù)類型定義的對象在賦值時都必須遵守數(shù)據(jù)賦值的規(guī)范,不同類型之間的數(shù)據(jù)不能賦值,相同類型不同位長的數(shù)據(jù)之間也不能相互賦值。但這樣會很不方便,因此IEEE的一些包集合中給出了一些數(shù)據(jù)類型之間的轉(zhuǎn)換函數(shù),不同類型之間的數(shù)據(jù)可以先經(jīng)過轉(zhuǎn)換函數(shù)轉(zhuǎn)換為相同類型,然后進行賦值。

表3.2給出了一些常用的轉(zhuǎn)換函數(shù)名稱及其功能。表3.2VHDL中常用轉(zhuǎn)換函數(shù)下面舉幾個簡單的例子:

signalA:STD_LOGIC_VECTOR(7downto0);

signalB:INTEGERrange0to200;

signalMY_ADDRESS:STD_LOGIC_VECTOR(31downto0);

A<=CONV_STD_LOGIC_VECTOR(B,8);

B<=CONV_INTEGER(A)

MY_ADDRESS<=CONV_STD_LOGIC_VECTOR(X"000027AC");

注意:在使用這些函數(shù)的時候,一定要在文件開始將IEEE庫和函數(shù)所在的包集合包含進來。 3.5VHDL語言運算操作符

VHDL中有5種運算操作符,分別為邏輯運算符(Logical)、關(guān)系運算符(Relational)、算術(shù)運算符(Arithmetic)、移位運算符(Shift)和并置運算符(Concatenation),其中移位運算符是VHDL-93中新加的運算符。在運算過程中將操作符作用于操作數(shù),完成計算。操作符標識需要進行的計算,操作數(shù)標識用于計算的數(shù)據(jù)。使用操作符的過程中要注意,所有的操作符都是對應(yīng)于確定的數(shù)據(jù)類型的,例如,VHDL內(nèi)嵌的算術(shù)操作符就不能對BIT_VECTOR和STD_LOGIC_VECTOR類型的數(shù)據(jù)進行運算。IEEE的STD_LOGIC_ARITH包集合對這類情況進行了擴展,加入了相應(yīng)的子程序,供設(shè)計者調(diào)用。因此,在程序中如果要對兩個BIT_VECTOR或STD_LOGIC_VECTOR的數(shù)據(jù)進行算術(shù)運算,就需要將STD_LOGIC_ARITH包集合包含進來。

表3.3中列出了VHDL中支持的運算操作符,與C語言類似,運算操作符也有優(yōu)先級。表3.3操作符及優(yōu)先級

1.邏輯運算符

VHDL中共有7種邏輯運算符,其中xnor是在VHDL-93中新定義的,見表3.4。表3.4邏?輯?運?算?符邏輯運算符可對BOOLEAN、BIT、BIT_VECTOR、STD_LOGIC和STD_LOGIC_VECTOR的數(shù)據(jù)對象做運算。其中,not是單目運算符,其他為雙目運算符。在計算時,運算符兩側(cè)的數(shù)據(jù)類型必須相同。

用邏輯運算符運算的實例如下:

signalA,B,C:BIT_VECTOR(3downto0);

signalD,E,F,G:STD_LOGIC_VECTOR(1downto0);

signalH,I,J,K:BIT;

signalL,M,N,O,P,Q:BOOLEAN;

A<=BandC;

D<=EorForG;

H<=(InandJ)nandK;

L<=(MxorN)and(OxorP);通常,在一個表達式中使用多個不同的操作符時,要用括號標明操作符的優(yōu)先級。而如果多個操作符相同,則可以不用括號標明。上例中給出了對應(yīng)的實例。

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

VHDL中有6種關(guān)系運算符,所有的關(guān)系運算符都返回BOOLEAN類型的結(jié)果,見表3.5。表3.5關(guān)?系?運?算?符關(guān)系運算符中,“=”和“/=”可以對所有類型的數(shù)據(jù)運算,而其他的操作符只能對枚舉類型、整數(shù)類型、枚舉類型的一維數(shù)組或整數(shù)等類型的數(shù)據(jù)做運算。在運算時,符號兩邊的數(shù)據(jù)類型必須相同,但數(shù)據(jù)的位數(shù)不一定相同。位數(shù)不同的兩個數(shù)據(jù)作比較時需要注意,VHDL中的數(shù)組類型(包括BIT_VECTOR和STD_LOGIC_VECTOR)的比較是按照類似于字母排序的方式進行的,排序時從數(shù)組最左邊的元素開始對比,直至發(fā)現(xiàn)第一個不同的元素,排在前面的數(shù)小于排在后面的數(shù),舉一個簡單的例子,如“101011”和“1011”的比較,兩個數(shù)的前3位都相同,因為“1011”的第四位為“1”而“101011”的第四位為“0”,因此“1011”>“101011”成立,如圖3.19所示。圖3.19不同位長數(shù)據(jù)的比較另外一種情況,如果短數(shù)組剛好是長數(shù)組的前面一部分,那么短數(shù)組在排序時排在長數(shù)組的前面,也就是短數(shù)組的值小于長數(shù)組的值,例如“101”就小于“101000”。

3.移位運算符

VHDL-93中新定義了6種移位運算符,運算符的含義及示意圖如表3.5所示。表3.5移?位?運?算?符算術(shù)向左移位時,填入的位值為最后一個位值;算術(shù)向右移位時,填入的位值為第一個位值;邏輯向左和邏輯向右移位時,默認新填入的位值都為0;向左旋轉(zhuǎn)時,填入的位值為第一個位值;向右旋轉(zhuǎn)時,填入的位值為最后一個位值。

舉一個簡單的例子,如果A?=?"10010101",則

Asll2

為 "01010100"

Asrl3

為 "00010010"

Asla3

為 "10101111"

Asra2為 "11100101"

Arol3

為 "10101100"

Aror5為 "10101100"移位運算符在使用時要注意,雖然運算符在VHDL-93中已經(jīng)定義,但在IEEE的包集合中,只定義了SIGNED和UNSIGNED類型的移位運算操作符,對于其他數(shù)據(jù)類型,目前還沒有定義。如果在綜合器或仿真器中要對其他類型的數(shù)據(jù)使用移位操作符,可以嘗試換一種寫法描述移位,例如:

Asll2

描述為A<=A(5downto0)&"00";

Asrl3描述為A<=“000”&A(7downto3);

Asla3描述為A<=A(4downto0)&A(0)&A(0)A(0);

Asra2描述為A<=A(7)&A(7)&A(7downto2);

Arol3描述為A<=A(4downto0)&A(7downto5);

Aror5描述為A<=A(4downto0)&A(7downto5);

4.算術(shù)運算符

VHDL中有10種算術(shù)運算符,如表3.6。表3.6算?術(shù)?運?算?符算術(shù)運算符中正“+”和負“-”是單目運算符,操作數(shù)可以為整數(shù)、實數(shù)和物理量等類型。

加法和減法操作符兩邊必須是相同類型的數(shù)據(jù),操作數(shù)也可以為整數(shù)、實數(shù)和物理量。乘除法的操作數(shù)可以同為整數(shù)或?qū)崝?shù),物理量可以被整數(shù)或?qū)崝?shù)相乘或相除,結(jié)果仍為一個物理量。物理量除以同一類型的物理量結(jié)果為一個整數(shù)量。求模和取余的操作數(shù)必須都為整數(shù)類型。指數(shù)運算符的左側(cè)操作數(shù)可以是任意整數(shù)或?qū)崝?shù),右側(cè)操作數(shù)應(yīng)為整數(shù)。我們之前提到過,VHDL并沒有預(yù)定義STD_LOGIC_VECTOR和BIT_VECTOR類型的加減法運算操作符,而IEEE在STD_LOGIC_ARITH包集合中對數(shù)組的加減法運算等操作符做了重載。因此,要在代碼中對這些數(shù)組類型的數(shù)據(jù)做加減運算,必須聲明使用STD_LOGIC_ARITH包集合。而且在使用時,運算符兩端的數(shù)組位長必須相等。

算術(shù)運算符中真正能夠綜合的運算符只有“+”、“-”和“*”,對于“/”、“mod”、“rem”,在分母為2的乘方次常數(shù)時,可以將這些操作用位運算實現(xiàn),因此是可以綜合的。

5.并置運算符

并置運算符“&”用于標量和復(fù)合類型數(shù)據(jù)的并置連接,使用并置運算符可以很靈活地將標量或數(shù)組組織在一起,形成更大的數(shù)組。例如:

signalA_VEC,B_VEC:STD_LOGIC_VECTOR(7downto0);

signalZ_VEC:STD_LOGIC_VECTOR(15downto0);

signalA_BIT,B_BIT,C_BIT,D_BIT:STD_LOGIC;

signalX_VEC:STD_LOGIC_VECTOR(2downto0);

signalY_VEC:STD_LOGIC_VECTOR(8downto0);

Z_VEC<=A_VEC&B_VEC;

--A_VEC作為Z_VEC的高8位,B_VEC作為Z_VEC的低8位

X_VEC<=A_BIT&B_BIT&C_BIT;

--X_VEC從高到低的3個位的值分別用A_BIT、B_BIT和C_BIT賦值

Y_VEC<=B_VEC&D_BIT;

--B_VEC作為Y_VEC的高8位,D_BIT作為Y_VEC的最低位

在前面數(shù)組類型的介紹中曾提及,數(shù)組的賦值可以采用聯(lián)合賦值的方式,這種方式其實也可以認為是并置運算的另一種形式。 3.6VHDL語言的描述語句

為了能夠?qū)τ布男袨樽龈咝У亟?,VHDL采用兩類描述語句,一類稱為并發(fā)描述語句(Concurrent),另一類稱為順序描述語句(Sequential)。

并發(fā)描述語句具有共時性,一個模塊的結(jié)構(gòu)體描述中,所有的并發(fā)語句都是同時進行的,與語句在程序中的位置無關(guān)。而順序語句具有順序性,它是按照語句在程序中的前后位置順序執(zhí)行的。下面舉一個簡單的例子說明結(jié)構(gòu)體描述中的并發(fā)描述語句與順序描述語句,如圖3.20所示。圖3.20并發(fā)語句與順序語句3.6.1有關(guān)規(guī)則和基本語句

1.VHDL命名規(guī)則

VHDL中使用的名稱,在命名時都需要符合VHDL的標識符命名規(guī)范,如實體名稱、端口名稱、結(jié)構(gòu)體名稱、變量名稱和信號名稱。

VHDL-87的短標識符命名規(guī)范為:

●標識符可以由英文字母、數(shù)字及下劃線組成;

●標識符必須以英文字母開頭;

●標識符不允許連續(xù)出現(xiàn)兩個下劃線;

●標識符最后一個字符不能是下劃線;

●標識符中英文字母不區(qū)分大小寫;

●?VHDL中的保留關(guān)鍵字不能作為標識符來使用。

VHDL的標識符中,英文字母不區(qū)分大小寫,例如CURRENT_STATE、current_state和CURRENT_state等是相同的,表示同一個對象。但VHDL中的常量字符不屬于標識符,因此大小寫是不同的。例如對STD_LOGIC類型或STD_LOGIC_VECTOR類型的信號代入高阻值“Z”時需要注意:

signalSIG_A:STD_LOGIC;

signalSIG_B:STD_LOGIC_VECTOR(2downto0);

SIG_A<='Z'; --正確

SIG_A<='z'; --錯誤,小寫z沒有定義;

SIG_B<="ZZZ"; --正確

SIG_B<="zzz"; --錯誤,小寫z沒有定義;

2.注釋標記方法

VHDL的注釋標記符為“--”,注釋的內(nèi)容為從“--”符號開始,一直到當(dāng)前行的結(jié)束。在之前的示例代碼中,我們已經(jīng)多次使用這一符號進行注釋,這里不再舉例說明。

需要注意,“--”對于VHDL程序是注釋符號,但一些其他工具經(jīng)常使用這個符號作為參數(shù)傳遞的接口。如我們經(jīng)??吹降摹?-synopsystranslate_on”和“--synopsystranslate_off”等。

3.信號代入語句

信號代入的語法結(jié)構(gòu)為:

目標信號名稱<=信號量表達式;信號的代入不是即時的。也就是說,即使信號量表達式發(fā)生了變化,最終賦予目標信號的值也不一定就是信號量的值。分為三種情況:

(1)如果信號只在一個進程中被賦值,而且在順序執(zhí)行一次Process中的語句時,只被賦值一次,那么信號的值就是被執(zhí)行語句中信號量表達式計算的結(jié)果值。

(2)如果信號只在一個進程中被賦值,但在進程內(nèi)部被多次賦值,那么只有最后一條賦值語句是起作用的。即使這個信號在進程中先被賦值,又被讀出,然后又被賦值,那么被讀出的信號的值仍是最后一次的賦值結(jié)果。

(3)如果信號在多個進程中被賦值,這些驅(qū)動器的結(jié)果將會被連接在一起,而形成多驅(qū)動的情況。有一些綜合器在遇到這種情況時將會報錯。信號在這種情況下的賦值情況與底層電路的實現(xiàn)方法有關(guān)。VHDL中給出了一種判決函數(shù),用于解決這種問題。我們將在并發(fā)描述語句的內(nèi)容中介紹這種判決函數(shù)。

所有在“ifCLK'eventandCLK='1'then…”或“ifrising_edge(CLK)then…”后描述的信號代入語句,在綜合后都會生成一個寄存器。上面例子綜合后的結(jié)果如圖3.21所示。圖3.21時序電路中信號代入的綜合結(jié)果前面講過,實體的端口在結(jié)構(gòu)體描述時被默認為信號,只是對信號的輸入/輸出屬性做了限定。這里舉一個例子,說明信號的賦值方法與最終綜合的電路之間的關(guān)系。

假設(shè)要實現(xiàn)的電路圖如圖3.22所示。圖3.22綜合后的目標電路通過分析可以得知,方法B的代碼與圖3.22中的電路是對應(yīng)的,方法A的實現(xiàn)明顯是錯誤的,Q為輸出端口,不能用“Q<=Q+1”對Q進行賦值。

那么方法C和方法D得到的綜合電路應(yīng)該是什么樣的?讀者可以對照圖3.23所示的電路圖對代碼進行分析。圖3.23綜合電路(a)方法C;(b)方法D

4.wait語句

wait語句是等待語句,?在進程(Process)的順序描述語句中用于控制進程狀態(tài)的變化。wait語句設(shè)定一定的條件,當(dāng)進程執(zhí)行到wait語句時,進程就掛起,直到設(shè)定的條件滿足時再繼續(xù)執(zhí)行。

wait語句可以設(shè)定4種不同的條件,分別為:

●?waiton:等待敏感信號變化;

●?waituntil:等待條件滿足;

●?waitfor:等待限定的時間;

●?wait:無限等待。

1)?waiton

waiton語句的語法結(jié)構(gòu)為:

waiton敏感信號[,敏感信號];

當(dāng)進程(Process)中的順序描述語句執(zhí)行到waiton語句時將會掛起,直到敏感信號中的任一信號發(fā)生變化,進程將結(jié)束掛起,繼續(xù)執(zhí)行waiton后的語句。

2)?waituntil

waituntil語句的語法結(jié)構(gòu)為:

waituntil條件表達式;

語法結(jié)構(gòu)中,條件表達式的結(jié)果為布爾量,表達式滿足條件時,返回“true”;不滿足時,返回“false”。進程在運行到waituntil語句時將會掛起,當(dāng)表達式中任何一個信號發(fā)生變化時,表達式的結(jié)果會被重新計算。如果計算結(jié)果為“true”,則繼續(xù)執(zhí)行后續(xù)語句;如果計算結(jié)果為“false”,則保持掛起狀態(tài)。

3)?waitfor

waitfor語句表示等待固定的時間,它的語法結(jié)構(gòu)為:

waitfor時間表達式;

時間表達式的含義是,表達式的運算結(jié)果為一個時間值。如果時間表達式是一個常量,則waitfor語句將等待固定的時間;如果時間表達式是一個計算式,那么計算的結(jié)果應(yīng)該是一個時間值。進程執(zhí)行到wait?for語句時將掛起,等待時間表達式所指示的時間長度,然后繼續(xù)執(zhí)行后續(xù)語句。

4)?wait

單獨地使用wait語句表示無限等待。最后依據(jù)wait表示進程將一直等待下去。

實際使用wait語句時,可以將上述的wait語句混合使用,混合使用的語法結(jié)構(gòu)為:

wait[on敏感信號列表][until條件表達式][for時間表達式];

當(dāng)on語句的敏感信號列表中的任一信號發(fā)生變化時,until語句的條件表達式將被重新計算。如果結(jié)果為“true”,則進程繼續(xù)執(zhí)行wait后的語句;如果結(jié)果為“false”,則進程保持掛起。

for語句相對比較獨立,只要wait語句已經(jīng)等待了時間表達式所指示的時間,則進程結(jié)束掛起,繼續(xù)執(zhí)行wait后的語句。在使用wait語句進行建模時需要注意,waiton、waitfor和wait語句是不可綜合的。waituntil語句只有在條件表達式為時鐘的邊緣時,如waituntilCLOCK='1'時,是可綜合的,否則也是不可綜合的。可綜合的語句在行為層次建模和RTL建模時都可以使用,不可綜合的語句只有在行為層次建模時可以使用。但是有一些綜合器,例如ISE中的XST,不支持對所有wait語句的綜合。

5.變量賦值語句

變量賦值語句用于改變一個變量的值,其語法結(jié)構(gòu)為:

變量名稱:=表達式;

變量賦值符號兩側(cè)的數(shù)據(jù)類型必須相同,賦值符號右側(cè)的表達式可以是常量、變量或信號。例如:根據(jù)變量在程序中使用情況的不同,變量綜合后的結(jié)果可能是連線(Wire)、鎖存器(Latch)或寄存器(Register)。在時序電路的順序描述語句中,如果變量在被賦值之前被讀取,那么綜合后將會產(chǎn)生一個寄存器;如果這種情況發(fā)生在組合邏輯電路中,那么綜合后將會產(chǎn)生一個鎖存器。

例如,下面的代碼:圖3.24變量綜合后的電路圖圖3.25另一種變量綜合后的電路圖3.6.2并發(fā)描述語句

1.進程語句(Process)

進程表示一個處理過程,在一個結(jié)構(gòu)體中可以包含多個進程。進程與進程之間是并行的,進程內(nèi)部包含一組順序描述語句,進程內(nèi)部的語句是按先后次序順序執(zhí)行的。

我們在之前的例程中曾多次用到進程語句,它的語法結(jié)構(gòu)如下:敏感變量列表中列出將會觸發(fā)進程執(zhí)行的所有信號,這些信號可以包含實體的接口信號,進程的敏感變量列表用括號括起來,如果進程有多個敏感信號;則信號之間用逗號隔開。如果process描述的是時序電路,則敏感列表中必須包含時鐘信號,而如果process描述的是組合邏輯,則敏感變量列表中應(yīng)包含全部的敏感信號,否則會引起行為仿真結(jié)果和綜合后結(jié)果不同的現(xiàn)象。

process的敏感信號列表與wait語句中的敏感信號是等價的,?process在執(zhí)行之前也要等待敏感信號的變化,因此process中對敏感信號的等待成為隱式等待,而wait語句的等待稱為顯式等待。VHDL中規(guī)定,如果進程中使用了wait語句,則process后不允許使用敏感變量列表。進程的聲明語句用于聲明在process內(nèi)部使用的函數(shù)、過程、類型定義、常量和變量。

順序描述語句是對進程行為功能的描述,進程每被觸發(fā)一次,進程內(nèi)的順序描述語句順序執(zhí)行一次。

這里再舉一個簡單的例子說明進程的用法:一個結(jié)構(gòu)體的多個進程之間是通過信號來傳遞信息的,而且進程之間只能用信號傳遞信息,因此通過信號連接的多個進程通常也被稱為VHDL的連接模型。

進程語句是可綜合VHDL語句中最有用的一條,但是并不是每個進程語句都是可以綜合的,為了使代碼有較高的性能,通常process語句用以下限定的模板進行編寫,設(shè)計者在工程設(shè)計中可以參考:

2.直接信號代入語句

直接信號代入語句即指信號代入語句。信號代入語句既可以在process語句中使用,作為順序描述語句的構(gòu)成部分,也可以在process外部使用,作為并發(fā)語句。例如:

3.條件式信號代入語句

條件式信號代入語句是if/else順序描述語句的并發(fā)表示形式。條件式信號代入語句的語法結(jié)構(gòu)為:●如果條件1滿足,則給目標信號賦值為表達式1;

●如果條件1不滿足,而條件2滿足,則給目標信號賦值為表達式2;

●如果條件1、2都不滿足,而條件3滿足,則給目標信號賦值為表達式3;

●如果條件1、2、…、n都不滿足,則給目標信號賦值

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論