Verilog中Case語句

實際問題中常常需要用到多分支選擇,使用if語句導致內容繁瑣;更明智的做法是使用case語句,case語句是一種多分支選擇語句,可以方便的處理多分支選擇。本文通過實際例子,講解case語句的使用,以及case語句的變體casez和casex的使用:

目錄

 

一、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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章