case/casez/casex 的區分與使用


 參考:http://www.cnblogs.com/poiu-elab/archive/2012/11/02/2751323.html

  與  verilog數字系統設計基礎

  一般來說,使用最多的是CASE語句,casez和casex基本上很少使用,不過因為它們的功能強大,不能不學會它的使用。

    一般性的常識是使用casez,強烈的建議不要使用casex。首先要明確的是'?'代表的不是don't care,而是'z'。再有就是case/casez/casex其實都是可綜合的,這一點也要記住。

 區分:

   case語句的表達式的值有4中情況:0、1、z、x。4種是不同的,故表達式要嚴格的相等才可以操作分支語句。

   casez語句中的表達式情況有三種:0、1、x。不用關心z,z可以和任何數值相等,即z =0.z= 1,z=x;

   casex語句的表達式情況有二種:0、1.不用關心x和z。即x=z=0,x=z=1.

 另外表達式的值是按從上到下的順序來與分支條件的比較,如果相等,則不再與下面的分支相比較而直接執行該分支的語句。

  

實例分析看不同:

一、simulation difference

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
復制代碼

不同的sel,對應

復制代碼
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/z/x,所以就得到了上面的結果。很是嚴格

2. casez,就是會把z/?匹配成任意,也會把任意匹配成z/?的。

復制代碼
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.)
復制代碼

首先,case的描述,匹配都是從上到下進行的,如果使用了casez,看上面的casez的列表,只要輸入有z/?的話,就能和任意匹配,只要列表的index項有z/?,就能匹配任意項,再對照上面的例子,就明了了。

3、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 1? also) 
    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/?的輸入的時候,都不會care,只管不是大大情況來匹配,上面的解釋也是很容易看懂。就不多說了。

二、synthesis difference

綜合的時候又是另一番景象了,因為綜合工具其實都不會管你什么x/z/?之類的,他能認識什么呢?讓我們再來測試一下,case/casez/casex不同寫法的綜合結果,例子都是同樣的

1、例子1

case (sel) 
    2'b00   :   mux_out = mux_in[0]; 
    2'b01   :   mux_out = mux_in[1]; 
    2'b1?   :   mux_out = mux_in[2]; 
    default :   mux_out = mux_in[3]; 
endcase 

       

2、例子2

case (sel) 
    2'b00   :   mux_out = mux_in[0]; 
    2'b01   :   mux_out = mux_in[1]; 
    2'b1x   :   mux_out = mux_in[2]; 
    default :   mux_out = mux_in[3]; 
endcase

     

通過上面兩個例子我們得到的結論是:

1. Case statement will not consider for synthesis, the items containing x or z. 
2. Casez and Casex will give the same output after synthesis, treating both x, z in case items as dont cares.

就是說你的case(不是casez/casex的時候)的index列表里面的x和z,都被綜合工具認為是不可達到的狀態就被去掉了

casez和casex里面的x/z都被認為是don't care,所以綜合出的電路會是一致的。

 

三、simulation vs synthesis

例子

casez (sel) 
    2'b00   :   mux_out = mux_in[0]; 
    2'b01   :   mux_out = mux_in[1]; 
    2'b1?   :   mux_out = mux_in[2]; 
    default :   mux_out = mux_in[3]; 
endcase

再看simulation與synthesis的結果

+---+-----------------------------------+-----------------------------------+
|   |               casez               |               casex               |
|sel|   Pre-synthesis   Post-synthesis  |   Pre-synthesis  Post-synthesis   |
+---+-----------------------------------+-----------------------------------+
|xx |   mux_in[3]       x               |   mux_in[0]       x               |
|1x |   mux_in[2]       mux_in[2]       |   mux_in[2]       mux_in[2]       |
|0x |   mux_in[3]       x               |   mux_in[0]       x               |
|zz |   mux_in[0]       x               |   mux_in[0]       x               |
|1z |   mux_in[2]       mux_in[2]       |   mux_in[2]       mux_in[2]       |
|0z |   mux_in[0]       x               |   mux_in[0]       x               |
+---+-----------------------------------+-----------------------------------+

作者此時說了兩句話就是Another interesting, very important observation is that when ever there is a mismatch, post-synthesis result will become x. During RTL simulation if sel becomes xx, casez executes default statement(which is the intended behaviour) but casex executes case item1 (which is not the intended behaviour), clearly a mismatch.


看上面的表這就能說明問題了,不管用casez還是casex,simulation和synthesis的結果都會有出入的,所以在寫代碼的時候,考慮到綜合,casez與casex都是完全等同的了,就不必要非得糾結寫哪個比較好了。

或許casez有那么一點好處,能體現在

casez (sel) 
    000: y = a; 
    001: y = b; 
    01?: y = c; 
    1??: y = d; 
endcase

這樣的代碼,如果用case寫的話

case (sel) 
    000             :   y = a; 
    001             :   y = b; 
    010,011         :   y = c; 
    100,101,110,111 :   y = d; 
endcase

就是這點有點罷了~

 

四、summary

1、我們在寫代碼的時候如果用了case,那么就不要在index列表里面出現x/z/?,綜合工具認不出這些,都會當做don't care
2、casez和casex綜合的結果是一致的。
3、casez稍好用一些,因為它可以用來代表don't care的值
4、最重要的一點就是,casez和casex其實沒有孰優孰劣

就這樣,以后我用的時候沒准會更多的用casez,case其實也是好東西,最好弄明白了自己真正要表達的意思是什么再動手寫代碼,還要深刻理解case/casez/casex到底起到的什么作用~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM