《數(shù)字電路設(shè)計(jì)及Verilog HDL實(shí)現(xiàn)》課件第3章_第1頁
《數(shù)字電路設(shè)計(jì)及Verilog HDL實(shí)現(xiàn)》課件第3章_第2頁
《數(shù)字電路設(shè)計(jì)及Verilog HDL實(shí)現(xiàn)》課件第3章_第3頁
《數(shù)字電路設(shè)計(jì)及Verilog HDL實(shí)現(xiàn)》課件第3章_第4頁
《數(shù)字電路設(shè)計(jì)及Verilog HDL實(shí)現(xiàn)》課件第3章_第5頁
已閱讀5頁,還剩121頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

3.1VerilogHDL程序的基本結(jié)構(gòu)

3.2VerilogHDL的數(shù)據(jù)類型

3.3VerilogHDL的運(yùn)算符

3.4VerilogHDL的基本語句

3.5模塊化程序設(shè)計(jì)

第3章VerilogHDL的基本語法

VerilogHDL程序由模塊(module)組成,模塊的基本結(jié)構(gòu)如圖3.3.1所示。一個(gè)完整的模塊由模塊端口定義和模塊內(nèi)容兩部分組成,模塊內(nèi)容包括I/O聲明、信號類型聲明和功能描述。3.1VerilogHDL程序的基本結(jié)構(gòu)圖3.1.1VerilogHDL程序模塊結(jié)構(gòu)例如,定義一個(gè)1位全加器full_addr模塊,其輸入/輸出端口有5個(gè):a、b是全加器的兩個(gè)加數(shù)輸入;cin是低位的進(jìn)位輸入;s是全加器的和輸出;cout是全加器向高位的進(jìn)位輸

出。其格式如下:

modulefull_addr(s,cout,a,b,cin);//模塊端口定義

inputa,b,cin;//I/O聲明

outputs,cout;

assign{cout,s}=a+b+cin;//功能描述

endmodule模塊的設(shè)計(jì)遵循以下規(guī)則:

(1)模塊內(nèi)容位于module和endmodule之間;每個(gè)模塊都有一個(gè)名字,即模塊名,如full_addr,模塊名中可以包含英文字母、數(shù)字和下劃線,并以英文字母開頭。

(2)除endmodule外,所有的語句后面必須有分號“;”。

(3)語句可以是單條語句,也可以是用begin和end兩個(gè)保留字包圍起來的由多條語句組成的復(fù)合語句。

(4)可以用“/*…*/”或“//…”對程序的任何部分作注釋,增加程序的可讀性和可維護(hù)性。3.1.1模塊端口定義

模塊端口定義用來聲明設(shè)計(jì)模塊的輸入/輸出端口,其格式如下:

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

模塊的端口是設(shè)計(jì)電路模塊與外部聯(lián)系的全部輸入/輸出端口信號,是設(shè)計(jì)實(shí)體的對外引腳,是使用時(shí)外界可以看到的部分(不包括電源線和地線),多個(gè)端口之間用逗號“,”隔開。3.1.2模塊內(nèi)容

模塊內(nèi)容用于對信號的I/O狀態(tài)及信號類型進(jìn)行聲明,并描述模塊的功能。

1.I/O聲明

模塊的I/O聲明用來聲明各端口信號流動方向,包括輸入(input)、輸出(output)和雙向(inout)。I/O聲明格式如下:

1)輸入聲明

如果信號位寬為1位,那么聲明格式為

input端口1,端口2,端口3,…;

如果信號位寬大于1位,那么聲明格式為

input[msb:lsb]端口1,端口2,端口3,…;

其中,msb和lsb分別表示信號最高位和最低位的編號。

2)輸出聲明

如果信號位寬為1位,那么聲明格式為

output端口1,端口2,端口3,…;

如果信號位寬大于1位,那么聲明格式為

output[msb:lsb]端口1,端口2,端口3,…;

3)輸入、輸出聲明

如果信號位寬為1位,那么聲明格式為

inout端口1,端口2,端口3,…;

如果信號位寬大于1位,那么聲明格式為

inout[msb:lsb]端口1,端口2,端口3,…;

2.信號類型聲明

信號類型聲明用來說明電路的功能描述中所用信號的數(shù)據(jù)類型,常用的信號類型有連線型(wire)、寄存器型(reg)、整型(integer)、實(shí)型(real)、時(shí)間型(time)等。

3.功能描述

功能描述是VerilogHDL程序的主要部分,用來描述設(shè)計(jì)模塊內(nèi)部結(jié)構(gòu)和模塊端口間的邏輯關(guān)系,在電路上相當(dāng)于器件的內(nèi)部結(jié)構(gòu)。功能描述可以用assign語句、實(shí)例化元件、always塊語句、initial塊等語句來實(shí)現(xiàn)。

1)用assign語句實(shí)現(xiàn)

這種方式很簡單,只要在assign后面加一個(gè)賦值語句即可。assign語句一般適合對組合邏輯進(jìn)行描述,稱為連續(xù)賦值方式。

例如,描述一個(gè)兩輸入的與門可寫為

assigna=b&c;

2)用實(shí)例元件實(shí)現(xiàn)

用實(shí)例化元件實(shí)現(xiàn)就是利用VerilogHDL提供的元件庫來實(shí)現(xiàn)一個(gè)邏輯關(guān)系。

例如,用實(shí)例化元件表示一個(gè)兩輸入的與門可以寫為

andu1(q,a,b);

其中,and是VerilogHDL元件庫中與門的元件名;u1是實(shí)例化后的與門名稱;q是與門的輸出;a、b是與門的輸入端。要求模塊中每個(gè)實(shí)例化后的元件名稱必須是唯一的。

3)用always塊實(shí)現(xiàn)

always塊語句可以實(shí)現(xiàn)各種邏輯,常用于組合和時(shí)序邏輯的功能描述。一個(gè)程序設(shè)計(jì)模塊中可以包含一個(gè)或多個(gè)always塊語句。程序運(yùn)行中,在某些條件滿足時(shí),就重復(fù)執(zhí)行always塊中的語句。

例如,表示一個(gè)帶有異步清除端的D觸發(fā)器可寫為

always@(posedgeclkorposedgeclr)

begin

if(clr)q<=0;

elseq<=d;

end

4)用initial塊實(shí)現(xiàn)

initial塊語句與always塊語句類似,不過在程序中initial塊語句只被執(zhí)行一次,常用于電路的初始化。3.2.1常量

在程序運(yùn)行過程中,其值不能改變的量稱為常量。在VerilogHDL中有三類常量:整型、實(shí)型和字符串型。

1.整型常量

在VerilogHDL中,整型常量的表示格式為

<位寬>′<進(jìn)制><數(shù)值>3.2VerilogHDL的數(shù)據(jù)類型位寬:位寬是對應(yīng)的二進(jìn)制寬度。當(dāng)定義的位寬比常數(shù)實(shí)際的位寬大時(shí),在常數(shù)的左邊自動填補(bǔ)0,但如果常數(shù)的最左邊一位是x或z時(shí),那么就在左邊自動填補(bǔ)x或z;當(dāng)定義的位寬比常數(shù)實(shí)際的長度小時(shí),在最左邊的相應(yīng)位就被截?cái)唷?/p>

進(jìn)制:整型數(shù)有四種進(jìn)制形式:

(1)二進(jìn)制(b或B)。

(2)十進(jìn)制(d或D)。

(3)八進(jìn)制(o或Q)。

(4)十六進(jìn)制(h或H)。數(shù)值:二進(jìn)制數(shù)值可以用下列四種基本的值來表示:

(1)0:邏輯0或“假”。

(2)1:邏輯1或“真”。

(3)x:未知。

(4)z:高阻。

這四種值的解釋都內(nèi)置于語言中,如一個(gè)為0的值是指邏輯0,一個(gè)為1的值是指邏輯1,一個(gè)為z的值是指高阻抗,一個(gè)為x的值是指邏輯不定值。x值和z值都是不區(qū)分大小寫的。例如:

6′B10X1Z0//6位二進(jìn)制數(shù),從低位數(shù)起第2位為高阻,第4位為不定值

5′O37

//5位八進(jìn)制數(shù)

4′D98

//4位十進(jìn)制數(shù)

7′H1A

//7位十六進(jìn)制數(shù)

8′h4Z

//8位十六進(jìn)制值,即0100zzzz

-8′D76

//8位十進(jìn)制值,即-76,符號必須寫在最前邊另外,整型常量還有兩種表示方式,其格式為

′<進(jìn)制><數(shù)值>

<數(shù)值>

在不指定位寬時(shí),缺省位寬由機(jī)器系統(tǒng)決定,但至少為32位;如果數(shù)值中既無位寬,也無進(jìn)制,則缺省為十進(jìn)制數(shù)。例如:

′O35//位寬為32位的八進(jìn)制數(shù)

′H67//位寬為32位的十六進(jìn)制數(shù)

92

//十進(jìn)制數(shù)92

-100//十進(jìn)制數(shù)-100

2.實(shí)型常量

實(shí)型數(shù)可以用十進(jìn)制計(jì)數(shù)法和科學(xué)計(jì)數(shù)法兩種格式表示。在表示小數(shù)時(shí),小數(shù)點(diǎn)兩邊必須都有數(shù)字,否則為非法的表示形式。

例如:

7.56//十進(jìn)制數(shù)計(jì)數(shù)法

4.

//非法表示,小數(shù)點(diǎn)后應(yīng)有數(shù)字

34.56e2//科學(xué)計(jì)數(shù)法,其值為3456(e與E相同)

6E-2//科學(xué)計(jì)數(shù)法,其值為0.06

3.字符串型常量

字符串是用雙引號括起來的字符序列,它必須寫在同一行,不能分行書寫。字符串中的每個(gè)字符都是以其ASCII碼進(jìn)行存放的,一個(gè)字符串可以看做是8位的ASCII碼值序列。

例如:

″hello!″//按字母順序存放,每個(gè)字母為8位ASCII碼

另外,還存在一些特殊字符,這些特殊字符又稱轉(zhuǎn)義字符,用“\”來說明。常用的特殊字符的表示及含義如表3.2.1所示。表3.2.1特殊字符的表示及含義

4.參數(shù)常量

在VerilogHDL中用parameter來定義常量,即用parameter定義一個(gè)標(biāo)識符代表一個(gè)常量,稱為參數(shù)常量或符號常量,這樣可以增加程序的可讀性和可維護(hù)性。

參數(shù)常量定義格式如下:

parameter標(biāo)識符1=表達(dá)式1,標(biāo)識符2=表達(dá)式2,…,標(biāo)識符n=表達(dá)式n;

例如:

parameterPI=3.14,A=8′B10110101,WORD_LENGTH=16;3.2.2變量

在程序運(yùn)行過程中,其值可以改變的量稱為變量。在VerilogHDL中,變量的數(shù)據(jù)類型很多,這里只對常用的幾種變量類型進(jìn)行介紹。

1.wire型

wire是網(wǎng)絡(luò)數(shù)據(jù)類型之一,表示結(jié)構(gòu)實(shí)體之間的物理連接。網(wǎng)絡(luò)類型的變量不僅不能儲存值,而且必須受到驅(qū)動器的驅(qū)動。如果沒有驅(qū)動器連接到網(wǎng)絡(luò)型的變量上,那么其值為高阻值。網(wǎng)絡(luò)型數(shù)據(jù)有很多種,但最常用的是wire型。

wire型變量常用來表示以assign語句生成的組合邏輯信號,輸入/輸出信號在默認(rèn)情況下自動定義為wire型。wire型信號可作為任何語句中的輸入,也可作為assign語句和實(shí)例化元件的輸出。

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

wire[msb:lsb]變量1,變量2,…,變量n;

其中,wire是定義符;[msb:lsb]中的msb和lsb分別表示wire型變量的最高位和最低位的編號,位寬由msb和lsb確定,如果不指定位寬,那么位寬自動默認(rèn)為1;定義多個(gè)變量時(shí),變量之間用逗號隔開。例如:

wirea,b;//定義了兩個(gè)1位wire型變量a、b

wire[7:0]m,n;//定義了兩個(gè)8位wire型變量m、n,最低位為第0位,最高位為第7位

wire[8:1]x,y;//定義了兩個(gè)8位wire型變量x、y,最低位為第1位,最高位為第8位

2.reg型

reg是寄存器類型,是數(shù)據(jù)存儲單元的抽象,其對應(yīng)的是具有狀態(tài)保持功能的電路元件,如觸發(fā)器、鎖存器等。

reg型變量只能在always和initial塊中被賦值,通過賦值語句改變r(jià)eg型變量的值,若reg型變量未被初始化,則其值為未知值x。reg型變量與wire型變量的區(qū)別是:wire型變量需要持續(xù)地驅(qū)動,而reg型變量保持最后一次的賦值。

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

reg[msb:lsb]變量1,變量2,…,變量n;

其中,reg是定義符;[msb:lsb]中的msb和lsb分別表示reg型變量的最高位和最低位的編號,位寬由msb和lsb確定,如果不指定位寬,則自動默認(rèn)為1。例如:

regx0,y0;//定義了兩個(gè)1位reg型變量x0、y0

reg[7:0]d,q;//定義了兩個(gè)8位reg型變量d、q,最低位為第0位,最高位為第7位

reg[8:1]sum;//定義了一個(gè)8位reg型變量sum,最低位為第1位,最高位為第8位

3.memory型

memory型是存儲器型,是通過建立reg型數(shù)組來描述的,可以描述RAM存儲器、ROM存儲器和reg文件。

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

reg[msb:lsb]存儲單元1[n1:m1],存儲單元2[n2:m2],…,存儲單元i[ni:mi];

其中,[n1:m1],[n2:m2],…,[ni:mi]分別表示存儲單元的編號范圍。例如:

regmemory1[1023:0];//存儲器為1024個(gè)單元,每個(gè)單元為1位

reg[7:0]memory2[15:0];//存儲器為16個(gè)單元,每個(gè)單元為8位

reg[32:1]memory2[1:512];//存儲器為512個(gè)單元,每個(gè)單元為32位

值得注意的是,對存儲單元的訪問可以通過數(shù)組的索引進(jìn)行。例如,以下語句分別用于定義4個(gè)存儲單元,每個(gè)單元為8位,單元編號為0~3,然后給每個(gè)存儲單元賦值。

reg[8:1]RAM[3:0];

RAM[0]=8′H1A;

RAM[1]=8′H00;

RAM[2]=8′H55;

RAM[3]=8′H31;

4.integer型

integer型是32位帶符號整型變量,用于對循環(huán)控制變量的說明,典型應(yīng)用是高層次的行為建模,它與后面的time和real類型一樣是不可綜合的。也就是說,這些類型是純數(shù)學(xué)的抽象描述,不與任何物理電路相對應(yīng)。

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

integer變量1,變量2,…,變量n;例如:

integeri,j;//定義了兩個(gè)整型變量i,j

integerd[1:8];//定義了一個(gè)含有8個(gè)數(shù)據(jù)的整型數(shù)組

5.time型

time類型用于存儲和處理時(shí)間,是64位無符號數(shù)。

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

time變量1,變量2,…,變量n;

6.real型

real型是64位帶符號實(shí)型變量,用于存儲和處理實(shí)型數(shù)據(jù)。

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

real變量1,變量2,…,變量n;1.算術(shù)運(yùn)算符

算術(shù)運(yùn)算符包括:

+(加法運(yùn)算符或正值運(yùn)算符,如x+y,+8)

-(減法運(yùn)算符或負(fù)值運(yùn)算符,如x-y,-90)

*(乘法運(yùn)算符,如x*y)

/(除法運(yùn)算符,如x/y)

%(取模運(yùn)算符,如x%y)3.3VerilogHDL的運(yùn)算符

2.邏輯運(yùn)算符

邏輯運(yùn)算符包括:

&&(邏輯與)

||(邏輯或)

!(邏輯非)

邏輯運(yùn)算符操作的結(jié)果為0(假)或1(真)。例如,假設(shè):

a=′b0;//0為假

b=′b1;//1為真

那么:

A&&b結(jié)果為0(假)

a||b結(jié)果為1(真)

!a結(jié)果為1(真)

!b結(jié)果為0(假)在判斷一個(gè)數(shù)是否為真時(shí),以0代表“假”,以非0代表“真”。

例如,假設(shè):

ABus=′b0111;

BBus=′b0101;

那么:

ABus||BBus結(jié)果為1(真)

ABus&&BBus結(jié)果為1(真)

!ABus結(jié)果為0(假)

3.關(guān)系運(yùn)算符

關(guān)系運(yùn)算符包括:

<

(小于)

<=

(小于等于)

>

(大于)

>=

(大于等于)

關(guān)系運(yùn)算符是用來確定指定的兩個(gè)操作數(shù)之間的關(guān)系是否成立的,如果成立,結(jié)果為1(真);如果不成立,結(jié)果為0(假)。例如,假設(shè):

m=19;

n=5;

那么:

m>n結(jié)果為1(真)

a>=b結(jié)果為1(真)

m<n結(jié)果為0(假)

a<=b結(jié)果為0(假)

4.等值運(yùn)算符

等值運(yùn)算符包括:

==(邏輯相等)

!=(邏輯不等)

===(全等)

!==(非全等)“==”運(yùn)算符稱為邏輯相等運(yùn)算符,而“===”稱為全等運(yùn)算符,兩個(gè)運(yùn)算符都是比較兩個(gè)數(shù)是否相等的。如果兩個(gè)操作數(shù)相等,那么運(yùn)算結(jié)果為邏輯值1;如果兩個(gè)操作數(shù)不相等,那么運(yùn)算結(jié)果為邏輯0。不同的是由于操作數(shù)中的某些位可能存在不定值x或高阻值z,這時(shí)邏輯相等在進(jìn)行比較時(shí),結(jié)果為不定值x,而全等運(yùn)算符是按位進(jìn)行比較的,對這些不定位或高阻位也進(jìn)行比較,只要兩個(gè)操作數(shù)完全一致,則結(jié)果為1(真),否則結(jié)果為0。

與“==”和“===”相同,“!=”的運(yùn)算結(jié)果可能為1、0或x,而“!==”的運(yùn)算結(jié)果只有兩種狀態(tài),即1或0。例如,假設(shè):

d1=4′b010x;

d2=4′b010x;

那么:

d1==d2結(jié)果為x

d1===d2結(jié)果為1

5.位運(yùn)算符

位運(yùn)算符包括:

~

(非)

&

(與)

~&

(與非)

|

(或)

~|

(或非)

^

(異或)

^~或~^(同或)位運(yùn)算符是對兩個(gè)操作數(shù)按位進(jìn)行邏輯運(yùn)算的。當(dāng)兩個(gè)操作數(shù)的位數(shù)不同時(shí),自動在位數(shù)較少的操作數(shù)的高位補(bǔ)0。

例如,假設(shè):

x=8′b01011111;

y=4′b1100;

那么:

x&y=8′b00001100

x|y=8′b01011111

~x=8′b10100000

~y=4′b0011

x~&y=8′b11110011

x~|y=8′b10100000

x^y=8′b01010011

x^~y=8′b10101100

6.縮減運(yùn)算符

縮減運(yùn)算符包括:

&

(與)

~&

(與非)

|

(或)

~|

(或非)

^

(異或)

^~

(同或)

縮減運(yùn)算符與邏輯運(yùn)算符的法則一樣,但縮減運(yùn)算符是對單個(gè)操作數(shù)按位進(jìn)行邏輯遞推運(yùn)算的,運(yùn)算結(jié)果為1位二進(jìn)制數(shù)。例如:

reg[7:0]a;

regb

b=&a;

程序中,“b=&a;”語句與“b=a[0]&a[1]&a[2]&a[3]&a[4]&a[5]&a[6]&a7];”語句等價(jià)。

7.移位運(yùn)算符

移位運(yùn)算符包括:

<<(左移)

>>(右移)

左移和右移運(yùn)算符是對操作數(shù)進(jìn)行邏輯移位操作的,空位用0進(jìn)行填補(bǔ)。

移位運(yùn)算的格式為

a<<n或a>>n

其中,a為操作數(shù);n為移位的次數(shù)。例如,假設(shè):

i=8;

m=3

那么:

i<<m結(jié)果為64

i>>m結(jié)果為1

8.條件運(yùn)算符

條件運(yùn)算符是:

?:

條件運(yùn)算符是唯一的一個(gè)三目運(yùn)算符,即條件運(yùn)算符需要三個(gè)操作數(shù)。

條件運(yùn)算符格式如下:

條件?表達(dá)式1:表達(dá)式2

條件表達(dá)式的含義是:如果條件為真,則結(jié)果為表達(dá)式1的值;如果條件為假,則結(jié)果為表達(dá)式2的值。例如:

a=10,b=20;

y=a>b?a:b;

由于a>b條件為假,因此,y的值為b的值。

9.拼接運(yùn)算符

拼接運(yùn)算符是:

{}

拼接運(yùn)算符用來將兩個(gè)或多個(gè)數(shù)據(jù)的某些位拼接起來。

拼接運(yùn)算符格式如下:

{數(shù)據(jù)1的某些位,數(shù)據(jù)2的某些位,…,數(shù)據(jù)n的某些位}

例如:

X={a[7:4],b[3],c[2:0]}

表示X是由a的第7~4位、b的第3位和c的第2~0位拼接而成的。

10.運(yùn)算符的優(yōu)先級

在一個(gè)表達(dá)式中出現(xiàn)多種運(yùn)算符時(shí),其運(yùn)算的優(yōu)先級順序如表3.3.1所示。表3.3.1運(yùn)算符的運(yùn)算優(yōu)先級3.4.1賦值語句

在VerilogHDL中,賦值語句有兩種:連續(xù)賦值語句和過程賦值語句。

1.連續(xù)賦值語句

連續(xù)賦值語句用來驅(qū)動wire型變量,這一變量必須事先定義過。使用連續(xù)賦值語句時(shí),只要輸入端操作數(shù)的值發(fā)生變化,該語句就重新計(jì)算并刷新賦值結(jié)果。連續(xù)賦值語句用來描述組合邏輯。3.4VerilogHDL的基本語句連續(xù)賦值語句格式如下:

assign#(延時(shí)量)wire型變量名=賦值表達(dá)式;

語句的含義是:只要右邊賦值表達(dá)式中有變量發(fā)生變化,就重新計(jì)算表達(dá)式的值,新結(jié)果在指定的延時(shí)時(shí)間單位以后賦值給wire型變量。如果不指定延時(shí)量,則延時(shí)量默認(rèn)為0。

例如,下面語句表示只要a或b發(fā)生變化,就重新計(jì)算a和b相與的值,計(jì)算結(jié)果賦值給c。

wirea,b,c;

assignc=a&b;

2.過程賦值語句

過程賦值語句是在initial或always語句塊內(nèi)賦值的,它用于對reg型、memory型、integer型、time型和real型變量賦值,這些變量在下一次過程賦值之前保持原來的值。過程賦值語句分為兩類,分別為阻塞賦值和非阻塞賦值。

1)阻塞賦值

阻塞賦值的賦值符為“=”,它在該語句結(jié)束時(shí)就完成賦值操作。

阻塞賦值格式如下:

變量=賦值表達(dá)式;

2)非阻塞賦值

非阻塞賦值的賦值符為“<=”,它在塊結(jié)束時(shí)才完成賦值操作。

非阻塞賦值格式如下:

變量<=賦值表達(dá)式;

過程中使用阻塞賦值與非阻塞賦值的主要區(qū)別是:一條阻塞賦值語句執(zhí)行時(shí),下一條語句被阻塞,即只有當(dāng)一條語句執(zhí)行結(jié)束,下條語句才能執(zhí)行;非阻塞賦值語句中,各條語句是同時(shí)執(zhí)行的。也可以理解為,阻塞賦值是串行執(zhí)行的,非阻塞賦值是并行執(zhí)行的。為了理解這兩種賦值,下面分析兩段程序的執(zhí)行過程。程序段1:

begin

r1=2;

r2=r1;

r3=r2;

end

程序段2:

begin

r1<=2;

r2<=r1;

r3<=r2;

end3.4.2條件語句

1.if…else語句

if語句是用來判斷給定的條件是否滿足,根據(jù)判定的結(jié)果為真或假決定執(zhí)行的操作。

VerilogHDL語言提供了三種形式的if語句。

1)if(表達(dá)式)語句

例如:

if(x>y)q=x;

2)if(表達(dá)式)語句1else語句2

例如:

if(Reset)

Q=0;

else

Q=D;

3)if(表達(dá)式1)語句1

elseif(表達(dá)式2)語句2

elseif(表達(dá)式3)語句3

elseif(表達(dá)式m)語句m

else語句n

例如:

if(x>y)Q=in1;

if(x==y)Q=in2;

else

Q=in3;

2.case語句

case語句是一種多分支語句,if語句每次只能有兩個(gè)分支可供選擇,而實(shí)際應(yīng)用中常常需要多分支選擇,VerilogHDL語言中的case語句可以直接處理多分支選擇。

case語句格式如下:

case(控制表達(dá)式)

分支項(xiàng)表達(dá)式1:語句1

分支項(xiàng)表達(dá)式2:語句2

分支項(xiàng)表達(dá)式m:語句m

default:語句n

endcase

case語句首先對控制表達(dá)式求值,然后依次對各分支項(xiàng)表達(dá)式求值并進(jìn)行比較,遇到第一個(gè)與控制表達(dá)式值相匹配分支中的語句被執(zhí)行。一個(gè)case結(jié)構(gòu)中可以有多個(gè)分支,但這些值必須互斥。缺省分支覆蓋所有沒有被分支表達(dá)式覆蓋的其他分支。

分支表達(dá)式和各分支項(xiàng)表達(dá)式不必都是常量表達(dá)式。在case語句中,x值和z值作為文字值進(jìn)行比較。例如,下面case結(jié)構(gòu)表示的是一個(gè)3:8譯碼器的程序。

moduleseg(SW,Q);

input[2:0]SW;//SW為3位輸入端口

output[7:0]Q;//Q為3:8譯碼器的8個(gè)輸出端口

reg[7:0]Q;

always@(SW)//SW中有狀態(tài)改變時(shí),執(zhí)行case結(jié)構(gòu)的語句

begin

case(SW)

3′b000:Q=8′b11111110;

3′b001:Q=8′b11111101;

3′b010:Q=8′b11111011;

3′b011:Q=8′b11110111;

3′b100:Q=8′b11101111;

3′b101:Q=8′b11011111;

3′b110:Q=8′b10111111;

3′b111:Q=8′b01111111;

endcase

end

endmodule3.4.3循環(huán)語句

VerilogHDL中有四類循環(huán)語句,它們是:

(1)forever循環(huán)。

(2)repeat循環(huán)。

(3)while循環(huán)。

(4)for循環(huán)。

1.forever循環(huán)語句

forever循環(huán)語句用于連續(xù)執(zhí)行過程,其格式如下:

forever語句

forever循環(huán)語句常用于產(chǎn)生周期性的波形。它與always語句不同之處在于它不能獨(dú)立寫在程序中,而必須寫在initial塊中。例如:

initial

begin

clock=0;

#5forever

#10clock=~clock;

end

2.repeat循環(huán)語句

repeat循環(huán)語句是用于執(zhí)行指定循環(huán)次數(shù)的過程語句,其格式如下:

repeat(表達(dá)式)語句

repeat循環(huán)語句中的表達(dá)式通常為常量表達(dá)式,表示循環(huán)的次數(shù)。如果循環(huán)計(jì)數(shù)表達(dá)式的值不確定,即為x或z時(shí),那么循環(huán)次數(shù)按0處理。例如,下面是用repeat語句完成算式S=1+2+3+4+…+100的程序。

initial

begin

s=0;

i=1;

repeat(100)

begin

s=s+i;

i=i+1

end

end

3.while循環(huán)語句

while循環(huán)執(zhí)行過程賦值語句直到指定的條件為假,其格式如下:

while(條件)語句

執(zhí)行while時(shí),先對條件進(jìn)行判斷,如果條件為真,那么執(zhí)行該語句;如果條件為假,那么退出循環(huán);如果條件在開始時(shí)就為假,那么就不執(zhí)行該語句;如果條件為x或z,那么按0(假)處理。

例如,下面是用while語句完成對定義的256個(gè)存儲單元初始化的程序段。

reg[7:0]memory[0:255];

initial

begin

reg[7:0]i;

i=0;

while(i<=255)

memory[i]=0;

i=i+1

end

4.for循環(huán)語句

for循環(huán)語句按照指定的次數(shù)重復(fù)執(zhí)行過程賦值語句若干次,其格式如下:

for(初值表達(dá)式;條件;循環(huán)變量增值)語句

for循環(huán)的執(zhí)行過程為

(1)計(jì)算初值表達(dá)式。

(2)進(jìn)行條件判斷,若條件為真,繼續(xù)第(3)步;若條件為假,則轉(zhuǎn)到第(5)步。

(3)執(zhí)行過程語句,對循環(huán)變量進(jìn)行增值。

(4)轉(zhuǎn)回第(2)步繼續(xù)執(zhí)行。

(5)執(zhí)行for循環(huán)下面的語句。例如,下面是用for語句、加法語句和移位語句實(shí)現(xiàn)x×y的程序。

reg[15:0]x,;

reg[31:0]s;

initial

begin

reg[3:0]i;

s=0;

for(i=0;i<=15;i=i+1)

if(y[i])s=s+(x<<i);

end3.4.4結(jié)構(gòu)聲明語句

VerilogHDL中任何過程模塊都從屬于四種結(jié)構(gòu)說明語句:

initial說明語句、always說明語句、task說明語句和function說明語句。

1.initial說明語句

initial語句常用于對各變量的初始化。一個(gè)程序模塊中可以有多個(gè)initial語句,所有initial語句在程序一開始時(shí)同時(shí)執(zhí)行,并且只執(zhí)行一次。

initial語句格式如下:

initial語句例如:

initial

begin

reset=1;

#3reset=0;

#5reset=1;

end

2.always說明語句

與initial語句一樣,一個(gè)程序中可以有多個(gè)always語句,always語句也是在程序一開始時(shí)立即被執(zhí)行的,不同的是always語句不斷地重復(fù)運(yùn)行。但always語句后跟的語句是否執(zhí)行要看其敏感事件列表是否滿足,若有條件滿足,則運(yùn)行一次語句。

always語句格式如下:

always@(敏感事件列表)語句

always語句后面是一個(gè)敏感事件列表,該敏感事件列表的作用是激活always語句執(zhí)行的條件,敏感事件可以是電平觸發(fā),也可以是邊沿觸發(fā)。電平觸發(fā)的always塊常用于描述組合邏輯的行為,而邊沿觸發(fā)的always塊常用于描述時(shí)序行為。

always語句后面的敏感事件可以是單個(gè)事件,也可以是多個(gè)事件,多個(gè)事件之間用or連接。在敏感事件列表中,如果敏感事件是電平信號,那么直接列出信號名;如果敏感事件是邊沿信號,那么可分為上升沿和下降沿,上升沿觸發(fā)的信號前加關(guān)鍵字posedge,下降沿觸發(fā)的信號前加關(guān)鍵字negedge。例如,用clk的上升沿使count加1的程序?yàn)?/p>

reg[7:0]count

always@(posedgeclk)

begin

count=count+1b′1;

end

如果要用clk的下降沿使count加1,只需將程序中的敏感事件改為negedgeclk即可。例如,一個(gè)電平敏感型鎖存器的程序如下:

modulelatch(enable,date,q)

inputenable;

input[7:0]data;

output[7:0]q;

reg[7:0]q;

always@(enableordata)

begin

if(enable)

q<=data;

end

3.task說明語句

1)任務(wù)定義語句

任務(wù)定義語句的格式如下:

task任務(wù)名;

端口聲明語句;

類型聲明語句;

語句

endtask

2)任務(wù)的調(diào)用

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

任務(wù)名(端口名列表);

例如,在運(yùn)算器中,經(jīng)常用到加法運(yùn)算,加法運(yùn)算有8位加法、16位加法、32位加法等,16位加法和32位加法又可以用8位加法器實(shí)現(xiàn)。這樣就可以定義一個(gè)任務(wù)實(shí)現(xiàn)8位加法運(yùn)算,而16位加法和32位加法通過多次調(diào)用8位加法運(yùn)算的任務(wù)來實(shí)現(xiàn)。

下面代碼中,定義了一個(gè)任務(wù)adder8完成8位二進(jìn)制數(shù)加法運(yùn)算,通過在always塊中兩次調(diào)用任務(wù)adder8實(shí)現(xiàn)了16位數(shù)a和b的加法運(yùn)算,相加結(jié)果存放在sum中,進(jìn)位存放在cout中。

moduleadd16(a,b,cin,sum,cout);

input[15:0]a,b;

inputcin;

output[15:0]sum;

outputcout;

reg[15:0]sum;

regcout;

regc8;

always@(aorborcin)

begin

adder8(a[7:0],b[7:0],cin,sum[7:0],c8);

adder8(a[15:8],b[15:8],c8,sum[15:8],cout);

end

taskadder8;

input[7:0]ta,tb;

inputtcin;

output[7:0]tsum;

outputtcout;

begin

{tcout,tsum}=ta+tb+tcin;

end

endtask

endmodule使用任務(wù)時(shí),需要注意以下幾點(diǎn):

(1)任務(wù)的定義和調(diào)用必須在同一個(gè)模塊內(nèi)。任務(wù)定義不能出現(xiàn)在任何一個(gè)過程塊內(nèi)部,任務(wù)的調(diào)用應(yīng)在always塊、initial塊或另一個(gè)任務(wù)中。

(2)任務(wù)定義時(shí),task語句后沒有端口名列表,輸入輸出端口名是通過端口聲明語句進(jìn)行順序聲明的;一個(gè)任務(wù)也可以沒有輸入輸出端口。

(3)當(dāng)任務(wù)被調(diào)用時(shí),任務(wù)被激活。如果一個(gè)任務(wù)有輸入輸出端口,調(diào)用時(shí)需列出端口名列表,其順序和類型應(yīng)與任務(wù)定義中完全一致。

(4)進(jìn)行任務(wù)調(diào)用時(shí),參數(shù)的傳遞是按值傳遞的,不能按址傳遞。

(5)一個(gè)任務(wù)可以調(diào)用別的任務(wù)或函數(shù),可調(diào)用的任務(wù)和函數(shù)的個(gè)數(shù)不受限制。

4.function說明語句

function說明語句用來定義函數(shù)。函數(shù)類似高級語言中的函數(shù),用來單獨(dú)完成某項(xiàng)具體的操作。函數(shù)可以作為表達(dá)式中的一個(gè)操作數(shù),也可被模塊、任務(wù)或其他函數(shù)調(diào)用,函數(shù)調(diào)用時(shí)有一個(gè)返回值。

1)函數(shù)語句定義

function定義格式如下:

function〈返回值的類型或范圍〉函數(shù)名

端口聲明語句;

類型聲明語句;

語句

endfunction

2)函數(shù)的調(diào)用

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

函數(shù)名(端口名列表);

函數(shù)與任務(wù)一樣,也是用來完成一個(gè)獨(dú)立的任務(wù)的,但函數(shù)與任務(wù)有以下不同點(diǎn):

(1)函數(shù)只能有一個(gè)返回值,而任務(wù)卻可以有多個(gè)或沒有返回值。函數(shù)的返回值只是通過函數(shù)名返回的,而任務(wù)的返回值則是通過輸出端口傳遞的。

(2)函數(shù)至少有一個(gè)輸入變量,而任務(wù)可以沒有或有多個(gè)任何類型的變量。

(3)函數(shù)只能與主模塊共用一個(gè)仿真時(shí)間,而任務(wù)可以定義自己的仿真時(shí)間單位。

(4)函數(shù)不能調(diào)用任務(wù),而任務(wù)能調(diào)用其他任務(wù)和函數(shù)。例如,下面程序是一個(gè)用function函數(shù)實(shí)現(xiàn)將兩位十六進(jìn)制數(shù)轉(zhuǎn)換成對應(yīng)的兩個(gè)共陽極七段LED顯示代碼的例子。其中,SW用于輸入兩位十六進(jìn)制數(shù),十六進(jìn)制數(shù)要在七段LED上進(jìn)行顯示,必須將其轉(zhuǎn)換成其對應(yīng)的七段顯示代碼,hex0和hex1就是分別用來輸出的對應(yīng)的七段共陰極LED顯示代碼。moduledisplay(SW,hex0,hex1);

input[7:0]SW;

output[6:0]hex0;

reg[6:0]hex0;

output[6:0]hex1;

reg[6:0]hex1;

always@(SW)

begin

hex0=seg_7(SW[3:0]);

hex1=seg_7(SW[7:4]);

end

function[6:0]seg_7;

input[3:0]num;

case(num)

4′h1:seg_7=7′b1111001;

4′h2:seg_7=7′b0100100;

4′h3:seg_7=7′b0110000;

4′h4:seg_7=7′b0011001;

4′h5:seg_7=7′b0010010;

4′h6:seg_7=7′b0000010;

4′h7:seg_7=7′b1111000;

4′h8:seg_7=7′b0000000; 4′h9:seg_7=7′b0011000;

4′ha:seg_7=7′b0001000;

4′hb:seg_7=7′b0000011;

4′hc:seg_7=7′b1000110;

4′hd:seg_7=7′b0100001;

4′he:seg_7=7′b0000110;

4′hf:seg_7=7′b0001110;

4′h0:seg_7=7′b1000000;

endcase

endfunction

endmodule3.4.5編譯預(yù)處理語句

1.宏定義(′define和′undef)

′define指令是用一個(gè)標(biāo)識符代替一個(gè)字符串,其定義格式如下:

′define宏名字符串

例如:

′defineWORDSIZE16

reg[′WORDSIZE-1:0]data1;//相當(dāng)于reg[15:0]data1;對于宏的定義應(yīng)注意以下幾點(diǎn):

(1)宏名可以用小寫字母,也可以用大寫字母,為了與變量名區(qū)別,建議使用大寫字母。

(2)宏定義語句后不跟分號,如果加了分號,則連同分號一起進(jìn)行置換。

(3)宏定義語句可以在模塊內(nèi),也可以在模塊外。

(4)在引用宏時(shí),必須在宏名前加符號“′”。宏定義將在整個(gè)文件內(nèi)起作用,若要取消宏前面定義的宏,則用′undef指令。

例如:

′defineBYTE8

wire[′BYTE-1:0]bus;//相當(dāng)于wire[7:0]bus;

′undefBYTE//在′undef后,BYTE的宏定義不再有效

2.文件包含(′include)

′include語句用來實(shí)現(xiàn)文件的包含操作,它可以將一個(gè)源文件包含到本文件中。其語句格式為

′include″文件名″

例如:

′include″d:\eda\s1.v″

編譯時(shí),這一行由d:\eda\s1.v文件中的內(nèi)容替代。

3.時(shí)間尺度(′timescale)

在VerilogHDL模型中,所有時(shí)延都用單位時(shí)間表述。使用′timescale預(yù)編譯指令將時(shí)間單位與實(shí)際時(shí)間相關(guān)聯(lián)。該指令用于定義時(shí)間單位和時(shí)間精度。

′timescale預(yù)編譯指令格式為

′timescale時(shí)間單位/時(shí)間精度其中,時(shí)間單位用來定義模塊中仿真時(shí)間的基準(zhǔn)單位,時(shí)間精度用來聲明模塊仿真時(shí)間的精確程度,該參數(shù)用于對時(shí)間值進(jìn)行取整操作。時(shí)間單位和時(shí)間精度由值1、10和100以及單位s、ms、μs、ns、ps和fs組成。例如:

′timescale1ns/100ps

表示時(shí)延單位為1ns,時(shí)延精度為100ps。′timescale編譯指令在模塊說明外部出現(xiàn),并且影響后面所有的時(shí)延值。例如:

′timescale10ns/100ps

always#1.55clock=~clock;

′timescale語句表示模塊中的時(shí)間值均為10ns的整數(shù)倍,延時(shí)時(shí)間的最小分辨率為十分之一納秒(100ps),即延時(shí)時(shí)間可表示為帶一位小數(shù)的實(shí)型數(shù)。這樣,根據(jù)時(shí)間精度,1.55取整為1.6,那么,clock變反的時(shí)間間隔為16ns。在編譯過程中,′timescale指令影響這一編譯指令后面所有模塊中的時(shí)延值,直至遇到另一個(gè)′timescale指令。當(dāng)一個(gè)設(shè)計(jì)中的多個(gè)模塊帶有自身的′timescale編譯指令時(shí),則用最小的時(shí)間精度來決定仿真時(shí)間單位。例如:

′timescale1ns/100ps

moduleAndFunc(Z,A,B);

outputZ;

inputA,B;

and#5.22Al(Z,A,B);

endmodule

′timescale10ns/1ns

moduleTB;

regPutA;

initial

begin

PutA=0;

#5.21PutA=1;

#10.4PutA=0;

end

endmodule在這個(gè)例子中,每個(gè)模塊都有自身的′timescale編譯指令。在第一個(gè)模塊中,5.22對應(yīng)5.2ns;在第二個(gè)模塊中,5.21對應(yīng)52ns,10.4對應(yīng)104ns。如果仿真模塊TB,那么設(shè)計(jì)中的所有模塊最小時(shí)間精度為100ps,因此,所有延遲將換算成精度為100ps,延遲52ns現(xiàn)在對應(yīng)520*100ps,104對應(yīng)1040*100ps。更重要的是,仿真使用100ps為時(shí)間精度。若仿真模塊AndFunc,則由于模塊TB不是模塊AddFunc的子模塊,因此模塊TB中的′timescale程序指令將不再有效。

4.條件編譯(′ifdef、′else、′endif)

一般情況下,源程序中的所有語句行都參加編譯。但是有時(shí)希望其中一部分語句只在條件滿足時(shí)才進(jìn)行編譯,條件不滿足時(shí)不編譯這些語句,或者編譯另外一組語句,這就是條件編譯。條件編譯語句格式如下:

′ifdefCOMPUTER-PC

parameterWORD_SIZE=16

′else

parameterWORD_SIZE=32

′endif在實(shí)際的應(yīng)用系統(tǒng)設(shè)計(jì)時(shí),如果將所有功能用一個(gè)模塊完成,會造成模塊設(shè)計(jì)復(fù)雜,可讀性差。為了便于設(shè)計(jì),可以將一個(gè)大的系統(tǒng)分層次、分模塊進(jìn)行設(shè)計(jì),

溫馨提示

  • 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論