0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

阻塞赋值和非阻塞赋值的用法一篇文章就够了

汽车玩家 来源:FPGA技术联盟 作者:Jarvis 2020-01-30 17:41 次阅读

对于VerilogHDL语言中,经常在always模块中,面临两种赋值方式:阻塞赋值和非阻塞赋值。对于初学者,往往非常迷惑这两种赋值方式的用法,本章节主要介绍这两种文章的用法。其实,有时候概念稍微不清楚,Bug就会找到我们,下面一文扫清阻塞赋值和非阻塞赋值所有的障碍。

基本概念

阻塞赋值(Blocking Assignment)

阻塞赋值的基本描述格式为:

[变量] = [逻辑表达式];

阻塞赋值在执行的时候,右端表达式执行并赋值到左边变量,不会受任何情况打断。所以在本次赋值结束之前他“阻塞”了当前其他的赋值任务,阻塞赋值的操作和C语言中的变量赋值非常相似。

非阻塞赋值(Nonblocking assignment)

非阻塞赋值的基本描述格式为:

[变量] 《= [逻辑表达式];

非阻塞赋值行为有些细微之处比较难以理解。我们最好从硬件角度来理解,always模块可以被认为是纯硬件模块,当always模块被激活时,非阻塞赋值的右侧表达式就开始执行;当always模块所有表达式执行结束之后,所有执行结果才赋值到左侧变量当中。之所以称为“非阻塞”就是在本条赋值语句执行的过程中,其他赋值语句也可以执行。

金规

1. 在组合逻辑电路描述中采用阻塞赋值

阻塞赋值和非阻塞赋值虽然都可以用来描述同一电路,以1位比较器举例来解释这种差别。

阻塞赋值实现1bit比较器

module eq1_block

input wire i0, i1,

output reg eq

);

reg p0, p1;

always @(i0,i1) // i0 和i1 在敏感量列表当中

// 语句描述的顺序非常关键

begin

p0 = ~i0 & ~i1;

p1 = i0 & i1;

eq = p0 | p1;

end

endmodule

分析:程序中,敏感量列表中包含i0和i1,只要这两个变量有一个发生改变,都会激活always语句,那么p0、p1和eq就会顺序赋值,最终eq赋值就会被更新,所以这三条语句的描述顺序非常关键,假如将最后一条语句提前:

always @(i0,i1)

begin

eq = p0 | p1;

p0 = ~i0 & ~i1;

p1 = i0 & i1;

end

在第一条描述中,由于p0和p1还没有被赋予新值,所以p0和p1依然保持原来的赋值,这样得到的最终结果显然是错误的。

非阻塞赋值实现1bit比较器

module eq1_non_block

input wire i0, i1,

output reg eq

);

reg p0, p1;

always @(i0,i1,p0,p1) // p0, p1依然在敏感量列表中

// 描述顺序无关紧要

begin

p0 《= ~i0 & ~i1;

p1 《= i0 & i1;

eq 《= p0 | p1;

end

endmodule

分析:p0和p1包含在敏感量列表当中,当i0 或者 i1有所变化,always模块被激活,p0和p1在第一个时钟节拍结束时赋值,由于eq值为基于p0和p1原来保持值的赋值,所以eq不变,当前赋值结束时,always模块重新被激活,由于p0和p1被改变(这就是p0和p1放在敏感量列表中的原因),eq变量在第二个时钟节拍赋予了新值。从以上分析,即使将以上语句的顺序发生改变,也不会影响最终结果,因为eq的赋值以及always模块的激活与这些语句的顺序并没关系。

总结:虽然两种描述方法都可以描述同一电路,但是两个电路的结果是有区别的,采用非阻塞赋值法描述仿真的时候花的时间更长一些,电路输出结果在时序上也有微弱差别,鉴于此,我们有这么一条原则“在组合逻辑电路描述中采用阻塞赋值”。

2. 时序逻辑描述,采用非阻塞赋值方式赋值

就单独一个寄存器来说,阻塞赋值和非阻塞赋值都可以描述存储单元,如DFF可以描述为

always@(posedge clk)

q 《= d;

也可以描述为

always@(posedge clk)

q = d;

但是当设计中存在多个寄存器描述单元的时候,就会有细微的查别,假设有两个寄存器在每个时钟的上升沿进行数据交换,采用阻塞赋值描述如下:

always@(posedge clk)

a = b;

always@(posedge clk)

b = a;

在时钟的上升沿,两个always语句同时被激活并且并行执行,一个时钟节拍后两条语句执行结束,按照verilog语法标准,两个always语句执行结果时间顺序上谁都有可能在前面,这样一来,如果第一个always语句执行在前面,由于阻塞赋值,所以变量a立即得到b的赋值,那么当第二个always块执行之后,变量b得到a的赋值,由于刚才第一个always执行的时候b值赋予了a,所以现在b的值会维持不变,还是原来的值。

同样的道理,如果第二个always模块先执行了,那么a就会保持自身值不变,从Verilog语法角度来看,两种结果都是有效的。但是从数字电路的角度来说,明显引起了竞争。

下面我们将阻塞赋值修改为非阻塞赋值,以上代码修改为:

always@(posedge clk)

a 《= b;

always@(posedge clk)

b 《= a;

采用非阻塞赋值,由于原始信号在赋值语句中使用,所以a和b都会得到正确的值,而与顺序没有关系。所以在时序逻辑描述中,阻塞赋值往往会引起条件竞争,所以要采用非阻塞赋值方式赋值。

总结一下

① 在组合逻辑电路描述中采用阻塞赋值

② 时序逻辑描述,采用非阻塞赋值方式赋值

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 阻塞赋值
    +关注

    关注

    0

    文章

    9

    浏览量

    9156
  • VerilogHDL
    +关注

    关注

    2

    文章

    39

    浏览量

    19075
收藏 人收藏

    评论

    相关推荐

    socket编程中的阻塞阻塞

    在网络编程中, socket 是个非常重要的概念,它提供了个抽象层,使得开发者可以不必关心底层的网络通信细节。 socket 编程中的阻塞
    的头像 发表于 11-01 16:13 128次阅读

    Verilog HDL的基础知识

    本文继续介绍Verilog HDL基础知识,重点介绍赋值语句、阻塞阻塞、循环语句、同步与异步、函数与任务语法知识。
    的头像 发表于 10-24 15:00 168次阅读
    Verilog HDL的基础知识

    socket阻塞阻塞的区别是什么

    在计算机编程中,socket 是种通信端点,用于在网络中进行数据传输。Socket 可以是阻塞的或阻塞的,这两种模式在处理数据传输时有不同的行为。
    的头像 发表于 08-16 11:13 574次阅读

    请问使用lwip创建socket,该如何做到阻塞的接收发送数据?

    请问使用lwip创建socket,该如何做到阻塞的接收发送数据?
    发表于 06-19 06:02

    关于Verilog的些基本语法

    、always@(边沿触发):阻塞赋值语句,对应时序逻辑电路。G、always@(电平触发):阻塞赋值语句,对应组合逻辑电路。 注意:
    发表于 05-31 18:31

    为什么指针之间不要随意赋值呢?

    指针之间也不能随意赋值
    的头像 发表于 03-28 17:13 495次阅读
    为什么指针之间不要随意<b class='flag-5'>赋值</b>呢?

    什么是阻塞阻塞

    什么是阻塞阻塞?我们就用管道的读写来举例子。
    的头像 发表于 03-25 10:04 464次阅读

    如何在8051单片机上编程阻塞延迟函数?

    术语阻塞意味着微控制器的主代码在整个延迟期间被阻塞(什么都不做)。对于小的延迟和简单的问题,这通常是可以接受的,但可能导致不可接受的操作。
    发表于 02-29 11:48 721次阅读

    mapgis如何给区属性赋值

    MapGIS是款功能强大的地理信息系统软件,它提供了丰富的功能和工具,使用户能够对地理数据进行快速、高效的管理和分析。其中个重要的功能就是给区属性赋值,即对地图中的区域进行分类和标记,以便更好
    的头像 发表于 02-23 17:49 2061次阅读

    proteus属性赋值工具怎么用

    Proteus是种电路设计和仿真软件,在进行电路设计和仿真时,属性赋值是非常重要的步骤。属性赋值工具可以帮助用户快速有效地配置电路元件的属性,从而实现电路的准确仿真。下面是关于Proteus属性
    的头像 发表于 02-23 17:19 4068次阅读

    verilog同步和异步的区别 verilog阻塞赋值阻塞赋值的区别

    Verilog是种硬件描述语言,用于设计和模拟数字电路。在Verilog中,同步和异步是用来描述数据传输和信号处理的两种不同方式,而阻塞赋值
    的头像 发表于 02-22 15:33 1526次阅读

    oracle sql 定义变量并赋值

    赋值可以通过使用PL/SQL语句块或使用SQL*Plus工具来实现。下面将详细介绍这两种方法以及它们的具体用法。 使用PL/SQL语句块定义和赋值变量: 在Oracle SQL中,PL/SQL是
    的头像 发表于 12-06 10:46 2664次阅读

    SIMATIC S7-1500 PLC S7-SCL赋值详解

    通过赋值个变量接受另个变量或者表达式的值。在赋值运算符“;=”左边的是变量,该变量接受右边的地址或者表达式的值。
    的头像 发表于 11-29 09:24 3081次阅读

    python用input赋值多个变量

    在Python中,可以使用 input 函数从用户那里获取输入,并将输入赋值给变量。当用户输入多个值时,可以使用空格、逗号或其他分隔符将它们分开。下面将详细介绍如何使用 input 函数赋值多个变量
    的头像 发表于 11-23 15:37 3123次阅读

    python循环创建变量并赋值

    循环是Python编程中非常重要的个概念,它可以让我们轻松地重复执行某些代码块,从而简化编程过程并提高代码的效率。在循环中,我们经常需要创建变量并赋值,这是非常常见的操作。接下来,我将详尽地解释在
    的头像 发表于 11-23 14:51 1609次阅读