版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第4章硬件描述語言VerilogHDL
4.1HDL簡介4.2初步認(rèn)知4.3VerilogHDL基本知識(shí)4.4數(shù)據(jù)類型、操作符和表達(dá)式4.5數(shù)據(jù)流建模4.6行為級(jí)建模4.7結(jié)構(gòu)級(jí)建模4.8測試平臺(tái)及測試激勵(lì)的建立4.9良好的編程風(fēng)格本章主要介紹VerilogHDL語言的一些基本知識(shí),目的是使初學(xué)者能夠掌握HDL設(shè)計(jì)方法,初步了解并掌握VerilogHDL語言的基本知識(shí),能讀懂簡單的設(shè)計(jì)代碼并能進(jìn)行一些簡單設(shè)計(jì)的VerilogHDL建模。
4.1節(jié)介紹了HDL的一些基礎(chǔ)知識(shí),對比了VerilogHDL和VHDL語言,討論了硬件描述語言的發(fā)展趨勢。
4.2節(jié)中,在讀者沒有任何語法知識(shí)基礎(chǔ)的情況下,通過一個(gè)簡單的例子,讀者可看到程序的基本結(jié)構(gòu)及在Modelsim中進(jìn)行仿真的結(jié)果,使得讀者對VerilogHDL及其仿真有了初步的感性認(rèn)識(shí)。
4.3~4.7節(jié)介紹了VerilogHDL的基本語法知識(shí),討論了多種不同的建模風(fēng)格,是學(xué)習(xí)VerilogHDL語言需要掌握的知識(shí)內(nèi)容。
4.8~4.9節(jié)是在學(xué)習(xí)VerilogHDL基礎(chǔ)知識(shí)后,需要進(jìn)一步了解和注意的內(nèi)容。
4.1HDL簡介
20世紀(jì)80年代前,集成電路設(shè)計(jì)工程師只能采用代工廠提供的專用電路圖來進(jìn)行手工設(shè)計(jì)。對于復(fù)雜的數(shù)字邏輯電路,設(shè)計(jì)師從原理設(shè)計(jì)、功能設(shè)計(jì)、電路設(shè)計(jì)到版圖設(shè)計(jì)一般要經(jīng)歷一年以上的設(shè)計(jì)周期,其中僅版圖布線一環(huán),工程師就要花費(fèi)數(shù)周的時(shí)間才能完成。隨著大規(guī)模集成電路的研發(fā),集成數(shù)百萬邏輯門的電路變得非常復(fù)雜,很難通過傳統(tǒng)的面包板測試法驗(yàn)證設(shè)計(jì)的系統(tǒng)。在此基礎(chǔ)上,后端工程師開始尋找通過EDA(ElectronicDesignAutomation,電子設(shè)計(jì)自動(dòng)化)的設(shè)計(jì)方法將手工設(shè)計(jì)轉(zhuǎn)變?yōu)橛?jì)算機(jī)輔助設(shè)計(jì)方法。前端的工程師也希望使用一種標(biāo)準(zhǔn)的語言來進(jìn)行硬件的設(shè)計(jì),以提高設(shè)計(jì)的復(fù)雜度和可靠性,因此,HDL(HardwareDescriptionLanguage,硬件描述語言)應(yīng)運(yùn)而生。4.1.1關(guān)于硬件描述語言
隨著電子設(shè)計(jì)技術(shù)的飛速發(fā)展,設(shè)計(jì)的集成度、復(fù)雜度越來越高,集成度達(dá)億只晶體管以上的芯片已經(jīng)屢見不鮮,傳統(tǒng)的設(shè)計(jì)方法已滿足不了設(shè)計(jì)的要求。為使如此復(fù)雜的芯片變得易于被人腦理解,很有必要用一種高級(jí)語言來表達(dá)其功能,隱藏其具體實(shí)現(xiàn)的細(xì)節(jié)(類似于使用高級(jí)程序語言取代匯編語言一樣),對數(shù)字電路和數(shù)字邏輯系統(tǒng)能夠進(jìn)行形式化的描述,這就是硬件描述語言。
通過使用HDL和EDA工具進(jìn)行設(shè)計(jì)的優(yōu)勢非常明顯:數(shù)字邏輯電路設(shè)計(jì)者可利用HDL來描述自己的設(shè)計(jì)思想,然后利用EDA工具進(jìn)行仿真,再由邏輯綜合工具自動(dòng)綜合到門級(jí)電路,最后用ASIC或FPGA實(shí)現(xiàn)其功能。
HDL是EDA技術(shù)的重要組成部分,常見的HDL主要有VerilogHDL、VHDL、ABEL、AHDL、SystemVerilog和SystemC。其中VerilogHDL和VHDL在目前的EDA設(shè)計(jì)中使用最多,也獲得了幾乎所有主流EDA工具的支持。
采用HDL最顯著的意義在于:能夠通過基于語言的描述,對于正在進(jìn)行設(shè)計(jì)的電路自動(dòng)進(jìn)行綜合,而不用經(jīng)歷人工設(shè)計(jì)方法中那些費(fèi)力的步驟,如卡諾圖求最小邏輯等。
1.VerilogHDL
VerilogHDL是在使用最廣泛的C語言的基礎(chǔ)上發(fā)展起來的一種硬件描述語言。它是由GDA(GatewayDesignAutomation)公司在1983年末首創(chuàng)的,最初只設(shè)計(jì)了一個(gè)仿真與驗(yàn)證工具,之后又陸續(xù)開發(fā)了相關(guān)的故障模擬與時(shí)序分析工具。1985年,推出了它的第三個(gè)商用仿真器Verilog-XL,獲得了巨大的成功,從而使得VerilogHDL迅速得到推廣應(yīng)用。1989年,Cadence公司收購了GDA公司,1990年,Cadence公司公開發(fā)表了VerilogHDL,并成立了OVI(OpenVerilogInternational)組織來負(fù)責(zé)VerilogHDL語言的發(fā)展。1995年,制定了VerilogHDL的IEEE(TheInstituteofElectricalandElectronicsEngineers)標(biāo)準(zhǔn),即IEEE1364-1995。2001年,一個(gè)更加完善的VerilogHDL標(biāo)準(zhǔn)即IEEE1364-2001誕生了。
VerilogHDL用于從算法級(jí)、門級(jí)到開關(guān)級(jí)的多種抽象設(shè)計(jì)層次的數(shù)字系統(tǒng)建模,被建模的數(shù)字系統(tǒng)對象的復(fù)雜度可以是簡單的門,也可以是完整的數(shù)字電子系統(tǒng)。數(shù)字系統(tǒng)能夠按層次描述,并可在相同描述中顯式地進(jìn)行時(shí)序建模。
VerilogHDL語言具有下述描述能力:設(shè)計(jì)的行為特性、設(shè)計(jì)的數(shù)據(jù)流特性、設(shè)計(jì)的結(jié)構(gòu)組成以及包含響應(yīng)監(jiān)控和設(shè)計(jì)驗(yàn)證方面的時(shí)延和波形產(chǎn)生機(jī)制。此外,VerilogHDL語言提供了編程語言接口,通過該接口可以在模擬、驗(yàn)證期間從事外部訪問設(shè)計(jì),包括模擬的具體控制和進(jìn)行。VerilogHDL語言不僅定義了語法,而且對每個(gè)語法結(jié)構(gòu)都定義了清晰的模擬、仿真語義,能夠使用Verilog仿真器進(jìn)行驗(yàn)證。
VerilogHDL語言從C編程語言中繼承了多種操作符和結(jié)構(gòu)。VerilogHDL的核心子集非常易于學(xué)習(xí)和使用,這對大多數(shù)建模應(yīng)用來說已經(jīng)足夠了。使用同一種建模語言,就可對從最復(fù)雜的芯片到完整的電子系統(tǒng)進(jìn)行描述。
2.VHDL
VHDL的英文全稱是VeryHighSpeedIntegratedCircuitHardwareDescriptionLanguage,它于1983年由美國國防部(DOD)發(fā)起創(chuàng)建,由IEEE進(jìn)一步發(fā)展,并在1987年作為“IEEEstd1076”發(fā)布。從此,VHDL成為硬件描述語言的業(yè)界標(biāo)準(zhǔn)之一。1993年,IEEE對VHDL進(jìn)行了修訂(即IEEEStd1076-1993版本),從更高的抽象層次和系統(tǒng)描述能力上擴(kuò)展了VHDL的內(nèi)容。最新的VHDL版本是IEEEStd1076-2002。
創(chuàng)建VHDL的最初目標(biāo)是用于標(biāo)準(zhǔn)文檔的建立和電路功能模擬,其基本思想是在高層次上描述系統(tǒng)和元件的行為。到了20世紀(jì)90年代初,VHDL不僅可以作為系統(tǒng)模擬的建模工具,而且可以作為電路系統(tǒng)的設(shè)計(jì)工具,可以利用軟件工具將VHDL源碼自動(dòng)地轉(zhuǎn)化為以文本方式表達(dá)的基本邏輯元件連接圖,即網(wǎng)表文件,這種方法對于電路的自動(dòng)設(shè)計(jì)顯然是一個(gè)極大的推進(jìn)。
VHDL語言具有很強(qiáng)的電路描述和建模能力,能從多個(gè)層次對數(shù)字系統(tǒng)進(jìn)行建模和描述,從而大大簡化硬件設(shè)計(jì)任務(wù),提高設(shè)計(jì)效率和可靠性。VHDL具有與具體硬件電路無關(guān)和與設(shè)計(jì)平臺(tái)無關(guān)的特性,并且具有良好的電路行為描述和系統(tǒng)描述的能力,并在語言易讀性和層次化、結(jié)構(gòu)化設(shè)計(jì)方面表現(xiàn)出了強(qiáng)大的生命力和應(yīng)用潛力。因此,VHDL在支持各種模式的設(shè)計(jì)方法,如自頂向下與自底向上或混合方法方面,以及在面對當(dāng)今許多電子產(chǎn)品生命周期縮短,需要多次重新設(shè)計(jì)以融入最新技術(shù)、改變工藝等方面都表現(xiàn)出了良好的適應(yīng)性。
3.VerilogHDL與VHDL的對比
VerilogHDL和VHDL作為IEEE的工業(yè)標(biāo)準(zhǔn)硬件描述語言,得到了眾多EDA公司的支持,已成為事實(shí)上的通用硬件描述語言。
VHDL比VerilogHDL早幾年成為IEEE標(biāo)準(zhǔn),語法/結(jié)構(gòu)比較嚴(yán)格,因而編寫出的模塊風(fēng)格比較清晰,比較適合由較多的設(shè)計(jì)人員合作完成的特大型項(xiàng)目(100萬門以上)。而VerilogHDL獲得了較多的第三方工具支持,語法結(jié)構(gòu)比VHDL簡單,學(xué)習(xí)起來比VHDL容易,測試激勵(lì)模塊容易編寫。這兩種語言均可在不同抽象層次對電路進(jìn)行描述。抽象層次分為五個(gè)層次,分別為系統(tǒng)級(jí)、算法級(jí)、寄存器傳輸級(jí)、邏輯門級(jí)和開關(guān)電路級(jí)(如圖4-1所示)。
*VITAL:VHDLInitiativeTpwardsASICLibraries(面向ASIC的VHDL模型基準(zhǔn))。圖4-1VerilogHDL與VHDL建模能力的比較4.1.2VerilogHDL的特點(diǎn)
VerilogHDL充分保留了C語言簡潔、高效的編程風(fēng)格,其最大特點(diǎn)就是易學(xué)易用。如果有C語言的編程經(jīng)驗(yàn),那么就可以在較短時(shí)間內(nèi)快速學(xué)習(xí)和掌握。
VerilogHDL語言是一門標(biāo)準(zhǔn)硬件設(shè)計(jì)語言,采用標(biāo)準(zhǔn)的文本格式,與設(shè)計(jì)工具和實(shí)現(xiàn)工藝無關(guān),從而可以方便地進(jìn)行移植和重用,它具有多層次的抽象,適合于電子系統(tǒng)設(shè)計(jì)的所有階段。由于它容易被機(jī)器和人工閱讀,因此它支持硬件設(shè)計(jì)的開發(fā)、驗(yàn)證、綜合、測試以及硬件設(shè)計(jì)數(shù)據(jù)的交流,便于維護(hù)、修改和最終硬件電路的獲得。VerilogHDL的特點(diǎn)包括:
簡單、直觀和高效。
設(shè)計(jì)可以在多個(gè)層次上加以描述,從開關(guān)級(jí)、門級(jí)、寄存器傳輸級(jí)(RegisterTansferLevel,RTL)到算法級(jí)。
可以用多種不同方式或混合方式對設(shè)計(jì)建模。
開關(guān)級(jí)基本結(jié)構(gòu)模型可以使用內(nèi)置開關(guān)級(jí)原語進(jìn)行完整建模。
基本邏輯門可以使用內(nèi)置門級(jí)原語進(jìn)行完整建模。
提高了邏輯設(shè)計(jì)的效率,降低了設(shè)計(jì)成本,更重要的是縮短了設(shè)計(jì)周期。
多方位的仿真可以在設(shè)計(jì)完成之前檢測到其錯(cuò)誤,減少設(shè)計(jì)重復(fù)的次數(shù),使第一次投片便能成功實(shí)現(xiàn)芯片成為可能。
使檢測各種設(shè)計(jì)方案變得容易和方便,對方案的修改只需要修改HDL程序就行了,這比修改原理圖要容易得多。
由于具有以上這些特點(diǎn),VerilogHDL語言已經(jīng)被絕大多數(shù)的IC設(shè)計(jì)者所采用。4.1.3硬件描述語言的發(fā)展趨勢
數(shù)字邏輯電路的速度和復(fù)雜性正在迅速地增長,這就要求設(shè)計(jì)者從更高的抽象層次對電路進(jìn)行描述。這樣做的好處是設(shè)計(jì)者只需從功能的角度進(jìn)行分析設(shè)計(jì),由EDA工具來完成具體的實(shí)現(xiàn)細(xì)節(jié)。
由于邏輯綜合工具可以從RTL描述生成門級(jí)網(wǎng)表,因此目前基于HDL的主流設(shè)計(jì)方式是RTL級(jí)設(shè)計(jì)。行為級(jí)綜合工具允許直接對電路的算法和行為進(jìn)行描述,然后由EDA工具在各個(gè)設(shè)計(jì)階段進(jìn)行轉(zhuǎn)換和優(yōu)化,但這對EDA工具提出了更高的要求。系統(tǒng)級(jí)設(shè)計(jì)采用的另一種技術(shù)是在采用自頂向下的方法的同時(shí),結(jié)合自底向上的方法。設(shè)計(jì)者通過使用現(xiàn)有的VerilogHDL模塊、基本功能模塊或第三方提供的核心功能模塊來快速搭建系統(tǒng),以便進(jìn)行仿真。這種方法降低了開發(fā)費(fèi)用,縮短了開發(fā)周期。這種用于數(shù)字系統(tǒng)設(shè)計(jì)的預(yù)先設(shè)計(jì)好的電路功能模塊稱為IP(IntelligentProperty)。IP核在EDA技術(shù)和開發(fā)中越來越重要,是數(shù)字系統(tǒng)模塊化設(shè)計(jì)、規(guī)?;O(shè)計(jì)及快速開發(fā)的重要技術(shù)和發(fā)展趨勢。
4.2初步認(rèn)知
為了讓讀者更快地了解VerilogHDL,本節(jié)在沒有介紹任何VerilogHDL語法知識(shí)的情況下,舉了幾個(gè)簡單的編程例子;并通過實(shí)際操作,讓讀者看到仿真的過程與效果。希望讀者能很快對VerilogHDL及其仿真有較全面的感性認(rèn)識(shí)。
4.2.1門級(jí)風(fēng)格的描述
圖4-2是一個(gè)2選1數(shù)據(jù)選擇器(MUX)的電路結(jié)構(gòu)圖:圖4-22選1MUX的結(jié)構(gòu)圖以下使用內(nèi)置門原語對2選1MUX的結(jié)構(gòu)進(jìn)行門級(jí)風(fēng)格描述:
modulemux_str(out,a,b,sel);
inputa,b,sel; //輸入端口聲明
outputout; //輸出端口聲明
notgatel(net1,sel); //非門gate1中,net1是輸出,sel是輸入
andgate2(net2,a,net1); //與門gate2中,net2是輸出,a和net1是輸入
andgate3(net3,b,sel);
orgate4(out,net2,net3);
endmodule
該2選1MUX由1個(gè)非門、2個(gè)與門、1個(gè)或門構(gòu)成。net1、net2、net3則是門與門之間的連線;not、and、or是VerilogHDL內(nèi)置的基本門原件。4.2.2數(shù)據(jù)流風(fēng)格的描述
用數(shù)據(jù)流描述方式對一個(gè)設(shè)計(jì)建模的最基本的機(jī)制就是使用連續(xù)賦值語句。在連續(xù)賦值語句中,線網(wǎng)類型變量被賦予某個(gè)值,右邊表達(dá)式的操作數(shù)無論何時(shí)發(fā)生變化,表達(dá)式都重新計(jì)算,計(jì)算結(jié)果被賦予左邊表達(dá)式的線網(wǎng)類型變量。以下使用數(shù)據(jù)流描述方式描述2選1MUX:
modulemux_flow(out,a,b,sel);
inputa,b,sel;
outputout;
assignout=(sel)?b:a;
endmodule
如上代碼中,當(dāng)a、b、sel發(fā)生變化時(shí),out將同時(shí)發(fā)生變化。4.2.3行為風(fēng)格的描述
行為風(fēng)格為抽象層次更高的設(shè)計(jì)風(fēng)格,常用于復(fù)雜數(shù)字系統(tǒng)的頂層邏輯設(shè)計(jì)。行為風(fēng)格使用initial語句(語句只執(zhí)行一次)和always語句(重復(fù)執(zhí)行),只有變量類型數(shù)據(jù)能夠在這兩種語句中被賦值,所有initial語句和always語句在0時(shí)刻開始并發(fā)執(zhí)行。
以下使用行為風(fēng)格描述方式給2選1MUX建模:
modulemux_beha(out,a,b,sel);
inputa,b,sel;
outputout;
regout;
always@(a,b,sel) //a,b,sel為敏感事件,一旦發(fā)生變化,即觸發(fā)后面代碼的執(zhí)行
out=(sel)?b:a;
endmodule4.2.4測試平臺(tái)的編寫
編寫了功能實(shí)現(xiàn)的代碼,還需要編寫另一個(gè)模塊,模擬數(shù)據(jù)的輸入和輸出,測試和驗(yàn)證功能模塊的正確性,該模塊稱為測試平臺(tái)(testbench)。
以下測試平臺(tái)可用于驗(yàn)證前述的三個(gè)2選1MUX例子(門級(jí)風(fēng)格、數(shù)據(jù)流風(fēng)格、行為風(fēng)格):
moduletestMux; //測試模塊名稱為testMux
regpa,pb,psel;
wirepout;
mux_behatmux(pout,pa,pb,psel); //調(diào)用mux_beha模塊,按端口順序?qū)?yīng)方式連接tmux為實(shí)例名稱initial
begin
pa=0;pb=0;psel=0;//賦予初值
#5pa=1;//5個(gè)單位時(shí)間延遲后進(jìn)行賦值
#5pb=1;
#5pa=0;
#5psel=1;
#5pa=1;
#5pb=0;
#5pa=0;
end
initial
$monitor(“time=%t,a=%b,b=%b,sel=%b,out=
%b”,$time,pa,pb,psel,pout);//調(diào)用系統(tǒng)任務(wù)$monitor,當(dāng)pa、pb、psel、pout中任一個(gè)發(fā)生變化時(shí)就輸出顯示
endmodule
代碼中通過模塊“mux_beha”生成一個(gè)實(shí)例“tMux”,通過端口順序與測試平臺(tái)“testMux”進(jìn)行連接;中間從“begin”到“end”部分的代碼,實(shí)現(xiàn)每過5個(gè)單位時(shí)間改變一次輸入的值組合,實(shí)現(xiàn)“pa”、“pb”、“psel”的值按照“000-100-110-010-011-111-101-001”的順序發(fā)生變化。通過圖4-3,讀者可更直觀地看到功能模塊(mux_beha)和測試模塊(testMux)的連接關(guān)系。
初學(xué)者會(huì)對模塊、實(shí)例與測試平臺(tái)的關(guān)系產(chǎn)生困惑。也可以這么理解:把設(shè)計(jì)好的“mux_beha”模塊看做一個(gè)零件(可復(fù)用),而實(shí)例“tMux”就是從零件庫里取出一個(gè)“mux_beha”這種型號(hào)的零件,并命名為“tMux”;然后對這個(gè)零件進(jìn)行測試,按端口接線后,輸入不同的信號(hào),就可查看到輸出結(jié)果了;而測試平臺(tái)就是專門用來測試數(shù)據(jù)和接收測試結(jié)果的一個(gè)模塊(輸出結(jié)果也是通過測試平臺(tái)的仿真結(jié)果來查看的)。圖4-3模塊之間的連接4.2.5使用Modelsim進(jìn)行仿真
類似C程序的運(yùn)行需要一個(gè)編譯和運(yùn)行環(huán)境一樣,VerilogHDL程序的運(yùn)行與驗(yàn)證也需要相應(yīng)的運(yùn)行環(huán)境,在此使用業(yè)界著名的Modelsim軟件進(jìn)行仿真。
在此使用前述的代碼(2選1MUX模塊及測試平臺(tái)),在Modelsim中進(jìn)行仿真,驗(yàn)證運(yùn)行的結(jié)果。
1.新建VerilogHDL文件
新建文件“mux2x1.v”,用記事本(或其它文本編輯器)打開,輸入代碼并保存。以下代碼為前述行為風(fēng)格“mux_beha”模塊和測試平臺(tái)“testMux”模塊的代碼合并所得:使用“mux_beha”模塊建立2選1MUX,使用“testMux”模塊進(jìn)行測試。
modulemux_beha(out,a,b,sel);
inputa,b,sel;
outputout;
regout;
always@(a,b,sel)
out=(sel)?a:b;
endmodule
/* 以上為2選1MUX的代碼,使用“mux_beha”模塊
以下為測試平臺(tái)的代碼,使用“testMux”模塊 */
moduletestMux;
regpa,pb,psel;
wirepout;
mux_behatmux(pout,pa,pb,psel);
initial
begin
pa=0;pb=0;psel=0;
#5pa=1;
#5pb=1;
#5pa=0;
#5psel=1;
#5pa=1;
#5pb=0;
#5pa=0;
#5;
end
initial
$monitor("time=%t,a=%b,b=%b,sel=%b,
out=%b",$time,pa,pb,psel,pout);endmodule
2.使用Modelsim打開文件
在已安裝Modelsim軟件的電腦中,雙擊“mux2x1.v”文件,或點(diǎn)擊右鍵,在彈出菜單中的“打開方式”子菜單中選擇“Modelsim”,即可使用Modelsim軟件打開該文件。Modelsim軟件界面如圖4-4所示。
值得注意的是,這樣的建立和打開文件方式并不是規(guī)范的操作流程,在此為了更快地讓初學(xué)者對仿真有個(gè)初步認(rèn)識(shí),因此簡化了操作步驟。更詳細(xì)、更規(guī)范的操作可參考5.5節(jié)的內(nèi)容。圖4-4Modelsim軟件
3.編譯
選擇“Compile”菜單的“CompileAll”或工具欄的圖標(biāo),彈出如圖4-5所示的窗口,選擇“mux2x1.v”文件,點(diǎn)擊“Compile”;彈出是否創(chuàng)建名為“work”的庫的詢問框,選擇“Yes”;“Transcript”小窗口會(huì)提示編譯結(jié)果,編譯成功后,點(diǎn)擊“Done”按鈕關(guān)閉對話框。
4.選擇仿真對象
選擇“Simulate”菜單的“StartSimulation”或工具欄的
圖標(biāo),在彈出的對話框中選擇“work”庫下的“testMux”模塊,點(diǎn)擊“OK”,如圖4-6所示。圖4-5編譯文件圖4-6選擇仿真對象
5.配置仿真顯示內(nèi)容
如果僅僅想看程序的輸出文本,則不需進(jìn)行本操作。
如果希望同時(shí)顯示波形,則進(jìn)行以下配置:點(diǎn)擊“Objects”窗口,點(diǎn)擊右鍵,選擇“Add”→“ToWave”菜單中的“SignalsinRegion”命令,該操作配置在波形窗口顯示的內(nèi)容。操作后,“Wave”小窗口的Messages欄將顯示如圖4-7所示的內(nèi)容。但此時(shí)仿真還沒開始運(yùn)行,故沒有波形顯示。圖4-7選擇波形顯示內(nèi)容
6.運(yùn)行仿真并查看結(jié)果
選擇“Simulate”→“Run”菜單中的“Run-All”命令或工具欄的圖標(biāo),“Transcript”小窗口將顯示如圖4-8所示的運(yùn)行結(jié)果。
“Wave”小窗口將顯示波形圖,點(diǎn)擊“Zoom”工具欄圖標(biāo)
可調(diào)整波形的查看效果,如圖4-9所示。圖4-8“Transcript”窗口顯示運(yùn)行結(jié)果圖4-9仿真結(jié)果波形圖4.2.6VerilogHDL在電路綜合中的應(yīng)用
電路綜合過程就是將設(shè)計(jì)者建立的電路模型與基本邏輯單元庫相結(jié)合,得到可以實(shí)現(xiàn)設(shè)計(jì)目標(biāo)功能的電路的過程。本節(jié)中討論的2選1MUX電路,從一開始就給出了其電路圖,但試想如果是一個(gè)規(guī)模較大的設(shè)計(jì),以手工方式化簡卡諾圖或邏輯表達(dá)式,然后再畫出電路圖,那工作量是多么巨大!在使用HDL語言對設(shè)計(jì)進(jìn)行描述時(shí),可以不用畫出電路圖,而是通過綜合工具把HDL代碼轉(zhuǎn)換為相應(yīng)的電路設(shè)計(jì)。
如前述的2選1數(shù)據(jù)選擇器的綜合結(jié)果如圖4-10所示。圖4-10綜合結(jié)果
4.3VerilogHDL基本知識(shí)
4.3.1標(biāo)識(shí)符和關(guān)鍵字
1.標(biāo)識(shí)符
VerilogHDL中的標(biāo)識(shí)符(Identifier)可以是任意一組字母、數(shù)字、$符號(hào)和_(下劃線)符號(hào)的組合。標(biāo)識(shí)符是區(qū)分大小寫的,第一個(gè)字符必須是字母或者下劃線,不能以數(shù)字和$符號(hào)開始。例如:Max,MIN(與Min不同),F(xiàn)our$,_Y2011。
2.轉(zhuǎn)義標(biāo)識(shí)符
相信讀者對C語言中的轉(zhuǎn)義字符已經(jīng)相當(dāng)熟悉,類似地,VerilogHDL中的轉(zhuǎn)義標(biāo)識(shí)符(EscapedIdentifier)以\(反斜線)符號(hào)開頭,以空格、制表符或換行符結(jié)尾;反斜線和結(jié)束空格并不是轉(zhuǎn)義標(biāo)識(shí)符的一部分。舉例如下:
\n 換行符
\t 制表符
\\ 字符\
\" 字符"
3.關(guān)鍵字
關(guān)鍵字是VerilogHDL中預(yù)留的表示特定含義的保留標(biāo)識(shí)符(與其它語言一樣),VerilogHDL中的關(guān)鍵字全部是小寫的。
例如,標(biāo)識(shí)符BEGIN(非關(guān)鍵字)與begin(這是個(gè)關(guān)鍵字)是不同的,轉(zhuǎn)義標(biāo)識(shí)符\begin與關(guān)鍵字begin是不同的。4.3.2編寫格式
1.格式
VerilogHDL是自由格式的,代碼可以在一行內(nèi)編寫,也可以跨越多行編寫。空格、制表符和空白行沒有特殊意義。舉例如下:
initialbegin pa=0;pb=0;pCin=0;end
和下面的代碼是一樣的:
initial
begin
pa=0;
pb=0;pCin=0;
end另外要注意如前述的,在VerilogHDL中大、小寫不同的標(biāo)識(shí)符是不同的。
2.注釋
VerilogHDL中有兩種形式的注釋,第一種形式如下:
pa=0;pb=0;pCin=0;//這是第一種注釋形式
第二種形式可以擴(kuò)展至多行:
pa=0;pb=0;pCin=0;/*這是第二種注釋形式,可以跨行進(jìn)行注釋*/4.3.3模塊和端口
1.模塊的組成
模塊是VerilogHDL設(shè)計(jì)中的基本功能塊,用于描述某個(gè)設(shè)計(jì)的功能或結(jié)構(gòu),以及它與其它模塊進(jìn)行通信的端口。端口是模塊與外部環(huán)境交互的接口和通道。例如IC芯片的輸入/輸出引腳就是它的端口。對于外部來說,模塊內(nèi)部是不可見的,對模塊的調(diào)用只能通過其端口進(jìn)行。模塊的組成如圖4-11所示。圖4-11模塊組成模塊定義說明:
(1)模塊以關(guān)鍵字module開始,并以關(guān)鍵字endmodule結(jié)束。
(2)模塊名、端口列表、端口聲明和可選的參數(shù)聲明必須出現(xiàn)在其它部分前面;同樣地,為了使模塊描述清晰和具有良好的可讀性,變量、寄存器、線網(wǎng)和參數(shù)等的聲明部分必須在使用前出現(xiàn),放在任何語句的前面。
(3)端口是模塊和外部環(huán)境交互的通道,一個(gè)模塊可以沒有端口。
(4)模塊內(nèi)部有5個(gè)組成部分:變量聲明、數(shù)據(jù)流語句、低層模塊實(shí)例、行為語句以及任務(wù)和函數(shù)。這5個(gè)部分可以出現(xiàn)在模塊的任意位置,順序也可以任意排列。
(5)對于模塊的定義只有關(guān)鍵字module、endmodule和模塊名是必須的,其它都是可選的。
(6)一個(gè)Verilog源文件可以包含多個(gè)模塊,而且對于模塊的排列也沒有要求。
2.模塊的端口定義
在模塊名的后面緊跟著的就是端口列表,如果模塊和外界沒有任何交互信號(hào),也可以沒有端口列表。
端口列表中的所有端口都必須在模塊中進(jìn)行聲明,根據(jù)端口的流動(dòng)方向,端口分為input(輸入)、output(輸出)和inout(輸入/輸出雙向)三種類型。
所有端口默認(rèn)的聲明為wire型,如果希望輸出端口能夠保存數(shù)據(jù),那就需要顯式地將端口聲明為reg型;不能將input端口和inout端口設(shè)為reg型,因?yàn)閞eg型是用于保存數(shù)據(jù)的,而輸入端口用來反映外界數(shù)據(jù)的變化,并不可以進(jìn)行保存。如建立一個(gè)半加器電路的模塊(如圖4-12所示),可使用如下代碼進(jìn)行描述:
moduleHAdder(A,B,Sum,Carry);
inputA,B;
outputSum,Carry;
assignSum=A^B;
assignCarry=A&B;
endmodule
代碼中模塊的名字是HAdder。模塊有兩個(gè)輸入端口A和B,兩個(gè)輸出端口Sum和Carry。由于沒有定義端口的位數(shù),所有端口大小都為1位;同時(shí),由于沒有各端口的數(shù)據(jù)類型說明,因此這四個(gè)端口都是默認(rèn)的線網(wǎng)數(shù)據(jù)類型wire。從模塊的內(nèi)部來說,輸入端口必須為線網(wǎng)類型,而輸出則可以是線網(wǎng)或reg數(shù)據(jù)類型。圖4-12半加器電路
3.模塊的調(diào)用
VerilogHDL中對模塊的調(diào)用和軟件編程對函數(shù)的調(diào)用有一定的區(qū)別。Verilog是硬件描述語言,由它所描述的模塊是一塊具體的硬件電路:所有模塊每被調(diào)用一次,其代表的電路就復(fù)制一次,相當(dāng)于在上一級(jí)調(diào)用模塊內(nèi)生成了一個(gè)“實(shí)例”,所以模塊的調(diào)用也稱為“模塊實(shí)例化”。
模塊調(diào)用語法:
模塊名實(shí)例名(端口連接關(guān)系表)
“模塊名”就是模塊定義的(緊跟module關(guān)鍵字)名稱。
“實(shí)例名”是所調(diào)用模塊的實(shí)例名稱(唯一標(biāo)識(shí))。
“端口連接關(guān)系表”用于說明該模塊實(shí)例端口所連接的外部信號(hào),它指明了模塊實(shí)例和外界的連接關(guān)系。
模塊調(diào)用的端口對應(yīng)方式包括按順序連接和按名字連接。
(1)按順序連接:外部的信號(hào)按順序排列,和模塊定義的端口列表中的端口按照排序位置一一對應(yīng)連接。其語法格式為
(信號(hào)名1,信號(hào)名2,….,信號(hào)名n)
(2)按名字連接:顯式地指明和上層模塊信號(hào)相連接的端口名,且端口連接關(guān)系表的順序可以是任意的,只要保證端口名和信號(hào)名匹配就可以了。其語法格式為
(.端口名1(信號(hào)名1),.端口名2(信號(hào)名2),…,.端口名n(信號(hào)名n))
如下代碼采用了兩種不同的端口對應(yīng)方式,效果是一致的。
moduleTop;
reg[7:0]X,Y;
regCIN;
wire[7:0]SUM;
wireCOUT;//調(diào)用現(xiàn)有模塊add,實(shí)例名為ADD1,按順序進(jìn)行調(diào)用
addADD1(SUM,COUT,CIN,X,Y);
//調(diào)用現(xiàn)有模塊add,實(shí)例名為ADD2,按名稱進(jìn)行匹配的,可以不按順序
addADD2(.cout(COUT),.sum(SUM),.cin(CIN),.y(Y),.x(X));
endmodule4.3.4系統(tǒng)任務(wù)和系統(tǒng)函數(shù)
為了便于設(shè)計(jì)者對仿真過程進(jìn)行控制,對仿真結(jié)果進(jìn)行分析,VerilogHDL提供了大量的系統(tǒng)功能調(diào)用。系統(tǒng)功能調(diào)用分為兩類:一種是任務(wù)型的功能調(diào)用,稱為系統(tǒng)任務(wù);另一種是函數(shù)型的功能調(diào)用,稱為系統(tǒng)函數(shù)。系統(tǒng)任務(wù)和系統(tǒng)函數(shù)均是以$字符開始的標(biāo)識(shí)符($<keyword>形式)。它們的區(qū)別在于:系統(tǒng)任務(wù)可以有0個(gè)或多個(gè)返回值,而系統(tǒng)函數(shù)只有一個(gè)返回值;系統(tǒng)任務(wù)可以帶有延遲,而系統(tǒng)函數(shù)不允許任何延遲。系統(tǒng)任務(wù)和系統(tǒng)函數(shù)內(nèi)置于VerilogHDL中給用戶隨意調(diào)用,這些操作包括屏幕顯示、選通監(jiān)控、連續(xù)監(jiān)視、文件輸入/輸出、仿真控制、各種函數(shù)調(diào)用等。篇幅所限,以下只介紹最常用的幾個(gè)系統(tǒng)任務(wù)和系統(tǒng)函數(shù)。
1.$display
$display是用于顯示變量、字符串和表達(dá)式的最常用系統(tǒng)任務(wù)之一,使用上類似C語言的printf語句,如:
$display("time=%t,a=%b,b=%b,Cin=%b,Sum=%b,Cout=%b",$time,pa,pb,pCin,Sum,Cout);
該語句可用在前述例子中用于顯示運(yùn)行結(jié)果(例子中原來用的是$monitor),語句中的$time是系統(tǒng)函數(shù),返回當(dāng)前的模擬時(shí)間。可用轉(zhuǎn)義字符輸出顯示各種不同的信息,如語句:
$display(“Howto\beginour\nwork?”);
將輸出顯示:
Howtobeginour
work?
2.$monitor
系統(tǒng)任務(wù)$monitor為用戶提供了對信號(hào)值變化進(jìn)行動(dòng)態(tài)監(jiān)視的手段,如前述例子中就用到了它,使得pa、pb、pCin、py當(dāng)中任一個(gè)發(fā)生變化時(shí)就輸出顯示,而不是等待程序運(yùn)行到該語句才進(jìn)行輸出(并發(fā)執(zhí)行)。
$monitor("time=%t,a=%b,b=%b,Cin=%b,Sum=%b,
Cout=%b",$time,pa,pb,pCin,Sum,Cout);
3.$stop和$finish
$stop任務(wù)使得仿真被掛起,但在該階段仍可以發(fā)送交互命令給仿真器。設(shè)計(jì)者可以在此模式下對設(shè)計(jì)進(jìn)行調(diào)試,比如想要暫停仿真以檢查信號(hào)值時(shí)可以使用。使用方法如下:
initial
#100$stop;
在100個(gè)單位時(shí)間后,仿真暫停。
與$stop不同的是,$finish任務(wù)將結(jié)束仿真,并退出仿真環(huán)境。
4.時(shí)間函數(shù)
時(shí)間函數(shù)包括:
(1)?$time:以64位的整數(shù)形式返回當(dāng)前的仿真時(shí)間。
(2)?$stime:以32位形式返回當(dāng)前的仿真時(shí)間。
(3)?$realtime:以實(shí)數(shù)形式返回當(dāng)前的仿真時(shí)間。
5.$random函數(shù)
系統(tǒng)函數(shù)$random用于產(chǎn)生一個(gè)隨機(jī)數(shù),其使用格式為:
$random[%b]
參數(shù)b>0,函數(shù)將產(chǎn)生一個(gè)范圍在(-b+1)到(b-1)間的隨機(jī)數(shù),如:
reg[0:7]rand_a;
rand_a=$random%51;
將產(chǎn)生一個(gè)-50~50之間的隨機(jī)數(shù)。
可以在需要時(shí)為測試模塊提供隨機(jī)脈沖序列,如:
reg[0:7]rand_a;
always
#(80+($random%51))rand_a=$random%51;
將在隨機(jī)產(chǎn)生的30~130延時(shí)間隔,隨機(jī)產(chǎn)生-50~50之間的隨機(jī)數(shù)。4.3.5常用編譯器指令
編譯器指令是以`(反引號(hào),注意非單引號(hào)’)開頭的標(biāo)識(shí)符,形式上為`<keyword>,此處只介紹最常用的編譯器指令。
1.`define和`undef
`define(宏定義)指令用于文本替換,它很像C語言中的#define指令,如:
`defineSIZE8
…
reg[`SIZE-1:0]pa;
注意,宏定義名必須用大寫,如上面代碼中的SIZE不能改為Size,一旦`define指令被編譯,其在整個(gè)編譯過程中都有效,并且能被多個(gè)文件使用。可用`undef指令取消前面定義的宏。例如:
`undefSIZE
2.`include
使用`include指令可以在編譯期間將一個(gè)Verilog源文件包含在另一個(gè)Verilog文件中,作用類似于C語言的#include。文件既可以用相對路徑名,也可以用絕對路徑名。例如:
`include“../head.v”
編譯時(shí),這一行由位于上一層文件夾中(“../”)的“head.v”的內(nèi)容替代。
3.`timescale
在VerilogHDL中,所有延遲都用單位時(shí)間表述,可使用`timescale編譯器指令將時(shí)間單位與實(shí)際時(shí)間相關(guān)聯(lián)。該指令用于定義延遲的單位和延遲精度。`timescale指令格式為:
`timescale<time_unit>/<time_precision>
`timescale指令在模塊說明的外部出現(xiàn)(如前面的例子),并且影響后面所有的延遲值。time_unit(時(shí)間單位)可以是值1、10和100,time_precision(時(shí)間精度)可以是s、ms、μs、ns、ps和fs。例如:
`timescale1ns/100ps表示延遲單位為1ns,延遲精度為1/10ns(100ps)。因此,延遲值3.33對應(yīng)3.3ns,延遲4.56對應(yīng)4.6ns。又如果指令為
`timescale10ns/1ns
則3.33對應(yīng)33ns,4.56對應(yīng)46ns。
設(shè)置了單位時(shí)間,則在VerilogHDL仿真器中的顯示單位和程序中的延遲控制都會(huì)受影響,如:
`timescale1ns/100ps
…
#5assignT1=A&Cin; //5個(gè)單位時(shí)間后執(zhí)行語句
assign#2T2=B&Cin; //計(jì)算B&Cin結(jié)果,延遲2個(gè)單位時(shí)間后賦值給T2
則代碼中#5、#2表示5個(gè)和2個(gè)時(shí)間單位,也就是5ns和2ns。如果在一個(gè)設(shè)計(jì)中包含多個(gè)模塊,各模塊各自帶有自身的`timescale且不一致,則模擬器總是定位在所有模塊的最小延遲精度上,并且所有延遲都相應(yīng)地?fù)Q算為最小延遲精度。在第5章的綜合例子驗(yàn)證了這一點(diǎn)。
4.4數(shù)據(jù)類型、操作符和表達(dá)式
4.4.1值的種類
VerilogHDL有下列四種基本的值:
(1)?0:邏輯0或“假”;
(2)?1:邏輯1或“真”;
(3)?x(X):未知狀態(tài),x對大小寫不敏感;
(4)?z(Z):高阻狀態(tài),z對大小寫不敏感。
在實(shí)際電路中有z態(tài),但沒有x態(tài)的情況。x態(tài)表示要么是高電平,要么是低電平,要視具體電路當(dāng)時(shí)所處的狀態(tài)而定,是VerilogHDL中定義的一種狀態(tài)(而實(shí)際沒有)。
VerilogHDL中有三類常量:整型(Integer)、實(shí)數(shù)型(Real)、字符串型(String)。
下劃線(_)可以隨意用在整數(shù)或?qū)崝?shù)中,它們就數(shù)值本身而言沒有意義,可用來提高易讀性。須注意的是,下劃線符號(hào)不能用作數(shù)字的首字符。
1.整型
整型可以用簡單的十進(jìn)制格式或指定位寬的基數(shù)格式表示。
(1)簡單的十進(jìn)制格式:由0~9數(shù)字組成的整數(shù),可在數(shù)值前加上“+”或“-”來表示正負(fù)。這種形式的整數(shù)值代表一個(gè)有符號(hào)的數(shù)。使用二進(jìn)制的補(bǔ)碼形式表示,如(32)10在6位的二進(jìn)制形式中為100000,在7位的二進(jìn)制形式中為0100000;-15在5位的二進(jìn)制形式中為10001,在6位的二進(jìn)制形式中為110001。
(2)指定位寬的基數(shù)格式:這種形式的整數(shù)格式為
[size]‘[signed]basevalue
指定位寬的基數(shù)格式及其含義如表4-1所示。表4-1格式及其含義
首先應(yīng)理解位寬的含義:位寬就是位的個(gè)數(shù),一個(gè)“位”只能存放一個(gè)“0”或一個(gè)“1”,所以,如果要表示數(shù)(8)10,即(1000)2,則需要4位以上的位寬。
以下為未指定位寬的整數(shù)常量的例子:
666 //沒有定義位寬,則默認(rèn)的位寬至少為32位
‘h123fe //默認(rèn)位寬的十六進(jìn)制數(shù)
以下為指定位寬的整數(shù)常量的例子:
5’O15 //5位八進(jìn)制數(shù)(15)8,即(01101)2
5‘D15 //5位十進(jìn)制數(shù)(15)10,即(01111)2
4’B1_01x //4位二進(jìn)制數(shù),最低位狀態(tài)未知,即(1010)2或(1011)2
5‘Hx //5位十六進(jìn)制數(shù),狀態(tài)未知
6'hZ //6位十六進(jìn)制數(shù),狀態(tài)高阻以下為有符號(hào)整數(shù)常量的例子:
‘sb1011 //未指定位寬,按默認(rèn)32位處理。有符號(hào)二進(jìn)制數(shù),表示有符號(hào)的-5
-8’d5 //占8位,相當(dāng)于-(8‘d5)
以下為錯(cuò)誤的例子:
8’d-5 //數(shù)值不能為負(fù)
-8‘d5 //’和基數(shù)d之間不允許出現(xiàn)空格
(2+1)‘b101 //位長不能夠作為表達(dá)式
當(dāng)位寬大于數(shù)值的實(shí)際位數(shù)時(shí),對無符號(hào)數(shù)在數(shù)的左邊填0補(bǔ)齊,對有符號(hào)數(shù)則在左邊填符號(hào)位補(bǔ)齊。但是,如果數(shù)的最左邊一位為x或z,則相應(yīng)地用x或z在左邊補(bǔ)位。例如:
8‘b10 //左邊添0占位,00000010
8’sb110 //左邊添符號(hào)位(1)占位,11111110
8‘bx1x0 //左邊添x占位,xxxxx1x0
16’hz12 //左邊添z占位,zzzzzzzz0001
0010(十六進(jìn)制轉(zhuǎn)換為二進(jìn)制,1位變4位)
當(dāng)位寬小于數(shù)值的實(shí)際位數(shù)時(shí),那么高位(最左邊的位)相應(yīng)地被截?cái)?。例如?/p>
4‘b1111_0011 //高位截?cái)啵韧?’b0011
5‘HFFF //FFF即’b111111111111,高位截?cái)?只保留低5位),等同于5‘H1F
問號(hào)(?)在數(shù)中可以代替值z,可以提高程序的可讀性。
2.實(shí)數(shù)型
與其它語言一樣,實(shí)數(shù)可使用十進(jìn)制計(jì)數(shù)法和科學(xué)計(jì)數(shù)法表示,例如:
1.8
45.67
3.1415926
123_45.6e4 //忽略下劃線
3.3E-2 //指數(shù)符號(hào)E大小寫不敏感
當(dāng)實(shí)數(shù)型需要轉(zhuǎn)換為整數(shù)型時(shí),將通過對小數(shù)部分進(jìn)行四舍五入,隱式地轉(zhuǎn)換為最靠近的整數(shù)型常量,如34.5轉(zhuǎn)換為35,-3.6轉(zhuǎn)換為-4。
3.字符串型
字符串是雙引號(hào)內(nèi)的字符序列,不能分成多行書寫,例如:
“Operation”
“file->newproject”
用ASCII值(8位)表示的字符可看做是無符號(hào)整數(shù),因此字符串是ASCII值的序列。如為了存儲(chǔ)字符串“Operation”(9個(gè)字符長度),變量需要8?×?9位:
reg[1:8*9]string1;
…
string1="Operation";4.4.2數(shù)據(jù)類型
1.線網(wǎng)(Net)與變量(Variable)
VerilogHDL中,根據(jù)賦值和對值的保持方式不同,數(shù)據(jù)類型分為線網(wǎng)(Net)類型和變量(Variable)類型。這兩類數(shù)據(jù)也代表了不同的硬件結(jié)構(gòu)。
(1)線網(wǎng)類型體現(xiàn)了結(jié)構(gòu)實(shí)體(如門級(jí)元件)之間的物理連接關(guān)系,它的值由驅(qū)動(dòng)元件的值(例如連續(xù)賦值或門級(jí)元件的輸出)決定。如果沒有驅(qū)動(dòng)元件連接到線網(wǎng),線網(wǎng)的缺省值為z(高阻)。
(2)變量類型是數(shù)據(jù)存儲(chǔ)單元的抽象,從上一次賦值到下一次賦值期間,變量的值保持不變。其含義與其它語言中的變量一致。
2.線網(wǎng)類型
線網(wǎng)表示硬件單元之間的連接,就像真實(shí)電路中一樣,線網(wǎng)由其連接器件的輸出端連續(xù)驅(qū)動(dòng)。在圖4-13中,線網(wǎng)a連接到與門gate1的輸出端,它將連續(xù)地獲得gate1的輸出值(b&c)。
線網(wǎng)類型中包括多種類型,有wire、wand、wor、tri、triand、trior和trireg。線網(wǎng)類型默認(rèn)的線網(wǎng)位寬為1,默認(rèn)值為z(只有trireg類型的默認(rèn)值為x)。其中wire類型最為常用,在VerilogHDL中,如對某個(gè)信號(hào)的線網(wǎng)類型不予以聲明,則線網(wǎng)類型被缺省地設(shè)置為1位的wire型線網(wǎng)。
wire線網(wǎng)只能用連續(xù)賦值語句進(jìn)行賦值,或通過模塊實(shí)例的輸出端口賦值。可參閱前面的例子。圖4-13線網(wǎng)連接
3.變量類型
有5種不同的變量類型:reg、integer、time、real、realtime。
(1)寄存器(reg)變量類型。reg變量數(shù)據(jù)類型是最常見的數(shù)據(jù)類型,其對應(yīng)的是具有狀態(tài)保持作用的硬件電路,如觸發(fā)器、鎖存器等。reg變量與線網(wǎng)型數(shù)據(jù)的區(qū)別在于:reg變量保持最后一次賦值結(jié)果,而線網(wǎng)型數(shù)據(jù)需要有連續(xù)的驅(qū)動(dòng);reg變量只能在always語句和initial語句中被賦值。reg類型聲明形式如下:
reg[msb:lsb]reg1,reg2,...regN;變量名全部用小寫字母,格式中msb和lsb定義了范圍,并且均為常數(shù)值表達(dá)式。范圍定義是可選的,如果沒有定義范圍,則缺省值為1位變量。例如:
regpa,pb; //pa,pb為1位變量
reg[3:0]pc; //pc為4位變量
變量可以取任意長度,變量中的值通常被解釋為無符號(hào)數(shù),例如:
moduletest;
reg[1:4]pa,pb;
initial
begin
pa=-2; //-2的補(bǔ)碼是1110,1110被賦給pa,故pa的值為14
pb=5; //pb的值為5(0101)
$display("%d,%d",pa,pb);
end
endmodule
(2)整型(integer)變量類型。整數(shù)變量包含整數(shù)值。整數(shù)變量可以作為普通變量使用,通常用于高層次行為建模,如對循環(huán)控制變量的說明。其說明形式如下:
integerinteger1,integer2,...intergerN[msb:1sb];
msb和lsb用于定義整數(shù)數(shù)組的范圍,是可選的參數(shù)。一個(gè)整數(shù)最少有32位,具體實(shí)現(xiàn)時(shí)可提供更多的位。定義舉例如下:
integerpa,pb,pc; //3個(gè)整型變量
integerp[2:6]; //5個(gè)整型變量組成的數(shù)組
(3)時(shí)間(time)變量類型。time類型的變量用于存儲(chǔ)和處理時(shí)間,常與系統(tǒng)函數(shù)$time一起使用。time類型變量使用方式如下:
timetime_id1,time_id2,...,time_idN[msb:1sb];
時(shí)間類型的變量只存儲(chǔ)無符號(hào)數(shù),每個(gè)變量存儲(chǔ)一個(gè)至少64位的時(shí)間值。
(4)實(shí)數(shù)(real)和實(shí)數(shù)時(shí)間(realtime)變量類型。實(shí)數(shù)(real)變量的聲明格式為:
realreal_reg1,real_reg2,...,real_regN;實(shí)數(shù)變量的缺省值為0,不能指定位寬,如果將值x和z賦予real類型變量,則這些值將作0處理。如:
realpa;
…
pa=‘b10x1Z; //pa在賦值后的值為’b10010
實(shí)數(shù)時(shí)間(realtime)變量的聲明格式為
realtimerealtime_reg1,realtime_reg2,...,realtime_regN;
4.?dāng)?shù)組(Array)類型
(1)數(shù)組。可以用一條數(shù)組語句聲明線網(wǎng)和變量的(一維或多維)數(shù)組,數(shù)組的元素可以是標(biāo)量或者向量(也有稱矢量)。
初學(xué)者很容易對向量和數(shù)組的概念產(chǎn)生疑惑,舉例如下:
wirepa; //pa為1位的線網(wǎng)(wire類型),是一個(gè)標(biāo)量
wire[0:7]pb; //pb為1個(gè)8位的向量,wire類型
wirepc[0:7],pd[1:4]; /*pc由8個(gè)、pd由4個(gè)元素組成的數(shù)組,其中每個(gè)元素是一個(gè)標(biāo)量元素(1位wire)*/
wire[0:7]pe[0:3]; //4個(gè)元素組成的數(shù)組,每個(gè)元素是1個(gè)8位的向量例子中的類型(wire)可以改為線網(wǎng)和變量中的各種類型,如reg、integer、time等。可用不同類型數(shù)組元素來定義數(shù)組,如:
integerpf[0:7][0:7]; //8?×?8的二維數(shù)組,每個(gè)元素都是整型變量
reg[0:3]pg[0:7][16:1]; //8?×?16的二維數(shù)組,每個(gè)元素為位寬為4的寄存器變量
一個(gè)數(shù)組元素可以通過一條單獨(dú)的賦值語句進(jìn)行賦值,但整個(gè)數(shù)組或數(shù)組的一部分不能用一條單獨(dú)的賦值語句進(jìn)行賦值,在接下來討論存儲(chǔ)器的例子中可以看到具體的操作
方式。
(2)存儲(chǔ)器。存儲(chǔ)器是由reg變量組成的數(shù)組(一維)。存儲(chǔ)器的定義方式如下:
reg[msb:1sb]memory1[upper1:lower1],
memory2[upper2:lower2],...;
例如:
regpa[1:3] //pa為3個(gè)1位reg變量組成的數(shù)組
reg[0:3]pb[0:31] //pb為32個(gè)4位reg變量組成的數(shù)組
在賦值語句中需要注意:n個(gè)1位reg變量和1個(gè)n位存儲(chǔ)器是不同的;存儲(chǔ)器賦值不能在一條賦值語句中完成,但是變量可以。因此在存儲(chǔ)器被賦值時(shí),需要由一個(gè)數(shù)組索引來指定。下例說明它們之間的不同。
reg[1:5]pa; //pa為1個(gè)5位寄存器變量(向量)
…
pa=5‘b11101;
//可在一條語句中完成賦值
上述賦值是正確的,但下述賦值不正確:
regpb[1:5]; //pb為5個(gè)1位變量的存儲(chǔ)器
…
pb=5'b11101; //錯(cuò)誤,不可在一條語句中完成賦值可以分別通過對存儲(chǔ)器中每個(gè)字賦值的方法給存儲(chǔ)器賦值,例如:
regpb[1:5]; //pb為5個(gè)1位變量的存儲(chǔ)器
…
pb[1]=1;
pb[2]=0;
pb[3]=1;
pb[4]=1;
pb[5]=1;也可以由m個(gè)n位reg變量組成存儲(chǔ)器,其賦值舉例如下:
reg[0:3]px[1:3]; //px由3個(gè)4位reg變量組成
…
px[1]=4‘h8;
px[2]=4’he;
px[3]=4'hF;
5.參數(shù)
(1)參數(shù)的定義。參數(shù)是一個(gè)常量,可使用關(guān)鍵字parameter在模塊內(nèi)定義常數(shù)。使用時(shí)經(jīng)常用參數(shù)定義延遲和變量的寬度。參數(shù)被賦值一次后不能像變量一樣重新賦值。參數(shù)定義舉例如下:
parameterline_width=256;
parameterBIT=1,BYTE=8,PI=3.14159;
parametermyFILE=“/home/testing/FAdd1.v”;
參數(shù)值也可以在編譯時(shí)被改變,可用defparam重新定義參數(shù)。
(2)參數(shù)與宏定義(`define)。參數(shù)與宏定義(`define)的作用似乎很類似,其區(qū)別在于:參數(shù)是局部的,只在其定義的模塊內(nèi)部起作用;而宏定義是全局的,它對同時(shí)編譯的多個(gè)文件起作用。從形式上看,參數(shù)的定義在模塊內(nèi)部,語句結(jié)束需寫上分號(hào)(;);而宏定義的定義在模塊外部,語句結(jié)束時(shí)不寫分號(hào)(;)。
(3)局部參數(shù)。局部參數(shù)使用關(guān)鍵字localparam定義,其作用等同于參數(shù),只是局部參數(shù)的值不能改變。在某些情況下,為了避免參數(shù)被意外更改(如狀態(tài)機(jī)的狀態(tài)編碼),可將其定義為局部參數(shù)。但如果局部參數(shù)是用其它非局部參數(shù)所定義的,則外部賦值使得參數(shù)值發(fā)生變化時(shí),局部參數(shù)也間接地發(fā)生變化,如:
parameterlwidth=256;
localparamdbl_lwidth=2*lwidth;
defparamlwidth=32;
局部參數(shù)dbl_lwidth會(huì)因?yàn)閰?shù)lwidth值的變化而產(chǎn)生變化。4.4.3操作數(shù)
1.操作數(shù)類型
操作數(shù)可以是以下類型:常數(shù)、參數(shù)、線網(wǎng)、變量、位選、部分位選、存儲(chǔ)器和數(shù)組元素和函數(shù)調(diào)用。
操作數(shù)可以是4.4.2節(jié)闡述的常數(shù),各種數(shù)據(jù)類型可以是數(shù)據(jù)的一部分(如位選和部分位選),也可以是函數(shù)的調(diào)用。以下簡單討論對位選和部分位選、存儲(chǔ)器和數(shù)組元素的處理。
2.位選和部分位選
位選是從向量中抽取特定的位。形式如下:
net_or_reg_vector[bit_select_expr]
部分位選是在向量中選擇連續(xù)的若干位。形式如下:
net_or_reg_vector[msb_const_expr:1sb_const_expr]
舉例如下:
reg[0:3]pa;
wire[0:3]pb;
regX,Y;
reg[0:2]Z;
…
pa=4'b1010;
X=pa[3]; //變量的位選,結(jié)果為1'b0
Y=pb[2]; //線網(wǎng)的位選
Z=pa[0:2]; //部分位選,結(jié)果為3'b101
X=pb[5]; //超出尋址范圍,返回值為x
3.存儲(chǔ)器和數(shù)組元素
存儲(chǔ)器元素(單元)是指從存儲(chǔ)器中選擇一個(gè)字。形式如下:
memory[word_address]
舉例如下:
reg[1:8]pa,pb[0:15]; //pa位寬為8,pb的每個(gè)數(shù)組元素(16個(gè))位寬為8
reg[1:2]X,Y;
...
pa=pb[6]; //存儲(chǔ)器的第6個(gè)單元
X=pb[10][5]; //第10個(gè)元素第5位的值
Y=pb[8][3:4]; //第8個(gè)元素第[3:4]位的值4.4.4操作符
1.操作符及其優(yōu)先級(jí)
VerilogHDL中的操作符與C語言類似,可以分為9種類型,如表4-2所示。表中優(yōu)先級(jí)數(shù)字越小,運(yùn)算優(yōu)先級(jí)越高;“元”列表示使用該運(yùn)算符時(shí)操作數(shù)的個(gè)數(shù),如2表示2元運(yùn)算符,有些書籍和語言也稱為“目”。
從表中可看到,凡是一元運(yùn)算符,其優(yōu)先級(jí)均為1,最先進(jìn)行運(yùn)算。
與C語言中的“左結(jié)合性”一樣,VerilogHDL中除條件操作符(?:)從右向左運(yùn)算外,其余所有操作符均自左向右運(yùn)算,如“A+B-C”等價(jià)于“(A+B)-C”。也可使用圓括號(hào)()改變運(yùn)算的順序,這屬于計(jì)算機(jī)語言的基本常識(shí)了。“條件操作符(?:)從右向左運(yùn)算”可能會(huì)讓讀者產(chǎn)生疑問,誤會(huì)為“:”比“?”先進(jìn)行運(yùn)算。所謂的結(jié)合性是指操作符之間的結(jié)合性,而“?:”是一個(gè)整體。舉例如下:表達(dá)式“a>b?2:c>d?1:0”,根據(jù)優(yōu)先級(jí)可以理解為“(a>b)?2:(c>d)?1:0”;再根據(jù)右結(jié)合性,可理解為“(a>b)?2:((c>d)?1:0)”。
2.算術(shù)操作符
算術(shù)操作符有:+(一元加和二元加)、-(一元減和二元減)、*(乘)、/(除)、%(取模)。
在使用算術(shù)操作符時(shí),需要注意以下內(nèi)容:
(1)整數(shù)除法截?cái)嘈?shù)部分。例如“7/4”的運(yùn)算結(jié)果為1。
(2)取模操作符求出與第一個(gè)操作符符號(hào)相同的余數(shù)。例如“7%4”結(jié)果為3,而“-7%4”結(jié)果為-3,11%-3結(jié)果為2。
(3)如果算術(shù)操作符中的任意操作數(shù)是X或Z,那么整個(gè)結(jié)果為X。例如“'b110x+'b111”結(jié)果為不確定數(shù)'bxxxx。表4-2操作符
(4)算術(shù)操作結(jié)果的位寬由最大操作數(shù)的位寬決定。如代碼:
reg[0:3]sum,pa;
reg[0:1]pb;
…
sum=pa+pb;
pa+pb的計(jì)算結(jié)果的長度為4位,但如果計(jì)算有溢出,則溢出部分被丟棄。
(5)在賦值語句下,算術(shù)操作結(jié)果的長度由操作符左端目標(biāo)長度決定。如代碼:
reg[0:5]sum;
reg[0:3]pa,pb;
…
sum=pa+pb;
由于賦值語句左端sum的位寬為6位,是最大位寬,故所有的運(yùn)算都使用6位進(jìn)行。
(6)表達(dá)式中整數(shù)數(shù)值的使用。如前所述,整數(shù)數(shù)值可以表示為兩種不同格式:簡單的十進(jìn)制和基數(shù)格式。在表達(dá)式被機(jī)器編譯后,一個(gè)十進(jìn)制格式的負(fù)整數(shù)被編譯為有符號(hào)的二進(jìn)制補(bǔ)碼格式,一個(gè)無符號(hào)基數(shù)格式的負(fù)整數(shù)被編譯成無符號(hào)數(shù)。如:
integera;
…
a=-12/3 //結(jié)果為-4
a=-'d12/3 //結(jié)果為1431655761讀者可能很驚訝為何-‘d12/3的運(yùn)算結(jié)果居然那么大(1431655761),學(xué)習(xí)過C語言的讀者也應(yīng)遇到過類似問題。下面來了解一下計(jì)算的過程:在表達(dá)式中,由于a為整型(Integer)變量,而整型變量類型最少為32位(如4.4.2節(jié)中關(guān)于整型變量類型的描述),故-’d12也使用32位;12的二進(jìn)制為1100,-12的32位補(bǔ)碼為“11111111111111111111111111110100”;由于“一個(gè)無符號(hào)基數(shù)格式的負(fù)整數(shù)被編譯成無符號(hào)數(shù)”,該數(shù)被當(dāng)成無符號(hào)數(shù)除以3,得“1010101010101010101010101010001”(31位),該數(shù)就是最后的結(jié)果1431655761了。
可見執(zhí)行算術(shù)和賦值操作時(shí),注意哪些操作數(shù)應(yīng)該被當(dāng)作無符號(hào)數(shù)處理,哪些被當(dāng)作有符號(hào)數(shù)處理是非常重要的。
(7)有符號(hào)數(shù)和無符號(hào)數(shù)。以下類型作無符號(hào)數(shù)處理:線網(wǎng)、reg寄存器變量、沒有符號(hào)標(biāo)記s的基數(shù)格式整數(shù)。以下類型作有符號(hào)數(shù)處理:整型變量、十進(jìn)制形式的整數(shù)、
有符號(hào)的線網(wǎng)、有符號(hào)的reg寄存器變量、有符號(hào)標(biāo)記s的基數(shù)格式整數(shù)。
舉例如下:
reg[0:5]pa;
integerpb;
...
pa=-4'd12; //reg變量pa的十進(jìn)制數(shù)為52(二進(jìn)制數(shù)110100)
pb=-4'd12; //整型變量pb的十進(jìn)制數(shù)為-12(二進(jìn)制數(shù)110100)由于pa為reg變量,故只存儲(chǔ)無符號(hào)數(shù),12的二進(jìn)制數(shù)為001100(pa為6位),故其補(bǔ)碼為110100,無符號(hào)二進(jìn)制數(shù)110100對應(yīng)的十進(jìn)制數(shù)為52;而pb為整型變量,可存儲(chǔ)有符號(hào)數(shù),二進(jìn)制數(shù)110100仍表示有符號(hào)數(shù),故數(shù)值沒有發(fā)生變化。
以下為帶符號(hào)標(biāo)記s的例子:
integera;
…
a=-'sd12/3; //帶符號(hào)標(biāo)記s,結(jié)果為-4
a=-4'sd12/3; /*12的二進(jìn)制數(shù)為1100。因?yàn)橹挥?位,(4'sd12)部分把1100當(dāng)成了有符號(hào)數(shù),有符號(hào)數(shù)1100就是表示-4。-(-4)/3的結(jié)果為1*/
3.關(guān)系操作符
關(guān)系操作符有:>(大于)、<(小于)、>=(不小于)、<=(不大于)。關(guān)系操作符的結(jié)果為真(1)或假(0)。如果操作數(shù)中有一位為X或Z,那么結(jié)果為X。如“2>4”的結(jié)果為0,“2<6‘hxF”的結(jié)果為x。
如果操作數(shù)的位寬不同,則位寬較小的操作數(shù)在高位方向(左方)補(bǔ)0。如“'b100<='b0110”等價(jià)于“'b0100<='b0110”,結(jié)果為1。
4.相等操作符
相等關(guān)系操作符有:==(邏輯相等)、!=(邏輯不等)、===(全等)、!==(非全等)。
相等(==)和全等(===)都表示相等,其區(qū)別在于:相等運(yùn)算符逐位比較2個(gè)操作數(shù)相應(yīng)位的值是否相等,但如果任一操作數(shù)中的某一位為x或z,則結(jié)果為x;全等運(yùn)算符也是逐位比較,但不同的是,它將x和z也看做為一種邏輯狀態(tài)而參與比較,兩個(gè)操作數(shù)相應(yīng)同時(shí)為x或z時(shí),才認(rèn)為相等。舉例如下:
pa=‘b010x1;
pb=’b10x1; //左方補(bǔ)0,相當(dāng)于‘b010x1
m=(pa==pb);
n=(pa===pb);
如果操作數(shù)的位寬不同,則位寬較小的操作數(shù)在高位方向(左方)補(bǔ)0。pb相當(dāng)于'bo1ox1。pa==pb的結(jié)果為x,而pa===pb的結(jié)果為1。
5.邏輯操作符
邏輯操作符有:&&(邏輯與)、||(邏輯或)、!(邏輯非)。
例如:pa=‘b0;pb=’b1;,則“pa&&pb”的結(jié)果為0,“pa||pb”的結(jié)果為1,“!pa”的結(jié)果為1。
對于向量操作,非0向量被作為1處理。例如“0010”將當(dāng)作“1”進(jìn)行計(jì)算,如:
pa='b0010&&'b001; //pa結(jié)果為1
pb='b0010||'b0; //pb結(jié)果為1
pc=!'b100; //pc結(jié)果為0
pd=!x //pd結(jié)果為x
pe=!z //pe結(jié)果為x
6.按位操作符
按位操作符有:~(一元非
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《延安大學(xué)研究生》課件
- 幼兒園周四營養(yǎng)食譜
- 《爆管應(yīng)急處理預(yù)案》課件
- 《汽車回收再生服務(wù)》課件
- 教育行業(yè)前臺(tái)服務(wù)總結(jié)
- 醫(yī)療行業(yè)前臺(tái)工作體會(huì)
- 財(cái)務(wù)工作成長心得
- 康復(fù)閱讀護(hù)士的工作總結(jié)
- 客戶信用評估總結(jié)
- 《淺談酒店市場營銷》課件
- 文創(chuàng)產(chǎn)品可行性報(bào)告
- 江蘇省徐州市2023-2024學(xué)年八年級(jí)上學(xué)期期末抽測道德與法治試題
- 8.1《荷花淀》同步練習(xí)()
- 浙江省杭州市2023-2024學(xué)年四年級(jí)上學(xué)期科學(xué)高頻易錯(cuò)期末考前卷(教科版)
- 汽車產(chǎn)量統(tǒng)計(jì)研究報(bào)告
- 甲烷事故應(yīng)急預(yù)案
- 醫(yī)藥倉儲(chǔ)部人員崗位職責(zé)及工作內(nèi)容培訓(xùn)課件
- 三明醫(yī)改調(diào)研社會(huì)實(shí)踐報(bào)告
- 人員密集場所安全常識(shí)
- 泵設(shè)備故障預(yù)警與診斷技術(shù)
- 臺(tái)球廳打架應(yīng)急預(yù)案
評論
0/150
提交評論