加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

Verilog HDL基礎(chǔ)之:數(shù)據(jù)類型和運(yùn)算符

2013/08/21
1
閱讀需 38 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

 

常用數(shù)據(jù)類型

Verilog HDL中總共有19種數(shù)據(jù)類型,數(shù)據(jù)類型是用來表示數(shù)字電路硬件中的數(shù)據(jù)儲(chǔ)存和傳送元素的。在本書中,我們先只介紹4個(gè)最基本的數(shù)據(jù)類型,它們分別是:reg型,wire型,integer型和parameter型。

其他數(shù)據(jù)類型在后面的章節(jié)里逐步介紹,讀者也可以查閱附錄中Verilog HDL語(yǔ)法參考書的有關(guān)章節(jié)逐步掌握。其他的類型如下:large型、medium型、scalared型、time型、small型、tri型、trio型、tri1型、triand型、trior型、trireg型、vectored型、wand型和wor型。

這些數(shù)據(jù)類型除time型外都與基本邏輯單元建庫(kù)有關(guān),與系統(tǒng)設(shè)計(jì)沒有很大的關(guān)系。在一般電路設(shè)計(jì)自動(dòng)化的環(huán)境下,仿真用的基本部件庫(kù)是由半導(dǎo)體廠家和EDA工具廠家共同提供的。系統(tǒng)設(shè)計(jì)工程師不必過多地關(guān)心門級(jí)和開關(guān)級(jí)的Verilog HDL語(yǔ)法現(xiàn)象。Verilog HDL語(yǔ)言中也有常量和變量之分,它們分別屬于以上這些類型。下面對(duì)最常用的幾種進(jìn)行介紹。

常量

常量是在程序運(yùn)行過程中其值不能被改變的量。下面首先對(duì)在Verilog HDL語(yǔ)言中使用的數(shù)字及其表示方式進(jìn)行介紹。

1.?dāng)?shù)字

(1)整數(shù)。

在Verilog HDL中,整型常量有以下4種進(jìn)制表示形式。

① 二進(jìn)制整數(shù)(b或B)。

② 十進(jìn)制整數(shù)(d或D)。

③ 十六進(jìn)制整數(shù)(h或H)。

④ 八進(jìn)制整數(shù)(o或O)。

數(shù)字表達(dá)方式有以下3種。

① <位寬><進(jìn)制><數(shù)字>,這是一種全面的描述方式。

② <進(jìn)制><數(shù)字>,在這種描述方式中,數(shù)字的位寬采用缺省位寬(這由具體的機(jī)器系統(tǒng)決定,但至少32位)。

③ <數(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ù)來表示),如下例所示:

8'b10101100     //位寬為8的數(shù)的二進(jìn)制表示,'b表示二進(jìn)制

8'ha2             //位寬為8的數(shù)的十六進(jìn)制,'h表示十六進(jìn)制。

(2)x和z值。

在數(shù)字電路中,x代表不定值,z代表高阻值。一個(gè)x可以用來定義十六/八/二進(jìn)制數(shù)的四/三/一位二進(jìn)制數(shù)的狀態(tài)。z的表示方式同x類似。z還有一種表達(dá)方式是可以寫作?。在使用case表達(dá)式時(shí)建議使用這種寫法,以提高程序的可讀性,如下例所示:

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ù)其低四位值為不定值

(3)負(fù)數(shù)。

一個(gè)數(shù)字可以被定義為負(fù)數(shù),只需在位寬表達(dá)式前加一個(gè)減號(hào),并且減號(hào)必須寫在數(shù)字定義表達(dá)式的最前面。注意減號(hào)不可以放在位寬和進(jìn)制之間,也不可以放在進(jìn)制和具體的數(shù)之間,如下例所示:

-8'd5            //這個(gè)表達(dá)式代表5的補(bǔ)數(shù)(用8位二進(jìn)制數(shù)表示)

8'd-5            //非法格式

(4)下劃線(underscore_)。

下劃線可以用來分隔數(shù)字的表達(dá)以提高程序可讀性。但不可以用在位寬和進(jìn)制處,只能用在具體的數(shù)字之間,例如:

16'b1010_1011_1111_1010          //合法格式

8'b_0011_1010                     //非法格式

當(dāng)常量不聲明位數(shù)時(shí),默認(rèn)值是32位,每個(gè)字母用8位的ASCII值表示,例如:

10=32'd10=32'b1010               //十進(jìn)制和二進(jìn)制

1=32'd1=32'b1                     //十進(jìn)制和二進(jìn)制

-1=-32'd1=32'hFFFFFFFF          //十進(jìn)制和十六進(jìn)制

'BX=32'BX=32'BXXXXXXX…X         //默認(rèn)聲明為32位

"AB"=16'B01000001_01000010       //每個(gè)字母用8位表示

2.參數(shù)(Parameter)

在Verilog HDL中用parameter來定義常量,即用parameter來定義一個(gè)標(biāo)識(shí)符代表一個(gè)常量,稱為符號(hào)常量,即標(biāo)識(shí)符形式的常量。采用標(biāo)識(shí)符代表一個(gè)常量可提高程序的可讀性和可維護(hù)性。parameter型數(shù)據(jù)是一種常數(shù)型的數(shù)據(jù),其說明格式如下:

Parameter    參數(shù)名1=表達(dá)式,參數(shù)名2=表達(dá)式, …, 參數(shù)名n=表達(dá)式;

parameter是參數(shù)型數(shù)據(jù)的確認(rèn)符,確認(rèn)符后跟著一個(gè)用逗號(hào)分隔開的賦值語(yǔ)句表。在每一個(gè)賦值語(yǔ)句的右邊必須是一個(gè)常數(shù)表達(dá)式。也就是說,該表達(dá)式只能包含數(shù)字或先前已定義過的參數(shù),例如:

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í)可通過參數(shù)傳遞改變?cè)诒灰媚K或?qū)嵗幸讯x的參數(shù)。下面將通過一個(gè)例子進(jìn)一步說明在層次調(diào)用的電路中改變參數(shù)常用的一些用法。

module Decode(A,F);                                    //模塊聲明

      parameter Width=1, Polarity=1;                   //參數(shù)聲明

      ……………

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);                     //模塊引用,并傳遞參數(shù)(4,0)

      Decode  #(5)  D2(A5,F32);                      //模塊引用,并傳遞參數(shù)(5)

endmodule

在引用Decode實(shí)例時(shí),D1和D2的Width將采用不同的值,分別為4和5,且D1的Polarity將為0??捎美又兴玫姆椒▉砀淖儏?shù),即用“#(4,0)”向D1中傳遞“Width=4,Polarity=0”,用“#(5)”向D2中傳遞“Width=5,Polarit=1”。

變量

變量是在程序運(yùn)行過程中,其值可以改變的量。在Verilog HDL中變量類型有很多種,這里只對(duì)常用的幾種變量進(jìn)行介紹。

 

1.網(wǎng)絡(luò)類型變量

網(wǎng)絡(luò)類型表示結(jié)構(gòu)實(shí)體(例如門)之間的物理連接。網(wǎng)絡(luò)類型的變量不能儲(chǔ)存值,而且它必需受到驅(qū)動(dòng)器(例如門或連續(xù)賦值語(yǔ)句,assign)的驅(qū)動(dòng)。如果沒有驅(qū)動(dòng)器連接到網(wǎng)絡(luò)類型的變量上,則該變量就是高阻的,即其值為z。

常用的網(wǎng)絡(luò)類型變量包括wire型和tri型。這兩種變量都是用于連接器件單元,它們具有相同的語(yǔ)法格式和功能。之所以提供這兩種名字來表達(dá)相同的概念是為了與模型中所使用的變量的實(shí)際情況相一致。

wire型變量通常是用來表示單個(gè)門驅(qū)動(dòng)或連續(xù)賦值語(yǔ)句驅(qū)動(dòng)的網(wǎng)絡(luò)型數(shù)據(jù),tri型變量則用來表示多驅(qū)動(dòng)器驅(qū)動(dòng)的網(wǎng)絡(luò)型數(shù)據(jù)。如果wire型或tri型變量沒有定義邏輯強(qiáng)度(logic strength),在多驅(qū)動(dòng)源的情況下,邏輯值會(huì)發(fā)生沖突,從而產(chǎn)生不確定值。

表1所示為在同等驅(qū)動(dòng)強(qiáng)度下,兩個(gè)驅(qū)動(dòng)源驅(qū)動(dòng)的wire型和tri型變量的真值表。

表1                                                        wire/tri型變量真值表

wire/tri型變量雙驅(qū)動(dòng)源運(yùn)算結(jié)果

       驅(qū)動(dòng)源1

驅(qū)動(dòng)源2

0

1

x

z

0

0

x

x

0

1

 

1

x

1

x

x

x

x

x

z

0

1

x

z

wire型變量常用來表示用于以assign關(guān)鍵字指定的組合邏輯信號(hào)。Verilog程序模塊中輸入/輸出信號(hào)類型缺省時(shí)自動(dòng)定義為wire型。wire型變量可以用作任何方程式的輸入,也可以用作“assign”語(yǔ)句或?qū)嵗妮敵?。wire型變量的聲明格式如下:

wire [n-1:0] 變量名1,變量名2,…,變量名i;   //共有i條總線,每條總線內(nèi)有n條線路

也可以如下表示:

wire [n:1] 變量名1,變量名2,…,變量名i;    //共有i條總線,每條總線內(nèi)有n條線路

其中,wire是wire型變量的確認(rèn)符,[n-1:0]和[n:1]代表該變量的位寬,即該變量有幾位,最后跟著的是變量的名字。如果一次定義多個(gè)變量,變量名之間用逗號(hào)隔開。聲明語(yǔ)句的最后要用分號(hào)表示語(yǔ)句結(jié)束。如下所示:

wire  a;                                      //定義了一個(gè)一位的wire型變量

wire [7:0] b;                              //定義了一個(gè)八位的wire型變量

wire [4:1] c, d;                          //定義了兩個(gè)四位的wire型變量

2.寄存器型變量

寄存器是數(shù)據(jù)儲(chǔ)存單元的抽象。寄存器型變量的關(guān)鍵字是reg。通過賦值語(yǔ)句可以改變寄存器儲(chǔ)存的值,其作用與改變觸發(fā)器儲(chǔ)存的值相當(dāng)。

Verilog HDL語(yǔ)言提供了功能強(qiáng)大的結(jié)構(gòu)語(yǔ)句使設(shè)計(jì)者能有效地控制是否執(zhí)行這些賦值語(yǔ)句。這些控制結(jié)構(gòu)用來描述硬件觸發(fā)條件,例如時(shí)鐘的上升沿和多路器的選通信號(hào)。reg類型變量的缺省初始值為不定值,即x。

reg型變量常用來表示用于“always”模塊內(nèi)的指定信號(hào),常代表觸發(fā)器。通常,在設(shè)計(jì)中要由“always”塊通過使用行為描述語(yǔ)句來表達(dá)邏輯關(guān)系。在“always”塊內(nèi)被賦值的每一個(gè)信號(hào)都必須定義成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)識(shí)符,[n-1:0]和[n:1]代表該變量的位寬,即該變量有幾位(bit),最后跟著的是變量的名字。如果一次定義多個(gè)變量,變量名之間用逗號(hào)隔開。聲明語(yǔ)句的最后要用分號(hào)表示語(yǔ)句結(jié)束。如下所示:

reg  rega;                          //定義了一個(gè)一位的名為rega的reg型變量

reg [3:0]  regb;                  //定義了一個(gè)四位的名為regb的reg型變量

reg [4:1]  regc, regd;          //定義了兩個(gè)四位的名為regc和regd的reg型變量

reg型變量可以賦正值,也可以賦負(fù)值。但當(dāng)一個(gè)reg型變量是一個(gè)表達(dá)式中的操作數(shù)時(shí),它的值將被當(dāng)作是無(wú)符號(hào)值,即正值。例如:當(dāng)一個(gè)四位的寄存器用作表達(dá)式中的操作數(shù)時(shí),如果開始寄存器被賦以值-1,則在表達(dá)式中進(jìn)行運(yùn)算時(shí),其值被認(rèn)為是+15。

3.存儲(chǔ)器型變量

Verilog HDL通過對(duì)reg型變量建立數(shù)組來對(duì)存儲(chǔ)器建模,用于描述RAM型存儲(chǔ)器、ROM存儲(chǔ)器和reg文件。數(shù)組中的每一個(gè)單元通過一個(gè)數(shù)組索引進(jìn)行尋址。由于在Verilog語(yǔ)言中沒有多維數(shù)組存在,因此memory型數(shù)據(jù)是通過擴(kuò)展reg型數(shù)據(jù)的地址范圍來生成的。其格式如下:

reg [n-1:0] 存儲(chǔ)器名[m-1:0];

或:

reg [n-1:0] 存儲(chǔ)器名[m:1];

在這里,reg[n-1:0]定義了存儲(chǔ)器中每一個(gè)存儲(chǔ)單元的大小,即該存儲(chǔ)單元是一個(gè)n位的寄存器。存儲(chǔ)器名后的[m-1:0]或[m:1]則定義了該存儲(chǔ)器中有多少個(gè)這樣的寄存器。最后用分號(hào)結(jié)束定義語(yǔ)句。下面舉例說明:

reg [7:0]  mema[255:0];                //定義一個(gè)名為mema的256×8的存儲(chǔ)器

這個(gè)例子定義了一個(gè)名為mema的存儲(chǔ)器,該存儲(chǔ)器有256個(gè)8位的存儲(chǔ)器。該存儲(chǔ)器的地址范圍是0~255。需要注意的是,對(duì)存儲(chǔ)器進(jìn)行地址索引的表達(dá)式必須是常數(shù)表達(dá)式。

另外,在同一個(gè)數(shù)據(jù)類型聲明語(yǔ)句里,可以同時(shí)定義存儲(chǔ)器型數(shù)據(jù)和reg型數(shù)據(jù)。    例如:

parameter  wordsize=16, memsize=256;                           //定義兩個(gè)參數(shù)

reg [wordsize-1:0] mem[memsize-1:0],writereg, readreg;  //使用可變參數(shù)來定義存儲(chǔ)器

盡管memory型數(shù)據(jù)和reg型數(shù)據(jù)的定義格式很相似,但要注意其不同之處。如一個(gè)由n個(gè)1位寄存器構(gòu)成的存儲(chǔ)器組是不同于一個(gè)n位的寄存器的,如下所示:

reg [n-1:0] rega;                   //一個(gè)n位的寄存器

reg mema [n-1:0];                   //一個(gè)由n個(gè)1位寄存器構(gòu)成的存儲(chǔ)器組

一個(gè)n位的寄存器可以在一條賦值語(yǔ)句里進(jìn)行賦值,而一個(gè)完整的存儲(chǔ)器則不行,例如:

rega =0;                             //合法賦值語(yǔ)句

mema =0;                             //非法賦值語(yǔ)句

如果想對(duì)memory中的存儲(chǔ)單元進(jìn)行讀寫操作,必須指定該單元在存儲(chǔ)器中的地址。下面的寫法是正確的。

mema[3]=0;                      //給memory中的第3個(gè)存儲(chǔ)單元賦值為0。

進(jìn)行尋址的地址索引可以是表達(dá)式,這樣就可以對(duì)存儲(chǔ)器中的不同單元進(jìn)行操作。表達(dá)式的值可以取決于電路中其他的寄存器的值。例如可以用一個(gè)加法計(jì)數(shù)器來做RAM的地址索引。

 

常用運(yùn)算符

Verilog HDL語(yǔ)言的運(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ǔ)言中運(yùn)算符所帶的操作數(shù)是不同的,按其所帶操作數(shù)的個(gè)數(shù)運(yùn)算符可分為以下3種。

單目運(yùn)算符(unary operator):可以帶一個(gè)操作數(shù),操作數(shù)放在運(yùn)算符的右邊。

二目運(yùn)算符(binary operator):可以帶兩個(gè)操作數(shù),操作數(shù)放在運(yùn)算符的兩邊。

三目運(yùn)算符(ternary operator):可以帶三個(gè)操作數(shù),這三個(gè)操作數(shù)用三目運(yùn)算符分隔開。

例如:

clock = ~clock;          // ~ 是一個(gè)單目取反運(yùn)算符,clock是操作數(shù)。

c = a | b;                // | 是一個(gè)二目按位或運(yùn)算符,a 和 b是操作數(shù)。

r = s ? t : u;           // ?: 是一個(gè)三目條件運(yùn)算符,s,t,u是操作數(shù)。

下面對(duì)常用的幾種運(yùn)算符進(jìn)行介紹。

1.基本的算術(shù)運(yùn)算符

在Verilog HDL語(yǔ)言中,算術(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)算時(shí),結(jié)果值要略去小數(shù)部分,只取整數(shù)部分。而進(jìn)行取模運(yùn)算時(shí),結(jié)果值的符號(hào)位采用模運(yùn)算式里第一個(gè)操作數(shù)的符號(hào)位,例如:

10%3          1       //余數(shù)為1

11%3          2        //余數(shù)為2

12%3          0       //余數(shù)為0,即無(wú)余數(shù)

-10%3         -1      //結(jié)果取第一個(gè)操作數(shù)的符號(hào)位,所以余數(shù)為-1

11%3          2       //結(jié)果取第一個(gè)操作數(shù)的符號(hào)位,所以余數(shù)為2.

注意

在進(jìn)行算術(shù)運(yùn)算操作時(shí),如果某一個(gè)操作數(shù)有不確定的值x,則整個(gè)結(jié)果也為不定值x。

2.位運(yùn)算符

Verilog HDL作為一種硬件描述語(yǔ)言是針對(duì)硬件電路而言的。在硬件電路中信號(hào)有4種狀態(tài)值1、0、x和z。在電路中信號(hào)進(jìn)行與或非時(shí),反映在Verilog HDL中則是相應(yīng)的操作數(shù)的位運(yùn)算。Verilog HDL提供了以下5種位運(yùn)算符。

  • ~ :(取反)
  •  & :(按位與)
  • | :(按位或)
  • ^ :(按位異或)
  •  ^~:(按位同或(異或非))

說明:

  • 位運(yùn)算符中除了~是單目運(yùn)算符以外,均為二目運(yùn)算符,即要求運(yùn)算符兩側(cè)各有一個(gè)操作數(shù)。
  • 位運(yùn)算符中的二目運(yùn)算符要求對(duì)兩個(gè)操作數(shù)的相應(yīng)位進(jìn)行運(yùn)算操作。

下面對(duì)各運(yùn)算符分別進(jìn)行介紹。

“取反”運(yùn)算符~

~是一個(gè)單目運(yùn)算符,用來對(duì)一個(gè)操作數(shù)進(jìn)行按位取反運(yùn)算。如表2所示為單目運(yùn)算符~的運(yùn)算規(guī)則表。

表2                                                             ~ 運(yùn)算規(guī)則表

~運(yùn)算

操  作  數(shù)

結(jié)    果

1

0

0

1

x

x

舉例說明:

rega='b1010;         //rega的初值為'b1010

rega=~rega;         //rega的值進(jìn)行取反運(yùn)算后變?yōu)?#39;b0101

“按位與”運(yùn)算符&

按位與運(yùn)算就是將兩個(gè)操作數(shù)的相應(yīng)位進(jìn)行與運(yùn)算,其運(yùn)算規(guī)則如表3所示。

表3                                                              & 運(yùn)算規(guī)則表

& 運(yùn)算

          操作數(shù)1

操作數(shù)2

0

1

x

0

0

0

0

1

0

1

x

x

0

x

x

“按位或”運(yùn)算符 |

按位或運(yùn)算就是將兩個(gè)操作數(shù)的相應(yīng)位進(jìn)行或運(yùn)算,其運(yùn)算規(guī)則如表4所示。

表4                                                              | 運(yùn)算規(guī)則表

| 運(yùn)算

           操作數(shù)1

操作數(shù)2

0

1

x

0

0

1

x

1

1

1

1

x

x

1

x

“按位異或”運(yùn)算符^(也稱之為XOR運(yùn)算符)

按位異或運(yùn)算就是將兩個(gè)操作數(shù)的相應(yīng)位進(jìn)行異或運(yùn)算,其運(yùn)算規(guī)則如表5所示。

表5                                                              ^ 運(yùn)算規(guī)則表

^ 運(yùn)算

            操作數(shù)1

操作數(shù)2

0

1

x

0

0

1

x

1

1

0

x

x

x

x

x

“按位同或”運(yùn)算符^~

按位同或運(yùn)算就是將兩個(gè)操作數(shù)的相應(yīng)位先進(jìn)行異或運(yùn)算再進(jìn)行非運(yùn)算,其運(yùn)算規(guī)則如表6所示。

表6                                                           ^~ 運(yùn)算規(guī)則表

^~ 運(yùn)算

          操作數(shù)1

操作數(shù)2

0

1

x

0

1

0

x

1

0

1

x

x

x

x

x

 

不同長(zhǎng)度的數(shù)據(jù)進(jìn)行位運(yùn)算

兩個(gè)長(zhǎng)度不同的數(shù)據(jù)進(jìn)行位運(yùn)算時(shí),系統(tǒng)會(huì)自動(dòng)將兩者按右端對(duì)齊。位數(shù)少的操作數(shù)會(huì)在相應(yīng)的高位用0填滿,以使兩個(gè)操作數(shù)按位進(jìn)行操作。

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

在Verilog HDL語(yǔ)言中存在3種邏輯運(yùn)算符。

  • &&:(邏輯與)
  • ||:(邏輯或)
  • ! :(邏輯非)

“&&”和“||”是二目運(yùn)算符,它要求有兩個(gè)操作數(shù),如(a>b)&&(b>c),(a<b)||(b<c)。“!”是單目運(yùn)算符,只要求一個(gè)操作數(shù),如!(a>b)。如表7所示為邏輯運(yùn)算的真值表。它表示當(dāng)a和b的值為不同的組合時(shí),各種邏輯運(yùn)算所得到的值。

表7                                                            邏輯運(yùn)算真值表

操  作  數(shù)

邏輯運(yùn)算及結(jié)果

a

b

!a

!b

a&&b

a||b

 

邏輯運(yùn)算符中“&&”和“||”的優(yōu)先級(jí)別低于關(guān)系運(yùn)算符,“!”的優(yōu)先級(jí)別高于算術(shù)運(yùn)算符,例如。

(a>b)&&(x>y)       可寫成:      a>b && x>y

(a==b)||(x==y)     可寫成:      a==b || x==y

(!a)||(a>b)        可寫成:      !a || a>b

為了提高程序的可讀性,明確表達(dá)各運(yùn)算符間的優(yōu)先關(guān)系,建議使用括號(hào)。

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

關(guān)系運(yùn)算符共有以下4種。

  • a < b:(a小于b)
  • a > b:(a大于b)
  • a <= b:(a小于或等于b)
  • a >= b:(a大于或等于b)

在進(jìn)行關(guān)系運(yùn)算時(shí),如果聲明的關(guān)系是假的(flase),則返回值是0;如果聲明的關(guān)系是真的(true),則返回值是1;如果某個(gè)操作數(shù)的值不定,則關(guān)系是模糊的,返回值是不定值。

所有的關(guān)系運(yùn)算符有著相同的優(yōu)先級(jí)別。關(guān)系運(yùn)算符的優(yōu)先級(jí)別低于算術(shù)運(yùn)算符的優(yōu)先級(jí)別,例如。

a < size-1            //這種表達(dá)方式等同于下面一行的表達(dá)方式

a < (size-1)

size - (1 < a)     //這種表達(dá)方式不等同于下面一行的表達(dá)方式

size - 1 < a

從上面的例子可以看出這兩種不同運(yùn)算符的優(yōu)先級(jí)別。當(dāng)表達(dá)式size -(1<a)進(jìn)行運(yùn)算時(shí),關(guān)系表達(dá)式先被運(yùn)算,然后返回結(jié)果值0或1被size減去。而當(dāng)表達(dá)式 size -1<a 進(jìn)行運(yùn)算時(shí),size先被減去1,然后再同a相比。

5.等式運(yùn)算符

在Verilog HDL語(yǔ)言中存在4種等式運(yùn)算符。

  • = =:(等于)
  • != :(不等于)
  • = = =:(等于)
  • != =:(不等于)

這4個(gè)運(yùn)算符都是二目運(yùn)算符,它要求有兩個(gè)操作數(shù)。“= =”和“!=”又稱為邏輯等式運(yùn)算符,其結(jié)果由兩個(gè)操作數(shù)的值決定。由于操作數(shù)中某些位可能是不定值x和高阻值z(mì),結(jié)果可能為不定值x。

“= = =”和“!= =”運(yùn)算符則不同,它在對(duì)操作數(shù)進(jìn)行比較時(shí),對(duì)某些位的不定值x和高阻值z(mì)也進(jìn)行比較。兩個(gè)操作數(shù)必需完全一致,其結(jié)果才是1,否則為0。“= = =”和“!= =”運(yùn)算符常用于case表達(dá)式的判別,所以又稱為“case等式運(yùn)算符”。

這4個(gè)等式運(yùn)算符的優(yōu)先級(jí)別是相同的。下面畫出“= =”與“= = =”的真值表,幫助理解兩者間的區(qū)別。

表8                                                          等式運(yùn)算符真值表

= = = 運(yùn)算

         操作數(shù)1

操作數(shù)2

0

1

x

z

0

1

0

0

0

1

0

1

0

0

x

0

0

1

0

z

0

0

0

1

= = 運(yùn)算

          操作數(shù)1

操作數(shù)2

0

1

x

z

0

1

0

x

x

1

0

1

x

x

x

x

x

x

x

z

x

x

x

x

 

下面舉一個(gè)例子說明“= =”與“= = =”的區(qū)別。

if(A==1’bx)  $display( "AisX" );      //當(dāng)A等于X時(shí),這個(gè)語(yǔ)句不執(zhí)行

if(A===1’bx) $display( "AisX" ); //當(dāng)A等于X時(shí),這個(gè)語(yǔ)句執(zhí)行

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

在Verilog HDL中有兩種移位運(yùn)算符。

<<:(左移位運(yùn)算符)

>>:(右移位運(yùn)算符)

其使用方法如下:

a >> n;

a << n;

a代表要進(jìn)行移位的操作數(shù),n代表要移幾位。這兩種移位運(yùn)算都用0來填補(bǔ)移出的空位。下面舉例說明:

module  shift;

     reg [3:0]  start, result;

     initial begin

          start  = 1;                    //start在初始時(shí)刻設(shè)為值0001

          result = (start<<2);       //移位后,start的值0100,然后賦給result

     end

endmodule

從上面的例子可以看出,start在移過兩位以后,用0來填補(bǔ)空出的位。進(jìn)行移位運(yùn)算時(shí)應(yīng)注意移位前后變量的位數(shù),下面舉例說明。

4’b1001<<1 = 5’b10010;                //左移1位后用0填補(bǔ)低位

4’b1001<<2 = 6’b100100;               //左移2位后用00填補(bǔ)低位

1<<6 = 32’b1000000;                    //左移6位后用000000填補(bǔ)低位

4’b1001>>1 = 4’b0100;                  //右移1位后,低1位丟失,高1位用0填補(bǔ)

4’b1001>>4 = 4’b0000;                  //右移4位后,低4位丟失,高4位用0填補(bǔ)

7.位拼接運(yùn)算符(Concatation)

在Verilog HDL語(yǔ)言有一個(gè)特殊的運(yùn)算符:位拼接運(yùn)算符{}。用這個(gè)運(yùn)算符可以把兩個(gè)或多個(gè)信號(hào)的某些位拼接起來進(jìn)行運(yùn)算操作。其使用方法如下:

{信號(hào)1的某幾位,信號(hào)2的某幾位,..,..,信號(hào)n的某幾位}

即把某些信號(hào)的某些位詳細(xì)地列出來,中間用逗號(hào)分開,最后用大括號(hào)括起來表示一個(gè)整體信號(hào),例如:

{a,b[3:0],w,3’b101}

也可以寫成為:

{a,b[3],b[2],b[1],b[0],w,1’b1,1’b0,1’b1}

在位拼接表達(dá)式中不允許存在沒有指明位數(shù)的信號(hào)。這是因?yàn)樵谟?jì)算拼接信號(hào)的位寬的大小時(shí)必需知道其中每個(gè)信號(hào)的位寬。

位拼接也可以用重復(fù)法來簡(jiǎn)化表達(dá)式,如下所示:

{4{w}}            //等同于{w,w,w,w}

位拼接還可以用嵌套的方式來表達(dá),如下所示:

{b,{3{a,b}}}     //等同于{b,a,b,a,b,a,b}

用于表示重復(fù)的表達(dá)式必須是常數(shù)表達(dá)式,如上例中的4和3。

8.縮減運(yùn)算符(reduction operator)

縮減運(yùn)算符是單目運(yùn)算符,也有與、或、非運(yùn)算。其與、或、非運(yùn)算規(guī)則類似于位運(yùn)算符的與、或、非運(yùn)算規(guī)則,但其運(yùn)算過程不同。位運(yùn)算是對(duì)操作數(shù)的相應(yīng)位進(jìn)行與、或、非運(yùn)算,操作數(shù)是幾位數(shù),則運(yùn)算結(jié)果也是幾位數(shù)。而縮減運(yùn)算則不同,縮減運(yùn)算是對(duì)單個(gè)操作數(shù)進(jìn)行與、或、非遞推運(yùn)算,最后的運(yùn)算結(jié)果是一位的二進(jìn)制數(shù)。

縮減運(yùn)算的具體運(yùn)算過程如下。

(1)先將操作數(shù)的第一位與第二位進(jìn)行與、或、非運(yùn)算。

(2)將運(yùn)算結(jié)果與第三位進(jìn)行與、或、非運(yùn)算,依次類推,直至最后一位。

例如:

reg [3:0] B;

reg C;

C = &B;

相當(dāng)于:

C =( ( B[0]&B[1] ) & B[2] ) & B[3];

由于縮減運(yùn)算的與、或、非運(yùn)算規(guī)則類似于位運(yùn)算符與、或、非運(yùn)算規(guī)則,這里不再詳細(xì)講述,可參照位運(yùn)算符的運(yùn)算規(guī)則介紹。

9.優(yōu)先級(jí)別

各種運(yùn)算符的優(yōu)先級(jí)別關(guān)系如表9所示。

表9                                                          運(yùn)算符優(yōu)先級(jí)別表

運(yùn)  算  符

優(yōu) 先 級(jí) 別

! ~

* / %

+ -

<< >>

< <= > >=

== != === !==

&

^ ^~

|

&&

||

? :

 

 

 

 

 

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

華清遠(yuǎn)見(www.farsight.com.cn)是國(guó)內(nèi)領(lǐng)先嵌入師培訓(xùn)機(jī)構(gòu),2004年注冊(cè)于中國(guó)北京海淀高科技園區(qū),除北京總部外,上海、深圳、成都、南京、武漢、西安、廣州均有直營(yíng)分公司。華清遠(yuǎn)見除提供嵌入式相關(guān)的長(zhǎng)期就業(yè)培訓(xùn)、短期高端培訓(xùn)、師資培訓(xùn)及企業(yè)員工內(nèi)訓(xùn)等業(yè)務(wù)外,其下屬研發(fā)中心還負(fù)責(zé)嵌入式、Android及物聯(lián)網(wǎng)方向的教學(xué)實(shí)驗(yàn)平臺(tái)的研發(fā)及培訓(xùn)教材的出版,截止目前為止已公開出版70余本嵌入式/移動(dòng)開發(fā)/物聯(lián)網(wǎng)相關(guān)圖書。企業(yè)理念:專業(yè)始于專注 卓識(shí)源于遠(yuǎn)見。企業(yè)價(jià)值觀:做良心教育、做專業(yè)教育,更要做受人尊敬的職業(yè)教育。