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 @   远航路上ing  阅读(14157)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示