• 关于veriolg中阻塞与非阻塞赋值问题


    在一开始学到阻塞和非阻塞的时候,所被告知的两者的区别就在于阻塞是串行的,非阻塞是并行的。但是虽然知道这个不同点,有些时候还是很难真正区分用两者电路的区别,在这就通过几个例子来解释一下。

    以一个简单的串行流水线寄存器为例:d-q1-q2-q3.

    1,采用阻塞赋值

    代码:always @ (posedge clk) begin q1=d; q2=q1; q3=q2; end

    这样的代码将会导致每一个寄存器输出都是d,即d将无延时的传送给q3(即q3=d)。因为采用的是阻塞赋值,当时钟上升沿到来时,先执行q1=d,再执行q2=q1。以此类推,最后所以寄存器的值都变成了d.反映到电路中的结果就是一个单独的直接从d到q3的寄存器,不符合流水线要求。

    2,依然采用阻塞赋值,但是赋值顺序有变化

    代码:always @ (posedge clk) begin q3=q2; q2=q1; q1=d; end

    当我们改变赋值顺序后,综合的电路是符合要求的。当上升沿到来,先执行q3=q2,则q3的值是上一个时钟沿时q2的值。类似的,当上升沿到来后,每个寄存器的值都往后移动了一位,也就实现了预期的流水线结构。但是这样的缺点就在于我们要仔细的安排赋值的顺序,容易出错,且增加工作量。

    3,采用非阻塞赋值

    代码:always @ (posedge clk) begin q1<=d; q2<=q1; q3<=q2; end

    由于非阻塞赋值是并发执行的,当时钟沿到来时,每个寄存器更新的值都是赋值寄存器在上一个时钟沿所被赋予的值,也就真正实现了流水线的结构。而且采用非阻塞赋值的好处在于,不用想阻塞赋值一样需要考虑赋值顺序问题。

    另外一个问题是,为什么在组合逻辑中需要使用阻塞赋值?

    在大多数情况下,都应该使用非阻塞赋值,这也比较符合电路并发执行的特点。但是在组合逻辑中并不一定。

    例如:

    always @ (a or b or c or d) begin

    temp1<=a & b;

    temp2<=c & d;

    y<=temp1 | temp2;

    end

    在这个组合逻辑中,我们希望实现的是先将ab相与,cd相与,再将产生的temp1,temp2相或。但由于采用的是非阻塞赋值,是并发执行的。当执行y<=temp1 | temp2时,temp1,temp2的值并未更新,也就是说y输出的是上一个触发时temp1 | temp2的值,即延后了一次触发。

    而如果此时采用阻塞赋值的话,则能正确实现电路。

    不过对于这个问题,我还是觉得并不是说组合逻辑导致要使用阻塞赋值,而是说电路功能决定到底使用哪种。即便上面的例子是时序电路,如果要实现相同的逻辑,则依然要用阻塞赋值。而如果你是使用类似之前提到的移位的功能,则即便用的是组合逻辑,也需要用非阻塞赋值。

    至于为什么会有组合电路用阻塞的说法,应该是大部分时候组合逻辑功能需要阻塞赋值,且这是一个规范吧,毕竟规范有时候不是很好解释,但是却在工作中大有裨益。当然,这只是我个人观点,有不同意见者希望不吝指教。

  • 相关阅读:
    行为的封装
    分页功能-----》链表实现
    python入门教程链接
    作用域 属性链接 存储类型
    Codeforces Round #598 (Div. 3)
    CCPC2018-湖南全国邀请赛
    【洛谷P2494】 [SDOI2011]保密(分数规划+最小割)
    【洛谷P3329】 [ZJOI2011]最小割(最小割树)
    【BZOJ3716】[PA2014]Muzeum(贪心+网络流)
    【洛谷P4542】 [ZJOI2011]营救皮卡丘(费用流)
  • 原文地址:https://www.cnblogs.com/flyuea/p/8421596.html
Copyright © 2020-2023  润新知