打印

Verilog中阻塞与非阻塞式赋值解惑

[复制链接]
2155|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
FangTT|  楼主 | 2013-1-15 21:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Verilog中阻塞与非阻塞式赋值是比较让初学者难以理解的两种赋值方式,今天我就来谈一谈它们之间的区别:
使用过VHDL的朋友都知道,VHDL中信号使用非阻塞式 ,而变量类似于阻塞赋值。
阻塞式过程赋值与非阻塞式过程赋值在Verilog中表示如下:
c = a & b; 阻塞式过程赋值
c <= a & b; 非阻塞式过程赋值
两种赋值不会对语句本身的赋值有影响,但会影响以后对赋值结果的引用。一般的参考书中建议组合逻辑使用阻塞式,时序逻辑使用非阻塞式。且语句块 中如果只有一条赋值语句,是阻塞还是非阻塞都没有任何不一样。
非阻塞式过程赋值的赋值对象是在未来(即当前仿真时刻结束时)被赋值。
下面我们具体分析一下阻塞和非阻塞赋值的语义本质:
阻塞:在本语句中“右式计算”和“左式更新”完全完成之后,才开始执行下一条语句;
非阻塞:当前语句的执行不会阻塞下 一语句的执行。
先看阻塞赋值的情况:
我们来看这段代码:


always语句块对Clk的上升沿敏感,当发生Clk 0~1的跳变时,执行该always语句。
在begin...end语句块中所有语句是顺序执行的,而且最关键的是,阻塞赋值是在本语句中“右式计算”和“左式更新”完全完成之后,才开 始执行下一条语句的。
在本例中,D的值赋给Q1以后,再执行Q2 = Q1;同样在Q2的值更新以后,才执行Q3 = Q2。这样,最终的计算结果就是Q3 = D。
所有的语句执行完以后,该always语句等待Clk的上升沿,从而再一次触发begin...end语句。
接下来,再看看非阻塞赋值的情况。
所谓非阻塞赋值,顾名思义,就是指当前语句的执行不会阻塞下一语句的执行。


首先执行Q1 <= D,产生一个更新事件,将D的当前值赋给Q1,但是这个赋值过程并没有立刻执行,而是在事件队列中处于等待状态。
然后执行Q2 <= Q1,同样产生一个更新事件,将Q1的当前值(注意上一语句中将D值赋给Q1的过程并没有完成,Q1还是旧值)赋给Q2,这个赋值事件也将在事件队列中处 于等待状态。
再执行Q3 <= Q2,产生一个更新事件,将Q2的当前值赋给Q3,这个赋值事件也将在事件队列中等待执行。
这时always语句块执行完成,开始对下一个Clk上升沿敏感。
那么什么时候才执行那3个在事件队列中等待的事件呢?只有当当前仿真时间内的所有活跃事件和非活跃事件都执行完成后,才开始执行这些非阻塞赋值 的更新事件。这样就相当于将D、Q1和Q2的值同时赋给了Q1、Q2和Q3。
注:
*仿真器首先按照仿真时间对事件进行排序,然后再在当前仿真时间里按照事件的优先级顺序进行 排序。
*活跃事件是优先级最高的事件。在活跃事件之间,它们的执行顺序是随机的。阻塞赋值(=)、 连续赋值(assign)以及非阻塞赋值的右式计算等都属于活跃事件。

相关帖子

沙发
GoldSunMonkey| | 2013-1-15 22:59 | 只看该作者
感谢分享

使用特权

评论回复
板凳
xjsxjtu| | 2013-1-16 23:09 | 只看该作者
GoldSunMonkey 发表于 2013-1-15 22:59
感谢分享

不错啊

使用特权

评论回复
地板
Dick00| | 2013-1-17 14:10 | 只看该作者
这个讲解及这个例子还是比较不错的,很贴切。具体来说就是阻塞式赋值为立即执行语句,对后续语句有影响,非阻塞赋值为非即时性赋值,不影响后面的引用。

使用特权

评论回复
5
GoldSunMonkey| | 2013-1-17 21:11 | 只看该作者
Dick00 发表于 2013-1-17 14:10
这个讲解及这个例子还是比较不错的,很贴切。具体来说就是阻塞式赋值为立即执行语句,对后续语句有影响,非 ...

你的头像,我很喜欢啊:loveliness:

使用特权

评论回复
6
qin552011373| | 2013-1-17 23:30 | 只看该作者
不错的资料  感谢

使用特权

评论回复
7
jakfens| | 2013-1-18 09:49 | 只看该作者
:D

使用特权

评论回复
8
GoldSunMonkey| | 2013-1-19 22:50 | 只看该作者
qin552011373 发表于 2013-1-17 23:30
不错的资料  感谢

别客气兄弟

使用特权

评论回复
9
GoldSunMonkey| | 2013-1-19 22:50 | 只看该作者
jakfens 发表于 2013-1-18 09:49

笑什么呢

使用特权

评论回复
10
jakfens| | 2013-1-20 20:43 | 只看该作者
GoldSunMonkey 发表于 2013-1-19 22:50
笑什么呢

就看看:D

使用特权

评论回复
11
GoldSunMonkey| | 2013-1-20 22:06 | 只看该作者
jakfens 发表于 2013-1-20 20:43
就看看

哈哈,软件装上了么??

使用特权

评论回复
12
qingniao966| | 2013-1-20 22:17 | 只看该作者
GoldSunMonkey 发表于 2013-1-20 22:06
哈哈,软件装上了么??

关心我一下啊

使用特权

评论回复
13
GoldSunMonkey| | 2013-1-20 22:25 | 只看该作者
qingniao966 发表于 2013-1-20 22:17
关心我一下啊

我去

使用特权

评论回复
14
Dick00| | 2013-1-21 11:21 | 只看该作者
GoldSunMonkey 发表于 2013-1-17 21:11
你的头像,我很喜欢啊

我媳妇!不能随便乱喜欢

使用特权

评论回复
15
小狼君君| | 2013-1-21 13:35 | 只看该作者
GoldSunMonkey 发表于 2013-1-20 22:06
哈哈,软件装上了么??

没装上

使用特权

评论回复
16
jakfens| | 2013-1-22 10:06 | 只看该作者
GoldSunMonkey 发表于 2013-1-20 22:06
哈哈,软件装上了么??

:lol 我这个账号bug了 登录不了 所以用了小号

使用特权

评论回复
17
tongzhezhe| | 2013-1-22 14:37 | 只看该作者
非阻塞的例子里说always执行完了,不去执行更新?那什么时候执行更新?那句活跃性和非活跃性事件完成太理论了点,不懂。是指整个模块,不是单个的always语句?

使用特权

评论回复
18
GoldSunMonkey| | 2013-1-22 21:54 | 只看该作者
小狼君君 发表于 2013-1-21 13:35
没装上

还有小号 。天。哈哈

使用特权

评论回复
19
GoldSunMonkey| | 2013-1-22 21:54 | 只看该作者
jakfens 发表于 2013-1-22 10:06
我这个账号bug了 登录不了 所以用了小号

没下下来?

使用特权

评论回复
20
wmsk| | 2013-1-23 22:22 | 只看该作者
Dick00 发表于 2013-1-17 14:10
这个讲解及这个例子还是比较不错的,很贴切。具体来说就是阻塞式赋值为立即执行语句,对后续语句有影响,非 ...

真的很不错啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

45

主题

172

帖子

4

粉丝