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