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到底起到的什么作用~

posted on 2017-05-26 09:23  guolongnv  阅读(1816)  评论(0编辑  收藏  举报