关于Verilog中的case、casex、casez

本文

主要介绍Verilog语法中case,casex,casez的区别,以及建议使用方法。

版本 说明
0.1 初版发布

关于case

  • 代码:
1
2
3
4
5
6
7
8
9
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 y case item
00 a 00
11 g default
xx g default
x0 c x0
1z f 1?
z1 g default

可见,case语法对四值0 1 X Z是严格匹配的,并且语义中“?”代表Z值。

关于casez

  • 代码
1
2
3
4
5
6
7
8
9
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
  • 结果:
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的匹配顺序是从上到下。根据上面casez的匹配列表,可见casez语法将表达式的“z/?”与输入的任意值(0 1 X Z)匹配,而表达式的“x 0 1”和输入的“x 0 1”还是严格匹配。所以,一般我们对于不关心的信号位使用casez语句,并在选项中将该位设为"z/?"。这也是最推荐的写法。

关于casex

  • 代码
1
2
3
4
5
6
7
8
9
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
  • 结果:
sel y case item
00 a 00
11 d 1x (would have matched with 1? also)
xx a 00 (would have matched with all)
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的匹配顺序也是从上到下。根据上面casex的匹配列表,可见casex语法将将表达式中“z/?/x”与输入的任意值(0 1 X Z)匹配,而表达式中的“0 1”与输入的“0 1”严格匹配。

总结

总结如下:

  • case、casex、casez的匹配顺序都是从上到下。
  • case严格匹配,casez中表达式z/?代表不关心该位的状态值(最好使用?),casex中表达式x/z/?代表不关心该位的状态值。
  • case、casex、casez都是可综合的,不过在case中综合电路无法解析x/z/?,会将其认为不关心,这样会使RTL语义和综合电路间产生偏差,所以case语句表达式中不建议使用x/z/?。
  • 尽量不使用casex,因为在初始条件下,控制信号可能存在大量x,使用casex会对电路的选择功能造成混乱,隐藏选择信号x值对电路功能的影响。

推荐使用casez,代码格式如下:

1
2
3
4
5
6
casez (sel)
    2'b00:      y = a;
    2'b01:      y = b;
    2'b1?:      y = c;
    default :   y = d;
endcase

代码功能等同于:

1
2
3
4
5
6
case (sel)
    2'b00:            y = a;
    2'b01:            y = b;
    2'b10,2'b11:      y = c;
    default :         y = d;
endcase

文章原创,可能存在部分错误,欢迎指正,联系邮箱 cao_arvin@163.com。