版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二四年度智慧教育解決方案提供合同2篇
- 二零二五年度城市綠化工程捐款合同3篇
- 2025年度醫(yī)院病房窗簾定制與配送合同范本4篇
- 二零二五版文化娛樂產(chǎn)業(yè)內(nèi)部股東股權(quán)置換合同4篇
- 2025年度工業(yè)自動化生產(chǎn)線安裝調(diào)試協(xié)議4篇
- 二零二五年度門窗行業(yè)智能制造解決方案合同3篇
- 二零二五版拌合料生產(chǎn)設(shè)備采購與維護合同4篇
- 二零二五年度精密車床采購合同(含原裝配件供應(yīng))2篇
- 二零二五年度高等教育學(xué)生生活體驗合作協(xié)議4篇
- 2025年度房地產(chǎn)開發(fā)項目預(yù)售款分期支付合同4篇
- 鹽酸埃克替尼臨床療效、不良反應(yīng)與藥代動力學(xué)的相關(guān)性分析的開題報告
- 消防設(shè)施安全檢查表
- 組合結(jié)構(gòu)設(shè)計原理 第2版 課件 第6、7章 鋼-混凝土組合梁、鋼-混凝土組合剪力墻
- 建筑公司資質(zhì)常識培訓(xùn)課件
- 旅居管家策劃方案
- GB/T 26316-2023市場、民意和社會調(diào)查(包括洞察與數(shù)據(jù)分析)術(shù)語和服務(wù)要求
- 春節(jié)值班安全教育培訓(xùn)
- 帶狀皰疹護理查房
- 平衡計分卡-化戰(zhàn)略為行動
- 幼兒園小班下學(xué)期期末家長會PPT模板
- 幼兒教師干預(yù)幼兒同伴沖突的行為研究 論文
評論
0/150
提交評論