转载:【 Verilog HDL 】case, casez, casex 之干货总结

原地址:https://blog.csdn.net/Reborn_Lee/article/details/82390445

Verilog HDL中的case语句有两种变种,casex和casez,既然存在这两种形式,肯定是合理的,为了应对特殊的情况。我们只需要掌握其具体用法,需用用到的地方就用上,倒也不必考虑太多。(我见有些人还分析综合前和综合后,这种探索精神值得肯定,但目前来说,我没理由考虑那么多,究竟有没有意义我也不知道!)

最后,本文内容参考:《从算法设计到硬件逻辑的实现》,这是一本好书,让我学到了很多知识。


case语句是一种多分支选择语句,if语句只有两个分支可供选择,而实际问题中常常需要用到多分支选择,Verilog语言提供的case语句直接处理多分支选择。case语句通常用于微处理器的指令译码,
它的一般形式如下:
1) case(表达式) <case分支项> endcase
2) casez(表达式) <case分支项> endcase
3) casex(表达式) <case分支项> endcase
case分支项的一般格式如下:
分支表达式: 语句
缺省项(default项): 语句

说明:
a) case括弧内的表达式称为控制表达式,case分支项中的表达式称为分支表达式。控制表达式通常表示为控制信号的某些位,分支表达式则用这些控制信号的具体状态值来表示,因此分支表达式又可以称为常量表达式。
b) 当控制表达式的值与分支表达式的值相等时,就执行分支表达式后面的语句。如果所有的分支表达式的值都没有与控制表达式的值相匹配的,就执行default后面的语句。
c) default项可有可无,一个case语句里只准有一个default项。(具体而言,尽量要有一个default,可以是一个空语句。当然语法上,没有default也不会报错。)


下面是一个简单的使用case语句的例子。该例子中对寄存器rega译码以确定result的值。
 


 
 
  1. reg [ 15: 0] rega;
  2. reg [ 9: 0] result;
  3. case(rega)
  4. 16 'd0: result = 10 'b0111111111;
  5. 16 'd1: result = 10 'b1011111111;
  6. 16 'd2: result = 10 'b1101111111;
  7. 16 'd3: result = 10 'b1110111111;
  8. 16 'd4: result = 10 'b1111011111;
  9. 16 'd5: result = 10 'b1111101111;
  10. 16 'd6: result = 10 'b1111110111;
  11. 16 'd7: result = 10 'b1111111011;
  12. 16 'd8: result = 10 'b1111111101;
  13. 16 'd9: result = 10 'b1111111110;
  14. default: result = 'bx;
  15. endcase

继续给出注意事项:

d) 每一个case分项的分支表达式的值必须互不相同,否则就会出现矛盾现象(对表达式的同一个值,有多种执行方案)。
e) 执行完case分项后的语句,则跳出该case语句结构,终止case语句的执行。
f) 在用case语句表达式进行比较的过程中,只有当信号的对应位的值能明确进行比较时,比较才能成功。因此要注意详细说明case分项的分支表达式的值。
g) case语句的所有表达式的值的位宽必须相等,只有这样控制表达式和分支表达式才能进行对应位的比较。一个经常犯的错误是用'bx, 'bz 来替代 n'bx, n'bz,这样写是不对的,因为信号x, z的缺省宽度是机器的字节宽度,通常是32位(此处 n 是case控制表达式的位宽)。


casez和casex:

下面先给出 case, casez, casex 的真值表:

对于那些分支表达式中存在不定值x和高阻值z位时,case语句提供了处理这种情况的手段。下面的两个例子介绍了处理x,z值位的case语句。(注意分支表达式中的z可以写成?)!

给出几个应用实例:

1)


 
 
  1. case ( select[ 1: 2] )
  2. 2 'b00: result = 0;
  3. 2 'b01: result = flaga;
  4. 2 'b0x,
  5. 2 'b0z: result = flaga? 'bx : 0;
  6. 2 'b10: result = flagb;
  7. 2 'bx0,
  8. 2 'bz0: result = flagb? 'bx : 0;
  9. default: result = 'bx;
  10. endcase

2)


 
 
  1. case(sig)
  2. 1 'bz: $display("signal is floating");
  3. 1 'bx: $display( "signal is unknown");
  4. default: $display( "signal is %b", sig);
  5. endcase

Verilog HDL针对电路的特性提供了case语句的其它两种形式用来处理case语句比较过程中的不必考虑的情况( don't care condition )。其中casez语句用来处理不考虑高阻值z的比较过程,casex语句则将高阻值z和不定值都视为不必关心的情况。所谓不必关心的情况,即在表达式进行比较时,不将该位的状态考虑在内。这样在case语句表达式进行比较时,就可以灵活地设置以对信号的某些位进行比较。见下面的两个例子:

3)


 
 
  1. reg[ 7: 0] ir;
  2. casez(ir)
  3. 8 'b1???????: instruction1(ir);
  4. 8 'b01??????: instruction2(ir);
  5. 8 'b00010???: instruction3(ir);
  6. 8 'b000001??: instruction4(ir);
  7. endcase

4)


 
 
  1. reg[ 7: 0] r, mask;
  2. mask = 8 'bx0x0x0x0;
  3. casex(r^mask)
  4. 8 'b001100xx: stat1;
  5. 8 'b1100xx00: stat2;
  6. 8 'b00xx0011: stat3;
  7. 8 'bxx001100: stat4;
  8. endcase

 

 

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值