《Xilinx FPGACPLD設(shè)計(jì)初級(jí)教程》課件第3章_第1頁(yè)
《Xilinx FPGACPLD設(shè)計(jì)初級(jí)教程》課件第3章_第2頁(yè)
《Xilinx FPGACPLD設(shè)計(jì)初級(jí)教程》課件第3章_第3頁(yè)
《Xilinx FPGACPLD設(shè)計(jì)初級(jí)教程》課件第3章_第4頁(yè)
《Xilinx FPGACPLD設(shè)計(jì)初級(jí)教程》課件第3章_第5頁(yè)
已閱讀5頁(yè),還剩151頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第3章VerilogHDL語(yǔ)言基礎(chǔ)知識(shí)3.1VerilogHDL簡(jiǎn)介

3.2VerilogHDL模塊的基本結(jié)構(gòu)

3.3VerilogHDL語(yǔ)言規(guī)范3.4VerilogHDL語(yǔ)言中的常量和變量3.5VerilogHDL語(yǔ)言中的運(yùn)算符3.6VerilogHDL語(yǔ)言中的塊語(yǔ)句和賦值語(yǔ)句3.7過(guò)程語(yǔ)句3.8條件語(yǔ)句3.9循環(huán)語(yǔ)句3.10task和function說(shuō)明語(yǔ)句3.11系統(tǒng)任務(wù)和函數(shù)3.12編譯預(yù)處理

習(xí)題3

3.1VerilogHDL簡(jiǎn)介

3.1.1硬件描述語(yǔ)言HDL

硬件描述語(yǔ)言(HardwareDescriptionLanguage,HDL)是一種用文本形式描述數(shù)字電路和設(shè)計(jì)數(shù)字邏輯系統(tǒng)的語(yǔ)言。數(shù)字邏輯電路設(shè)計(jì)者可利用這種語(yǔ)言來(lái)描述硬件電路的思想,然后利用電子設(shè)計(jì)自動(dòng)化(ElectronicDesignAutomation,EDA)工具進(jìn)行仿真,再自動(dòng)綜合到門(mén)級(jí)電路,用ASIC或FPGA實(shí)現(xiàn)其功能。目前,這種稱之為高層次設(shè)計(jì)(HighLevelDesign)的方法已被廣泛采用。硬件描述語(yǔ)言的發(fā)展至今已有20多年的歷史,并成功應(yīng)用于設(shè)計(jì)的各個(gè)階段(仿真、驗(yàn)證、綜合等)。到20世紀(jì)80年代,已出現(xiàn)了上百種硬件描述語(yǔ)言,它們對(duì)設(shè)計(jì)自動(dòng)化起到了極大的促進(jìn)和推動(dòng)作用。但是,這些語(yǔ)言一般各自面向特定的設(shè)計(jì)領(lǐng)域與層次,而且眾多的語(yǔ)言使用戶無(wú)所適從,因此急需一種面向設(shè)計(jì)的多領(lǐng)域、多層次且得到普遍認(rèn)同的標(biāo)準(zhǔn)硬件描述語(yǔ)言。進(jìn)入20世紀(jì)80年代后期,硬件描述語(yǔ)言向著標(biāo)準(zhǔn)化的方向發(fā)展。最終,VHDL和VerilogHDL語(yǔ)言適應(yīng)了這種趨勢(shì)的要求,先后成為IEEE標(biāo)準(zhǔn)。3.1.2VerilogHDL的歷史

VerilogHDL是在1983年,由GDA(GatewayDesignAutomation)公司的PhilMoorby為模擬器產(chǎn)品開(kāi)發(fā)而首創(chuàng)的硬件建模語(yǔ)言。PhilMoorby后來(lái)成為Verilog-XL的主要設(shè)計(jì)者和Cadence公司的第一個(gè)合伙人。在1984~1985年,Moorby設(shè)計(jì)出了第一個(gè)關(guān)于Verilog-XL的仿真器,1986年,他提出了用于快速門(mén)級(jí)仿真的XL算法,這是他在VerilogHDL的發(fā)展史上做出的又一巨大貢獻(xiàn)。隨著Verilog-XL算法的成功,VerilogHDL語(yǔ)言得到了迅速發(fā)展。1989年,Cadence公司收購(gòu)了GDA公司,VerilogHDL語(yǔ)言成為Cadence公司的私有財(cái)產(chǎn)。1990年,Cadence公司決定公開(kāi)VerilogHDL語(yǔ)言,于是成立了OVI(OpenVerilogInternational)組織來(lái)負(fù)責(zé)VerilogHDL語(yǔ)言的發(fā)展?;赩erilogHDL的優(yōu)越性,IEEE于1995年制定了VerilogHDL的IEEE標(biāo)準(zhǔn),稱為IEEEStandard1364-1995。3.1.3VerilogHDL語(yǔ)言與C語(yǔ)言的比較

VerilogHDL作為一種高級(jí)的硬件描述編程語(yǔ)言,具有類似于C語(yǔ)言的風(fēng)格。其中的許多語(yǔ)句(如if語(yǔ)句、case語(yǔ)句等)和C語(yǔ)言中的對(duì)應(yīng)語(yǔ)句十分相似。表3.1中列舉了兩種語(yǔ)言中一些相同或相似的關(guān)鍵字,表3.2中對(duì)比了這兩種語(yǔ)言的運(yùn)算符。由此可看出,如果讀者已經(jīng)掌握C語(yǔ)言編程的基礎(chǔ),那么學(xué)習(xí)VerilogHDL并不困難,我們只要對(duì)VerilogHDL某些語(yǔ)句的特殊方面著重理解,并加強(qiáng)上機(jī)練習(xí)就能很好地掌握它,就能利用它的強(qiáng)大功能來(lái)設(shè)計(jì)復(fù)雜的數(shù)字邏輯電路。表3.1C語(yǔ)言與VerilogHDL語(yǔ)言相對(duì)應(yīng)的關(guān)鍵字比較表3.2C語(yǔ)言與VerilogHDL語(yǔ)言相對(duì)應(yīng)的運(yùn)算符比較值得注意的是,VerilogHDL語(yǔ)言與C語(yǔ)言的最大不同在于,C程序是順序執(zhí)行語(yǔ)句,VerilogHDL程序是并行執(zhí)行語(yǔ)句,即用C語(yǔ)言寫(xiě)出的代碼是一行接一行依次執(zhí)行的,而用VerilogHDL語(yǔ)言寫(xiě)出的代碼是在同一時(shí)間同時(shí)運(yùn)行的。 3.2VerilogHDL模塊的基本結(jié)構(gòu)

VerilogHDL程序的基本設(shè)計(jì)單元是“模塊”(module)。一個(gè)模塊又由幾個(gè)部分組成。為了清晰地說(shuō)明模塊的構(gòu)成,下面舉例說(shuō)明如何用VerilogHDL語(yǔ)言描述一個(gè)簡(jiǎn)單的與門(mén)邏輯單元結(jié)構(gòu)。其與門(mén)邏輯單元如圖3.1所示。圖3.1與門(mén)邏輯單元上述程序中,第一行定義了模塊的端口,聲明了模塊的輸入/輸出口;第二行利用input關(guān)鍵字定義a、b為輸入端口;第三行利用output關(guān)鍵字定義c為輸出端口;第四行定義了端口的數(shù)據(jù)類型;第五行則描述了模塊實(shí)現(xiàn)的功能,描述完成后用endmodule關(guān)鍵字完成這個(gè)模塊的設(shè)計(jì)。上述程序的第五行也可寫(xiě)成“andA1(c,a,b)”,其中,A1為與門(mén)邏輯單元定義的名字。在VerilogHDL語(yǔ)言中一些基本的邏輯門(mén)和開(kāi)關(guān)級(jí)結(jié)構(gòu)模型都內(nèi)置在其中,在程序設(shè)計(jì)中可直接使用。這種描述電路的方式叫做門(mén)級(jí)結(jié)構(gòu)描述,此方式將在第4章中詳細(xì)介紹。通過(guò)上面的例子可以看出,VerilogHDL的模塊設(shè)計(jì)是通過(guò)module和endmodule聲明語(yǔ)句實(shí)現(xiàn)的。每個(gè)VerilogHDL程序包括4個(gè)主要部分:模塊聲明、I/O說(shuō)明、信號(hào)類型說(shuō)明和邏輯功能描述。

1.模塊聲明

模塊的端口聲明了模塊的輸入/輸出口。其格式如下:

module 模塊名(口1,口2,口3,口4,…);

模塊結(jié)束的關(guān)鍵字為:endmodule。

2.?I/O說(shuō)明

對(duì)模塊的輸入/輸出端口說(shuō)明有如下三種格式:

(1)輸入口:

input端口名1,端口名2,…,端口名N; //(共有N個(gè)輸入口)

(2)輸出口:

output端口名1,端口名2,…,端口名N; //(共有N個(gè)輸出口)

(3)輸入/輸出口:

inout端口名1,端口名2,…,端口名N; //(共有N個(gè)輸入/輸出口)

I/O說(shuō)明也可以寫(xiě)在端口聲明語(yǔ)句中。其格式如下:

modulemodule_name(inputport1,inputport2,…,outputport1,outputport2,…,inoutport1,inoutport2,...);

3.信號(hào)類型說(shuō)明

VerilogHDL語(yǔ)言提供了各種信號(hào)類型,它們代表數(shù)字電路中的各種物理連接和物理實(shí)體。在模塊中所有用到的信號(hào)都必須進(jìn)行數(shù)據(jù)類型的定義。如果類型沒(méi)有定義,則綜合器將其默認(rèn)為wire型數(shù)據(jù)類型。

下面為定義信號(hào)數(shù)據(jù)類型的幾個(gè)例子。

wireA,B,C;

//定義信號(hào)A、B、C的數(shù)據(jù)類型為wire連線型

reg[3:0]counter; //定義信號(hào)counter的數(shù)據(jù)類型為4位reg型

4.邏輯功能描述

邏輯功能描述是模塊中最重要的部分。對(duì)電路的邏輯描述有多種方法,除了下面工程中常用的三種方法外,還可以調(diào)用用戶自定義函數(shù)(function)和任務(wù)(task)等來(lái)描述邏輯電路。

1)用“assign”聲明語(yǔ)句

例如:

assignf=(~a&c);

“assign”語(yǔ)句一般給wire型數(shù)據(jù)信號(hào)賦值。這種方法的句法很簡(jiǎn)單,只需寫(xiě)一個(gè)“assign”,后面再加一個(gè)邏輯方程式即可。

2)用元件例化

例如:

nandnand2_inst(c,a,b);

上述語(yǔ)句表示在設(shè)計(jì)中用到一個(gè)同與非門(mén)(nand)一樣的名為nand2_inst的與門(mén),其輸入端為a、b,輸出端為c。要求每個(gè)實(shí)例元件的名字必須是唯一的,以避免與其他調(diào)用與非門(mén)(nand)的實(shí)例混淆。采用元件例化的方法就如同在C語(yǔ)言下調(diào)用庫(kù)函數(shù)一樣。用VerilogHDL語(yǔ)言進(jìn)行數(shù)字電路設(shè)計(jì)時(shí)有兩種元件例化的方式:一種是例化VerilogHDL語(yǔ)言中本身內(nèi)置的基本邏輯門(mén)和開(kāi)關(guān)級(jí)結(jié)構(gòu)模型;另一種是通過(guò)支持VerilogHDL語(yǔ)言的數(shù)字電路設(shè)計(jì)軟件例化自帶的擴(kuò)充系列元件庫(kù)。比如,在本書(shū)第6章提到的DCM(數(shù)字時(shí)鐘管理器)就是ISE中自帶的元件庫(kù),而在其他公司的設(shè)計(jì)軟件中將不會(huì)有此DCM元件庫(kù)。用“always”塊既可用于描述組合邏輯,又可描述時(shí)序邏輯。上面的例子用“always”塊生成了一個(gè)2選1的多路選擇器,這是一種行為描述方式?!癮lways”塊可用很多種語(yǔ)法來(lái)表達(dá)邏輯,例如上例中就用了if...else語(yǔ)句來(lái)表達(dá)邏輯關(guān)系。不管設(shè)計(jì)者用哪種語(yǔ)法表達(dá)邏輯關(guān)系,最終綜合工具會(huì)把源代碼自動(dòng)綜合成相對(duì)應(yīng)的器件邏輯構(gòu)造方式。例如,對(duì)于CPLD器件,綜合工具將生成相對(duì)應(yīng)的門(mén)級(jí)結(jié)構(gòu)來(lái)表示組合或時(shí)序的邏輯電路;對(duì)于FPGA器件,綜合工具將生成相對(duì)應(yīng)的LUT(查表)法來(lái)表示組合或時(shí)序的邏輯電路。上面三個(gè)例子分別采用“assign”語(yǔ)句、元件例化和“always”塊來(lái)描述邏輯功能。這三個(gè)例子描述的邏輯功能是同時(shí)執(zhí)行的。也就是說(shuō),如果把這三項(xiàng)寫(xiě)到一個(gè)Verilog模塊文件中,則它們的次序不會(huì)影響邏輯實(shí)現(xiàn)的功能。這就是前面提到的VerilogHDL語(yǔ)言與C語(yǔ)言的不同。此外,VerilogHDL程序是并行執(zhí)行語(yǔ)句,C程序是順序執(zhí)行語(yǔ)句。然而,在“always”模塊內(nèi),邏輯是按照指定的順序執(zhí)行的,這對(duì)于初學(xué)者來(lái)說(shuō)很不容易理解。難道這個(gè)說(shuō)法是錯(cuò)誤的嗎?其實(shí)VerilogHDL語(yǔ)言定義了一個(gè)串行塊(begin-end)語(yǔ)法,在begin-end串行塊中的語(yǔ)句是按照串行方式順序執(zhí)行的,定義這個(gè)串行塊語(yǔ)法很重要,因?yàn)榇蠖鄶?shù)邏輯都存在因果關(guān)系。但請(qǐng)注意,兩個(gè)或更多的“always”模塊也是同時(shí)執(zhí)行的,但是模塊內(nèi)部的語(yǔ)句是順序執(zhí)行的。這個(gè)VerilogHDL語(yǔ)法現(xiàn)象很重要,初學(xué)者需要重點(diǎn)理解。

3.3VerilogHDL語(yǔ)言規(guī)范

VerilogHDL語(yǔ)言和其他語(yǔ)言一樣,也有自己的語(yǔ)言規(guī)范。下面介紹一些基本的語(yǔ)言規(guī)范。

1.空白符

在VerilogHDL程序代碼中,空白符包括空格、tab、換行和換頁(yè)。使用空白符是為了使程序閱讀起來(lái)更方便,在綜合時(shí)空白符被忽略。

2.注釋

注釋是為了使閱讀者更容易理解程序,在綜合時(shí)也將被忽略。在VerilogHDL程序代碼中有兩種注釋方式。

(1)單行注釋:以“//”開(kāi)始到本行結(jié)束,不允許續(xù)行,如上例中的“//”注釋。

(2)多行注釋:以“/*”開(kāi)始,到“*/”結(jié)束。

3.標(biāo)志符

VerilogHDL中的標(biāo)志符可以是字母、數(shù)字以及符號(hào)“$”和“_”(下劃線)的任意組合,但標(biāo)志符的第一個(gè)字符必須以字母或者下劃線開(kāi)頭。另外,標(biāo)志符還可以用“\”開(kāi)頭,以空白符結(jié)尾,但反斜線和空白符在綜合時(shí)將被忽略。標(biāo)志符是區(qū)分大小寫(xiě)的。以下是幾個(gè)合法標(biāo)志符的舉例。

_nand2_inst//以下劃線開(kāi)頭的標(biāo)志符

counter//以字母開(kāi)頭的標(biāo)志符

\full_add1//“\”將被忽略,等同于full_add1標(biāo)志符

COUNTER//COUNTER與counter是不同的標(biāo)志符

以下是幾個(gè)非法標(biāo)志符的舉例。

50counter//非法,標(biāo)志符不允許以數(shù)字開(kāi)頭

cnt# //非法,標(biāo)志符中不允許包含字符#

4.關(guān)鍵字

VerilogHDL語(yǔ)言中的關(guān)鍵字是區(qū)分大小寫(xiě)的。例如,把關(guān)鍵字“always”寫(xiě)成“ALWAYS”是錯(cuò)誤的,這樣“ALWAYS”就變成了標(biāo)志符。

3.4VerilogHDL語(yǔ)言中的常量和變量

3.4.1常量

在程序運(yùn)行過(guò)程中,其值不能被改變的量稱為常量。VerilogHDL中的常量主要包括3種類型:整數(shù)型、實(shí)數(shù)型和字符串型。下劃線符號(hào)“_”可以隨意用在整數(shù)或?qū)崝?shù)中,它在綜合時(shí)將被忽略,其作用是提高易讀性。但要注意的是,下劃線符號(hào)在常量中不能作為首字符來(lái)用。

VerilogHDL有下列4種基本的值。

(1)?0:低電平、邏輯0或“假”。

(2)?1:高電平、邏輯1或“真”。

(3)?x或X:未知的邏輯狀態(tài)。

(4)?z或Z:高阻態(tài)。這4種值的含義都內(nèi)置于語(yǔ)言中。例如一個(gè)為0的值,綜合工具會(huì)根據(jù)語(yǔ)句的環(huán)境自動(dòng)判斷出是表示邏輯還是條件。另外,VerilogHDL語(yǔ)言中并不是只有值1表示條件為真,除0以外所有確定的數(shù)值都表示條件為真。在門(mén)的輸入或一個(gè)表達(dá)式中為“z”的值通常理解成“x”。此外,x值和z值都是不區(qū)分大小寫(xiě)的。也就是說(shuō),值Ox3z與值OX3Z是相同的。VerilogHDL中的常量是由以上四類基本值組成的。

1.整數(shù)型

在VerilogHDL中,定義整數(shù)型常量的方式如下:

+/-<位寬>'<進(jìn)制><數(shù)字>“+/-”定義整數(shù)的正負(fù)。整數(shù)為正數(shù)時(shí),“+”可忽略不寫(xiě);整數(shù)為負(fù)數(shù)時(shí),“-”應(yīng)寫(xiě)在數(shù)字定義表達(dá)式的最前面。注意:負(fù)號(hào)不可以放在位寬和進(jìn)制之間,也不可以放在進(jìn)制和具體的數(shù)之間。

位寬為整數(shù)對(duì)應(yīng)的二進(jìn)制寬度,它的單位為bit。

進(jìn)制用來(lái)定義整數(shù)的類型,它有以下4種表示形式:

(1)二進(jìn)制整數(shù)(b或B);

(2)十進(jìn)制整數(shù)(d、D或缺省);

(3)十六進(jìn)制整數(shù)(h或H);

(4)八進(jìn)制整數(shù)(o或O)。

數(shù)字是基于進(jìn)制的數(shù)字序列。另外,十六進(jìn)制中的a~f是不區(qū)分大小寫(xiě)的。以下是一些合法的整數(shù)表達(dá)式的舉例:

8'b10101111 //位寬為8位的二進(jìn)制數(shù)

8'hF2 //位寬為8位的十六進(jìn)制數(shù)

6'o71 //位寬為6位的八進(jìn)制數(shù)

4'd8 //位寬為4位的十進(jìn)制數(shù)

以下是一些非法的整數(shù)表達(dá)式的舉例:

4'd-9 //非法,負(fù)號(hào)應(yīng)該放在最左邊,即?-4'd9

(5+3)'b11001011 //非法,位寬不能為表達(dá)式在定義整數(shù)表達(dá)式時(shí)還應(yīng)注意以下幾點(diǎn):

(1)當(dāng)數(shù)字不說(shuō)明位寬時(shí),數(shù)字的位寬采用缺省位寬(這由具體的機(jī)器系統(tǒng)決定,但至少為32位)。如果一個(gè)整數(shù)的位寬沒(méi)有定義,則其寬度為相應(yīng)值中定義的位數(shù)。

例如:

hf2 //至少32位十六進(jìn)制數(shù)

'b101 //3位二進(jìn)制數(shù)

'o566 //3位八進(jìn)制數(shù)

(2)在默認(rèn)位寬與進(jìn)制情況下,整數(shù)就代表十進(jìn)制的數(shù)。

例如:

76 //表示十進(jìn)制數(shù)76

-35 //表示十進(jìn)制數(shù)-35

(3)?x(或z)在二進(jìn)制中代表1位x(或z),在八進(jìn)制中代表3位x(或z),在十六進(jìn)制中代表4位x(或z)。

例如:

6'bxxx010 //等同于6'ox2

8'b1001zzzz //等同于8'h9z

(4)如果定義的位寬比實(shí)際的位數(shù)長(zhǎng),則通常在數(shù)字左邊填0補(bǔ)位。對(duì)于數(shù)字左邊一位是x或z的情況,就要用相對(duì)應(yīng)的x或z來(lái)補(bǔ)位。

例如:

8'b11 //等同于8'b00000011

8'bx01z //等同于8'bxxxxx01z

如果定義的位寬比實(shí)際的位數(shù)小,那么最左邊多余的位將被忽略。

例如:

4'b1101_1100 //等同于4'b1100

(5)?“?”是高阻態(tài)z的另一種表達(dá)符號(hào),二者是等價(jià)的。另外,在使用case表達(dá)式時(shí)建議使用這種寫(xiě)法,以提高程序的可讀性。

例如:

12'dz //位寬為12位的十進(jìn)制數(shù),其值為高阻值

12'd? //等同于12'dz

(6)下劃線可以用來(lái)分隔數(shù)字,以提高程序可讀性。但不可以用在位寬和進(jìn)制處,只能用在具體的數(shù)字之間。

例如:

16'b1010_1011_1111_1010 //合法格式

8'b_0011_1010 //非法格式

(7)在定義整數(shù)型常量的方式中,位寬和“'”之間以及進(jìn)制和數(shù)值之間允許出現(xiàn)空格,但在“'”和進(jìn)制之間以及數(shù)值之中是不允許出現(xiàn)空格的。

例如:

8'b1011_1010 //合法格式

8'b1011_1011 //非法格式

2.實(shí)數(shù)型

實(shí)數(shù)型數(shù)據(jù)可用以下兩種形式定義:

(1)十進(jìn)制計(jì)數(shù)法,規(guī)定此方法的小數(shù)點(diǎn)兩側(cè)必須有數(shù)字,如5.0、6.728、-0.1、6。

(2)科學(xué)計(jì)數(shù)法,如35_1.2e2(其值為35120.0)、2.6E-3(其值為0.0026)。

VerilogHDL語(yǔ)言中的實(shí)數(shù)型數(shù)據(jù)可轉(zhuǎn)化為整數(shù)型數(shù)據(jù),其轉(zhuǎn)化方法采用數(shù)學(xué)中的四舍五入法則。

3.字符串型

字符串是雙引號(hào)內(nèi)的字符序列。字符串不能分成多行書(shū)寫(xiě)。另外,字符串中一個(gè)字母為8位ASCII值,存儲(chǔ)一串字符串的位空間大小需用字符串中的個(gè)數(shù)乘以8來(lái)計(jì)算。字符串中的空格也算一個(gè)字符。例如:

"VerilogHDL" //定義字符串

...

reg[11*8:1]Message; //申請(qǐng)存儲(chǔ)空間

Message="VerilogHDL"

字符串中的特殊字符需用“\”來(lái)說(shuō)明,如

\n //換行符

\t //Tab鍵

\\ //字符“\”本身

\" //雙引號(hào)"

\206 //八進(jìn)制數(shù)206對(duì)應(yīng)的ASCII值3.4.2符號(hào)常量

在VerilogHDL語(yǔ)言中,可用parameter來(lái)定義常量,即用parameter定義一個(gè)標(biāo)識(shí)符來(lái)代表一個(gè)常量,此常量稱為符號(hào)常量。采用標(biāo)識(shí)符代表一個(gè)常量可提高程序的可讀性和可維護(hù)性。parameter型數(shù)據(jù)是一種常量型數(shù)據(jù),其說(shuō)明格式如下:

parameter 參數(shù)名1?=?表達(dá)式,參數(shù)名2?=?表達(dá)式,…,參數(shù)名n?=?表達(dá)式:例如:

parameterdatawidth=8;//定義參數(shù)datawidth為常量8

parametere=25,f=29; //定義兩個(gè)常數(shù)參數(shù)

parameterr=5.7; //聲明r為一個(gè)實(shí)型參數(shù)

parameterbyte_size=8,byte_msb=byte_size-1; //用常數(shù)表達(dá)式賦值

利用parameter型數(shù)據(jù)可方便地在層次模塊間改變參數(shù)。下面用一個(gè)例子進(jìn)行示范。引用acreage實(shí)例時(shí),d1、d2的width將采用不同的值2和5,且d1的height為5,即用#(2,5)向d1中傳遞width=2,height=5,用#(5)向d2中傳遞width=5,height仍為1。

3.4.3變量

變量是指在程序運(yùn)行過(guò)程中可以任意改變的量。VerilogHDL語(yǔ)言中變量有以下兩種定義類型。

(1)線網(wǎng)類型(net):表示VerilogHDL結(jié)構(gòu)化元件間的物理連線,它的值由驅(qū)動(dòng)元件的值決定,例如連續(xù)賦值或門(mén)的輸出。線網(wǎng)的缺省值為z(高阻態(tài))。

(2)寄存器類型(register):表示一個(gè)抽象的數(shù)據(jù)存儲(chǔ)單元,它只能在always語(yǔ)句和initial語(yǔ)句中被賦值。寄存器的缺省值為x(未知狀態(tài))。

net數(shù)據(jù)類型包括wire、tri、wor、trior、wand、triand、trieg、tri0、tri1、supply0和supply1。register數(shù)據(jù)類型包括reg、integer、real和time。線網(wǎng)類型中的wire類型和寄存器類型中的reg類型是在工程中經(jīng)常用到的兩種類型,其他的幾乎不用。因此下面我們將詳細(xì)介紹這兩種類型。

1.?wire型變量

wire型數(shù)據(jù)常用來(lái)表示用assign關(guān)鍵字指定的組合邏輯信號(hào)。VerilogHDL程序模塊中輸入/輸出信號(hào)類型缺省時(shí)自動(dòng)定義為wire型。wire型信號(hào)可以用作任何方程式的輸入,也可以用作“assign”語(yǔ)句或?qū)嵗妮敵觥?/p>

wire型變量的定義格式如下:

wire[n-1:0]數(shù)據(jù)名1,數(shù)據(jù)名2,…,數(shù)據(jù)名n;

wire是wire型數(shù)據(jù)的確認(rèn)符,[n-1:0]代表該數(shù)據(jù)的位寬,數(shù)據(jù)名用來(lái)定義變量的名字。如果一次定義多個(gè)數(shù)據(jù),則數(shù)據(jù)名之間用逗號(hào)隔開(kāi)。聲明語(yǔ)句的最后要用分號(hào)表示語(yǔ)句結(jié)束。例如:

wirea; //定義了一個(gè)1位的名為a的wire型數(shù)據(jù)變量

wire[7:0]b; //定義了一個(gè)8位的名為b的wire型數(shù)據(jù)變量

wire[8:1]c; //定義了一個(gè)8位的名為c的wire型數(shù)據(jù)變量

wire[9:2]d; //定義了一個(gè)8位的名為d的wire型數(shù)據(jù)變量

2.?reg型變量

reg型數(shù)據(jù)常用在“always”和“initial”過(guò)程塊中,reg型數(shù)據(jù)的缺省初始值是不定值。reg型數(shù)據(jù)可以賦正值,也可以賦負(fù)值。但當(dāng)一個(gè)reg型數(shù)據(jù)是一個(gè)表達(dá)式中的操作數(shù)時(shí),它的值被當(dāng)作無(wú)符號(hào)值,即正值。例如,當(dāng)一個(gè)四位的寄存器用作表達(dá)式中的操作數(shù)時(shí),如果開(kāi)始寄存器被賦以值-1,則在表達(dá)式中進(jìn)行運(yùn)算時(shí),其值被認(rèn)為是+15。

reg型變量的定義格式與wire類似,如下所示:

reg[n-1:0]數(shù)據(jù)名1,數(shù)據(jù)名2,…,數(shù)據(jù)名n;

reg是reg型數(shù)據(jù)的確認(rèn)標(biāo)識(shí)符,[n-1:0]代表該數(shù)據(jù)的位寬,數(shù)據(jù)名用來(lái)定義變量的名字。如果一次定義多個(gè)數(shù)據(jù),則數(shù)據(jù)名之間用逗號(hào)隔開(kāi)。聲明語(yǔ)句的最后要用分號(hào)表示語(yǔ)句結(jié)束。

例如:

rega; //定義了一個(gè)1位的名為a的reg型數(shù)據(jù)變量

reg[3:0]b; //定義了一個(gè)4位的名為b的reg型數(shù)據(jù)變量

reg[4:1]c,d; //定義了兩個(gè)4位的名為c、d的reg型數(shù)據(jù)變量在VerilogHDL語(yǔ)言中,用reg類型變量可構(gòu)成寄存器和存儲(chǔ)器,其中,存儲(chǔ)器也被稱為數(shù)組。它們的定義格式如下:

reg[n-1:0]數(shù)據(jù)名1,數(shù)據(jù)名2,…; //定義寄存器

reg[n-1:0]數(shù)據(jù)名1[i-1:0],數(shù)據(jù)名2[j-1:0],…; //定義存儲(chǔ)器例如:

regmybit; //定義一個(gè)名為mybit的1位寄存器

reg[7:0]mybyte; //定義一個(gè)名為mybyte的8位寄存器

regmyarray[3:0]; //定義四個(gè)名為myarray的1位存儲(chǔ)器

reg[7:0]memory[11:0]; //定義一個(gè)名為memory的行為12位、列為8位的數(shù)組雖然寄存器和存儲(chǔ)器的定義格式很相似,但它們的讀/寫(xiě)操作也有不同之處。一個(gè)由n個(gè)1位寄存器構(gòu)成的存儲(chǔ)器組是不同于一個(gè)n位寄存器的。例如:

reg[n-1:0]rega; //一個(gè)n位寄存器

regmema[n-1:0]; //一個(gè)由n個(gè)1位寄存器構(gòu)成的存儲(chǔ)器組

一個(gè)n位寄存器可以在一條賦值語(yǔ)句中進(jìn)行賦值,而一個(gè)完整的存儲(chǔ)器則不行。

例如:

rega=?0; //合法賦值語(yǔ)句

mema=?0; //非法賦值語(yǔ)句如果想對(duì)memory中的存儲(chǔ)單元進(jìn)行讀/寫(xiě)操作,則必須指定該單元在存儲(chǔ)器中的地址。例如,下面的寫(xiě)法是正確的。

mema[3]=0; //給memory中的第3個(gè)存儲(chǔ)單元賦值為0

注意:如果要對(duì)變量重新賦值,那么此變量就只能出現(xiàn)在一個(gè)過(guò)程語(yǔ)句中。 3.5VerilogHDL語(yǔ)言中的運(yùn)算符

VerilogHDL語(yǔ)言的運(yùn)算符范圍很廣,按其功能大致可分為以下幾類:

(1)算術(shù)運(yùn)算符(+、-、*、/、%);

(2)位運(yùn)算符(~、&、|、^、^~、~^);

(3)邏輯運(yùn)算符(&&、||、!);

(4)關(guān)系運(yùn)算符(>、<、>=、<=);

(5)等式運(yùn)算符(==、!=、===、!==);

(6)移位運(yùn)算符(<<、>>);

(7)條件運(yùn)算符(?:);

(8)拼接運(yùn)算符({?});

(9)縮減運(yùn)算符(&、~&、|、~|、^、~^、^~)。

上述運(yùn)算符在使用時(shí)同C語(yǔ)言的運(yùn)算符一樣,也有優(yōu)先級(jí)別。表3.3是對(duì)各種運(yùn)算符的優(yōu)先級(jí)的說(shuō)明。不過(guò)建議在書(shū)寫(xiě)程序時(shí)用括號(hào)(?)來(lái)控制運(yùn)算符的優(yōu)先級(jí),這樣可增加程序的可讀性,避免出錯(cuò)。表3.3運(yùn)算符的優(yōu)先級(jí)別在VerilogHDL語(yǔ)言中運(yùn)算符所帶的操作數(shù)是不同的,按其所帶操作數(shù)的個(gè)數(shù)運(yùn)算符可分為以下三種:

(1)單目運(yùn)算符:可以帶一個(gè)操作數(shù),操作數(shù)放在運(yùn)算符的右邊。

(2)雙目運(yùn)算符:可以帶兩個(gè)操作數(shù),操作數(shù)放在運(yùn)算符的兩邊。

(3)三目運(yùn)算符:可以帶三個(gè)操作,這三個(gè)操作數(shù)用三目運(yùn)算符分隔開(kāi)。例如:

clk=~clk; //“~”是一個(gè)單目取反運(yùn)算符,clk是操作數(shù)

c=a|b; //“|”是一個(gè)雙目按位或運(yùn)算符,a和b是操作數(shù)

r=s?a:b; //“?:”是一個(gè)三目條件運(yùn)算符,s、a和b是操作數(shù)

下面按功能分類對(duì)運(yùn)算符的使用進(jìn)行介紹。3.5.1算術(shù)運(yùn)算符

在VerilogHDL語(yǔ)言中,常用的算術(shù)運(yùn)算符包括以下5種:

(1)?+:加法運(yùn)算符;

(2)?-:減法運(yùn)算符;

(3)?*:乘法運(yùn)算符;

(4)?/:?除法運(yùn)算符;

(5)?%:求模運(yùn)算符,或稱為求余運(yùn)算符,如7%3的值為1。

注意:在進(jìn)行算術(shù)運(yùn)算操作時(shí),如果某一個(gè)操作數(shù)有不確定的值x,則整個(gè)結(jié)果也為不定值x。3.5.2位運(yùn)算符

VerilogHDL語(yǔ)言中位運(yùn)算符包括:

(1)?~:按位取反;

(2)?&:按位與;

(3)?|:按位或;

(4)?^:按位異或;

(5)?^~?或?~^:按位同或(異或非)。

下面對(duì)各運(yùn)算符分別進(jìn)行介紹。

1.按位取反運(yùn)算符

按位取反是一個(gè)單目運(yùn)算符,用來(lái)對(duì)一個(gè)操作數(shù)進(jìn)行按位取反運(yùn)算,其運(yùn)算規(guī)則如表3.4所示。表3.4按位取反的真值表

2.按位與運(yùn)算符

按位與運(yùn)算就是將兩個(gè)操作數(shù)的相應(yīng)位進(jìn)行與運(yùn)算,其運(yùn)算規(guī)則如表3.5所示。表3.5按位與的真值表

3.按位或運(yùn)算符

按位或運(yùn)算就是將兩個(gè)操作數(shù)的相應(yīng)位進(jìn)行或運(yùn)算,其運(yùn)算規(guī)則如表3.6所示。表3.6按位或的真值表

4.按位異或運(yùn)算符

按位異或運(yùn)算就是將兩個(gè)操作數(shù)的相應(yīng)位進(jìn)行異或運(yùn)算,其運(yùn)算規(guī)則如表3.7所示。表3.7按位異或的真值表

5.按位同或運(yùn)算符

按位同或運(yùn)算就是將兩個(gè)操作數(shù)的相應(yīng)位先進(jìn)行異或運(yùn)算再進(jìn)行非運(yùn)算,其運(yùn)算規(guī)則如表3.8所示。表3.8按位同或的真值表注意:兩個(gè)長(zhǎng)度不同的數(shù)據(jù)進(jìn)行位運(yùn)算時(shí),系統(tǒng)會(huì)自動(dòng)使兩者遵守右端對(duì)齊原則。位數(shù)少的操作數(shù)會(huì)在相應(yīng)的高位用0填滿,以使兩個(gè)操作數(shù)按位進(jìn)行操作。

例如,A=5'b10101,B=2'b11,則有:

~A=5'b01010;

A&B=5'b00001;

A|B=5'b10111;

A^B=5'b10110;

A^~B=5'b01001。3.5.3邏輯運(yùn)算符

VerilogHDL語(yǔ)言中邏輯運(yùn)算符包括:

(1)?&&:邏輯與;

(2)?||:邏輯或;

(3)?!:邏輯非;

“&&”和“||”是雙目運(yùn)算符,“!”是單目運(yùn)算符。表3.9為邏輯運(yùn)算符的真值表。表中的“真”表示操作數(shù)位中有邏輯1出現(xiàn),即位中的邏輯不全為0;“假”則表示操作數(shù)位中的邏輯全為0。表3.9邏輯運(yùn)算符的真值表例如:若A=1,B=0,C=4'b1001,D=4'b0000,則有:

!A=0;!B=1;A&&B=0;A||B=1;

!C=0;!D=1;C&&D=0;C||D=1;3.5.4關(guān)系運(yùn)算符

VerilogHDL語(yǔ)言中關(guān)系運(yùn)算符包括:

(1)?<:小于;

(2)?>:大于;

(3)?<=:小于或等于;

(4)?>=:大于或等于。

注:“<=”操作符可作為賦值符號(hào),這將在3.6節(jié)中詳細(xì)講解。

關(guān)系運(yùn)算符是雙目運(yùn)算符。在進(jìn)行關(guān)系運(yùn)算時(shí),如果兩個(gè)操作數(shù)比較的結(jié)果是假,則返回值是0;如果比較的結(jié)果是真,則返回值是1;如果某個(gè)操作數(shù)的值不定,則關(guān)系是模糊的,返回值是不確定值。3.5.5等式運(yùn)算符

VerilogHDL語(yǔ)言中等式運(yùn)算符包括:

(1)?==:等于;

(2)?!=:不等于;

(3)?===:全等;

(4)?!==:不全等。這四種運(yùn)算符都是雙目運(yùn)算符,其結(jié)果由兩個(gè)操作數(shù)的值決定。但“==”和“!=”運(yùn)算符會(huì)比“===”和“!==”運(yùn)算符多出一個(gè)比較結(jié)果——不定值(x)。這是因?yàn)椴僮鲾?shù)中某些位可能是不定值x和高阻值z(mì)。用“==”和“!=”運(yùn)算符進(jìn)行比較時(shí),結(jié)果可能為不定值x;“===”和“!==”運(yùn)算符則不同,它們?cè)趯?duì)操作數(shù)進(jìn)行比較時(shí)對(duì)某些位的不定值x和高阻值z(mì)也進(jìn)行比較,兩個(gè)操作數(shù)必須完全一致,其比較結(jié)果只有1或0?!?==”和“!==”運(yùn)算符常用于case表達(dá)式的判別,所以又稱為“case等式運(yùn)算符”。這四個(gè)等式運(yùn)算符的優(yōu)先級(jí)別是相同的。表3.10列出了“==”和“===”運(yùn)算符的真值表。“!=”和“!==”運(yùn)算符的真值表類似,讀者可自行推導(dǎo)出來(lái)。表3.10相等運(yùn)算符(==)和全等運(yùn)算符(===)的真值表下面舉例說(shuō)明“==”和“===”的區(qū)別。例如:

if(A==1'bx)beginend;(當(dāng)A等于x時(shí),這個(gè)語(yǔ)句不執(zhí)行)

if(A===1'bx)beginend;(當(dāng)A等于x時(shí),這個(gè)語(yǔ)句執(zhí)行)3.5.6移位運(yùn)算符

在VerilogHDL中有以下兩種移位運(yùn)算符:

(1)?>>:右移;

(2)?<<:左移。

其使用方法如下:

a>>n或a<<n

a代表要進(jìn)行移位的操作數(shù),n代表要移幾位。這兩種移位運(yùn)算都用0來(lái)填補(bǔ)移出的空位。例如:

start=1; //start在初始時(shí)刻的值設(shè)為0001

result=(start<<2); //移位后,start的值為0100,然后賦給result從上面的例子中可以看出,start在移過(guò)兩位以后,用0來(lái)填補(bǔ)空出的位。

進(jìn)行移位運(yùn)算時(shí)應(yīng)注意移位前后變量的位數(shù),例如:

4'b1001<<1=5'b10010;

4'b1001<<2=6'b100100;

1<<6=32'b1000000;

4'b1001>>1=4'b0100;

4'b1001>>4=4'b0000;3.5.7條件運(yùn)算符

VerilogHDL中的條件運(yùn)算符為?:。

該條件運(yùn)算符的定義與C語(yǔ)言中的定義一樣。方式如下:

信號(hào)=條件?真條件返回的表達(dá)式:假條件返回的表達(dá)式;

例如:

out=(a>=b)?a:b;

這是一個(gè)比較器語(yǔ)句,返回兩者(a和b)中較大的數(shù)。3.5.8位拼接運(yùn)算符

VerilogHDL語(yǔ)言中的拼接運(yùn)算符為{}。

該運(yùn)算符可以把兩個(gè)或多個(gè)信號(hào)的某些位拼接起來(lái)。其使用方法如下:

{信號(hào)1的某幾位,信號(hào)2的某幾位,...,...,信號(hào)n的某幾位}

即把某些信號(hào)的某些位詳細(xì)地列出來(lái),中間用逗號(hào)分開(kāi),最后用大括號(hào)括起來(lái)表示一個(gè)整體信號(hào)。

例如:

{a,b[6:5],c,3'b101} //等同于{a,b[6],b[5],c,1'b1,1'b0,1'b1}

{b,{3{a,b}}} //等同于{b,a,b,a,b,a,b}3.5.9縮減運(yùn)算符

VerilogHDL中的縮減運(yùn)算符如下:

(1)?&:與;

(2)?~&:與非;

(3)?|:或;

(4)?~|:或非;

(5)?^:異或;

(6)?~^或^~:同或??s減運(yùn)算符是單目運(yùn)算符,放在操作數(shù)前面。縮減運(yùn)算是對(duì)單個(gè)操作數(shù)進(jìn)行邏輯遞推運(yùn)算,最后的運(yùn)算結(jié)果是一位二進(jìn)制數(shù)??s減運(yùn)算的具體運(yùn)算過(guò)程為:第一步將操作數(shù)的第一位與第二位進(jìn)行邏輯運(yùn)算,第二步將運(yùn)算結(jié)果與第三位進(jìn)行邏輯運(yùn)算,依次類推,直至最后一位。

例如:

reg[3:0]A;

regC;

C=&A; //等同于C=((A[0]&A[1])&A[2])&A[3]

3.6VerilogHDL語(yǔ)言中的塊語(yǔ)句和賦值語(yǔ)句

3.6.1塊語(yǔ)句

在VerilogHDL程序中,塊語(yǔ)句是用塊標(biāo)志符begin-end或fork-join來(lái)界定的一組語(yǔ)句,這類似于C語(yǔ)言中的“{?}”,通常用來(lái)將兩條或多條語(yǔ)句組合在一起。3.6.2賦值語(yǔ)句

在VerilogHDL語(yǔ)言中,信號(hào)有以下兩種賦值方式:

(1)?=:阻塞賦值;

(2)?<=:非阻塞賦值。

阻塞賦值和非阻塞賦值的區(qū)別是:阻塞賦值在阻塞語(yǔ)句結(jié)束時(shí)就立即完成賦值操作;非阻塞賦值是在整個(gè)過(guò)程塊結(jié)束時(shí)才完成賦值操作。在上例的“always”塊中采用阻塞賦值方式,定義了兩個(gè)reg型信號(hào)b和c,clk信號(hào)的上升沿到來(lái)時(shí),a先賦值給b,然后b賦值給c(即等于a)。需要注意的是,上述兩個(gè)步驟是在同一個(gè)clk周期內(nèi)執(zhí)行的,并且?guī)缀鯖](méi)有延遲。阻塞賦值描述的電路如圖3.2所示。圖3.2阻塞賦值描述的電路如果把上例“always”塊中的阻塞賦值方式改為非阻塞賦值方式(即b<=a,c<=b),則在clk信號(hào)的上升沿到來(lái)時(shí),a賦值給b和b賦值給c是同時(shí)進(jìn)行的,即在同一個(gè)clk周期內(nèi)b取a的值,同時(shí)c取b的值,但c并沒(méi)有把b更新后的值取出來(lái),而取的是原來(lái)的b值,這樣一來(lái),c值將總比b值延遲一個(gè)clk周期。非阻塞賦值描述的電路如圖3.3所示。圖3.3非阻塞賦值描述的電路阻塞語(yǔ)句和非阻塞語(yǔ)句是兩個(gè)非常重要的概念,在應(yīng)用中應(yīng)加以區(qū)別。通常,阻塞賦值用于描述組合邏輯電路,而非阻塞賦值則用于描述時(shí)序邏輯電路。

3.7過(guò)程語(yǔ)句

VerilogHDL語(yǔ)言中的一般過(guò)程模塊都從屬于以下兩種結(jié)構(gòu)的說(shuō)明語(yǔ)句。

(1)?initial說(shuō)明語(yǔ)句;

(2)?always說(shuō)明語(yǔ)句。

initial和always說(shuō)明語(yǔ)句在仿真的一開(kāi)始同時(shí)執(zhí)行。initial語(yǔ)句只執(zhí)行一次,相反,always語(yǔ)句則不斷地重復(fù)執(zhí)行,直到仿真過(guò)程結(jié)束。在一個(gè)模塊中,使用initial和always語(yǔ)句的次數(shù)是不受限制的。3.7.2always語(yǔ)句

always過(guò)程語(yǔ)句使用的模板如下:

always@(<敏感信號(hào)表達(dá)式>)

begin

//過(guò)程賦值

//if-else、case、casex、casez選擇語(yǔ)句

//for、while等循環(huán)塊

//task、function調(diào)用

end

always過(guò)程語(yǔ)句通常帶有觸發(fā)條件,觸發(fā)條件被寫(xiě)在敏感信號(hào)列表中,只有當(dāng)觸發(fā)條件滿足條件或發(fā)生變化時(shí),其后的“begin-end”塊語(yǔ)句才能被執(zhí)行。

敏感信號(hào)可以分為兩種類型:邊沿敏感型、電平敏感型。

1.邊沿敏感型

例如:

always@(posedgeclockornegedgereset)//由兩個(gè)邊沿觸發(fā)always塊

begin

end

posedge和negedge是VerilogHDL提供的兩個(gè)關(guān)鍵字。上述敏感信號(hào)中posedgeclock表示時(shí)鐘信號(hào)clock的上升沿作為觸發(fā)條件,而negedge

reset則表示reset信號(hào)的下降沿作為觸發(fā)條件。 3.8條件語(yǔ)句

3.8.1if-else語(yǔ)句

if語(yǔ)句類似C語(yǔ)言中的if-else語(yǔ)句。其使用方法有以下三種:

(1)?if(表達(dá)式) 語(yǔ)句;

(2)?if(表達(dá)式) 語(yǔ)句1;

?else 語(yǔ)句2;

(3)?if(表達(dá)式1) 語(yǔ)句1;

elseif(表達(dá)式2) 語(yǔ)句2;

?elseif(表達(dá)式3) 語(yǔ)句3;

?…

elseif(表達(dá)式m) 語(yǔ)句m;

?else 語(yǔ)句n;在使用if-else語(yǔ)句時(shí),應(yīng)注意以下幾點(diǎn):

(1)上述三種形式中,“表達(dá)式”一般為邏輯表達(dá)式或關(guān)系表達(dá)式,也可以是1位的變量。系統(tǒng)對(duì)表達(dá)式的值進(jìn)行判斷,若為0、x、z,則按“假”處理;若為1,則按“真”處理,執(zhí)行指定的語(yǔ)句。

(2)在if和else后面可以包含多個(gè)操作語(yǔ)句,多操作語(yǔ)句時(shí)用begin和end這兩個(gè)關(guān)鍵詞將幾個(gè)語(yǔ)句包含起來(lái)成為一個(gè)復(fù)合塊語(yǔ)句。例如:

(3)“表達(dá)式”中允許一定形式的簡(jiǎn)寫(xiě)方式。

例如:

if(a)//等同于if(a==1)

if(!b)//等同于if(b!=1)

(4)?if語(yǔ)句可以嵌套使用。在if語(yǔ)句中包含一個(gè)或多個(gè)if語(yǔ)句稱為if語(yǔ)句的嵌套使用。一般形式如下:當(dāng)敏感表達(dá)式的值為1時(shí),執(zhí)行語(yǔ)句1;當(dāng)值為2時(shí),執(zhí)行語(yǔ)句2;依次類推。如果敏感表達(dá)式的值與上面列出的值都不符,則執(zhí)行default后面的語(yǔ)句。如果前面已列出了敏感表達(dá)式所有可能的取值,則default語(yǔ)句可以省略。

例如:

//此程序?yàn)楸緯?shū)實(shí)驗(yàn)五中的一小段程序,它的作用是依次快速點(diǎn)亮EZBoard開(kāi)發(fā)

//板上的四位數(shù)碼管。因人眼存在惰性現(xiàn)象,故誤認(rèn)為四位數(shù)碼管同時(shí)處于點(diǎn)亮狀態(tài)

always@(posedgems2_clkornegedgesys_rst)begin在case語(yǔ)句中,敏感表達(dá)式與1~n間的比較是一種全等比較,必須保證兩者對(duì)應(yīng)位的值全等。casez與casex語(yǔ)句是case語(yǔ)句的兩種擴(kuò)展類型。在casez語(yǔ)句中,如果分支表達(dá)式某些位的值為高阻z,那么對(duì)這些位的值就不予比較,即此位的值相等,因此只需比較其他的位。在casex語(yǔ)句中,如果比較的雙方有一方的某些位的值是x或z,那么該位的值就都不予比較。case、casez和casex的比較關(guān)系如表3.11所示。表3.11case、casez和casex語(yǔ)句的真值表此外,可用符號(hào)“?”來(lái)表示0、1、z、x這四種值。 3.9循環(huán)語(yǔ)句

在VerilogHDL中提供如下四種類型的循環(huán)語(yǔ)句。

(1)?forever語(yǔ)句;

(2)?repeat語(yǔ)句;

(3)?while語(yǔ)句;

(4)?for語(yǔ)句。

一般綜合器只支持for循環(huán)語(yǔ)句,不過(guò)建議盡量少用for循環(huán)語(yǔ)句,因?yàn)閒or循環(huán)語(yǔ)句占用的邏輯資源大。循環(huán)語(yǔ)句一般用于仿真語(yǔ)言中。下面對(duì)各種循環(huán)語(yǔ)句進(jìn)行詳細(xì)介紹。3.9.1forever語(yǔ)句

forever語(yǔ)句的使用格式如下:

forever 語(yǔ)句;

forever begin

多條語(yǔ)句

end

forever循環(huán)語(yǔ)句常用于產(chǎn)生周期性的波形,用來(lái)作為仿真測(cè)試信號(hào)。它與always語(yǔ)句的不同之處在于不能獨(dú)立寫(xiě)在程序中,而必須寫(xiě)在initial塊中。3.9.2repeat語(yǔ)句

repeat語(yǔ)句的使用格式如下:

repeat(循環(huán)次數(shù)表達(dá)式)語(yǔ)句;

repeat(循環(huán)次數(shù)表達(dá)式)???begin

多條語(yǔ)句

end3.9.3while語(yǔ)句

while語(yǔ)句的使用格式如下:

while(循環(huán)次數(shù)條件表達(dá)式)語(yǔ)句

while(循環(huán)次數(shù)條件表達(dá)式)begin

多條語(yǔ)句

end

下面舉一個(gè)while語(yǔ)句的例子,該例用while循環(huán)語(yǔ)句實(shí)現(xiàn)了一個(gè)32位整數(shù)的循環(huán)顯示。3.9.4for語(yǔ)句

for循環(huán)語(yǔ)句的一般形式如下:

for(表達(dá)式1;表達(dá)式2;表達(dá)式3)語(yǔ)句

for語(yǔ)句的執(zhí)行過(guò)程如下:

(1)先求解表達(dá)式1。

(2)求解表達(dá)式2,若其值為真(非0),則執(zhí)行for語(yǔ)句中指定的內(nèi)嵌語(yǔ)句,然后執(zhí)行下面的第3步;若為假(0),則結(jié)束循環(huán),轉(zhuǎn)到第(5)步。

(3)若表達(dá)式為真,則在執(zhí)行指定的語(yǔ)句后,求解表達(dá)式3。

(4)轉(zhuǎn)回上面的步驟(2)繼續(xù)執(zhí)行。

(5)執(zhí)行for語(yǔ)句下面的語(yǔ)句。

3.10task和function說(shuō)明語(yǔ)句

3.10.1task說(shuō)明語(yǔ)句

task說(shuō)明語(yǔ)句的格式如下:

task<任務(wù)名>;

<端口及數(shù)據(jù)類型聲明語(yǔ)句>

<語(yǔ)句1>

<語(yǔ)句2>

<語(yǔ)句n>

endtask

任務(wù)的調(diào)用格式如下:

<任務(wù)名>(端口1,端口2,...,端口n);3.10.2function說(shuō)明語(yǔ)句

定義function函數(shù)的目的是返回一個(gè)用于表達(dá)式的值。其定義格式如下:

function<返回值的類型或范圍>(函數(shù)名);

<端口說(shuō)明語(yǔ)句>

<變量類型說(shuō)明語(yǔ)句>

<語(yǔ)句1>

<語(yǔ)句2>

<語(yǔ)句n>

endfunction

<返回值的類型或范圍>這一項(xiàng)是可選項(xiàng),如缺省則返回值為一位寄存器類型數(shù)據(jù)。函數(shù)的定義把函數(shù)返回值所賦值寄存器的名稱初始化為與函數(shù)同名的內(nèi)部變量。例如:

function[7:0]getbyte;

input[15:0]address;

begin

getbyte=address[7:0];//從地址字中提取低字節(jié)

end

endfunction

函數(shù)的調(diào)用格式如下:

<函數(shù)名>(<表達(dá)式>,<表達(dá)式>*)其中,函數(shù)名作為確認(rèn)符。下面的例子通過(guò)對(duì)兩次調(diào)用函數(shù)getbyte的結(jié)果值進(jìn)行位拼接運(yùn)算來(lái)生成一個(gè)字。

word=control?{getbyte(msbyte),getbyte(lsbyte)}:0;

與任務(wù)相比較,函數(shù)的使用有較多的約束。下面給出的是函數(shù)的使用規(guī)則。

(1)函數(shù)的定義不能包含有任何時(shí)間控制語(yǔ)句,即任何用#、@或wait來(lái)標(biāo)識(shí)的語(yǔ)句。

(2)函數(shù)不能啟動(dòng)任務(wù)。

(3)定義函數(shù)時(shí)至少要有一個(gè)輸入?yún)⒘俊?/p>

(4)在函數(shù)的定義中必須有一條賦值語(yǔ)句給函數(shù)中的一個(gè)內(nèi)部變量賦以函數(shù)的結(jié)果值,該內(nèi)部變量具有和函數(shù)名相同的名字。

3.11系統(tǒng)任務(wù)和函數(shù)

VerilogHDL的系統(tǒng)任務(wù)和系統(tǒng)函數(shù)主要用于仿真。在數(shù)字電路設(shè)計(jì)中,仿真是一個(gè)重要的環(huán)節(jié),它可以檢查電路邏輯設(shè)計(jì)的準(zhǔn)確性。一個(gè)復(fù)雜的邏輯電路被VerilogHDL語(yǔ)言描述后,綜合器綜合出來(lái)的只是一個(gè)個(gè)模塊的組合。如果中間的哪個(gè)模塊描述錯(cuò)誤,則此時(shí)不借助仿真器來(lái)查看內(nèi)部信號(hào),要查出錯(cuò)誤是相當(dāng)困難的。

仿真可分為前仿真和后仿真。在設(shè)計(jì)輸入階段進(jìn)行的仿真不考慮信號(hào)的時(shí)延等因素,稱為功能仿真,即前仿真;后仿真又稱時(shí)序仿真,它是指在選擇了具體器件并完成了布局布線后進(jìn)行的含電路實(shí)際關(guān)系的仿真。

VerilogHDL語(yǔ)言中有以下系統(tǒng)函數(shù)和任務(wù):

$bitstoreal、$rtoi、$display、$setup、$finish、$skew、$hold、$setuphold、$itor、$strobe、$period、$time、$printtimescale、$timefoemat、$realtime、$width、$realtobits、$write、$recovery。

在VerilogHDL語(yǔ)言中,每個(gè)系統(tǒng)函數(shù)和任務(wù)前面都用一個(gè)標(biāo)識(shí)符?$?來(lái)加以確認(rèn)。這些系統(tǒng)函數(shù)和任務(wù)提供了非常強(qiáng)大的功能。下面對(duì)一些常用的系統(tǒng)函數(shù)和任務(wù)逐一進(jìn)行介紹。3.11.1系統(tǒng)任務(wù)$display和$write

$display和$write的格式如下:

$display("格式控制符",輸出變量列表);

$display("字符串");

$write("格式控制符",輸出變量列表);

$write("字符串");

$display和?$write是兩個(gè)系統(tǒng)任務(wù),兩者的功能都類似于C語(yǔ)言中的printf函數(shù),都用于顯示結(jié)果信息。其區(qū)別是$display在執(zhí)行完整個(gè)函數(shù)后能自動(dòng)進(jìn)行換行,而?$write不能。如果想在一行里輸出多個(gè)信息,則可以使用?$write。在?$display和?$write中,定義信號(hào)的輸出格式控制符如表3.12所示。表3.12格?式?控?制?符有時(shí)輸出的信號(hào)需要用空格隔開(kāi),如用“\t”字符,表示一個(gè)Tab鍵。這種字符在VerilogHDL語(yǔ)言中叫做轉(zhuǎn)義字符。表3.13中列舉了幾種常用的轉(zhuǎn)義字符。表3.13轉(zhuǎn)義字符如果輸出列表中表達(dá)式的值包含有不確定的值或高阻值,則其輸出結(jié)果遵循以下規(guī)則:

(1)在輸出格式為十進(jìn)制的情況下:

①如果表達(dá)式值的所有位均為不定值,則輸出結(jié)果為小寫(xiě)的x。

②如果表達(dá)式值的所有位均為高阻值,則輸出結(jié)果為小寫(xiě)的z。

③如果表達(dá)式值的部分位為不定值,則輸出結(jié)果為大寫(xiě)的X。

④如果表達(dá)式值的部分位為高阻值,則輸出結(jié)果為大寫(xiě)的Z。

(2)在輸出格式為十六進(jìn)制和八進(jìn)制的情況下:

①每4位二進(jìn)制數(shù)為一組,代表一位十六進(jìn)制數(shù);每3位二進(jìn)制數(shù)為一組,代表1位八進(jìn)制數(shù)。

如果表達(dá)式值相對(duì)應(yīng)的某進(jìn)制數(shù)的所有位均為不定值,則該位進(jìn)制數(shù)的輸出結(jié)果為小寫(xiě)的x。

如果表達(dá)式值相對(duì)應(yīng)的某進(jìn)制數(shù)的所有位均為高阻值,則該位進(jìn)制數(shù)的輸出結(jié)果為小寫(xiě)的z。

如果表達(dá)式值相對(duì)應(yīng)的某進(jìn)制數(shù)的部分位為不定值,則該位進(jìn)制數(shù)的輸出結(jié)果為大寫(xiě)的X。

如果表達(dá)式值相對(duì)應(yīng)的某進(jìn)制數(shù)的部分位為高阻值,則該位進(jìn)制數(shù)的輸出結(jié)果為大寫(xiě)的Z。對(duì)于二進(jìn)制輸出格式,表達(dá)式值的每一位的輸出結(jié)果為0、1、x、z。例如:

$display("%d",1'bx);

輸出結(jié)果為:x。

$display("%h",14'bx0_1010);

輸出結(jié)果為:xxXa。

$display("%h

%o",12'b001x_xx10_1x01,12'b001_xxx_101_x01);

輸出結(jié)果為:XXX1x5X。

注意:因?yàn)?$write在輸出時(shí)不換行,所以要注意它的使用??梢栽?$write中加入換行符\n,以確保明確地輸出顯示格式。3.11.2系統(tǒng)任務(wù)?$monitor

$monitor的格式如下:

$monitor(“格式控制符”,輸出變量名列表);

$monitor與$display和$write類似,都是輸出控制類的系統(tǒng)任務(wù)。但任務(wù)$monitor提供了監(jiān)控輸出變量的功能,每當(dāng)輸出變量發(fā)生變化時(shí),任務(wù)$monitor都將再執(zhí)行一遍。

例如:

$monitor($time,,"a=%bb=%h",a,b);

每次a或b信號(hào)的值發(fā)生變化都會(huì)激活上面的語(yǔ)句,并顯示當(dāng)前仿真時(shí)間、二進(jìn)制格式的a信號(hào)值和十六進(jìn)制格式的b信號(hào)值。3.11.3系統(tǒng)函數(shù)?$time和?$realtime

$time和$realtime都是屬于返回仿真時(shí)間的系統(tǒng)函數(shù)。調(diào)用這兩個(gè)時(shí)間系統(tǒng)函數(shù)可以得到當(dāng)前時(shí)刻距離仿真開(kāi)始時(shí)刻的時(shí)間量值。$time函數(shù)與$realtime函數(shù)唯一不同之處是:$time函數(shù)以64位整數(shù)值的形式返回模擬時(shí)間,而$realtime函數(shù)以實(shí)數(shù)型數(shù)據(jù)返回模擬時(shí)間。

下面通過(guò)實(shí)例可看出$time和$realtime函數(shù)的具體區(qū)別,例如:上面的例子用仿真器,其輸出結(jié)果如下:

0 ts=x

2 ts=0

4 ts=1

$time顯示時(shí)刻受時(shí)間尺度比例的影響。在上面的例子中,時(shí)間尺度是10ns,因?yàn)?time輸出的時(shí)刻總是時(shí)間尺度的倍數(shù),所以在18ns和36ns時(shí)刻分別輸出的結(jié)果為1.8和3.6。但因?yàn)?time的輸出數(shù)值為整數(shù)形式,所以1.8和3.6四舍五入后就變成了2和4。如果將上例中的$time改為$realtime,則仿真后輸出值變?yōu)?/p>

0 ts=x

1.8 ts=0

3.6 ts=13.11.4系統(tǒng)任務(wù)?$stop和?$finish

$stop和$finish的格式如下:

$stop;

$stop(n);

$finish;

$finish(n);系統(tǒng)任務(wù)?$stop和?$finish用于對(duì)仿真過(guò)程進(jìn)行控制,分別表示中斷仿真和結(jié)束仿真。$?stop和?$finish后面可以帶參數(shù)n,n可以是0、1、2等值。如果不帶參數(shù),則默認(rèn)的參數(shù)值為1。下面給出了對(duì)于不同的參數(shù)值,系統(tǒng)輸出的特征信息。

(1)不輸出任何信息;

(2)輸出當(dāng)前仿真時(shí)刻和位置;

(3)輸出當(dāng)前仿真時(shí)刻、位置和在仿真過(guò)程中所用memory及CPU時(shí)間的統(tǒng)計(jì)。3.11.5系統(tǒng)任務(wù)?$readmemb和?$readmemh

在VerilogHDL程序中有兩個(gè)系統(tǒng)任務(wù)$readmemb和$readmemh,用來(lái)從文件中讀取數(shù)據(jù)到存儲(chǔ)器中。這兩個(gè)系統(tǒng)任務(wù)可以在仿真的任何時(shí)刻被執(zhí)行使用,其使用格式如下:

$readmemb("<數(shù)據(jù)文件名>",<存儲(chǔ)器名>,<起始地址>,<結(jié)束地址>);

$readmemh("<數(shù)據(jù)文件名>",<存儲(chǔ)器名>,<起始地址>,<結(jié)束地址>);在這兩個(gè)系統(tǒng)任務(wù)中,被讀取的數(shù)據(jù)文件的內(nèi)容只能包含空白位置(空格、換行、制表格(tab))、注釋行(//形式的和/*...*/形式的都允許)、二進(jìn)制或十六進(jìn)制的數(shù)字。數(shù)字中不能包含位寬說(shuō)明和格式說(shuō)明。對(duì)于?$readmemb系統(tǒng)任務(wù),每個(gè)數(shù)字必須是二進(jìn)制數(shù)字;對(duì)于$readmemh系統(tǒng)任務(wù),每個(gè)數(shù)字必須是十六進(jìn)制數(shù)字。數(shù)字中不定值x或X、高阻值z(mì)或Z和下劃線的使用方法及代表的意義與一般VerilogHDL程序中的用法及意義是一樣的。另外,數(shù)字必須用空白位置或注釋行來(lái)分隔開(kāi)。定義系統(tǒng)任務(wù)?$readmemb和?$readmemh時(shí),起始地址和結(jié)束地址均可缺省。如果缺省起始地址,則表示從存儲(chǔ)器的首地址開(kāi)始存儲(chǔ);如果缺省結(jié)束地址,則表示一直存儲(chǔ)到存儲(chǔ)器的結(jié)束地址。3.11.6系統(tǒng)函數(shù)?$random

$random是一個(gè)產(chǎn)生隨機(jī)數(shù)的函數(shù)。每次調(diào)用此函數(shù)將返回一個(gè)32位(bit)的隨機(jī)數(shù),該隨機(jī)數(shù)是一個(gè)帶符號(hào)的整型數(shù)。

其調(diào)用格式如下:

$random;

$random%n;當(dāng)$random函數(shù)后面定義了一個(gè)n(n需大于0)值時(shí),產(chǎn)生的隨機(jī)數(shù)就有了一定的范圍,其范圍是(-n+1)~(n-1)。

例如:

reg[23:0]data;

data=$random%80;//data的值是在-79~79之間的隨機(jī)數(shù)

3.12編?譯?預(yù)?處?理

VerilogHDL語(yǔ)言和C語(yǔ)言一樣也提供了編譯預(yù)處理的功能。“編譯預(yù)處理”是VerilogHDL編譯系統(tǒng)的一個(gè)組成部分。VerilogHDL語(yǔ)言允許在程序中使用幾種特殊的命令。Verilo

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論