#delay 如何用于 Verilog 非阻塞语句?

How does #delay work for Verilog non-blocking statements?

在第二个 $display 语句中 AB 会打印什么?

module blocking;

reg[0:7] A, B;

initial begin
   A = 3;
   #1 A = A + 1; 
   B = A + 1;
   $display("Blocking: A= %d B= %d", A, B ); // A = 4, B = 5
   A = 3;
   #1 A <= A + 1;
   B <= A + 1;
   #1 $display("Non-blocking: A= %d B= %d", A, B ); // A = ?, B = ?
end
endmodule

Verilog 中的事件调度如何处理延迟和非阻塞语句?

因为你在第二条$display语句之前有#1,所以会在AB解决后的下一个循环中执行。

假设我们处于周期#1。

A = 3; // at #1
#1 // (does not matter) --> #2
A <= A + 1; // #2 will do A + 1 and wait till the end of the cycle 
B <= A + 1; // #2 same as above
// at the end of the cycle #2 (nba scheduling bucket) before switching to #3 
//    A and B will be assigned '4'
#1 // --> #3
// new values of A and B are available here (4)
$display("Non-blocking: A= %d B= %d", A, B );

在第二个$display中,由于你把显示放在另一个时间段(#1),更新后的值AB将被打印出来.

module blocking;
   reg[0:7] A, B;
   
   initial begin
     A = 3;
#1   A = A + 1; 
     B = A + 1;
     $display("Blocking: A = %0d B = %0d", A, B ); // A = 4, B = 5
     A = 3;
#1   A <= A + 1;
     B <= A + 1;
#1   $display("Non-blocking: A = %0d B = %0d", A, B ); // A = ?, B = ?
   end
endmodule

输出:

Blocking: A = 4 B = 5
Non-blocking: A = 4 B = 4

但是如果你把$display放在同一个时间段(没有#1),那么AB的未更新值将被打印。

module blocking;
   reg[0:7] A, B;
   
   initial begin
     A = 3;
#1   A = A + 1; 
     B = A + 1;
     $display("Blocking: A = %0d B = %0d", A, B ); // A = 4, B = 5
     A = 3;
#1   A <= A + 1;
     B <= A + 1;
     $display("Non-blocking: A = %0d B = %0d", A, B ); // A = ?, B = ?
   end
endmodule

输出:

Blocking: A = 4 B = 5
Non-blocking: A = 3 B = 5

原因是 Verilog 中的事件调度。

$display 被安排在 活动区域 ,它在 NBA(非阻塞分配)区域 之前,因此它将在同一时隙中具有非阻塞分配信号的原始值。