Verilog 的 full_case、parallel_case 有什么用?
一句话回答
full_case 和 parallel_case 是写在 case(...) 后面的综合指导指令(synthesis directive):full_case 告诉综合工具“没列出的输入取值都当无关项(don't care)”,从而避免因为分支不全而推断锁存器;parallel_case 声明“各分支互斥、可同时匹配的情况不存在”,允许工具综合成并行比较器而不是带优先级的选择链。但它们大多只被综合器识别、仿真器忽略,容易造成仿真与综合行为不一致,现代 SystemVerilog 应改用 unique/priority 关键字并显式写 default。
两个指令分别做什么
verilog
casez (sel) // synopsys full_case parallel_case
3'b001: y = a;
3'b010: y = b;
3'b100: y = c;
endcasefull_case:补齐“没列到的 sel 取值”,把它们当 don't care。否则sel=3'b000时y保持旧值 → 推断锁存器;加了指令工具认为输出可任意,综合成纯组合。parallel_case:若存在多个分支能同时命中(比如用casez带?通配),默认会按书写顺序生成优先级逻辑;声明并行后工具认为不会同时命中,可综合成更快的并行比较器。
为什么危险
- 仿真与综合不一致:很多仿真器把
// synopsys ...当普通注释忽略,于是仿真里分支不全仍保持旧值(像锁存器),门电路却被综合成组合或 don't care,前后仿真对不上,极难调试。 full_case让未列分支变成 don't care,硅上真出现该输入时输出不确定。parallel_case若分支其实不互斥,是你向工具撒了谎,会得到与预期不符的电路。
推荐做法
- 显式写
default:,而不是依赖full_case;意图清晰、仿真综合一致。 - SystemVerilog 用语义精确的关键字:
unique case:分支互斥且必须覆盖(仿真器还能在违例时报错);priority case:明确就是优先级编码。
- 组合输出在进入 case 前给默认值,彻底杜绝锁存器。
常见坑
- 只在综合指令上做文章、不写
default,导致前后仿真不一致。 - 把
parallel_case用在其实重叠的casez上,硬件行为错误。 - 误以为这两个指令是 Verilog 语法,其实是工具约定的注释,换 EDA 工具可能失效。
总结
full_case 让综合器把未列分支当无关项以避免锁存器、parallel_case 声明分支互斥以并行实现,但它们是只被综合器识别的注释、仿真器会忽略,极易制造前后仿真不一致;正确姿势是显式写 default、给组合输出预置默认值,并在 SystemVerilog 里用语义严格、仿真期可检查的 unique case/priority case 取代这两条历史指令。