Verilog HDL基礎(chǔ)教程之:數(shù)據(jù)類型和運(yùn)算符
2.寄存器型變量
寄存器是數(shù)據(jù)儲存單元的抽象。寄存器型變量的關(guān)鍵字是reg。通過賦值語句可以改變寄存器儲存的值,其作用與改變觸發(fā)器儲存的值相當(dāng)。
Verilog HDL語言提供了功能強(qiáng)大的結(jié)構(gòu)語句使設(shè)計(jì)者能有效地控制是否執(zhí)行這些賦值語句。這些控制結(jié)構(gòu)用來描述硬件觸發(fā)條件,例如時鐘的上升沿和多路器的選通信號。reg類型變量的缺省初始值為不定值,即x。
reg型變量常用來表示用于“always”模塊內(nèi)的指定信號,常代表觸發(fā)器。通常,在設(shè)計(jì)中要由“always”塊通過使用行為描述語句來表達(dá)邏輯關(guān)系。在“always”塊內(nèi)被賦值的每一個信號都必須定義成reg型。和wire型變量類似,reg型變量的聲明格式如下:
reg [n-1:0] 變量名1,變量名2,…,變量名i; //共有i條總線,每條總線內(nèi)有n條線路
也可以如下表示:
reg [n:1] 變量名1,變量名2,…,變量名i; //共有i條總線,每條總線內(nèi)有n條線路
其中,reg是reg型變量的確認(rèn)標(biāo)識符,[n-1:0]和[n:1]代表該變量的位寬,即該變量有幾位(bit),最后跟著的是變量的名字。如果一次定義多個變量,變量名之間用逗號隔開。聲明語句的最后要用分號表示語句結(jié)束。如下所示:
reg rega; //定義了一個一位的名為rega的reg型變量
reg [3:0] regb; //定義了一個四位的名為regb的reg型變量
reg [4:1] regc, regd; //定義了兩個四位的名為regc和regd的reg型變量
reg型變量可以賦正值,也可以賦負(fù)值。但當(dāng)一個reg型變量是一個表達(dá)式中的操作數(shù)時,它的值將被當(dāng)作是無符號值,即正值。例如:當(dāng)一個四位的寄存器用作表達(dá)式中的操作數(shù)時,如果開始寄存器被賦以值-1,則在表達(dá)式中進(jìn)行運(yùn)算時,其值被認(rèn)為是+15。
3.存儲器型變量
Verilog HDL通過對reg型變量建立數(shù)組來對存儲器建模,用于描述RAM型存儲器、ROM存儲器和reg文件。數(shù)組中的每一個單元通過一個數(shù)組索引進(jìn)行尋址。由于在Verilog語言中沒有多維數(shù)組存在,因此memory型數(shù)據(jù)是通過擴(kuò)展reg型數(shù)據(jù)的地址范圍來生成的。其格式如下:
reg [n-1:0] 存儲器名[m-1:0];
或:
reg [n-1:0] 存儲器名[m:1];
在這里,reg[n-1:0]定義了存儲器中每一個存儲單元的大小,即該存儲單元是一個n位的寄存器。存儲器名后的[m-1:0]或[m:1]則定義了該存儲器中有多少個這樣的寄存器。最后用分號結(jié)束定義語句。下面舉例說明:
reg [7:0] mema[255:0]; //定義一個名為mema的256×8的存儲器
這個例子定義了一個名為mema的存儲器,該存儲器有256個8位的存儲器。該存儲器的地址范圍是0~255。需要注意的是,對存儲器進(jìn)行地址索引的表達(dá)式必須是常數(shù)表達(dá)式。
另外,在同一個數(shù)據(jù)類型聲明語句里,可以同時定義存儲器型數(shù)據(jù)和reg型數(shù)據(jù)。 例如:
parameter wordsize=16, memsize=256; //定義兩個參數(shù)
reg [wordsize-1:0] mem[memsize-1:0],writereg, readreg; //使用可變參數(shù)來定義存儲器
盡管memory型數(shù)據(jù)和reg型數(shù)據(jù)的定義格式很相似,但要注意其不同之處。如一個由n個1位寄存器構(gòu)成的存儲器組是不同于一個n位的寄存器的,如下所示:
reg [n-1:0] rega; //一個n位的寄存器
reg mema [n-1:0]; //一個由n個1位寄存器構(gòu)成的存儲器組
一個n位的寄存器可以在一條賦值語句里進(jìn)行賦值,而一個完整的存儲器則不行,例如:
rega =0; //合法賦值語句
mema =0; //非法賦值語句
如果想對memory中的存儲單元進(jìn)行讀寫操作,必須指定該單元在存儲器中的地址。下面的寫法是正確的。
mema[3]=0; //給memory中的第3個存儲單元賦值為0。
進(jìn)行尋址的地址索引可以是表達(dá)式,這樣就可以對存儲器中的不同單元進(jìn)行操作。表達(dá)式的值可以取決于電路中其他的寄存器的值。例如可以用一個加法計(jì)數(shù)器來做RAM的地址索引。
常用運(yùn)算符
Verilog HDL語言的運(yùn)算符范圍很廣,其運(yùn)算符按其功能可分為以下幾類。
算術(shù)運(yùn)算符:(+,-,×,/,%)。
賦值運(yùn)算符:(=,=)。
關(guān)系運(yùn)算符:(>,,>=,=)。
邏輯運(yùn)算符:(,||,!)。
條件運(yùn)算符:(?:)。
位運(yùn)算符:(~,|,^,,^~)。
移位運(yùn)算符:(,>>)。
拼接運(yùn)算符:({ })。
其他
在Verilog HDL語言中運(yùn)算符所帶的操作數(shù)是不同的,按其所帶操作數(shù)的個數(shù)運(yùn)算符可分為以下3種。
單目運(yùn)算符(unary operator):可以帶一個操作數(shù),操作數(shù)放在運(yùn)算符的右邊。
二目運(yùn)算符(binary operator):可以帶兩個操作數(shù),操作數(shù)放在運(yùn)算符的兩邊。
三目運(yùn)算符(ternary operator):可以帶三個操作數(shù),這三個操作數(shù)用三目運(yùn)算符分隔開。
例如:
clock = ~clock; // ~ 是一個單目取反運(yùn)算符,clock是操作數(shù)。
c = a | b; // | 是一個二目按位或運(yùn)算符,a 和 b是操作數(shù)。
r = s ? t : u; // ?: 是一個三目條件運(yùn)算符,s,t,u是操作數(shù)。
下面對常用的幾種運(yùn)算符進(jìn)行介紹。
1.基本的算術(shù)運(yùn)算符
在Verilog HDL語言中,算術(shù)運(yùn)算符又稱為二進(jìn)制運(yùn)算符,共有下面幾種。
+:(加法運(yùn)算符或正值運(yùn)算符,如ega+regb、+3)。
−:(減法運(yùn)算符或負(fù)值運(yùn)算符,如rega−3、−3)。
´:(乘法運(yùn)算符,如rega´3)。
/:(除法運(yùn)算符,如5/3)。
% :(模運(yùn)算符或求余運(yùn)算符,要求%兩側(cè)均為整型數(shù)據(jù),如7%3的值為1)。
在進(jìn)行整數(shù)除法運(yùn)算時,結(jié)果值要略去小數(shù)部分,只取整數(shù)部分。而進(jìn)行取模運(yùn)算時,結(jié)果值的符號位采用模運(yùn)算式里第一個操作數(shù)的符號位,例如:
10%3 1 //余數(shù)為1
11%3 2 //余數(shù)為2
12%3 0 //余數(shù)為0,即無余數(shù)
-10%3 -1 //結(jié)果取第一個操作數(shù)的符號位,所以余數(shù)為-1
11%3 2 //結(jié)果取第一個操作數(shù)的符號位,所以余數(shù)為2.
注意 | 在進(jìn)行算術(shù)運(yùn)算操作時,如果某一個操作數(shù)有不確定的值x,則整個結(jié)果也為不定值x。 |
評論