Verilog阻塞/非阻塞赋值电路角度解读

Verilog阻塞/非阻塞赋值电路角度解读



  • 对于具有一定软件基础的同学来说,赋值无非是将等号右边的数字赋给等号左边的变量。那么什么是阻塞/非阻塞赋值呢?在Verilog中,阻塞赋值和非阻塞赋值应用于截然不同的代码逻辑中。
  • 阻塞赋值用于组合逻辑(即无记忆数字逻辑电路,其任何时刻的输出仅取决于输入的组合),其在块内按顺序执行;而非阻塞赋值用于时序逻辑(任何一个时刻的输出状态由当时的输入信号和电路原来的状态共同决定),在块内并行执行。

  本文将站在电路角度上对阻塞与非阻塞赋值进行深入解读,希望大家能够知其然并知其所以然。本文将从综合区别/仿真时序/常见问题三部分进行介绍。


综合区别

   在我的理解中,阻塞和非阻塞是为了区分连线“wire”和D触发器的赋值。同样是赋值,在时序逻辑和组合逻辑中,其综合出来的电路结构是不同的。

  • &阻塞赋值‘=’,其综合结果是一根简单的导线,将上下级连接起来。最简单的阻塞赋值代码如下所示。
always @(*)begin
    b = a;
end

   对block进行综合,得到的就是简单的a与b的连线,而b可以是DFF/锁存器或连接线,其赋值将是每时每刻的。

在这里插入图片描述

  • 非阻塞赋值则截然不同,将阻塞赋值代码进行简单修改,得到非阻塞赋值代码。
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        b <= 1'b0;
    else 
        b <= a;
end

   综合出来将会是下图这样一个DFF采样电路,上一级的值被一个边沿触发的D触发器采样并保持,只在边沿的瞬间赋值。
在这里插入图片描述

  • 阻塞和非阻塞赋值取决于设计者希望赋值是边沿瞬间还是不间断的。

时序区别

   基于上述综合区别的理解,理解时序区别将变得简单。为什么阻塞赋值需要等block中前置的逻辑结束后才能执行,而非阻塞赋值可以同时执行?

always @(*)begin
    b[3:0] = a[3:0];
    c[3:0] = b[3:0];
end
  • 上述组合逻辑,实际电路将是一个串行的导线,从下图波形中也能看出,电路需要先将a值传递到b后,才能将b值传递给a,所以最后是c=a,这就是阻塞赋值的含义。
    在这里插入图片描述
    更改为非阻塞赋值,代码如下。
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        b[3:0] <= 4'h0;
        c[3:0] <= 4'h0; //wechat bug!
    end
    else begin
        b[3:0] <= a[3:0];
        c[3:0] <= b[3:0];
    end
end
  • 综合后的电路为两个边沿触发的D触发器,采样发生在边沿,只与触发前瞬间的输入有关,所以波形看起来会慢上一拍

在这里插入图片描述

常见问题

   在清楚区分阻塞和非阻塞逻辑后,入门阶段常会犯的一个错误——使用阻塞累加器,代码如下。


always @(*)begin
    a[3:0] = a[3:0] + 4'b1;
end
  • 这样的阻塞型累加器,会形成一个组合逻辑环路,累加在环路中不断运行,导致结果无法预测。因此,在进行类似电路设计时,应使用非阻塞赋值构成D触发器达到设计要求。




  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值