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

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

Verilog HDL基礎(chǔ)之:條件語句

2013/08/20
1
閱讀需 23 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

 

if語句

if語句是用來判定所給定的條件是否滿足,根據(jù)判定的結(jié)果(真或假)決定執(zhí)行給出的兩種操作之一。Verilog HDL語言提供了3種形式的if語句。

(1)無分支。

語法形式:

if (表達式)  語句;

例如:

if (a > b)  out1 <= int1;     //若a大于b,將int1賦予out1

(2)單級分支。

語法形式:

if(表達式)語句1;

else 語句2;

例如:

if(a>b) out1<=int1;       //若a大于b,將int1賦予out1;否則,將int2賦予out1

else out1<=int2;

(3)多級分支

語法形式:

if(表達式1)          語句1;

else  if(表達式2)   語句2;

else  if(表達式3)   語句3;

...

else  if(表達式m)   語句m;

else                   語句n;

例如:

if(a>b)            out1<=int1;        //若a大于b,將int1賦予out1

else  if(a==b)    out1<=int2;        //否則,如果a等于b,將int2賦予out1

else                 out1<=int3;        //否則,將int3賦予out1

關(guān)于if語句有如下6點說明:

(1)3種形式的if語句中,在if后面都有“表達式”,一般為邏輯表達式或關(guān)系表達式。系統(tǒng)對表達式的值進行判斷,若為0、x或z,按“假”處理;若為1,按“真”處理,執(zhí)行指定的語句。

(2)第二、第三種形式的if語句中,在每個else前面有一分號,整個語句結(jié)束處有一分號。

這是由于分號是Verilog HDL語句中不可缺少的部分,這個分號是if語句中的內(nèi)嵌套語句所要求的。如果無此分號,則出現(xiàn)語法錯誤。

但應(yīng)注意,不要誤認(rèn)為上面是兩個語句(if語句和else語句)。它們都屬于同一個if語句。else子句不能作為語句單獨使用,它必須是if語句的一部分,與if配對使用。

(3)在if和else后面可以包含一個內(nèi)嵌的操作語句,也可以有多個操作語句,此時用begin和end這兩個關(guān)鍵詞將幾個語句包含起來成為一個復(fù)合塊語句如下所示。

if(a>b)begin                        //使用begin_end語句實現(xiàn)多個賦值操作

     out1<=int1;

     out2<=int2;

end

else begin

     out1<=int2;

     out2<=int1;

end

注意

在end后不需要再加分號,因為begin_end內(nèi)是一個完整的復(fù)合語句,不需再附加分號。

(4)允許一定形式的表達式簡寫方式,例如:

if(expression)  等同于  if( expression == 1 )

if(!expression) 等同于  if( expression != 1 )

(5)if語句的嵌套。

在if語句中又包含一個或多個if語句,稱為if語句的嵌套,一般形式如下:

if(expression1)

     if(expression2)     語句1     (內(nèi)嵌if)

     else   語句2

else if(expression3)    語句3     (內(nèi)嵌if)

else   語句4

應(yīng)當(dāng)注意if與else的配對關(guān)系,else總是與它上面的最近的if配對。如果if與else的數(shù)目不一樣,為了實現(xiàn)程序設(shè)計者的企圖,可以用begin_end塊語句來確定配對關(guān)系,例如:

if() begin

     if()  語句1     (內(nèi)嵌if)

end

else  語句2

這時begin_end塊語句限定了內(nèi)嵌if語句的范圍,因此else與第一個if配對。注意begin_end塊語句在if_else語句中的使用,因為有時begin_end塊語句的不慎使用會改變邏輯行為,如下所示:

if(index>0)                                         //內(nèi)嵌for語句,無else分支

    for(scani=0;scani<index;scani=scani+1)    //內(nèi)嵌if語句

      if(memory[scani]>0) begin              //使用begin_end語句,有else分支

           $display("...");

           memory[scani]=0;

      end

      else                                            //此處為內(nèi)嵌if語句的分支

           $display("error-indexiszero");

...

盡管程序設(shè)計者把else寫在與第一個if(外層if)同一列上,希望與第一個if對應(yīng),但實際上else是與第二個if對應(yīng),因為它們相距最近。正確的寫法如下:

if(index>0) begin                                //內(nèi)嵌for語句,有else分支

     for(scani=0;scani<index;scani=scani+1)  //內(nèi)嵌if語句

          if(memory[scani]>0) begin          //使用begin_end語句,無else分支

              $display("...");

              memory[scani]=0;

        end

end

else                                                //此處為外部if語句的分支

     $display("error-indexiszero");

(6)if_else例子。

下面這段程序用if_else語句來檢測變量index以決定modify-seg1、modify-seg2、modify-seg3中哪一個的值應(yīng)當(dāng)與index相加作為memory的尋址地址。并且將相加值存入寄存器index以備下次檢測使用。程序的前10行定義寄存器和參數(shù)。

reg [31:0]  instruction, segment_area[255:0];   //定義寄存器

reg [7:0]   index;

reg [5:0]   modify_seg1, modify_seg2, modify_seg3;

parameter                                              //定義參數(shù)

      segment1=0,  inc_seg1=1,

      segment2=20, inc_seg2=2,

      segment3=64, inc_seg3=4,

      data=128;

//檢測寄存器index的值

if(index<segment2) begin                          //index<20時,執(zhí)行下列操作

      instruction = segment_area[index + modify_seg1];

      index = index + inc_seg1;

end

else  if(index<segment3) begin                   //20<index<64時,執(zhí)行下列操作

      instruction = segment_area[index + modify_seg2];

      index = index + inc_seg2;

end

else  if (index<data) begin                    //64<index<128時,執(zhí)行下列操作

      instruction = segment_area[index + modify_seg3];

      index = index + inc_seg3;

end

else                                                //index>128時,執(zhí)行下列操作

      instruction = segment_area[index];

case語句

case語句是一種多分支選擇語句,if語句只有兩個分支可供選擇,而實際問題中常常需要用到多分支選擇。Verilog語言提供的case語句直接處理多分支選擇。case語句通常用于微處理器的指令譯碼,它的一般形式如下:

(1)case (表達式)      <case分支項>   endcase

(2)casez(表達式)      <case分支項>   endcase

(3)casex(表達式)      <case分支項>   endcase

<case分支項>的一般語法格式如下:

分支表達式:       語句

缺省項(default項):      語句

 

關(guān)于case語句的幾點說明如下。

(1)case括弧內(nèi)的表達式稱為控制表達式,case分支項中的表達式稱為分支表達式??刂票磉_式通常表示為控制信號的某些位,分支表達式則用這些控制信號的具體狀態(tài)值來表示,因此分支表達式又可以稱為常量表達式。

(2)當(dāng)控制表達式的值與分支表達式的值相等時,就執(zhí)行分支表達式后面的語句。如果所有的分支表達式的值都沒有與控制表達式的值相匹配的,就執(zhí)行default后面的語句。

(3)default項可有可無,一個case語句里只能有一個default項。下面是一個簡單的使用case語句的例子。該例子中對寄存器rega譯碼以確定result的值。

reg [15:0]  rega;

reg [9:0]   result;

case(rega)

     16 'd0:  result = 10 'b0111111111;       //rega等于0時

     16 'd1:  result = 10 'b1011111111;       //rega等于1時

     16 'd2:  result = 10 'b1101111111;       //rega等于2時

     16 'd3:  result = 10 'b1110111111;       //rega等于3時

     16 'd4:  result = 10 'b1111011111;       //rega等于4時

     16 'd5:  result = 10 'b1111101111;       //rega等于5時

     16 'd6:  result = 10 'b1111110111;       //rega等于6時

     16 'd7:  result = 10 'b1111111011;       //rega等于7時

     16 'd8:  result = 10 'b1111111101;       //rega等于8時

     16 'd9:  result = 10 'b1111111110;       //rega等于9時

     default: result = 'bx;                     //rega不等于上面的值時

endcase

(4)每一個case分項的分支表達式的值必須互不相同,否則就會出現(xiàn)矛盾現(xiàn)象(對表達式的同一個值,有多種執(zhí)行方案)。

(5)執(zhí)行完case分項后的語句,則跳出該case語句結(jié)構(gòu),終止case語句的執(zhí)行。

(6)在用case語句表達式進行比較的過程中,只有當(dāng)信號的對應(yīng)位的值能明確進行比較時,比較才能成功,因此要詳細(xì)說明case分項的分支表達式的值。

(7)case語句的所有表達式的值的位寬必須相等,只有這樣控制表達式和分支表達式才能進行對應(yīng)位的比較。一個經(jīng)常犯的錯誤是用'bx、'bz 來替代n'bx、n'bz,這樣寫是不對的,因為信號x、z的缺省寬度是機器的字節(jié)寬度,通常是32位(此處 n 是case控制表達式的位寬)。

case語句與if語句的區(qū)別主要有以下兩點。

(1)與case語句中的控制表達式和多分支表達式相比,if結(jié)構(gòu)中的條件表達式更為直觀一些。

(2)對于那些分支表達式中存在不定值x和高阻值z時,case語句提供了處理這種情況的手段。下面的兩個例子介紹了處理x、z值case語句。

例1:case語句1。

case (select[1:2])

      2 'b00:  result = 0;               //select[1:2]等于00時

      2 'b01:  result = flaga;          //select[1:2]等于01時

      2 'b0x,

      2 'b0z:  result = flaga? 'bx: 0; //select[1:2]等于0x和0z時,執(zhí)行表達式

      2 'b10:  result = flagb;          //select[1:2]等于10時

      2 'bx0,

      2 'bz0:  result = flagb? 'bx :0; //select[1:2]等于x0和z0時,執(zhí)行表達式

      default: result = 'bx;            //select[1:2]不等于上面的值時

endcase

例2:case語句2

case(sig)

     1 'bz:    $display("signal is floating"); //sig為高阻時,打印輸出

     1 'bx:    $display("signal is unknown");  //sig為不定狀態(tài)時,打印輸出

     default:  $display("signal is %b", sig);  //為其他時,即0或1時,打印輸出

endcase

針對電路的特性,Verilog HDL提供了case語句的其他兩種形式用來處理不必考慮的情況(don't care condition)。其中casez語句用來處理不考慮高阻值z的比較過程,casex語句則將高阻值z和不定值都視為不必關(guān)心的情況。

所謂不必關(guān)心的情況,即在表達式進行比較時,不將該位的狀態(tài)考慮在內(nèi)。這樣在case語句表達式進行比較時,就可以靈活地設(shè)置,以對信號的某些位進行比較。如表3.10所示為case、casez、casex 的真值表:

表3.10                                                           case語句真值表

case

0

1

x

z

0

1

0

0

0

1

0

1

0

0

x

0

0

1

0

z

0

0

0

1

casez

0

1

x

z

0

1

0

0

1

1

0

1

0

1

x

0

0

1

1

z

1

1

1

1

casex

0

1

x

z

0

1

0

1

1

1

0

1

1

1

x

1

1

1

1

z

1

1

1

1

下面給出兩個例子來分別說明casez語句和casex語句。

例3:casez語句。

reg[7:0] ir;

casez(ir)

     8 'b1???????: instruction1(ir);             //只判斷ir的最高位

     8 'b01??????: instruction2(ir);             //只判斷ir的高2位

     8 'b00010???: instruction3(ir);             //只判斷ir的高5位

     8 'b000001??: instruction4(ir);             //只判斷ir的高6位

endcase

例4:casex語句。

reg[7:0] r, mask;

mask = 8'bx0x0x0x0;

casex(r^mask)                                       //判斷r^mask的結(jié)果

     8 'b001100xx: stat1;                           //不考慮低2位

     8 'b1100xx00: stat2;                           //不考慮第3、4位

     8 'b00xx0011: stat3;                           //不考慮第5、6位

     8 'bxx001100: stat4;                           //不考慮高2位

Endcase

其他條件語句

上面提到的if語句和case語句都只能應(yīng)用于always語句內(nèi)部。如果需要在always語句之外應(yīng)用條件語句,可以采樣這樣的語法結(jié)構(gòu):

assign data = (sel)?  a : b;

上面的語句的含義相當(dāng)于:

if (sel = 1)

     data = a;

else

     data =  b;

相關(guān)推薦

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

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