




版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 數(shù)據(jù)庫維護(hù)計(jì)劃
- 社區(qū)網(wǎng)絡(luò)安全的關(guān)注要點(diǎn)計(jì)劃
- 學(xué)校評價(jià)與反饋系統(tǒng)建設(shè)計(jì)劃
- 班級班規(guī)與紀(jì)律維護(hù)計(jì)劃
- 幼兒園小班數(shù)理邏輯訓(xùn)練計(jì)劃
- 財(cái)務(wù)資源保障計(jì)劃
- 課程外聯(lián)計(jì)劃
- 遠(yuǎn)程會診服務(wù)的進(jìn)展和挑戰(zhàn)計(jì)劃
- 科技賦能下的現(xiàn)代橋梁結(jié)構(gòu)設(shè)計(jì)變革
- 非標(biāo)智能裝備推動企業(yè)自動化的成功案例研究
- Unit5 What day is it today?(教學(xué)設(shè)計(jì))-2023-2024學(xué)年教科版(廣州)英語四年級下冊
- 《網(wǎng)絡(luò)信息安全教學(xué)》課件
- 徐州2025年江蘇徐州市口腔醫(yī)院招聘非在編醫(yī)務(wù)人員53人筆試歷年參考題庫附帶答案詳解-1
- 2025年01月2025中國作家協(xié)會所屬單位公開招聘11人筆試歷年典型考題(歷年真題考點(diǎn))解題思路附帶答案詳解
- 影視制作項(xiàng)目委托制作協(xié)議
- 用色彩情感引發(fā)共鳴社交媒體運(yùn)營秘訣
- 廣東2024年12月佛山市教育局公開選調(diào)1名公務(wù)員筆試歷年典型考題(歷年真題考點(diǎn))解題思路附帶答案詳解
- 植物角創(chuàng)設(shè)培訓(xùn)
- 《住院患者身體約束的護(hù)理》團(tuán)體標(biāo)準(zhǔn)解讀課件
- 2024年黑龍江建筑職業(yè)技術(shù)學(xué)院單招職業(yè)適應(yīng)性測試題庫全面
- MOOC 跨文化交際通識通論-揚(yáng)州大學(xué) 中國大學(xué)慕課答案
評論
0/150
提交評論