在 Verilog 中,(* parallel_case *) 是一个综合指令,用于告诉综合工具某个 case 语句的所有分支是互斥的,不会同时匹配多个条件。
一、语法和作用
(* parallel_case *)
case (1'b1)
signal_a: out = value1;
signal_b: out = value2;
signal_c: out = value3;
endcase
二、主要用途
1. 优化优先级逻辑
告诉工具 case 分支是并行的,不需要生成优先级编码逻辑。
// 没有 parallel_case - 可能生成优先级逻辑
module without_parallel(
input [2:0] sel,
output reg [1:0] out
);
always @(*) begin
case (1'b1)
sel[0]: out = 2'b01; // 可能有优先级
sel[1]: out = 2'b10;
sel[2]: out = 2'b11;
endcase
end
endmodule
// 使用 parallel_case - 生成并行多路选择器
module with_parallel(
input [2:0] sel,
output reg [1:0] out
);
always @(*) begin
(* parallel_case *)
case (1'b1)
sel[0]: out = 2'b01; // 并行处理,无优先级
sel[1]: out = 2'b10;
sel[2]: out = 2'b11;
endcase
end
endmodule
三、典型应用场景
1. "case (1'b1)" 模式
这种模式常用于实现并行的多路选择:
module priority_encoder(
input [3:0] requests,
output reg [1:0] grant
);
always @(*) begin
(* parallel_case *)
case (1'b1)
requests[0]: grant = 2'b00; // 所有分支互斥
requests[1]: grant = 2'b01;
requests[2]: grant = 2'b10;
requests[3]: grant = 2'b11;
default: grant = 2'b00;
endcase
end
endmodule
2. 状态机设计
在明确知道状态互斥时使用:
module fsm_example(
input clk, rst,
input [1:0] state,
output reg [2:0] output_signal
);
always @(*) begin
(* parallel_case *)
case (state)
2'b00: output_signal = 3'b001;
2'b01: output_signal = 3'b010;
2'b10: output_signal = 3'b100;
2'b11: output_signal = 3'b111;
endcase
end
endmodule
四、电路实现差异
1. 没有 parallel_case
输入 → [比较器1] → [多路器]
[比较器2] ───┘
[比较器3] ───┘
(可能有优先级)
2. 使用 parallel_case
输入 → [比较器1] → [多路器]
[比较器2] → [多路器]
[比较器3] → [多路器]
(并行处理)
五、注意事项
1. ⚠️ 重要警告
// 危险示例:实际上不是并行的!
module risky_example(
input [1:0] a, b,
output reg out
);
always @(*) begin
(* parallel_case *) // 错误的假设!
case (1'b1)
(a == 2'b00): out = 1'b0;
(b == 2'b01): out = 1'b1; // a和b可能同时满足条件!
(a > b): out = 1'b1;
endcase
end
endmodule
2. 仿真与综合不一致
和 full_case 一样,仿真器会忽略 parallel_case 指令:
module simulation_issue(
input a, b,
output reg out
);
always @(*) begin
(* parallel_case *)
case (1'b1)
a: out = 1'b0;
b: out = 1'b1; // 仿真时如果 a 和 b 都为1,会执行第一个匹配的
endcase
end
endmodule
六、最佳实践
1. 确保真正的互斥性
只在确定所有分支确实互斥时使用:
// 安全的使用方式
always @(*) begin
(* parallel_case *)
case (1'b1)
(sel == 2'b00): out = a;
(sel == 2'b01): out = b;
(sel == 2'b10): out = c;
(sel == 2'b11): out = d;
endcase
end
2. 结合 full_case 使用
(* full_case, parallel_case *)
case (state)
STATE_IDLE: next_state = STATE_READ;
STATE_READ: next_state = STATE_PROCESS;
STATE_WRITE: next_state = STATE_IDLE;
endcase
3. 现代替代方案
考虑使用 unique case(SystemVerilog):
// SystemVerilog - 更好的选择
always_comb begin
unique case (sel)
2'b00: out = a;
2'b01: out = b;
2'b10: out = c;
2'b11: out = d;
endcase
end
七、总结
-
parallel_case告诉综合工具所有 case 分支互斥 -
可以优化掉优先级逻辑,生成更并行的电路
-
必须确保分支真正互斥,否则会导致功能错误
-
仿真器会忽略该指令,可能造成仿真与综合不一致
-
在现代设计中,推荐使用 SystemVerilog 的
unique case代替
1万+

被折叠的 条评论
为什么被折叠?



