当事件发生时,对于代码块中的非阻塞赋值语句,先计算所有非阻塞语句在【事件发生时刻】的值,(即以<=右端表达式的值),最后才把计算出的值赋给<=左边的变量。
计算过程是以代码块中语句的书写顺序进行。虽有先后顺序,但<=右端表达式中变量的值均为【事件发生时刻】时的值。
C/C++ code?
1 2 3 4 5 6 | always @(posedge clk) begin // 时间点:clk上升沿事件发生时刻
a <= 1; // 事件发生时刻,a_temp = 1
a <= 2; // 事件发生时刻,a_temp = 2
a <= 3; // 事件发生时刻,a_temp = 3
end
// 在事件完成时刻,更新变量a的值 a = a_temp = 3
|
同一语句块中非阻塞重复赋值,虽然符合语法语义,但应杜绝出在在设计中。考察下面两语句块
C/C++ code?
1 2 3 4 5 6 7 8 9 10 11 12 13 | // 这段代码可以实现计数和清0
// 第2句只在条件满足时才对a_temp赋值为0,其它时候取第1句的赋值
always @(posedge clk) begin
a <= a + 1; // 事件发生时刻,a_temp =【事件发生时刻的a】+ 1
if ( a == 10 ) a <= 0; // 事件发生时刻,if(【事件发生时刻的a】== 10 ) a_temp = 0
end
// 这段代码只能实现计数,不能实现清零。
// 第2句任何时候都会再次对a_temp赋值为a+1,相当于第1句任何时候都不起作用
always@(posedge clk) begin
if ( a == 10 ) a <= 0; // 事件发生时刻,if(【事件发生时刻的a】== 10 ) a_temp = 0
a <= a + 1; // 事件发生时刻,a_temp =【事件发生时刻的a】+ 1
|