




版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 兼職工作合同協(xié)議
- 消防系統(tǒng)檢測(cè)合同
- 小數(shù)的意義(教學(xué)設(shè)計(jì))-2023-2024學(xué)年四年級(jí)下冊(cè)數(shù)學(xué)人教版
- 管理軟件系統(tǒng)購(gòu)買合同范文格式7篇
- 噸的認(rèn)識(shí)(教學(xué)設(shè)計(jì))-2024-2025學(xué)年三年級(jí)上冊(cè)數(shù)學(xué)人教版
- 雙手胸前傳接球 教學(xué)設(shè)計(jì)-2023-2024學(xué)年高二下學(xué)期體育與健康人教版必修第一冊(cè)
- 小學(xué)三年級(jí)數(shù)學(xué)幾百幾十加減幾百幾十水平練習(xí)習(xí)題
- 簡(jiǎn)易家用活動(dòng)平臺(tái)施工方案
- Unit 1 Lesson 3 The Sun Is Rising教學(xué)設(shè)計(jì) -2024-2025學(xué)年冀教版八年級(jí)英語(yǔ)下冊(cè)
- 第9課 兩宋的政治和軍事 教學(xué)設(shè)計(jì)-2023-2024學(xué)年高一上學(xué)期統(tǒng)編版(2019)必修中外歷史綱要上
- 《中國(guó)商貿(mào)文化》3.1古代商人
- 南宋北京大學(xué)歷史學(xué)系課件
- 重慶市房屋建筑與裝飾工程計(jì)價(jià)定額2018-建筑工程
- 三年級(jí)數(shù)學(xué)-解決問(wèn)題策略(蘇教版)
- 不吃路邊攤精品課件
- 《網(wǎng)絡(luò)服務(wù)器搭建、配置與管理-Linux(RHEL8、CentOS8)(微課版)(第4版)》全冊(cè)電子教案
- 心理評(píng)估與診斷簡(jiǎn)介
- 無(wú)痛病房管理課件
- 讓孩子變成學(xué)習(xí)的天使——由《第56號(hào)教室的奇跡》讀書(shū)分享
- 球泡檢驗(yàn)標(biāo)準(zhǔn)
- 振動(dòng)分析基礎(chǔ)講義1
評(píng)論
0/150
提交評(píng)論