• Verilog基础:阻塞/非阻塞赋值


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



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

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


    综合区别

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

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

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

    在这里插入图片描述

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

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

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

    时序区别

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

    always @(*)begin
        b[3:0] = a[3:0];
        c[3:0] = b[3:0];
    end
    
    • 1
    • 2
    • 3
    • 4
    • 上述组合逻辑,实际电路将是一个串行的导线,从下图波形中也能看出,电路需要先将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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 综合后的电路为两个边沿触发的D触发器,采样发生在边沿,只与触发前瞬间的输入有关,所以波形看起来会慢上一拍

    在这里插入图片描述

    常见问题

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

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




  • 相关阅读:
    针对《VPP实现策略路由》的修正
    图解ReentrantLock底层公平锁和非公平锁实现原理
    计算机毕设 SpringBoot+Vue校园网新闻系统 新闻推荐系统 新闻发布管理系统Java Vue MySQL数据库 远程调试 代码讲解
    JVM原理:JVM运行时内存模型(通俗易懂)
    修谱是一件好事:薪火相传,让老一辈庇护和提携后辈,造福乡里宗亲
    Linux~一些基本开发工具的使用(yum,vim,gcc,gdb,makefile)
    贪心算法之阿里巴巴与四十大盗——背包问题
    K8SYaml文件详解及编写示例
    应该下那个 ActiveMQ
    【笔试刷题训练】day_14
  • 原文地址:https://blog.csdn.net/sz_woshishazi/article/details/126453090