部分抄自李锐博恩博客:https://blog.csdn.net/Reborn_Lee/article/details/107888798
·timescale 定义仿真时间单位与精度,1ns是时间单位,即在仿真中用#10表示延迟10ns。1ps表示时间精度,比如你写 #3.5547968525 a <= 1;c <= 1;,那么它时间精度也只会有1ps(即在3.555ns时赋值语句便生效)。
module top_module;
reg a, b, c, q;
initial begin
$monitor("[%0t] a=%0b b=%0b c=%0b q=%0b", $time, a, b, c, q);
// Initialize all signals to 0 at time 0
a <= 0;
b <= 0;
c <= 0;
q <= 0;
// Inter-assignment delay: Wait for #5 time units
// and then assign a and c to 1. Note that 'a' and 'c'
// gets updated at the end of current timestep
#5 a <= 1;
c <= 1;
// Inter-assignment delay: Wait for #5 time units
// and then assign 'q' with whatever value RHS gets
// evaluated to
#5 q <= a & b | c;
#20;
end
endmodule
仿真结果
解读:0时刻结束时,a,b,c,q非阻塞赋值,全部被赋值为0;
延迟5ns结束后,a,c,非阻塞赋值,被赋值为1;
再延迟5ns结束时,q被非阻塞赋值。
Inter-assignment delay: Wait for #5 time units and then assign a and c to 1. Note that ‘a’ and ‘c’ gets updated at the end of current timestep
这是很基础的一句话,这句话说明了Verilog这门语言的基本特点,或者说Verilog中非阻塞赋值的基本特点,如下:
// Inter-assignment delay: Wait for #5 time units
// and then assign a and c to 1. Note that 'a' and 'c'
// gets updated at the end of current timestep
#5 a <= 1;
c <= 1;
这条语句,在第5ns时候虽然给a与c均赋值了1,但是此刻并不生效,而会在当前时间步长结束时生效,例如,我们在此刻加一个语句,使用a与c的值:
// Inter-assignment delay: Wait for #5 time units
// and then assign a and c to 1. Note that 'a' and 'c'
// gets updated at the end of current timestep
#5 a <= 1;
c <= 1;
q <= a&c;
对上面这句话的理解可以是,在5ns这一时刻,将1这个值传递给a和c,但是传递总是需要时间的,而在5ns这一时刻,会捕获a&c的值,然后将这个值传递给q。捕获时还没来得及更新,自然是捕获的旧值。
module tb;
reg a, b, c, q;
initial begin
$monitor("[%0t] a=%0b b=%0b c=%0b q=%0b", $time, a, b, c, q);
// Initialize all signals to 0 at time 0
a <= 0;
b <= 0;
c <= 0;
q <= 0;
// Inter-assignment delay: Wait for #5 time units
// and then assign a and c to 1. Note that 'a' and 'c'
// gets updated at the end of current timestep
#5 a <= 1;
c <= 1;
// Intra-assignment delay: First execute the statement
// then wait for 5 time units and then assign the evaluated
// value to q
q <= #5 a & b | c;
#20;
end
endmodule
在第5ns时候,a,b,q右边的值同时捕获,a和c在第5s被非阻塞赋值,也就是在第5ns末有效。
第5ns时,q值捕获到右边的表达式值,为0,然后再经过5秒,把这个0赋值给q.即q是在第5秒捕获到数据,但是在第10秒被赋值。
为了对比,我们在第5ns时,对a和c都进行阻塞赋值:
#5 a = 1;
c = 1;
q <= a & b | c;
#5 q <= a & b | c;
a = 1;
c = 1;
其实,阻塞赋值非阻塞赋值的本质区别就是。阻塞赋值,捕获完一个赋值一个,然后进行下一个,后面的赋值过程会被前一个堵住;而非阻塞赋值,全部同时捕获,然后同时赋值,赋值过程没有前后之分。
通过上面两个图,我们可以看出,当阻塞赋值,非阻塞赋值同时使用时,阻塞赋值会阻塞非阻塞赋值,非阻塞赋值内部还是同时捕获同时赋值。
#5 a = 1;
c = 1;
q <=#5 a & b | c;
这个的话,就是先阻塞赋值,将a,c进行赋值,然后同时在5ns这个时刻捕获q的值,然后再过5ns将这个值赋值给q。因为q的捕获被a,c的赋值过程给阻塞了,所以q捕获的是a,q的新值。