實際問題中常常需要用到多分支選擇,使用if語句導致內容繁瑣;更明智的做法是使用case語句,case語句是一種多分支選擇語句,可以方便的處理多分支選擇。本文通過實際例子,講解case語句的使用,以及case語句的變體casez和casex的使用:
目錄
一、case的用法
形式:
case(控制表達式/值)
分支表達式:執行語句
default:執行語句
endcase
功能:
自上而下,按照順序逐個對分支表達式進行判斷,如果這一分支表達式等於控制表達式的值,就執行其對應操作;均不相等時,執行default操作;
注意:
分支表達式不能重複,否則會出現衝突;
執行完某一操作後,跳出case語句;
控制表達式與多個分支表達式匹配,只執行從上至下首個匹配項(判斷順序進行,執行一次後就跳出case語句了);
測試:
設計一個四選一器件,驗證case語句功能:
實現代碼如下:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: guoliang CLL
//
// Create Date: 2020/03/02 16:51:44
// Design Name:
// Module Name: case_test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module case_test(
input [1:0]sel,
output reg [3:0]dout
);
always@(*)
begin
case(sel)
2'b00:begin
dout = 4'b0000;
end
2'b01:begin
dout = 4'b0001;
end
2'b10:begin
dout = 4'b0011;
end
2'b11:begin
dout = 4'b0111;
end
default:begin
dout = 4'b1111;
end
endcase
end
endmodule
測試文件如下:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: guoliang CLL
//
// Create Date: 2020/03/02 16:56:45
// Design Name:
// Module Name: case_tsb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module case_tsb(
);
reg [1:0]sel;
wire [3:0]dout;
initial
begin
sel = 2'b00;
#10 sel = 2'b10;
#10 sel = 2'b11;
#10 sel = 2'b01;
end
case_test inst1(.sel(sel),.dout(dout));
endmodule
仿真結果如下:
對應RTL電路如下:
二、casez與casex的用法
casez進行控制表達式與分支表達式的比較時,不關注高阻態位(不管是控制表達式還是條件表達式,這些位均默認爲匹配);
casex進行控制表達式與分支表達式的比較時,不關注高阻態,以及不定位(不管是控制表達式還是條件表達式,這些位均默認爲匹配);
示例1:
對於case語句:
case (sel)
2'b00: y = a;
2'b01: y = b;
2'bx0: y = c;
2'b1x: y = d;
2'bz0: y = e;
2'b1?: y = f;
default : y = g;
endcase
對應的結果爲:
Result:
sel y case item
00 a 00
11 g default
xx g default
x0 c x0
1z f 1?
z1 g default
可以看出,case可以識別出1/0/x/z,必須完全匹配才能執行對應的執行語句;反之就匹配default;
對於casez語句:
casez (sel)
2'b00: y = a;
2'b01: y = b;
2'bx0: y = c;
2'b1x: y = d;
2'bz0: y = e;
2'b1?: y = f;
default: y = g;
endcase
對應的結果爲:
Result:
sel y case item
00 a 00
11 f 1?
xx g default
x0 c x0 (would have matched with z0(item 5) if item 3 is not present.)
1z d 1x (would have matched with z0(item 5) & 1?(item 6) also.)
z1 b 01 (would have matched with 1?(item 6) also.)
可以看出,casez會把z/?匹配成任意,也會把任意匹配成z/?的;
對於casex語句:
casex (sel)
2'b00 : y = a;
2'b01 : y = b;
2'bx0 : y = c;
2'b1x : y = d;
2'bz0 : y = e;
2'b1? : y = f;
default : y = g;
endcase
對應的結果爲:
Result:
sel y case item
00 a 00
11 d 1x (would have matched with 1? also)
xx a 00 (would have matched with all items)
x0 a 00 (would have matched with all items except 01)
1z c x0 (would have matched with all items except 00,01)
z1 b 01 (would have matched with 1x, 1? also)
可以看出,casex會把x和z/?匹配成任意,也會把任意匹配成x和z/?的;
三、參考文獻
https://www.cnblogs.com/poiu-elab/archive/2012/11/02/2751323.html