




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第4章VerilogHDL硬件描述語言4.1
Verilog的基本語法4.1.1簡單的VerilogHDL模塊 VerilogHDL是以模塊(block)集合的形式來描述硬件系統(tǒng)的。模塊是VerilogHDL的基本單元,它用于描述某個設(shè)計的功能或結(jié)構(gòu)及其與其他模塊的外部接口。模塊可以代表從簡單門元件到復(fù)雜系統(tǒng)的任何一個硬件電路。每一個模塊都有接口部分,用于描述與其他模塊之間的連接關(guān)系。VerilogHDL的各個模塊之間是并行運行的。通常設(shè)計的硬件系統(tǒng)有一個頂層模塊,該頂層模塊的輸入/輸出分別代表系統(tǒng)的輸入/輸出。頂層模塊可以由若干個子模塊組成,每個子模塊代表著系統(tǒng)中具有特定功能的一個功能單元,各個子模塊通過端口相互連接起來,從而實現(xiàn)分層設(shè)計。模塊的基本組成結(jié)構(gòu)如下:Module<模塊名>(<端口列表>);端口說明(input,output,inout)參數(shù)定義(可選)(parameter)數(shù)據(jù)類型定義(wire,reg等)連續(xù)賦值語句(assign)過程塊語句(initial和always)(包括條件、選擇、循環(huán)等行為描述語句或語句塊)底層模塊實例引用語句(moduleinstantiations)函數(shù)和任務(wù)(function,task)endmodule其中,<模塊名>是模塊唯一的標(biāo)識符;<端口列表>是由模塊各個端口組成的,根據(jù)端口信號的方向,端口具有三種類型:輸入(input)端口、輸出(output)端口和雙向(inout)端口,這些端口用來與其他模塊進(jìn)行連接;端口說明用來說明各個端口的數(shù)據(jù)流向及數(shù)據(jù)寬度等;參數(shù)定義用來說明系統(tǒng)設(shè)計中用到的有關(guān)參數(shù);數(shù)據(jù)類型定義用來指定模塊內(nèi)各組件進(jìn)行信息交流所用的數(shù)據(jù)對象是寄存器型、存儲器型還是連線型。用于說明系統(tǒng)的邏輯功能及組成的語句有三種,包括連續(xù)賦值語句(assign)、過程塊(initial和always)語句和底層模塊實例引用語句(moduleinstantiations),其中連續(xù)賦值語句(assign)用于數(shù)據(jù)流描述,過程塊語句用于行為描述,內(nèi)含各種行為描述語句,而底層模塊實例引用語句則進(jìn)行結(jié)構(gòu)描述。在always塊內(nèi),被賦值的每個信號都必須定義為reg(寄存器)型變量。在VerilogHDL中,output端口信號可定義成寄存器型變量,并在always塊內(nèi)被賦值使用,而inout型雙向端口信號不能被定義成reg型變量,因此在always塊內(nèi)不能被直接賦值使用,這一點與VHDL中雙向端口的使用方法有所不同。VerilogHDL程序是由模塊組成的,每個模塊的內(nèi)容都包含在“module”和“endmodule”兩個語句之間。VerilogHDL程序的書寫格式與C語言類似,一行可以寫多條語句,也可以一條語句分成多行書寫,每條語句以英文輸入狀態(tài)下的分號結(jié)束,但endmodule語句后面不必寫分號。初學(xué)者經(jīng)常忘記第一行語句后面的分號,或輸入的是中文輸入狀態(tài)下的分號,這都會導(dǎo)致程序編譯時報錯。例4.1二選一選擇器。程序如下:moduleTwoSelOne(a,b,s,y);inputa,b;inputs;outputy;assigny=(s==0)?a:b;endmodule說明:程序第一行需要分號,而最后一行即endmodule語句后面不寫分號,程序中的逗號、分號等都應(yīng)該是在英文輸入狀態(tài)下輸入的,而不能在中文狀態(tài)下輸入;如果該模塊是頂層模塊,那么模塊名要與該工程名一致。在給模塊命名時,不能使用VerilogHDL中的關(guān)鍵詞,并且最好能“顧名思義”,方便以后在閱讀到該模塊時,看名字就能知道它的功能。一個模塊可以是一個元件或者一個設(shè)計單元。類似于C語言中的函數(shù)調(diào)用,底層模塊通常被整合在高層模塊中提供某個通用功能??梢栽谠O(shè)計中多處被使用。高層模塊通過調(diào)用、連接底層模塊的實例來實現(xiàn)復(fù)雜的功能。調(diào)用時只需要定義輸入/輸出接口,而不用關(guān)注底層模塊內(nèi)部如何實現(xiàn),這為程序的層次化、模塊化設(shè)計提供了便利,利于分工協(xié)作與維護(hù)。例4.2調(diào)用底層模塊實現(xiàn)二選一選擇器。程序如下:moduleTwoSelOne(a,b,s,y);inputa,b;inputs;outputy;wired,e,ns;notgate1(ns,s);andgate2(d,ns,a);andgate3(e,s,b);orgate4(y,d,e);endmodule4.1.2數(shù)據(jù)類型及其常量、變量VerilogHDL數(shù)據(jù)類型(DataTypes)主要用來說明存儲在數(shù)字硬件或傳送于數(shù)字組件間的數(shù)據(jù)類型。它不僅支持如整型、實型等抽象的數(shù)據(jù)類型,而且也支持物理數(shù)據(jù)類型來表示真實的硬件。物理數(shù)據(jù)類型有連線型(wire、tri等)和寄存器型(reg)兩種,這兩種類型的變量在定義時均要設(shè)置位寬,在缺省狀態(tài)時,位寬默認(rèn)為1位。變量的每一位可以取0、1、x或z中的任意值。除了與具體的硬件電路對應(yīng)的物理數(shù)據(jù)類型外,VerilogHDL還提供了整型(integer)、實型(real)、時間型(time)、參數(shù)型(parameter)等四種抽象的數(shù)據(jù)類型,這些抽象數(shù)據(jù)類型主要用于仿真。抽象數(shù)據(jù)類型只是純數(shù)學(xué)的抽象描述,不與任何實際的物理硬件相對應(yīng)。1.連線型數(shù)據(jù)類型連線型數(shù)據(jù)對應(yīng)于硬件電路中的物理信號連線,沒有電荷保持作用(trireg除外)。連線型數(shù)據(jù)必須由驅(qū)動源驅(qū)動。它有兩種驅(qū)動方式:一種是在結(jié)構(gòu)描述中把它連接到一個門或模塊的輸出端;另一種是用連續(xù)賦值語句assign對其賦值。當(dāng)沒有驅(qū)動源對其驅(qū)動時,它將保持高阻態(tài)。為了能夠精確地反映硬件電路中各種可能的物理信號的連接特性,VerilogHDL提供了多種連線型數(shù)據(jù),具體介紹如下。1)?wire和tri網(wǎng)絡(luò)連線(wire)和三態(tài)線(tri)的語法和功能基本一致。三態(tài)線(tri)可以用于描述多個驅(qū)動源驅(qū)動同一根線的線網(wǎng)類型。多個驅(qū)動源驅(qū)動一個連線時,線網(wǎng)的有效值如表4.1所示。表4.1多個驅(qū)動源驅(qū)動一個連線時線網(wǎng)的有效值wire(或tri)01xz00xx01x1x1xxxxxz01xz2)?wor和trior線網(wǎng)線或(wor)和三態(tài)線或(trior)的語法和功能基本一致。若驅(qū)動源為1,線或線網(wǎng)值為1,則多個驅(qū)動源驅(qū)動這類線網(wǎng)時,線網(wǎng)的有效值如表4.2所示。表4.2多個驅(qū)動源驅(qū)動線或線網(wǎng)時的有效值wor(或trior)01xz001x011111xx1xxz01xz3)?wand和triand線網(wǎng)線與(wand)和三態(tài)線與(triand)的語法和功能基本一致。若驅(qū)動源為0,線與線網(wǎng)值為0,則多個驅(qū)動源驅(qū)動這類線網(wǎng)時,線網(wǎng)的有效值如表4.3所示。wand(或triand)01xz00000101x1x0xxxz01xz表4.3多個驅(qū)動源驅(qū)動線與線網(wǎng)時的有效值4)?trireg線網(wǎng)trireg線網(wǎng)用于存儲數(shù)值,并且用于電容節(jié)點的建模。當(dāng)trireg的所有驅(qū)動源都處于高阻態(tài)時,trireg線網(wǎng)保存作用在線網(wǎng)上的最后一個值。trireg線網(wǎng)的初始值為x。5)?tri0和tri1線網(wǎng)tri0和tri1線網(wǎng)用于線邏輯的建模,其中,當(dāng)無驅(qū)動源時,tri0線網(wǎng)的值為0,tri1線網(wǎng)的值為1。多個驅(qū)動源驅(qū)動這類線網(wǎng)時,線網(wǎng)的有效值如表4.4所示。tri0(或tri1)01xz00xx01x1x1xxxxxz01x0(1)表4.4多個驅(qū)動源驅(qū)動tri0和tri1時線網(wǎng)的有效值6)?supply0和supply1線網(wǎng)supply0線網(wǎng)用于對低電平0的建模,supply1線網(wǎng)用于對電源,即高電平1的建模。連線型數(shù)據(jù)類型的定義格式為<連線型數(shù)據(jù)的類型><范圍><延遲時間><變量列表>;例如:
wiresignal1,signal2; //兩個連線型數(shù)據(jù)
tri[7:0]bus; //8位三態(tài)總線在VerilogHDL中,有的時候可以不需要聲明某種線網(wǎng)類型,缺省的線網(wǎng)類型為1位線與網(wǎng)??梢允褂镁幾g器偽指令?'default_nettype來改變這個隱式的線網(wǎng)說明方式。其調(diào)用格式為'default_nettypenet_kind向量線網(wǎng)是用關(guān)鍵詞scalared或者vectored來定義的。需要注意的是,vectored定義的向量線網(wǎng)必須整體進(jìn)行賦值。若沒有定義關(guān)鍵詞,缺省值為標(biāo)量。2.寄存器型數(shù)據(jù)類型1)寄存器數(shù)據(jù)寄存器數(shù)據(jù)對應(yīng)于具有狀態(tài)保持作用的硬件電路元件,如觸發(fā)器、鎖存器等。若寄存器數(shù)據(jù)未初始化,它將為未知狀態(tài)x。寄存器數(shù)據(jù)的關(guān)鍵字為reg,缺省時為1位數(shù)。寄存器數(shù)據(jù)與連線型數(shù)據(jù)的區(qū)別在于:寄存器數(shù)據(jù)保持最后一次的賦值,而連線型數(shù)據(jù)需要有持續(xù)的驅(qū)動。寄存器數(shù)據(jù)的驅(qū)動可以通過過程賦值語句實現(xiàn),在always塊內(nèi)被賦值的每一個信號都必須定義為reg型,即賦值操作符的右端變量必須是reg型的。寄存器數(shù)據(jù)的定義格式為reg<范圍><變量列表>;例如:reg
d1; //1位寄存器reg[3:0]state; //4位寄存器reg[4:1]rega,regb;//定義2個4位的分別名為rega,regb的reg型的寄存器2)存儲器數(shù)據(jù)存儲器數(shù)據(jù)實際上是一個寄存器數(shù)組,Verilog通過reg型變量建立數(shù)組來對存儲器建模,可以描述RAM、ROM存儲器和reg文件。數(shù)組中的每一個單元通過一個整數(shù)索引進(jìn)行尋址。存儲器型數(shù)據(jù)通過擴(kuò)展reg型數(shù)據(jù)的地址范圍來達(dá)到二維數(shù)組的效果,其使用的格式如下:reg[msb:lsb]存儲器名[n-1:0];其中reg[msb:lsb]定義了存儲器中每一個存儲單元的大小,即該存儲器單元是一個n位位寬的寄存器;存儲器后面的[n-1:0]定義了存儲器的大小,即該存儲器中有多少個這樣的寄存器。若寄存器說明中缺省[n-1:0],則是說明寄存器。例如:reg[7:0]regc; //regc為一個8位寄存器regmemb[15:0];//memb為16個1位寄存器的數(shù)組,即存儲器reg[7:0]memc[15:0]; //memc為16個8位寄存器的數(shù)組需要注意的是,存儲器不能像寄存器那樣賦值。一個n位的寄存器可以在一條賦值語句里進(jìn)行賦值,而一個完整的存儲器則不行。例如:regc=0;//合法賦值語句memc=0;//非法賦值語句如果想對存儲器中的存儲單元進(jìn)行讀寫操作,必須指定地址。例如:reg[7:0]memd[4:1];//定義4個字節(jié)的存儲器memdinitialbeginmemd[1]=0; //給存儲器單元memd[1]賦值為0memd[2]=1; //給存儲器單元memd[2]賦值為1memd[3]="Jan"; //給存儲器單元memd[3]賦值為字符串"Jan"memd[4]="Feb"; //給存儲器單元memd[4]賦值為字符串"Feb"end除此之外,還可以借助于系統(tǒng)函數(shù)$readmemb和$readmemh來將文件中的二進(jìn)制或十六進(jìn)制數(shù)據(jù)讀取到存儲器中。如:reg[7:0]mem[1:256] //先定義一個有256個地址的字節(jié)存儲器meminitial$readmemh("mem.data",mem);initial$readmemh("mem.data",mem,16);initial$readmemh("mem.data",mem128,1);上述第2條語句在仿真0時刻,將數(shù)據(jù)裝載到以地址為1的存儲器單元為起始存放單元的存儲器中去;第3條語句將數(shù)據(jù)裝載到以單元地址是16的存儲器單元為起始存放單元的存儲器中去,一直到地址是256的單元為止;第4條語句將從地址是128的單元開始裝載數(shù)據(jù),一直到地址為1的單元。在最后這種情況下,當(dāng)裝載完畢后,系統(tǒng)要檢查在數(shù)據(jù)文件里是否有128個數(shù)據(jù),如果沒有,系統(tǒng)提示錯誤信息。3.整型數(shù)據(jù)類型整型(integer)數(shù)據(jù)常用于對循環(huán)變量進(jìn)行說明,在算術(shù)運算中被視為二進(jìn)制補(bǔ)碼形式的有符號數(shù)。除了寄存器型數(shù)據(jù)被當(dāng)作無符號數(shù)處理之外,整型數(shù)據(jù)與32位寄存器型數(shù)據(jù)在實際意義上相同。整型數(shù)據(jù)的聲明格式為integer<寄存器型變量列表>;整型數(shù)據(jù)可以是二進(jìn)制(b或B)、十進(jìn)制(D或d)、十六進(jìn)制(h或H)或八進(jìn)制(O或o)。整型數(shù)據(jù)可以有下面三種書寫形式:(1)簡單十進(jìn)制格式,這種格式是直接由0~9的數(shù)字串組成的十進(jìn)制數(shù),可以用符號“+”或“-”來表示數(shù)的正負(fù),如789。(2)缺省位寬的基數(shù)格式,這種格式的書寫形式為'<base_format><number>其中,符號“'”為基數(shù)格式表示的固有字符,該字符不能省略,否則為非法表示形式;參數(shù)<base_format>用于說明數(shù)值采用的進(jìn)制格式;參數(shù)<number>為相應(yīng)進(jìn)制格式下的一串?dāng)?shù)字;這種格式未指定位寬,其缺省值至少為32位。例如:'h137FF //缺省位寬的十六進(jìn)制數(shù)(3)指定位寬的基數(shù)格式,這種格式的書寫形式為<size>'<base_format><number>其中,參數(shù)<size>用來指定所表示數(shù)的位寬,當(dāng)位寬小于數(shù)值的實際位數(shù)時,相應(yīng)的高位部分被忽略;當(dāng)位寬大于數(shù)值的實際位數(shù)且數(shù)值的最高位是0或1時,相應(yīng)的高位部分補(bǔ)0;當(dāng)位寬大于數(shù)值的實際位數(shù),但數(shù)值的最高位是x或z時,相應(yīng)的高位部分補(bǔ)x或z。二進(jìn)制的一個x或z表示1位處于x或z;八進(jìn)制的一個x或z表示3位二進(jìn)制位都處于x或z;十六進(jìn)制的一個x或z表示4位二進(jìn)制位都處于x或z。另外,數(shù)值中的z還可以用“?”來代替。例如:
4'b1101//4位二進(jìn)制數(shù)4.實型數(shù)據(jù)類型VerilogHDL支持實型(real)常量與變量。實型數(shù)據(jù)在機(jī)器碼表示法中是浮點型數(shù)值,可用于計算延遲時間。實型數(shù)據(jù)的聲明格式為real<變量列表>;例如:real
a;實型數(shù)據(jù)可以用十進(jìn)制與科學(xué)計數(shù)法兩種格式來表示,如果采用十進(jìn)制格式,小數(shù)點兩邊都必須是數(shù)字,否則為非法的表示形式,如:1.8、3.8E9。5.時間型數(shù)據(jù)類型時間型(time)數(shù)據(jù)與整型數(shù)據(jù)類似,只是它是64位無符號數(shù)。時間型數(shù)據(jù)主要用于對模擬時間的存儲與計算,常與系統(tǒng)函數(shù)?$time一起使用。時間型數(shù)據(jù)的聲明格式為time<寄存器型變量列表>;例如:timestart,stop;//聲明start和stop為兩個64位的時間變量6.參數(shù)型數(shù)據(jù)類型參數(shù)型數(shù)據(jù)(parameter)是被命名的常量,在仿真前對其賦值,在整個仿真過程中其值保持不變,數(shù)據(jù)的具體類型是由所賦的值來決定的??梢杂脜?shù)型數(shù)據(jù)定義變量的位寬及延遲時間等,從而增加程序的可讀性與易修改性。參數(shù)型數(shù)據(jù)的聲明格式為parameter<賦值列表>;例如:parameter
size=8;parameter
width=6,x=8;4.1.3
VerilogHDL操作符VerilogHDL提供了各種不同的操作符,例如算術(shù)操作符、取模操作符、邏輯操作符、關(guān)系操作符、相等操作符、按位操作符、歸約操作符、移位操作符、條件操作符及連接操作符。操作符會將其操作數(shù)按照所定義的功能計算以產(chǎn)生新值。大部分操作符為單目操作符或雙目操作符。單目操作符使用一個操作數(shù);雙目操作符使用兩個操作數(shù);條件操作符使用三個操作數(shù);連接操作符則可以使用任何個數(shù)的操作數(shù)。表4.5所列為常用的操作符。表4.5中的各操作符在處理實數(shù)時需特別注意,僅有部分操作符處理實數(shù)表達(dá)式有效。這些有效的操作符列于表4.6中。操作符類型操作符功能說明算術(shù)操作符+,-,*,/加、減、乘、除算術(shù)運算取模操作等%取模邏輯操作符!邏輯非&&邏輯與||邏輯或關(guān)系操作符<,>,<=,>=關(guān)系運算:小于、大于、小于等于、大于等于相等操作符==相等!=不等===全等!==非全等按位操作符~按位非&按位與|按位或^按位異或^~?或?~^按位異或非歸約操作符&歸約與~&歸約與非|歸約或~|歸約或非^歸約異或~^?或?^~歸約異或非移位操作符<<左移位>>右移位條件操作符?:條件連接操作符{}連接表4.5
Verilog操作符操作符功能說明+,-,*,/算術(shù)操作符>,>=,<,<=關(guān)系操作符!,&&,|邏輯操作符==,!=相等操作符?=條件操作符表4.6實數(shù)表達(dá)式中有效的操作符和其他高級語言一樣,VerilogHDL中的運算符也是具有優(yōu)先級的。表4.7給出了運算符優(yōu)先級從高到低的排列次序,同一行中的運算符優(yōu)先級相同。1.算術(shù)操作符算術(shù)操作符包括單目操作符和雙目操作符。算術(shù)表達(dá)式結(jié)果的長度由最長的操作數(shù)決定。賦值語句中,其結(jié)果的長度由操作符左端目標(biāo)長度決定。算術(shù)表達(dá)式的所有中間結(jié)果長度取最大操作數(shù)的長度。若算術(shù)操作符中的任一操作數(shù)中含有x或者z,則表達(dá)式的結(jié)果為x。算術(shù)操作符中,無符號數(shù)存儲在線網(wǎng)、寄存器或者基數(shù)形式的整數(shù)中;有符號數(shù)存儲在整數(shù)寄存器或者十進(jìn)制形式的整數(shù)中。算術(shù)操作符的使用舉例如下:
//單目操作符integer[7:0]a,b;a=-8; //?-8(單目操作符) b=+10; //?+10
//雙目操作符reg[3:0]a,b,c,d;a=4'b0010;assignc=a+b; //變量+變量assignd=b+2; //變量+常數(shù)//----------------------integera,b,c,d;a=12/3; //a=4b=11%5; //b=1c=-11%3; //c=-2算術(shù)操作符在寄存器數(shù)據(jù)類型中所產(chǎn)生的結(jié)果,與在整數(shù)數(shù)據(jù)類型中所產(chǎn)生的結(jié)果不盡相同。對寄存器來說,VerilogHDL將其視為不帶符號的數(shù)值;對整數(shù)數(shù)據(jù)類型來說,則為帶符號數(shù)值。例如,若將一個形式為<位寬><基底><數(shù)字>的負(fù)數(shù)賦值給一個寄存器,則此負(fù)數(shù)將以其2'S補(bǔ)碼存入寄存器:integera;reg[7:0]b;a=-8'd9; //a=-9(11110111)b=a/3; //b=-3(11111101),因為a為整數(shù)a=b/3; //a=84,因為253/32.關(guān)系操作符關(guān)系操作符為雙目操作符,它們將兩個操作數(shù)進(jìn)行比較:若結(jié)果為“真”,則設(shè)為邏輯值1;若結(jié)果為“假”,則設(shè)為邏輯值0。若兩個操作數(shù)中有未知值x,則其關(guān)系結(jié)果亦為未知值x。關(guān)系表達(dá)式中的操作數(shù)長度不同時,要在較短的操作數(shù)的左方補(bǔ)“0”,然后再進(jìn)行比較。例如,利用大于等于(>=)操作符求兩個數(shù)值的最大值的程序如下:modulemax(max_v,a,b)output[7:0]max_v;input[7:0]a,b;if(a>=b)max_v=a; //?a是最大值elsemax_v=b; //?b是最大值endmodule3.相等操作符對于相等操作符,如果兩個操作數(shù)所有的位值均相等,那么相等關(guān)系式成立,結(jié)果返回邏輯1,否則返回邏輯0。但若任何一個操作數(shù)中的某一位為未知數(shù)x或處于高阻態(tài),則結(jié)果為未知的。若兩個操作數(shù)的對應(yīng)位可取4個邏輯值,則相等運算符的運算規(guī)則可用表4.8來描述。如果兩個操作數(shù)的所有位取0或1,那么不等運算符與相等運算符的運算規(guī)則正好相反。如果任一個操作數(shù)中含有未知數(shù)x或高阻態(tài),則不等運算符與相等運算符的運算規(guī)則相同,如表4.9所示。對于全等操作符,其比較過程與相等操作符相同,但其返回結(jié)果只有邏輯1或邏輯0兩種狀態(tài),不存在未知數(shù),即全等操作符將未知數(shù)x與高阻態(tài)看做是邏輯狀態(tài)的一種參與比較,如果兩個操作數(shù)的相應(yīng)位均為x或z,那么全等關(guān)系成立,結(jié)果返回邏輯1。非全等操作符與全等操作符正好相反。表4.10給出了全等操作符的運算規(guī)則。例4.3用等于操作符編寫一個4位比較器。代碼如下:modulecompare1(a,b,comout);input[3:0]a,b;output[2:0]comout;reg[2:0]temp;always@(aorb)beginif(a>b)temp<=3'b100;elseif(a==b)temp<=3'b010;elsetemp<=3'b001;endassigncomout=temp;endmodule在對該程序進(jìn)行仿真時,當(dāng)a?=?4'b0101,b?=?4'1000時,輸出comout?=?3'b001,表示a?<?b;當(dāng)a?=?4'b1010,b?=?4'0101時,輸出comout?=?3'b100,表示a?>?b;當(dāng)a?=?4'b1100,b?=?4'1100時,輸出comout?=?3'b010,表示a?=?b。4.邏輯操作符VerilogHDL中存在三種邏輯運算符:&&:邏輯與;||:邏輯或;?。哼壿嫹?。其中“&&”和“||”是雙目操作符,它要求有兩個操作數(shù),如(a>b)&&(b>c),(a<b)||(b<c)。“!”是單目操作符,只要求一個操作數(shù),如?!(a>b)。表4.11為邏輯運算的真值表,它表示當(dāng)a和b的值為不同的組合時,各種邏輯運算所得到的值。邏輯運算符中“&&”和“||”的優(yōu)先級別低于關(guān)系運算符,“!”的優(yōu)先級別高于算術(shù)運算符。如:(a>b)&&(x>y)可寫成:a>b&&x>y;(a==b)||(x==y)可寫成:a==b||x==y;(!a)||(a>b)可寫成:!a||a>b。當(dāng)然,為了提高程序的可讀性,明確表達(dá)各運算符間的優(yōu)先關(guān)系,建議使用括號。5.按位操作符按位操作符對輸入操作數(shù)進(jìn)行按位操作,并且產(chǎn)生向量結(jié)果。若操作數(shù)的長度不相等,則在較短的操作數(shù)的左方添“0”。Verilog中位操作符共有5個操作符:取反(?~?)、按位與(?&?)、按位或(?|?)、按位異或(?^?)、按位同或(?^~?)。各位操作的結(jié)果按表4.12給出。例如,若a=4'b0011,b=4'b1101,c=4'b1010,則$display(~a); //?display4'b1100=12$display(a&b); //?display4'b0001=1$display(a|c); //?display4'b1011=11$display(b^c); //?display4'b0111=7$display(a^~c); //?display4'b0110=66.歸約操作符歸約操作符是單目操作符,其運算規(guī)則類似于按位操作符的運算規(guī)則,但其運算過程不同。按位運算是對操作數(shù)的相應(yīng)位進(jìn)行與、或等運算,操作數(shù)是幾位數(shù),則運算結(jié)果也是幾位數(shù)。而歸約運算則不同,歸約運算是對單個操作數(shù)進(jìn)行歸約的遞推運算,最后的運算結(jié)果是1位二進(jìn)制數(shù)。若操作數(shù)中含有未知值x或者z,則表達(dá)式的結(jié)果為x。歸約運算的運算過程為:先將操作數(shù)的第1位與第2位進(jìn)行歸約運算,然后將運算結(jié)果與第3位進(jìn)行歸約運算,依次類推,直到最后一位。例如,a=4'b1111,b=4'1010,則&a的結(jié)果為1,∣b的結(jié)果為1。7.移位操作符移位操作符是一種邏輯操作,操作符右側(cè)的操作數(shù)表示將操作符左側(cè)的操作數(shù)移位的次數(shù),不夠則添0。若操作數(shù)中含有x或者z,則移位表達(dá)式的結(jié)果為x。移位操作符還可完成VerilogHDL中的指數(shù)操作。例如,assignqout=div>>sh_bit;語句表示將div右移sh_bit位后的結(jié)果連續(xù)賦值給qout,它實際上是一個除法運算。8.條件操作符條件操作符為“?:”,其使用格式為cond_expression?expression_1:expression_2;若cond_expression為1(即為真),則表達(dá)式的值為expression_1;若cond_expression為0(即為假),則表達(dá)式的值為expression_2。若cond_expression為x或z,則表達(dá)式的值將是expression_1與expression_2按以下邏輯規(guī)則進(jìn)行按位操作后的結(jié)果:0與0得0,1與1得1,其余為x。例如:assigny=(sel)?a:b;//若條件sel=1,則y=a,否則y=b9.連接操作符連接操作符可將多個小的表達(dá)式合并形成一個大的表達(dá)式。VerilogHDL中,用符號“{}”實現(xiàn)多個表達(dá)式的連接運算,各個表達(dá)式之間用“,”隔開,其使用格式為{expression_1,expression_2,…,expression_n}除了非定長的常量外,任何表達(dá)式都可進(jìn)行連接運算。同時,連接運算也可以對信號的某些位進(jìn)行。例如,若a=1'b1,b=2'b01,c=5'b10111,則{a,b}將產(chǎn)生一個3位數(shù)3'b101,{c[4:2],b}將產(chǎn)生一個5位數(shù)5'b10101。10.復(fù)制操作符復(fù)制操作符“{{}}”是將一個表達(dá)式放入雙重大括號中,而復(fù)制因子放在第一層括號中,用來指定復(fù)制的次數(shù),通過重復(fù)相同的操作符來實現(xiàn)表達(dá)式的變大,其使用格式為{repeat_number{expression_1,expression_2,…,expression_n}}復(fù)制操作符為復(fù)制一個常量或變量提供了簡便方法。不過在多操作符的表達(dá)式中,需要考慮的問題是操作符的優(yōu)先級。例如,若a=1'b1,則{3{a}}的結(jié)果為3'b111。4.1.4過程語句1.?Initial過程區(qū)塊Initial區(qū)塊中可包含一個語句或以begin…end為句式的句塊內(nèi)所包括的多個語句。在仿真過程中,起始時間為0時,這個區(qū)塊內(nèi)部的語句僅執(zhí)行一次。若有多個initial區(qū)塊出現(xiàn)于模塊中,那么這些區(qū)塊各自獨立地并行執(zhí)行。initial區(qū)塊的目的是,在仿真時起始設(shè)定組件內(nèi)部的信號值,監(jiān)視信號動作過程及顯示相關(guān)信號的波形或數(shù)值。2.?always過程區(qū)塊always區(qū)塊類似initial區(qū)塊,二者不同之處是always區(qū)塊中的語句將重復(fù)地被執(zhí)行,形成一個無窮循環(huán),仿真時遇到?$finish或?$stop指令時才會停止。always區(qū)塊通常配合事件的表達(dá)式使用。所謂事件,就是某一信號發(fā)生狀態(tài)變化。例如,信號出現(xiàn)上升沿、下降沿或是數(shù)值改變時等,這些事件就是觸發(fā)條件。觸發(fā)條件寫在敏感信號表達(dá)式中,只有當(dāng)觸發(fā)條件滿足時,其后的“begin…end”塊語句才能被執(zhí)行。敏感信號表達(dá)式中應(yīng)列出影響塊內(nèi)取值的所有信號。若有兩個或兩個以上信號時,它們之間用“or”連接,其格式為always@(事件表示式1or事件表示式2or…or事件表示式n)begin<語句區(qū)>end以下各形式的事件表示式均是合法的always區(qū)塊。(1)事件表示式中特定值改變時:always@(clk)q=d; //當(dāng)clk的值改變時,執(zhí)行q=d,電平觸發(fā)(2)時鐘信號上升沿觸發(fā)時:always@(posedgeclk)q=d;//當(dāng)clk上升沿觸發(fā)時,執(zhí)行q=d,邊沿觸發(fā)(3)時鐘信號下降沿觸發(fā)時:always@(negedgeclk)q=d//當(dāng)clk下降沿觸發(fā)時,執(zhí)行q=d,邊沿觸發(fā)(4)時鐘信號或一個異步事件:always@(posedgeclkornegedgeclk)beginif(!clr)q=1'b0; //清除qelseq=d //加載dend(5)時鐘信號或多個異步事件:always@(posedgeclkornegedgesetornegedgeclr)beginif(set)q=1'b1 //設(shè)定qelseif(!clr)q=1'b0; //清除qelseq=d; //加載dend4.1.5賦值語句1.持續(xù)賦值語句(ContinuousAssignments)assign為持續(xù)賦值語句,主要用于對wire型變量的賦值。比如:assignc=a&b;在上面的賦值中,a、b、c三個變量皆為wire型變量,a和b信號的任何變化,都將隨時反映到c上來。2.過程賦值語句(ProceduralAssignments)過程賦值語句多用于對reg型變量進(jìn)行賦值。過程賦值語句只能出現(xiàn)在過程語句后面的過程塊中。過程賦值有阻塞(blocking)賦值和非阻塞(non_blocking)賦值兩種方式。(1)非阻塞(non_blocking)賦值方式。其賦值符號為“<=”,如:b<=a;非阻塞賦值在整個過程塊結(jié)束時才完成賦值操作,即b的值并不是立刻就改變的。(2)阻塞(blocking)賦值方式。其賦值符號為“=”,如:b=a;阻塞賦值在該語句結(jié)束時立即完成賦值操作,即b的值在該條語句結(jié)束后立刻改變。如果在一個塊語句中有多條阻塞賦值語句,那么在前面的賦值語句沒有完成之前,后面的語句就不能被執(zhí)行,仿佛被阻塞了(blocking)一樣,因此稱為阻塞賦值方式。(3)應(yīng)用舉例。例4.4非阻塞賦值實例。modulenon_block(c,b,a,clk);outputc,b;inputclk,a;regc,b;always@(posedgeclk)beginb<=a;c<=b;endendmodule圖4.1為例4.4的功能仿真圖,從圖上可以看出,在時鐘第1次上跳變前a?=?0,b?=?0,這些值被賦值給該上升沿之后的b和c,所以緊隨該上升沿之后b?=?0,c?=?0;在時鐘第二次上跳變前a?=?1,b?=?0,這些值被賦值給該上升沿之后的b和c,所以緊隨該上升沿之后b?=?1,c?=?0,其他同理。例4.5阻塞賦值實例。moduleblock(c,b,a,clk);outputc,b;inputclk,a;regc,b;always@(posedgeclk)beginb=a;c=b;endendmodule圖4.2為例4.5的功能仿真圖,從圖上可以看出,始終有c=b,是因為在阻塞賦值語句中,首先將a的值賦給b,執(zhí)行完成后,再將b得到的結(jié)果賦值給c,這樣一來,b和c的最終取值就一樣了。圖4.3和圖4.4分別為非阻塞賦值綜合結(jié)果和阻塞賦值綜合結(jié)果。比較二者可以發(fā)現(xiàn),實現(xiàn)阻塞賦值語句的電路中,b和c的輸出隨時都是一樣的,而非阻塞賦值中,b的現(xiàn)態(tài)為c的次態(tài)。圖4.1~圖4.4均為在QuartusⅡ8.1(32?bit)下得到的結(jié)果。4.1.6塊語句1.?begin…end區(qū)塊語句begin…end區(qū)塊用于將若干語句集合在一起,并且是順序(串行)執(zhí)行的,因此又稱為串行塊。串行塊的使用格式為begin:[塊名][塊內(nèi)部局部變量說明;]時間控制1行為語句1;時間控制n行為語句n;end串行塊執(zhí)行時具有如下特點:(1)串行塊內(nèi)的各條語句是按它們在塊內(nèi)出現(xiàn)的次序逐條順序執(zhí)行的,當(dāng)前面一條語句執(zhí)行完成后,下一條語句才能開始執(zhí)行。(2)塊中每條語句的延時控制都是相對于前一條語句結(jié)束時刻的延時控制。(3)在進(jìn)行仿真時,當(dāng)遇到串行塊時,塊中第一條語句就開始執(zhí)行;當(dāng)串行塊中最后一條語句執(zhí)行完畢時,程序流程控制就跳出串行塊,串行塊執(zhí)行結(jié)束;整個串行塊的執(zhí)行時間等于其內(nèi)部各條語句執(zhí)行時間的總和。串行塊通常使用在if、case語句及for循環(huán)中。在區(qū)塊語句中可與disable語句配合使用,用于中途跳離區(qū)塊,并將硬件執(zhí)行轉(zhuǎn)移至緊接區(qū)塊的下一語句。2.?fork…join區(qū)塊語句fork…join語句提供了一個并行處理區(qū)塊的仿真環(huán)境,在此區(qū)塊中的所有語句并行地被執(zhí)行,因此在這個區(qū)塊中的語句,其排列的次序并不影響執(zhí)行結(jié)果。fork…join區(qū)塊語句與begin…end區(qū)塊語句的最大不同點在于begin…end區(qū)塊內(nèi)的語句為順序結(jié)構(gòu),而fork…join區(qū)塊內(nèi)的語句為并行結(jié)構(gòu)。并行塊的書寫格式為fork:[塊名][塊內(nèi)部局部變量說明;]時間控制1行為語句1;時間控制n行為語句n;join其中,塊內(nèi)部局部變量說明可以是reg型變量說明語句、integer型變量說明語句、real型變量說明語句、time型變量說明語句及事件(event)說明語句。并行塊執(zhí)行時具有如下特點:(1)并行塊內(nèi)各條語句是同時并行執(zhí)行的,也就是說,當(dāng)程序流程控制進(jìn)入并行塊后,塊內(nèi)各條語句都各自獨立地同時開始執(zhí)行,各條語句的起始執(zhí)行時間都等于程序流程控制進(jìn)入該并行塊的時間。(2)塊內(nèi)各條語句中指定的延時控制都是相對于程序流程控制進(jìn)入并行塊時刻的延時,即相對于并行塊開始執(zhí)行時刻的延時。(3)當(dāng)并行塊內(nèi)所有的語句都已經(jīng)執(zhí)行完后,也就是當(dāng)執(zhí)行時間最長的那一條語句塊內(nèi)的語句執(zhí)行完后,程序流程控制才跳出并行塊,結(jié)束并行塊的執(zhí)行。整個并行塊的執(zhí)行時間等于執(zhí)行時間最長的那條語句所需的執(zhí)行時間。3.應(yīng)用舉例例4.6表4.13是begin…end和fork…join區(qū)塊語句的比較實例。在并行區(qū)塊中,兩個或更多個“always”過程塊、“assign”持續(xù)賦值語句、實例元件調(diào)用等操作都是同時執(zhí)行的。在“always”模塊內(nèi)部,其語句如果是非阻塞式賦值,則語句是并發(fā)執(zhí)行的;而如果是阻塞式賦值,則語句是按照指定的順序執(zhí)行的,語句的書寫順序?qū)Τ绦虻膱?zhí)行結(jié)果有著直接的影響。順序執(zhí)行模塊1:moduleserial1(q,a,clk);outputq,a;inputclk;regq,a;always@(posedgeclk)beginq=~q;a=~q;endendmodule順序執(zhí)行模塊2:moduleserial2(q,a,clk);outputq,a;inputclk;regq,a;always@(posedgeclk)begina=~q;q=~q;endendmodule順序執(zhí)行模塊1的仿真波形圖如圖4.5所示,順序執(zhí)行模塊2的仿真波形圖如圖4.6所示。順序執(zhí)行模塊1的綜合結(jié)果及順序執(zhí)行模塊2的綜合結(jié)果分別如圖4.7和圖4.8所示。4.1.7條件語句1.語句格式If…else條件語句的作用是根據(jù)判斷所給出的條件是否滿足來確定下一步要執(zhí)行的操作。通常可根據(jù)條件的多少采用如表4.14所示的四種不同的形式進(jìn)行判斷。2.應(yīng)用舉例例4.7計數(shù)器的設(shè)計。程序如下:moduleifelse(clock,reset,data,load,count);inputclock,reset,data,load;outputcount;regcount;always@(posedgeclockornegedgereset)beginif(!reset)//異步復(fù)位count<=0;elseif(!load)//同步置位count<=data;elsecount<=count+1;endendmodule4.1.8選擇語句1.?case語句case語句類似于if…else條件語句,其語法格式如下:case(狀況表示式)狀況1:begin<語句區(qū)塊1>;end狀況2:begin<語句區(qū)塊2>;enddefault:begin<語句區(qū)塊n>;endendcase其語法由case…endcase所包括,依不同的狀況決定執(zhí)行哪一語句區(qū),每一個case狀況的表達(dá)式的值必須互不相同,否則就會出現(xiàn)矛盾。每一狀況中<語句區(qū)塊>包含了一個或多個語句。若只存在一個語句,則begin…end可以省略。根據(jù)狀況表示式,逐一對比所列狀況,當(dāng)找到適合的狀況后,隨即執(zhí)行對應(yīng)的<語句區(qū)塊>,執(zhí)行完后跳離case…endcase語句區(qū)。因此各狀況的優(yōu)先次序由上而下,依序遞減,若所有的狀況都不符合,則執(zhí)行default中的“語句區(qū)n”。2.?casez語句casez語句與case語句的語法結(jié)構(gòu)和執(zhí)行過程完全一樣,唯一不同的地方在于其狀況表示,當(dāng)出現(xiàn)z及???時,其狀況判定可當(dāng)成don’tcare,亦即出現(xiàn)z或?位時不作比較。以下為正確的casez的語法結(jié)構(gòu)://優(yōu)先級選擇器case(sel)3'b??1:y=a; //第一優(yōu)先級3'b?10:y=b; //第二優(yōu)先級3'b100:y=c; //最低優(yōu)先級default:y=4'bzzzz;endcase在上例中,輸入為a、b、c,輸出為y。根據(jù)3位的選擇信號sel決定輸出,當(dāng)sel[0]?=?1時,不管sel[1]?與sel[2]?為何,其輸出y?=?a;若sel[0]?=?0且sel[1]?=?1,則不管sel[2]?為何,其輸出y?=?b;最后,只有在sel[2]?=?1、sel[1]?=?0且sel[0]?=?0時,輸出y才為c,亦即sel[0]?有最高決定權(quán),sel[1]?次之,而sel[2]?的決定權(quán)最低。3.?casex語句與case及casez語法相同,當(dāng)狀況表示式出現(xiàn)z、?及x時,其狀況判定可當(dāng)成don’tcare狀態(tài)而不作比較。需要注意的是,在casez和casex語句中都是用endcase結(jié)束,而不是endcasex或endcasez結(jié)束。casez和casex聲明語句的表達(dá)式中x(不確定值)和z(高阻值)可以和任何值相等,這可能給仿真結(jié)果帶來混亂。4.應(yīng)用舉例例4.8普通的四選一選擇器。程序如下:modulemux4_1(out,in0,in1,in2,in3,sel);outputout;inputin0,in1,in2,in3;input[1:0]sel;regout;always@(in0orin1orin2orin3orsel)//敏感信號列表case(sel)2'b00: out=in0;2'b01: out=in1;2'b10: out=in2;2'b11: out=in3;default:out=2'bx;endcaseendmodule例4.9具有優(yōu)先權(quán)的四選一選擇器。程序如下://具有優(yōu)先權(quán)的四選一選擇器mux4_1.vmodulemux4_1(y,sel,a,b,c,d);output[4:0]y; //選擇輸出input[3:0]sel; //選擇信號input[4:0]a,b,c,d; //多路輸入,a~d的優(yōu)先級從低到高reg[4:0]y;always@(seloraorborcord)begincasez(sel)4'bzzz1:y=a;4'bzz10:y=b;4'bz100:y=c;4'b1000:y=d;default:y=4'bzzzzz;endcaseendendmodulecase語句與if…else…if語句的區(qū)別主要有兩點:(1)與case語句中的控制表達(dá)式和分支表達(dá)式這種比較結(jié)構(gòu)相比,if-else-if結(jié)構(gòu)中的條件表達(dá)式更為直觀。(2)對于那些分支表達(dá)式中存在不定值x和高阻值z的情況,case語句提供了處理這種情況的手段,即采用casex和casez語句實現(xiàn)。需要指出的是,case語句的default分支雖然可以缺省,但是一般不要缺省,否則會和if語句中缺少else分支一樣,產(chǎn)生鎖存器。例如:always@(a[1:0]orb)begin case(a) 2'b00:q<=b; 2'b01:q<=b+1;end這樣就會生成鎖存器,一般為了使case語句可控,都需要加上default選項。如:always@(a[1:0]orb)begin case(a) 2'b00:q<=b; 2'b01:q<=b+1; default:q<=b+2;end所以在實際開發(fā)中,要避免生成鎖存器的錯誤發(fā)生。如果用if語句,最好寫上else選項;如果用case語句,最好寫上default選項。遵循上面兩條原則,就可以避免發(fā)生這種錯誤,使設(shè)計目標(biāo)明確,結(jié)果可控,同時也增加Verilog程序的可讀性。為此,在實際中如果有分支情況,則盡量選擇case語句,因為case語句的分支是并行執(zhí)行的,各個分支沒有優(yōu)先級的區(qū)別。而if語句的選擇分支是串行執(zhí)行的,是按照書寫順序逐次判斷的。如在設(shè)計中本沒有優(yōu)先級考慮,選用if語句會比選用case語句占用更多的硬件資源。4.1.9循環(huán)語句1.?for語句for循環(huán)的語法結(jié)構(gòu)為for(循環(huán)變量=低值;循環(huán)變量<高值;循環(huán)變量=循環(huán)變量+常量)begin<語句區(qū)塊>endfor語句的語法與計算機(jī)程序C語言中的for循環(huán)相似,其中高值必須大于或等于低值,每執(zhí)行完一次循環(huán),循環(huán)變量即加一次常數(shù),直到循環(huán)變量大于高值為止。在語句中,<語句區(qū)塊>可為一行以上的語句,若語句僅存在一行,則關(guān)鍵詞begin…end可以省略。2.?while循環(huán)while循環(huán)結(jié)構(gòu)的語法如下:while(條件判斷表示式)begin<語句區(qū)塊>;end若條件判斷表示式為真,則執(zhí)行<語句區(qū)塊>,直到條件判斷為假,才停止執(zhí)行。與C語句一樣,當(dāng)<語句區(qū)塊>僅存在一行語句時,關(guān)鍵詞begin…end即可取消。3.?forever循環(huán)forever循環(huán)以無條件方式執(zhí)行語句區(qū)塊,直到遇到disable語句為止,其語句格式為foreverbegin<語句區(qū)塊>end4.?repeat循環(huán)repeat的循環(huán)語法為repeat(表示式)begin<語句區(qū)塊>;end與前面的循環(huán)語句一樣,<語句區(qū)塊>可為一行或多行語句。若為一行語句,則關(guān)鍵詞begin…end可取消。<表示式>必須為一已知正數(shù)值或一常數(shù),不可為變量。若<表示式>中出現(xiàn)x或z,將被當(dāng)成0,則<語句區(qū)塊>將不被執(zhí)行。當(dāng)<語句區(qū)塊>出現(xiàn)disable指令時,不論循環(huán)次數(shù)是否執(zhí)行完畢,它都將自動離開循環(huán)。5.應(yīng)用舉例例4.10用for語句描述七人投票表決器,程序代碼如下:modulevoter7(pass,vote);outputpass;input[6:0]vote;reg[2:0]sum;integeri;regpass;always@(vote)beginsum=0;for(i=0;i<=6;I=i+1) //?for語句if(vote[i])sum=sum+1;if(sum[2])pass=1; //若超過4人贊成,則pass=1else pass=0;endendmodule例4.11用repeat循環(huán)設(shè)計一個計算字節(jié)中出現(xiàn)1的個數(shù)的電路。程序如下://用repeat循環(huán)計算字節(jié)中出現(xiàn)1的個數(shù)的電路repeat_1s.vmodulerepeat_1s(ones,din);output[3:0]ones; //?1的個數(shù)輸出parameterlength=8; //數(shù)據(jù)長度input[length-1:0]din; //?8位數(shù)據(jù)輸入reg[length-1:0]temp;reg[3:0]ones;reg[3:0]cout;always@(din)begincout=4'b0000;
temp=din; repeat(length)beginif(temp[0])cout=cout+4'b0001;temp=temp>>1; //右移一位endones=cout;endendmodule例4.12用while語句實現(xiàn)4位乘法器。代碼如下:modulemultiply_4(a,b,result);parameters=4;input[s:1]a,b;output[2*s:1]result;reg[2*s:1]result,a_temp;reg[s:1]b_temp,c_temp;always@(aorb)begin
result=0;
a_temp={4'b0,a};
b_temp=b;
c_temp=s;
while(c_temp>0)
begin if(b_temp[1])result=result+a_temp;elseresult=result; beginc_temp=c_temp-1;a_temp=a_temp<<1;b_temp=b_temp>>1; end
end endendmodule 4.2
VerilogHDL的描述風(fēng)格VerilogHDL的描述風(fēng)格(或者說描述方式)可分為三類:結(jié)構(gòu)型(Structural)描述、數(shù)據(jù)流型(DataFlow)描述、行為型(Behavioural)描述。4.2.1結(jié)構(gòu)型描述結(jié)構(gòu)型描述指描述實體連接的結(jié)構(gòu)方式,它通常通過實例進(jìn)行描述,將Verilog已定義的基元實例嵌入到語言中。在Verilog程序中可通過調(diào)用Verilog內(nèi)置門元件(門級結(jié)構(gòu)描述)、開關(guān)級元件(晶體管級結(jié)構(gòu)描述)、用戶自定義元件UDP(也在門級)、模塊化實例等方式描述電路的結(jié)構(gòu)。結(jié)構(gòu)化描述可以用不同類型的結(jié)構(gòu)來完成多層次的工程,即從簡單的門到非常復(fù)雜的元件(包括各種已完成的設(shè)計模塊)來描述整個系統(tǒng)。1.門級結(jié)構(gòu)描述門級結(jié)構(gòu)描述是指調(diào)用VerilogHDL內(nèi)部的基本門級元件來對硬件電路的結(jié)構(gòu)進(jìn)行描述,這種情況下模塊將由基本門級元件的實例組成。由于一個數(shù)字電路系統(tǒng)最終是由一個個邏輯門和開關(guān)所組成的,因此用邏輯門單元和開關(guān)單元來對硬件電路的組成結(jié)構(gòu)進(jìn)行描述是最直觀的??紤]到這一點,VerilogHDL把一些常用的基本邏輯門單元和開關(guān)單元的模型包含到語句內(nèi)部,這些模型被稱為基本門級元件(BasicGate-LevelPrimitives)和基本開關(guān)級元件(BasicSwitch-LevelPrimitives)。在Verilog中的內(nèi)置基本門級元件如表4.15所示。調(diào)用門元件的格式為門元件名字<例化的門名字>(<端口列表>)其中普通門的端口列表按下面的順序列出:(輸出,輸入1,輸入2,輸入3…);比如:anda1(out,in1,in2,in3); //三輸入與門對于三態(tài)門,則按如下順序列出輸入輸出端口:(輸出,輸入,使能控制端);比如:bufif1mytri1(out,in,enable); //高電平使能的三態(tài)門例4.13采用門級結(jié)構(gòu)描述實現(xiàn)一位全加器。代碼如下:modulefull_add1(a,b,cin,sum,cout);inputa,b,cin;outputsum,cout;wires1,m1,m2,m3;and(m1,a,b),(m2,b,cin),(m3,a,cin);xor(s1,a,b),(sum,s1,cin);or(cout,m1,m2,m3);endmodule圖4.9是該一位全加器綜合結(jié)果圖,圖中將兩個異或門綜合成一個3輸入的異或門。圖4.10是該一位全加器的功能仿真圖,從仿真結(jié)果看該程序設(shè)計正確。2.元件實例化元件實例化語句就是將預(yù)先設(shè)計好的模塊定義為一個元件,然后利用特定的語句將此元件與當(dāng)前設(shè)計中的指定端口相連接,從而為當(dāng)前設(shè)計模塊引入一個新的、低一級的設(shè)計層次。在這里,當(dāng)前設(shè)計模塊相當(dāng)于一個較大的電路系統(tǒng),所定義的實例化元件相當(dāng)于一個要插在這個電路系統(tǒng)板上的芯片,而當(dāng)前設(shè)計模塊中指定的端口則相當(dāng)于這塊電路板上準(zhǔn)備接受此芯片的一個插座。元件實例化語句是使VerilogHDL設(shè)計模塊構(gòu)成自上而下層次化設(shè)計的一種重要途徑。元件實例化語句的使用格式有兩種:(1)名字關(guān)聯(lián)方式:將實例化元件的端口名與關(guān)聯(lián)端口名通過“.實例化元件端口名(連接端口名)”的形式一一對應(yīng)地聯(lián)系起來的方式。其使用格式如下:實例化元件名元件實例化標(biāo)號(.實例化元件端口名(連接端口名),…);(2)位置關(guān)聯(lián)方式:按實例化元件端口的定義順序?qū)嵗膶?yīng)連接模塊端口名一一列出的一種關(guān)聯(lián)方式。其使用格式如下:實例化元件名元件實例化標(biāo)號(連接端口名,…);在位置關(guān)聯(lián)方式下,實例化元件名和元件實例化標(biāo)號的含義及使用要求同名字關(guān)聯(lián)方式;對于端口的映射關(guān)系,只要按實例化元件的端口定義順序列出當(dāng)前系統(tǒng)中的連接模塊端口名就行了。例4.14采用元件實例化語句設(shè)計一個2位級聯(lián)加法器。設(shè)計思路:2位加法器可以采用2個一位全加器級聯(lián)實現(xiàn),低位的進(jìn)位輸出作為高位的進(jìn)位輸入,其級聯(lián)結(jié)構(gòu)如圖4.11所示。程序如下:moduleadd_jl(sum,cout,a,b,cin);input[1:0]a,b;inputcin;output[1:0]sum;outputcout;full_add1f0(a[0],b[0],cin,sum[0],cin1);full_add1f1(a[1],b[1],cin1,sum[1],cout);endmodule圖4.12是該加法器在QuartusⅡ8.1開發(fā)軟件中的RTL視圖。從圖中可以看出,元件實例化語句綜合后的電路結(jié)構(gòu)與設(shè)計預(yù)期一致,同時,一個實例化語句對應(yīng)一個硬件。圖4.13是其功能仿真結(jié)果
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年北海市公安局招聘警務(wù)輔助人員考試筆試試題(含答案)
- 無蓋吐司教學(xué)課件
- 教學(xué)課件需要歸檔嗎
- 教學(xué)課件白楊
- 走進(jìn)魯迅教學(xué)課件
- 郭鵬驥課件教學(xué)
- 生命生命 教學(xué)課件
- 教育技術(shù)課件下載app
- 【青島】2025年山東青島平度市公立醫(yī)院及衛(wèi)生事業(yè)單位引進(jìn)及校園招聘93人筆試歷年典型考題及考點剖析附帶答案詳解
- 新疆小隊活動方案
- 2025至2030中國建筑水泥行業(yè)產(chǎn)業(yè)運行態(tài)勢及投資規(guī)劃深度研究報告
- 2025年中國數(shù)據(jù)庫市場研究報告
- 國家開放大學(xué)《思想道德與法治》社會實踐報告范文一
- 2024年包頭市公安局招聘專職留置看護(hù)警務(wù)輔助人員筆試真題
- 【9語安徽中考卷】2025年安徽省中考招生考試真題語文試卷(真題+答案)
- 非典型溶血尿毒綜合征多學(xué)科實踐共識解讀(2025版)
- 2025年空氣過濾器行業(yè)分析報告
- (高清版)DG∕TJ 08-507-2018 高強(qiáng)混凝土抗壓強(qiáng)度無損檢測技術(shù)標(biāo)準(zhǔn)
- 母子暑假協(xié)議書
- 租房學(xué)位合同協(xié)議書范本
- 《初三化學(xué)教材中探究性實驗的開發(fā)與應(yīng)用研究》開題報告
評論
0/150
提交評論