?
今天給大俠帶來(lái)的是一周掌握FPGA Verilog HDL 語(yǔ)法,今天開(kāi)啟第一天,下面咱們廢話就不多說(shuō)了,一起來(lái)看看吧。?在學(xué)習(xí)中,學(xué)習(xí)任何東西都有一個(gè)過(guò)程,一個(gè)初步認(rèn)識(shí)到慢慢了解再到精通掌握的過(guò)程,當(dāng)然,學(xué)習(xí)Verilog HDL語(yǔ)法也是一樣,首先你要了解什么是Verilog HDL,然后結(jié)合實(shí)踐再遵從理論,你才可能理解的更加迅速更加透徹。 ? ? ?Verilog HDL是一種用于數(shù)字邏輯電路設(shè)計(jì)的語(yǔ)言。用Verilog HDL描述的電路設(shè)計(jì)就是該電路的Verilog HDL模型。Verilog HDL既是一種行為描述的語(yǔ)言也是一種結(jié)構(gòu)描述的語(yǔ)言。這也就是說(shuō),既可以用電路的功能描述也可以用元器件和它們之間的連接來(lái)建立所設(shè)計(jì)電路的Verilog HDL模型。Verilog模型可以是實(shí)際電路的不同級(jí)別的抽象。這些抽象的級(jí)別和它們對(duì)應(yīng)的模型類(lèi)型共有以下五種。
-
系統(tǒng)級(jí)(system):用高級(jí)語(yǔ)言結(jié)構(gòu)實(shí)現(xiàn)設(shè)計(jì)模塊的外部性能的模型。
-
算法級(jí)(algorithm):用高級(jí)語(yǔ)言結(jié)構(gòu)實(shí)現(xiàn)設(shè)計(jì)算法的模型。
-
RTL級(jí)(Register Transfer Level):描述數(shù)據(jù)在寄存器之間流動(dòng)和如何處理這些數(shù)據(jù)的模型。
-
門(mén)級(jí)(gate-level):描述邏輯門(mén)以及邏輯門(mén)之間的連接的模型。?
-
開(kāi)關(guān)級(jí)(switch-level):描述器件中三極管和儲(chǔ)存節(jié)點(diǎn)以及它們之間連接的模型。
?
?
一個(gè)復(fù)雜電路系統(tǒng)的完整Verilog HDL模型是由若干個(gè)Verilog HDL模塊構(gòu)成的,每一個(gè)模塊又可以由若干個(gè)子模塊構(gòu)成。其中有些模塊需要綜合成具體電路,而有些模塊只是與用戶所設(shè)計(jì)的模塊交互的現(xiàn)存電路或激勵(lì)信號(hào)源。利用Verilog HDL語(yǔ)言結(jié)構(gòu)所提供的這種功能就可以構(gòu)造一個(gè)模塊間的清晰層次結(jié)構(gòu)來(lái)描述極其復(fù)雜的大型設(shè)計(jì),并對(duì)所作設(shè)計(jì)的邏輯電路進(jìn)行嚴(yán)格的驗(yàn)證。Verilog HDL行為描述語(yǔ)言作為一種結(jié)構(gòu)化和過(guò)程性的語(yǔ)言,其語(yǔ)法結(jié)構(gòu)非常適合于算法級(jí)和RTL級(jí)的模型設(shè)計(jì)。這種行為描述語(yǔ)言具有以下功能:
- 可描述順序執(zhí)行或并行執(zhí)行的程序結(jié)構(gòu)。?
- 用延遲表達(dá)式或事件表達(dá)式來(lái)明確地控制過(guò)程的啟動(dòng)時(shí)間。?
- 通過(guò)命名的事件來(lái)觸發(fā)其它過(guò)程里的激活行為或停止行為。?
- 提供了條件、if-else、case、循環(huán)程序結(jié)構(gòu)。?
- 提供了可帶參數(shù)且非零延續(xù)時(shí)間的任務(wù)(task)程序結(jié)構(gòu)。?
- 提供了可定義新的操作符的函數(shù)結(jié)構(gòu)(function)。?
- 提供了用于建立表達(dá)式的算術(shù)運(yùn)算符、邏輯運(yùn)算符、位運(yùn)算符。?
?
??
Verilog HDL語(yǔ)言作為一種結(jié)構(gòu)化的語(yǔ)言也非常適合于門(mén)級(jí)和開(kāi)關(guān)級(jí)的模型設(shè)計(jì)。因其結(jié)構(gòu)化的特點(diǎn)又使它具有以下功能:?
- 提供了完整的一套組合型原語(yǔ)(primitive);?
- 提供了雙向通路和電阻器件的原語(yǔ);?
- 可建立MOS器件的電荷分享和電荷衰減動(dòng)態(tài)模型。
?
Verilog HDL的構(gòu)造性語(yǔ)句可以精確地建立信號(hào)的模型。這是因?yàn)樵赩erilog HDL中,提供了延遲和輸出強(qiáng)度的原語(yǔ)來(lái)建立精確程度很高的信號(hào)模型。信號(hào)值可以有不同的的強(qiáng)度,可以通過(guò)設(shè)定寬范圍的模糊值來(lái)降低不確定條件的影響。Verilog HDL作為一種高級(jí)的硬件描述編程語(yǔ)言,有著類(lèi)似C語(yǔ)言的風(fēng)格。其中有許多語(yǔ)句如:if語(yǔ)句、case語(yǔ)句等和C語(yǔ)言中的對(duì)應(yīng)語(yǔ)句十分相似。如果讀者已經(jīng)掌握C語(yǔ)言編程的基礎(chǔ),那么學(xué)習(xí)Verilog HDL并不困難,我們只要對(duì)Verilog HDL某些語(yǔ)句的特殊方面著重理解,并加強(qiáng)上機(jī)練習(xí)就能很好地掌握它,利用它的強(qiáng)大功能來(lái)設(shè)計(jì)復(fù)雜的數(shù)字邏輯電路。下面我們將對(duì)Verilog HDL中的基本語(yǔ)法逐一加以介紹。 ? ? ? ?簡(jiǎn)單的Verilog HDL模塊 ? ? ??
簡(jiǎn)單的Verilog HDL程序介紹
下面先介紹幾個(gè)簡(jiǎn)單的Verilog HDL程序,然后從中分析Verilog HDL程序的特性。
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
上面這個(gè)例子通過(guò)連續(xù)賦值語(yǔ)句描述了一個(gè)名為adder的三位加法器可以根據(jù)兩個(gè)三比特?cái)?shù)a、b和進(jìn)位(cin)計(jì)算出和(sum)和進(jìn)位(count)。從例子中可以看出整個(gè)Verilog HDL程序是嵌套在module和 endmodule 聲明語(yǔ)句里的。 ? ?module adder ( count,sum,a,b,cin );
input [2:0] a,b;
input cin;
output count;
output [2:0] sum;
assign {count,sum} = a + b + cin;
endmodule
?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
module compare ( equal,a,b );
?
??input?[1:0]?a,b;?//聲明輸入信號(hào)a,b??
output equal; //聲明輸出信號(hào)equal
? assign equal=(a==b)?1:0;?
???/*如果a、b 兩個(gè)輸入信號(hào)相等,輸出為1。否則為0*/?
endmodule
上面這個(gè)程序通過(guò)連續(xù)賦值語(yǔ)句描述了一個(gè)名為compare的比較器。對(duì)兩比特?cái)?shù) a、b 進(jìn)行比較,如a與b相等,則輸出equal為高電平,否則為低電平。在這個(gè)程序中,/*........*/和//.........表示注釋部分,注釋只是為了方便程序員理解程序,對(duì)編譯是不起作用的。
?
??
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
module trist2(out,in,enable);
input in, enable;
output out;
??bufif1?mybuf(out,in,enable);?
??
endmodule
上面這個(gè)程序描述了一個(gè)名為trist2的三態(tài)驅(qū)動(dòng)器。程序通過(guò)調(diào)用一個(gè)在Verilog語(yǔ)言庫(kù)中現(xiàn)存的三態(tài)驅(qū)動(dòng)器實(shí)例元件bufif1來(lái)實(shí)現(xiàn)其功能。
?
??
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
module trist1(out,in,enable);
input in, enable;
output out;
mytri?tri_inst(out,in,enable);?//調(diào)用由mytri模塊定義的實(shí)例元件tri_inst?
endmodule?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
module mytri(out,in,enable);
input in, enable;
output out;
assign out = enable? in : 'bz;
endmodule
這個(gè)程序例子通過(guò)另一種方法描述了一個(gè)三態(tài)門(mén)。在這個(gè)例子中存在著兩個(gè)模塊。模塊trist1調(diào)用由模塊mytri定義的實(shí)例元件tri_inst。模塊trist1是頂層模塊。模塊mytri則被稱(chēng)為子模塊。?
?
??
通過(guò)上面的例子可以了解到:
-
Verilog HDL程序是由模塊構(gòu)成,每個(gè)模塊的內(nèi)容都是嵌在module和endmodule兩個(gè)語(yǔ)句之間。每個(gè)模塊實(shí)現(xiàn)特定的功能。模塊是可以進(jìn)行層次嵌套的。正因?yàn)槿绱?才可以將大型的數(shù)字電路設(shè)計(jì)分割成不同的小模塊來(lái)實(shí)現(xiàn)特定的功能,最后通過(guò)頂層模塊調(diào)用子模塊來(lái)實(shí)現(xiàn)整體功能。
-
每個(gè)模塊要進(jìn)行端口定義,并說(shuō)明輸入輸出口,然后對(duì)模塊的功能進(jìn)行行為邏輯描述。
-
Verilog HDL程序的書(shū)寫(xiě)格式自由,一行可以寫(xiě)幾個(gè)語(yǔ)句,一個(gè)語(yǔ)句也可以分寫(xiě)多行。
-
除了endmodule語(yǔ)句外,每個(gè)語(yǔ)句和數(shù)據(jù)定義的最后必須有分號(hào)。
-
可以用/*.....*/和//.......對(duì)Verilog HDL程序的任何部分作注釋。一個(gè)有使用價(jià)值的源程序都應(yīng)當(dāng)加上必要的注釋?zhuān)栽鰪?qiáng)程序的可讀性和可維護(hù)性。
?
??
模塊的結(jié)構(gòu)
Verilog的基本設(shè)計(jì)單元是“模塊”(block)。一個(gè)模塊是由兩部分組成的,一部分描述接口,另一部分描述邏輯功能,即定義輸入是如何影響輸出的。下面舉例說(shuō)明:- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
module block (a,b,c,d);
input a,b;
output c,d;
assign c= a | b ;
assign d= a & b;
endmodule
?
模塊的端口定義
模塊的端口聲明了模塊的輸入輸出口。
其格式如下:module 模塊名(口1,口2,口3,口4, ………);?
?
??
模塊內(nèi)容?
模塊的內(nèi)容包括I/O說(shuō)明、內(nèi)部信號(hào)聲明、功能定義。
1、I/O說(shuō)明的格式如下:
輸入口:input 端口名1,端口名2,………,端口名i; //(共有i個(gè)輸入口)?
輸出口:output 端口名1,端口名2,………,端口名j; //(共有j個(gè)輸出口)
I/O說(shuō)明也可以寫(xiě)在端口聲明語(yǔ)句里。其格式如下:?
- ?
module module_name(input port1,input port2,…output port1,output port2… );
?
2、內(nèi)部信號(hào)說(shuō)明:
在模塊內(nèi)用到的和與端口有關(guān)的 wire 和 reg 變量的聲明。?
如:reg [width-1 : 0] R變量1,R變量2 。。。。;?
wire [width-1 : 0] W變量1,W變量2 。。。。;……
?
3、功能定義:?
模塊中最重要的部分是邏輯功能定義部分。有三種方法可在模塊中產(chǎn)生邏輯。
1). 用“assign”聲明語(yǔ)句。
如:assign a = b & c; 這種方法的句法很簡(jiǎn)單,只需寫(xiě)一個(gè)“assign”,后面再加一個(gè)方程式即可。例子中的方程式描述了一個(gè)有兩個(gè)輸入的與門(mén)。
2).?用實(shí)例元件 。
如:and and_inst( q, a, b ); 采用實(shí)例元件的方法象在電路圖輸入方式下,調(diào)入庫(kù)元件一樣。鍵入元件的名字和相連的引腳即可,表示在設(shè)計(jì)中用到一個(gè)跟與門(mén)(and)一樣的名為and_inst的與門(mén),其輸入端為a, b,輸出為q。要求每個(gè)實(shí)例元件的名字必須是唯一的,以避免與其他調(diào)用與門(mén)(and)的實(shí)例混淆。?
3). 用“always”塊。
- ?
- ?
- ?
- ?
- ?
always @(posedge clk or posedge clr)
begin
if(clr) q <= 0;
else if(en) q <= d;
end
采用“assign”語(yǔ)句是描述組合邏輯最常用的方法之一。而“always”塊既可用于描述組合邏輯也可描述時(shí)序邏輯。上面的例子用“always”塊生成了一個(gè)帶有異步清除端的D觸發(fā)器?!癮lways”塊可用很多種描述手段來(lái)表達(dá)邏輯,例如上例中就用了if...else語(yǔ)句來(lái)表達(dá)邏輯關(guān)系。如按一定的風(fēng)格來(lái)編寫(xiě)“always”塊,可以通過(guò)綜合工具把源代碼自動(dòng)綜合成用門(mén)級(jí)結(jié)構(gòu)表示的組合或時(shí)序邏輯電路。
注意:如果用Verilog模塊實(shí)現(xiàn)一定的功能,首先應(yīng)該清楚哪些是同時(shí)發(fā)生的,哪些是順序發(fā)生的。上面三個(gè)例子分別采用了“assign”語(yǔ)句、實(shí)例元件和“always”塊。這三個(gè)例子描述的邏輯功能是同時(shí)執(zhí)行的。也就是說(shuō),如果把這三項(xiàng)寫(xiě)到一個(gè) VeriIog 模塊文件中去,它們的次序不會(huì)影響邏輯實(shí)現(xiàn)的功能。這三項(xiàng)是同時(shí)執(zhí)行的,也就是并發(fā)的。?
然而,在“always”模塊內(nèi),邏輯是按照指定的順序執(zhí)行的。“always”塊中的語(yǔ)句稱(chēng)為“順序語(yǔ)句”,因?yàn)樗鼈兪琼樞驁?zhí)行的。請(qǐng)注意,兩個(gè)或更多的“always”模塊也是同時(shí)執(zhí)行的,但是模塊內(nèi)部的語(yǔ)句是順序執(zhí)行的??匆幌隆癮lways”內(nèi)的語(yǔ)句,你就會(huì)明白它是如何實(shí)現(xiàn)功能的。if..else… if必須順序執(zhí)行,否則其功能就沒(méi)有任何意義。如果else語(yǔ)句在if語(yǔ)句之前執(zhí)行,功能就會(huì)不符合要求。為了能實(shí)現(xiàn)上述描述的功能,“always”模塊內(nèi)部的語(yǔ)句將按照書(shū)寫(xiě)的順序執(zhí)行。
?
??
?
? ? ?數(shù)據(jù)類(lèi)型及其常量、變量 ? ? ??
Verilog HDL中總共有十九種數(shù)據(jù)類(lèi)型,數(shù)據(jù)類(lèi)型是用來(lái)表示數(shù)字電路硬件中的數(shù)據(jù)儲(chǔ)存和傳送元素的。在這里我們先只介紹四個(gè)最基本的數(shù)據(jù)類(lèi)型,它們是:?reg型、wire型、integer型、parameter型,其它數(shù)據(jù)類(lèi)型在后面逐步介紹,也可以查閱相關(guān)Verilog HDL語(yǔ)法參考書(shū),其它的類(lèi)型如下:large型、medium型、scalared型、time型、small型、tri型、trio型、tri1型、triand型、trior型、trireg型、vectored型、wand型、wor型。這些數(shù)據(jù)類(lèi)型除time型外都與基本邏輯單元建庫(kù)有關(guān),與系統(tǒng)設(shè)計(jì)沒(méi)有很大的關(guān)系。在一般電路設(shè)計(jì)自動(dòng)化的環(huán)境下,仿真用的基本部件庫(kù)是由半導(dǎo)體廠家和EDA工具廠家共同提供的。系統(tǒng)設(shè)計(jì)工程師不必過(guò)多地關(guān)心門(mén)級(jí)和開(kāi)關(guān)級(jí)的Verilog HDL語(yǔ)法現(xiàn)象。Verilog HDL語(yǔ)言中也有常量和變量之分。它們分別屬于以上這些類(lèi)型。下面就最常用的幾種進(jìn)行介紹。 ? ??
? ? ?常量 ? ? ??
在程序運(yùn)行過(guò)程中,其值不能被改變的量稱(chēng)為常量。下面首先對(duì)在Verilog HDL語(yǔ)言中使用的數(shù)字及其表示方式進(jìn)行介紹。
?
一.?dāng)?shù)字型?
整數(shù):?
在Verilog HDL中,整型常量即整常數(shù)有以下四種進(jìn)制表示形式:
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ù)字表達(dá)方式有以下三種:?
1) <位寬><進(jìn)制><數(shù)字>這是一種全面的描述方式。
2) <進(jìn)制><數(shù)字>在這種描述方式中,數(shù)字的位寬采用缺省位寬(這由具體的機(jī)器系統(tǒng)決定,但至少32位)。
3) <數(shù)字>在這種描述方式中,采用缺省進(jìn)制十進(jìn)制。在表達(dá)式中,位寬指明了數(shù)字的精確位數(shù)。例如:一個(gè)4位二進(jìn)制數(shù)的數(shù)字的位寬為4,一個(gè)4位十六進(jìn)制數(shù)的數(shù)字的位寬為16(因?yàn)槊繂蝹€(gè)十六進(jìn)制數(shù)就要用4位二進(jìn)制數(shù)來(lái)表示)。見(jiàn)下例: 8'b10101100 //位寬為8的數(shù)的二進(jìn)制表示, 'b表示二進(jìn)制 8'ha2 //位寬為8的數(shù)的十六進(jìn)制,'h表示十六進(jìn)制。
?
x和z值:?
在數(shù)字電路中,x代表不定值,z代表高阻值。一個(gè)x可以用來(lái)定義十六進(jìn)制數(shù)的四位二進(jìn)制數(shù)的狀態(tài),八進(jìn)制數(shù)的三位,二進(jìn)制數(shù)的一位。z的表示方式同x類(lèi)似。z還有一種表達(dá)方式是可以寫(xiě)作?。在使用case表達(dá)式時(shí)建議使用這種寫(xiě)法,以提高程序的可讀性。見(jiàn)下例: 4'b10x0 //位寬為4的二進(jìn)制數(shù)從低位數(shù)起第二位為不定值 4'b101z //位寬為4的二進(jìn)制數(shù)從低位數(shù)起第一位為高阻值 12'dz //位寬為12的十進(jìn)制數(shù)其值為高阻值(第一種表達(dá)方式) 12'd? //位寬為12的十進(jìn)制數(shù)其值為高阻值(第二種表達(dá)方式) 8'h4x //位寬為8的十六進(jìn)制數(shù)其低四位值為不定值。
?
負(fù)數(shù):?
一個(gè)數(shù)字可以被定義為負(fù)數(shù),只需在位寬表達(dá)式前加一個(gè)減號(hào),減號(hào)必須寫(xiě)在數(shù)字定義表達(dá)式的最前面。注意減號(hào)不可以放在位寬和進(jìn)制之間也不可以放在進(jìn)制和具體的數(shù)之間。見(jiàn)下例: -8'd5 //這個(gè)表達(dá)式代表5的補(bǔ)數(shù)(用八位二進(jìn)制數(shù)表示) 8'd-5 //非法格式。
?
下劃線(underscore_):?
下劃線可以用來(lái)分隔開(kāi)數(shù)的表達(dá)以提高程序可讀性。但不可以用在位寬和進(jìn)制處,只能用在具體的數(shù)字之間。
見(jiàn)下例:?
16'b1010_1011_1111_1010 //合法格式?
8'b_0011_1010 //非法格式?
?
當(dāng)常量不說(shuō)明位數(shù)時(shí),默認(rèn)值是32位,每個(gè)字母用8位的ASCII值表示。?例:?
10=32’d10=32’b1010 21
1=32’d1=32’b1?
-1=-32’d1=32’hFFFFFFFF?
‘BX=32’BX=32’BXXXXXXX…X?
“AB”=16’B01000001_01000010
?
二.參數(shù)(Parameter)型?
在Verilog HDL中用parameter來(lái)定義常量,即用parameter來(lái)定義一個(gè)標(biāo)識(shí)符代表一個(gè)常量,稱(chēng)為符號(hào)常量,即標(biāo)識(shí)符形式的常量,采用標(biāo)識(shí)符代表一個(gè)常量可提高程序的可讀性和可維護(hù)性。parameter型數(shù)據(jù)是一種常數(shù)型的數(shù)據(jù),其說(shuō)明格式如下:
parameter 參數(shù)名1=表達(dá)式,參數(shù)名2=表達(dá)式, …, 參數(shù)名n=表達(dá)式;
parameter是參數(shù)型數(shù)據(jù)的確認(rèn)符,確認(rèn)符后跟著一個(gè)用逗號(hào)分隔開(kāi)的賦值語(yǔ)句表。在每一個(gè)賦值語(yǔ)句的右邊必須是一個(gè)常數(shù)表達(dá)式。也就是說(shuō),該表達(dá)式只能包含數(shù)字或先前已定義過(guò)的參數(shù)。見(jiàn)下例:
- ?
- ?
- ?
- ?
- ?
parameter msb=7; //定義參數(shù)msb為常量7
parameter e=25, f=29; //定義二個(gè)常數(shù)參數(shù)
parameter r=5.7; //聲明r為一個(gè)實(shí)型參數(shù)
parameter byte_size=8, byte_msb=byte_size-1; //用常數(shù)表達(dá)式賦值
parameter average_delay = (r+f)/2; //用常數(shù)表達(dá)式賦值
參數(shù)型常數(shù)經(jīng)常用于定義延遲時(shí)間和變量寬度。在模塊或?qū)嵗脮r(shí)可通過(guò)參數(shù)傳遞改變?cè)诒灰媚K或?qū)嵗幸讯x的參數(shù)。下面將通過(guò)兩個(gè)例子進(jìn)一步說(shuō)明在層次調(diào)用的電路中改變參數(shù)常用的一些用法。
- ?
- ?
- ?
- ?
- ?
- ?
module Decode(A,F);
parameter Width=1, Polarity=1;
??……………
??
endmodule?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
module Top;
wire[3:0] A4;
wire[4:0] A5;
wire[15:0] F16;
wire[31:0] F32;
Decode #(4,0) D1(A4,F16);
Decode #(5) D2(A5,F32);
endmodule
引用Decode實(shí)例時(shí),D1,D2的Width將采用不同的值4和5,且D1的Polarity將為0??捎美又兴玫姆椒▉?lái)改變參數(shù),即用 #(4,0)向D1中傳遞 Width=4,Polarity=0; 用#(5)向D2中傳遞Width=5,Polarity仍為1。
?
??
- ?
- ?
- ?
- ?
- ?
- ?
Module Test;
wire W;
Top T ( );
emdmodule
- ?
- ?
- ?
- ?
- ?
- ?
- ?
module Top;
wire W
Block B1 ( );
Block B2 ( );
endmodule
- ?
- ?
- ?
- ?
- ?
module Block;
Parameter P = 0;
endmodule
- ?
- ?
- ?
- ?
- ?
- ?
- ?
module Annotate;
defparam
Test.T.B1.P = 2,
Test.T.B2.P = 3;
endmodule
審核編輯:湯梓紅
評(píng)論