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 的用法。如有特定场景需要进一步示例,欢迎继续提问!
浙公网安备 33010602011771号