关于阻塞赋值与非阻塞赋值的讨论

相信各位坛友在学习Verilog的时候,一定会接触到阻塞赋值与非阻塞赋值。我在刚开始学习该语言的时候,对这两个概念不是很理解。进过我自己的学习和参考资料,现在我对它们有了一定的加深。特把我的心得给分享一下。
1.阻塞赋值
使用阻塞赋值的时候,说明该赋值语句阻塞后面语句的执行,当赋值完成以后,后面的语句从继续执行。在always和initial的过程块中,该阻塞赋值的变量在后面还要使用。现在看看下面的例子
module DFF_lianjie(q1,q2,D,clock);
input D,clock;
output q1,q2;
reg q1,q2;

always @(posedge clock)
begin
      q1=D;
      q2=q1;
end
endmodule
这个例子是在时序逻辑逻辑电路中,使用两个D触发器进行级联。但是由于我们在其中使用阻塞赋值,由于前一个赋值刚完成,就要使用这个被赋值去给另外的变量赋值。所以在综合的结果中,我们就看不到两个D触发器级联的现象,而是看见了两个平行的D触发器,其中的D输入端分别连接到两个触发器的输入端。这个例子加深了我们对阻塞赋值的理解,同时也说明了在时序逻辑电路中,不应该使用阻塞赋值,而应该采用非阻塞赋值。
2.非阻塞赋值
与阻塞赋值的含义不同,非阻塞赋值不会阻塞后面的语句执行。在always与initial的过程块中,非阻塞赋值的结果必须要在该过程块的仿真完成的末位才看得见。考虑下面的例子。
module combination(a1,a2,a3,a4,f);
input a1,a2,a3,a4;
output f;
reg f;

always @(a1 or a2 or a3 or a4)
begin
     f<=a1&a2;
    f<=f+a3|a4;
end
endmodule
这个组合逻辑的本意是要实现f=a1&a2+a3|a4。但是由于我们在过程块中使用了非阻塞赋值,那么则在仿真的过程中。由于非阻塞赋值是在过程块的仿真末位才出现结果,故执行f<=f+a3|a4的时候,因为f<=a1&a2的结果此时没有被后面的赋值表达式给识别出,此时第二个表达式中右边中的f的值为仿真刚进入到过程块中的时候的值,所以导致了仿真结果的错误。从这个例子中我们对非阻塞赋值也加深了认识,也说明了在组合逻辑中应该使用阻塞赋值操作。
我也来说两句 查看全部回复

最新回复

  • amormio124 (2008-10-13 17:02:10)

    LZ的例子实在是太。。。
    最简单的规则:
    组合逻辑用阻塞赋值,
    时序逻辑用非阻塞赋值。
  • fpgaxxxx (2008-10-13 17:48:21)

    和书上说得一样                      
  • zhouhong0809 (2008-10-13 18:34:16)

    不好意思,我从书上转载的。也算是心得
  • dodo4599 (2008-10-13 22:37:15)

    呵呵 2句话就可以了
  • trido_yang (2008-10-14 13:50:16)

    楼主关于非阻塞赋值的程序说明说的不全面,
    在时序仿真后的功能f=a1&a2+a3|a4,就是我们预期的结果
    这里的阻塞赋值和非阻塞赋值的结果是一样的
    楼主说的情况只是在功能仿真时出现
    正是由于前后仿真的差异,在组合逻辑中才不建议用非阻塞赋值,而不是不能用非阻塞赋值