#delay 如何用于 Verilog 非阻塞语句?
How does #delay work for Verilog non-blocking statements?
在第二个 $display
语句中 A
和 B
会打印什么?
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
,所以会在A
和B
解决后的下一个循环中执行。
假设我们处于周期#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
),更新后的值A
和B
将被打印出来.
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
),那么A
和B
的未更新值将被打印。
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(非阻塞分配)区域 之前,因此它将在同一时隙中具有非阻塞分配信号的原始值。
在第二个 $display
语句中 A
和 B
会打印什么?
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
,所以会在A
和B
解决后的下一个循环中执行。
假设我们处于周期#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
),更新后的值A
和B
将被打印出来.
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
),那么A
和B
的未更新值将被打印。
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(非阻塞分配)区域 之前,因此它将在同一时隙中具有非阻塞分配信号的原始值。