• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

SOC/IP验证工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

systemverilog中case的用法

在 SystemVerilog 中,case 语句用于执行多分支选择,其功能类似于 C 语言的 switch。除了传统的 case,SystemVerilog 还增加了 casez、casex 以及 unique、priority、inside 等增强特性,使分支判断更灵活、更安全。


1. 基本 case 语句

语法与 Verilog 相同,比较时按全等(===)规则进行,即匹配必须包括 0、1、x、z 完全一致。

case (expression)
  value1: statement1;
  value2: statement2;
  ...
  default: default_statement;
endcase

示例:

logic [1:0] sel;
case (sel)
  2'b00:   out = a;
  2'b01:   out = b;
  2'b10:   out = c;
  default: out = 'x;
endcase

注意:case 分支中的表达式必须完全匹配,例如 2'b0x 不会匹配 2'b00 或 2'b01。


2. casez 与 casex(通配符比较)

  • casez:将 value 中的 z 视为“不关心”(? 也可表示不关心),比较时对应位忽略。
  • casex:将 value 中的 z 和 x 都视为“不关心”。
logic [1:0] sel;
casez (sel)
  2'b0?:   out = a;   // 匹配 00 或 01
  2'b10:   out = b;
  2'b11:   out = c;
endcase

建议:尽量避免使用 casex,因为 x 可能是仿真未初始化的状态,容易掩盖设计问题。优先使用 casez 并明确使用 ? 表示通配符。


3. unique case 与 priority case

这两个修饰符用于提高代码的意图表达和仿真检查。

3.1 unique case

要求所有分支互斥(没有重叠条件),且必须覆盖所有可能的 case 表达式值(除非有 default)。若仿真时发现多条分支匹配或没有分支匹配,会发出警告。

unique case (sel)
  2'b00:   out = a;
  2'b01:   out = b;
  2'b10:   out = c;
  default: out = d;
endcase

3.2 priority case

表示分支按优先级顺序执行,只要第一个匹配的分支被执行。如果没有任何分支匹配,也会发出警告。

priority case (sel)
  2'b00:   out = a;
  2'b0?:   out = b;   // sel = 00 或 01 时,先匹配到 00,所以不会执行这里
  2'b1?:   out = c;
endcase

注意:unique 和 priority 是 SystemVerilog 新增的关键字,需要确保仿真器和综合工具支持。


4. case inside(集合成员匹配)

case inside 允许使用集合({})或范围([low:high])来指定分支条件,且支持通配符 ?。

logic [3:0] data;
case (data) inside
  [0:9]      : $display("decimal digit");
  10, 11, 12 : $display("10 to 12");
  4'b1??0    : $display("binary pattern 1xx0");
  default    : $display("other");
endcase
  • 范围 [a:b] 包含 a 和 b。
  • 使用 inside 时,比较是基于“相等”或“匹配集合”的,不涉及 x/z 的无关位(除非使用 ?)。

5. 其他常用技巧

5.1 使用 begin … end 包裹多个语句

case (op)
  0: begin
       res = a + b;
       flag = 1;
     end
  1: begin
       res = a - b;
       flag = 0;
     end
endcase

5.2 case 语句中的 break 等效行为

SystemVerilog 的 case 不会自动 fall-through,执行完匹配的分支后直接跳出 case,不需要 break。

5.3 反转 case(reverse case)

有时需要将表达式与多个值比较,可以用 case (1'b1) 实现“条件真值表”:

case (1'b1)
  (a == b) : out = 1;
  (c > d)  : out = 2;
  default  : out = 0;
endcase

这等价于 if-else if 链,但语法更紧凑。


6. 综合注意事项

  • 完全覆盖:建议总是包含 default 分支,防止产生锁存器。
  • 避免 casex:综合时 casex 可能不会按预期忽略 x,最好用 casez。
  • unique / priority:有些综合工具支持,可作为设计意图文档;如果工具不支持,会被当作普通 case 处理。

总结表

语句 比较规则 典型用途
case 全等比较(===) 精确值匹配
casez 忽略 z 或 ? 位 编码器、优先级(用 ?)
casex 忽略 z 和 x 位 不推荐
unique case 互斥且全覆盖 完整译码逻辑,仿真时检查冲突/遗漏
priority case 顺序优先 可重叠的优先级编码
case inside 集合 / 范围 / ? 通配符 数值区间判断、模式匹配

希望以上内容能帮你全面掌握 SystemVerilog 中 case 的用法。如有特定场景需要进一步示例,欢迎继续提问!

posted on 2026-06-20 17:16  SOC验证工程师  阅读(52)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3