always @(*)
#3 out1=in;
always @(*)
#3 out2<=in;
always @(*)
out3=#3 in;
always @(*)
out4<=#3 in;
assign #3 out5=in;
- 我们首先看第一个always块,当我们检测到in发生变化的时候,我们就会进入always块,进来之后第一件事就是延迟3个单位,然后再进行阻塞赋值。
- 延时3个单位以后,in的值为1,此时out1被赋值为1
- 紧接着in的值从1变成0,此时又会进入always块,延时3个单位,因此in在1个单位以后从0变成1这个变化always块其实是检测不到的。
- 延时3个单位以后,in的值为1,此时out1保持不变,仍然为1
- in从1变成0,进入always块,延时3个单位,out1的值被赋值为0
接下来我们看第二个always块,我们可以看到第二个always块为非阻塞赋值,但是此时该always块只有这一条赋值语句,而延时是带阻塞过程的,需要过3个时间单位才执行后面的非阻塞赋值语句,因此out2的变化其实跟out1是没有区别的。
我们再来看第三个always块,这个赋值语句相当于把in当前的值赋值给out3,但是要过3个时间单位才会执行。并且由于是阻塞赋值,会在赋值语句当中进行等待。
变化过程如下
- in从0变化成1,被赋值给out3,但是过3个时钟单位才会执行
- in从1变化成0,被赋值给out3,但是过3个时钟单位才会执行,此时always块被阻塞,无法感知1ns以后的输入信号变化。
- 过了3个时钟单位以后in的值为1保持不变,因此不会进入always块
- in的值从1变成0,被赋值给out3,但是过3个时钟单位才会执行
接下来我们看最后一个always块,和第三个always块的区别在于它是非阻塞赋值。因此当我们把in的值赋值给out3,虽然要过3个时钟单位才会执行,但是此时已经从赋值语句当中跳出来了,所以always块此时是能检测到信号变化的。
in从0变化成1,被赋值给out4,但是过3个时钟单位才会执行,此时always块仍然对信号变化敏感
in从1变化成0,被赋值给out4,但是过3个时钟单位才会执行,此时always块仍然对信号变化敏感
过了1个时钟单位以后in的值为0变成1,因此会进入always块,in的值被赋值给out3,但是过3个时钟单位才会执行。
in的值从1变成0,被赋值给out4,但是过3个时钟单位才会执行。
最后我们看assign赋值语句,其实它跟第一个always块类似,当感受到信号变化的时候,会阻塞3个时钟周期,再把当前的in赋值给out5,因此它的波形如图所示
都看到这儿了,点个赞呗
||
\/