Verilog 嵌套 "if" 语义
Verilog nested "if" semantics
下面两个代码块有什么区别?当我实施和 运行 它们时,我得到了不同的结果。但根据我个人的理解,它们在语义上应该是相同的。
M_state_d = M_state_q;
M_mx_d = M_mx_q;
V1
-----
PUSH_READ_state: begin
if ((&M_ctr_q)) begin
if ((&M_mx_q)) begin
M_state_d = POP_state;
M_mx_d = 1'h0;
end
M_state_d = PUSH_state;
end
end
V2
-----
PUSH_READ_state: begin
M_state_d = ((&M_ctr_q) && (&M_mx_q)) ? POP_state : ((&M_ctr_q) ? PUSH_state : M_state_q);
M_mx_d = ((&M_ctr_q) && (&M_mx_q)) ? 1'h0 : M_mx_q;
end
编辑:
好的,所以我将 V1 更改为
PUSH_READ_state: begin
if ((&M_ctr_q)) begin
M_state_d = PUSH_state; // I MOVED THIS
if ((&M_mx_q)) begin
M_state_d = POP_state;
M_mx_d = 1'h0;
end
end
end
并且行为变得相同。这是为什么?
考虑 &M_ctr_q && &M_mx_q
时您的原始代码中发生了什么。 M_state_d
的两项分配都将发生:
PUSH_READ_state: begin
if ((&M_ctr_q)) begin
if ((&M_mx_q)) begin
M_state_d = POP_state; // <- Assignment 1
M_mx_d = 1'h0;
end
M_state_d = PUSH_state; // <- Assignment 2
end
end
换句话说,当 &M_ctr_q
为真时,由于分配的顺序,您将始终分配 M_state_d = PUSH_state
(阻塞分配最后一个获胜)。
您的 V1 代码更新是避免该问题的一种解决方案,但您可能更愿意使分配更加明确(即使用 else
):
PUSH_READ_state: begin
if ((&M_ctr_q && &M_mx_q)) begin
M_state_d = POP_state;
M_mx_d = 1'h0;
end
else if (&M_ctr_q) begin
M_state_d = PUSH_state;
end
end
下面两个代码块有什么区别?当我实施和 运行 它们时,我得到了不同的结果。但根据我个人的理解,它们在语义上应该是相同的。
M_state_d = M_state_q;
M_mx_d = M_mx_q;
V1
-----
PUSH_READ_state: begin
if ((&M_ctr_q)) begin
if ((&M_mx_q)) begin
M_state_d = POP_state;
M_mx_d = 1'h0;
end
M_state_d = PUSH_state;
end
end
V2
-----
PUSH_READ_state: begin
M_state_d = ((&M_ctr_q) && (&M_mx_q)) ? POP_state : ((&M_ctr_q) ? PUSH_state : M_state_q);
M_mx_d = ((&M_ctr_q) && (&M_mx_q)) ? 1'h0 : M_mx_q;
end
编辑:
好的,所以我将 V1 更改为
PUSH_READ_state: begin
if ((&M_ctr_q)) begin
M_state_d = PUSH_state; // I MOVED THIS
if ((&M_mx_q)) begin
M_state_d = POP_state;
M_mx_d = 1'h0;
end
end
end
并且行为变得相同。这是为什么?
考虑 &M_ctr_q && &M_mx_q
时您的原始代码中发生了什么。 M_state_d
的两项分配都将发生:
PUSH_READ_state: begin
if ((&M_ctr_q)) begin
if ((&M_mx_q)) begin
M_state_d = POP_state; // <- Assignment 1
M_mx_d = 1'h0;
end
M_state_d = PUSH_state; // <- Assignment 2
end
end
换句话说,当 &M_ctr_q
为真时,由于分配的顺序,您将始终分配 M_state_d = PUSH_state
(阻塞分配最后一个获胜)。
您的 V1 代码更新是避免该问题的一种解决方案,但您可能更愿意使分配更加明确(即使用 else
):
PUSH_READ_state: begin
if ((&M_ctr_q && &M_mx_q)) begin
M_state_d = POP_state;
M_mx_d = 1'h0;
end
else if (&M_ctr_q) begin
M_state_d = PUSH_state;
end
end