case語句檢查給定的表達式是否與列表中的其他表達式之一相匹配,并據(jù)此進行分支。它通常用于實現(xiàn)一個多路復(fù)用器。
如果要檢查的條件很多,if-else結(jié)構(gòu)可能不合適,因為它會綜合成一個優(yōu)先編碼器而不是多路復(fù)用器。
語法
一個Verilog case語句以case關(guān)鍵字開始,以endcase關(guān)鍵字結(jié)束。在括弧內(nèi)的表達式將被精確地評估一次,并按其編寫順序與備選方案列表進行比較,與給定表達式匹配的備選方案的語句將被執(zhí)行。一塊多條語句必須分組,并在 begin 和 end 范圍內(nèi)。
case (<expression>)
case_item1 : <single statement>
case_item2,
case_item3 : <single statement>
case_item4 : begin
<multiple statements>
end
default : <statement>
endcase
如果所有的case項都不符合給定的表達式,則執(zhí)行缺省項內(nèi)的語句,缺省語句是可選的,在case語句中只能有一條缺省語句。case語句可以嵌套。
如果沒有符合表達式的項目,也沒有給出缺省語句,執(zhí)行將不做任何事情就退出case塊。Verilog HDL中的case語句有兩種變種,casex和casez:
case(表達式) <case分支項> endcase
casez(表達式) <case分支項> endcase
casex(表達式) <case分支項> endcase
缺省項:default:語句
case、casez、casex真實表:
實例
設(shè)計一個2位選擇信號,用于將其他三個3位輸入中的一個信號連接到被調(diào)用的輸出信號。根據(jù)sel的值,用case語句將正確的輸入分配到輸出。由于sel是一個2位信號,它可以有2^2種組合,從0到3。如果sel為3,默認語句有助于將輸出設(shè)置為0。
module my_mux (input [2:0] a, b, c,
[1:0] sel,
output reg [2:0] out);
always @ (a, b, c, sel) begin
case(sel)
2'b00 : out = a; // If sel=0, output is a
2'b01 : out = b; // If sel=1, output is b
2'b10 : out = c; // If sel=2, output is c
default : out = 0; // If sel is anything else, out is always 0
endcase
end
endmodule
綜合后的RTL原理圖;
case語句與if_else_if語句的區(qū)別
主要區(qū)別:
-
與case語句中的控制表達式和多分支表達式這種比較結(jié)構(gòu)相比,if_else_if結(jié)構(gòu)中的條 件表達式更為直觀一些。
-
對于那些分支表達式中存在不定值x和高阻值z位時,case語句提供了處理這種情況的手 段。下面的兩個例子介紹了處理x,z值位的case語句。
Verilog HDL針對電路的特性提供了case語句的其它兩種形式用來處理case語句比較過程中的不必考慮的情況( don’t care condition )。其中casez語句用來處理不考慮高阻值z的比較過程,casex語句則將高阻值z和不定值都視為不必關(guān)心的情況。
所謂不必關(guān)心的情況,即在表達式進行比較時,不將該位的狀態(tài)考慮在內(nèi)。這樣在case語句表達式進行比較時,就可以靈活地設(shè)置以對信號的某些位進行比較。見下面的兩個例子:
reg[7:0] ir;
casez(ir)
8'b1???????: instruction1(ir);
8'b01??????: instruction2(ir);
8'b00010???: instruction3(ir);
8'b000001??: instruction4(ir);
endcase
reg[7:0] r, mask;
mask = 8'bx0x0x0x0;
casex(r^mask)
8'b001100xx: stat1;
8'b1100xx00: stat2;
8'b00xx0011: stat3;
8'bxx001100: stat4;
endcase
鎖存器問題
Verilog HDL設(shè)計中容易犯的一個通病是由于不正確使用語言,生成了并不想要的鎖存器。下面我們
給出了一個在“always"塊中不正確使用if語句,造成這種錯誤的例子。
有鎖存器:
always @(al or d)begin
if(al)
q<=d;
end
檢查一下左邊的"always"塊,if語句保證了只有當(dāng)al=1時,q才取d的值。這段程序沒有寫出 al = 0 時的結(jié)果, 那么當(dāng)al=0時會怎么樣呢? 在"always"塊內(nèi),如果在給定的條件下變量沒有賦值,這個變量將保持原值,也就是說會生成一個鎖存器!
無鎖存器:
always @(al or d)begin
if(al)
q<=d;
else
q<=0
end
Verilog HDL程序另一種偶然生成鎖存器是在使用case語句時缺少default項的情況下發(fā)生的。
case語句的功能是:在某個信號(本例中的sel)取不同的值時,給另一個信號(本例中的q)賦不同的值。注意看下圖左邊的例子,如果sel=0,q取a值,而sel=11,q取b的值。這個例子中不清楚的是:如果sel取00和11以外的值時q將被賦予什么值?在下面左邊的這個例子中,程序是用Verilog HDL寫的,即默認為q保持原值,這就會自動生成鎖存器。
有鎖存器:
always @(sel[1:0] or a or b)begin
case(sel[1:0])
2'b00: q<=a;
2'b11: q<=b;
endcase
end
無鎖存器:文章來源:http://www.zghlxwxcb.cn/news/detail-620580.html
always @(sel[1:0] or a or b)begin
case(sel[1:0])
2'b00: q<=a;
2'b11: q<=b;
default:q<='b0;
endcase
end
`以上就是怎樣來避免偶然生成鎖存器的錯誤。如果用到if語句,最好寫上else項。如果用case語句,最好寫上default項。文章來源地址http://www.zghlxwxcb.cn/news/detail-620580.html
到了這里,關(guān)于Verilog基礎(chǔ)語法(13)之case語句的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!