在SystemVerilog中,case、casex和casez是三种不同的条件选择语句,它们在匹配规则上有重要区别:
1. 基本区别
语句 | 通配符 | 匹配规则 | 可综合程度 |
|---|---|---|---|
| 无 | 精确匹配 | 完全可综合 |
|
| 将 | 可综合,但需谨慎 |
|
| 将 | 通常不建议综合 |
2. 详细说明
case - 精确匹配
logic [2:0] sel; logic [3:0] out; always_comb begin case(sel) 3'b001: out = 4'b0001; 3'b010: out = 4'b0010; 3'b100: out = 4'b0100; default: out = 4'b0000; endcase end完全匹配二进制值
最安全,推荐用于可综合代码
casez - 忽略高阻和"?"
logic [2:0] sel; logic [3:0] out; // 匹配规则:忽略 z 和 ? always_comb begin casez(sel) 3'b001: out = 4'b0001; // 只匹配 001 3'b0?1: out = 4'b0010; // 匹配 0x1 (x=0/1) 3'bz10: out = 4'b0100; // 匹配 x10 (x=0/1/z) default: out = 4'b0000; endcase endz和?被视为"不关心"位常用于优先级编码器
casex - 忽略所有未知值
// 匹配规则:忽略 x、z 和 ? always_comb begin casex(sel) 3'b001: out = 4'b0001; // 只匹配 001 3'b0x1: out = 4'b0010; // 匹配 0x1 (x=0/1/x/z) 3'bxx0: out = 4'b0100; // 匹配 xx0 (x=0/1/x/z) default: out = 4'b0000; endcase endx、z、?都被视为"不关心"位主要在testbench中使用
3. 实际应用示例
优先级编码器(推荐使用 casez)
// 4位优先级编码器 logic [3:0] request; logic [1:0] grant; always_comb begin casez(request) 4'b1???: grant = 2'b11; // 最高位优先 4'b01??: grant = 2'b10; 4'b001?: grant = 2'b01; 4'b0001: grant = 2'b00; default: grant = 2'b00; endcase end避免使用 casex 的原因
// ❌ 潜在问题:仿真与综合不匹配 logic [1:0] state = 2'b0x; // 仿真时包含 x casex(state) 2'b0?: $display("Match"); // 会匹配,但综合后可能不会 // ... endcase4. 现代SystemVerilog推荐做法
使用unique case和priority case
// 1. 唯一case - 确保无重叠 unique case(sel) 2'b00: out = a; 2'b01: out = b; 2'b10: out = c; // 缺省2'b11会触发警告 endcase // 2. 优先级case - 工具识别优先级 priority casez(request) 4'b1???: grant = 3; 4'b01??: grant = 2; 4'b001?: grant = 1; 4'b0001: grant = 0; default: grant = 0; endcase5. 最佳实践指南
可综合代码中:
优先使用
case+unique/priority必要时使用
casez,但要明确注释避免使用
casex
Testbench中:
可使用
casex进行灵活的匹配但要注意可能隐藏仿真问题
安全使用 casez 的模式:
// 明确使用 ? 作为不关心位 always_comb begin casez({valid, opcode}) {1'b1, 5'b000?1}: // 明确标记 {1'b0, 5'b?????}: // 明确标记 // ... endcase end常见陷阱:
// ❌ 危险:可能意外匹配 casez(sel) 2'bz0: ... // 会匹配 00 和 10! // ✅ 安全:使用完整case case(sel) 2'b00, 2'b10: ... // 明确列出 endcase总结
精确匹配用
case - 最安全,首选需要通配符用
casez - 谨慎使用,用?明确标记Testbench用
casex - 避免在RTL中使用总是添加
unique/priority - 提高代码可读性和安全性必须要有
default - 除非使用unique case且已覆盖所有情况