verilog中的阻塞赋值与非阻塞赋值详解

更新时间:2023-07-16 22:40:06 阅读: 评论:0

verilog中的阻塞赋值与⾮阻塞赋值详解
⽹上看到的觉得不错分享下
组合逻辑的always模块中使⽤阻塞赋值;
与音乐有关的成语时序逻辑的always模块中使⽤⾮阻塞赋值;
可以这样理解,组合中计算马上赋值,时序逻辑中上升沿计算,下降沿赋值
关键是组合逻辑中是实时变化的,⽽时序逻辑中⼀个cycle才变化⼀次
⽐如:
always @(a or b)
毁灭英语
begin
c = a + b;
end
always @(podge clk)
begin
if(rst)
c <= 0;
el
c <= a + b;
end
在组合逻辑的always block中,a和b的变化都会引起c值的变化;
⽽时序逻辑中c⾄少会维持⼀个clock cycle,也就是说如果a和b的变化导致c变化的时间是在下⼀个clock的上升沿,⽽不会让c⽴刻改变
阻塞赋值“=”与⾮阻塞赋值“<=”的本质区别在于:
⾮阻塞赋值语句右端表达式计算完后并不⽴即赋值给左端,⽽是同时启动下⼀条语句继续执⾏,可以将其理解为所有的右端表达式RHS1、RHS2等在进程开始时同时计算,计算完后,等进程结束时同时分别赋给左端变量LHS1、LHS2等;
⽽阻塞赋值语句在每个右端表达式计算完后⽴即赋给左端变量,即赋值语句LHS1=RHS1执⾏完后LHS1是⽴即更新的,同时只有LHS1=RHS1执⾏完后才可执⾏语句LHS1=RHS2,依次类推。前⼀条语句的执⾏结果直接影响到后⾯语句的执⾏结果。
补充⽂章:
在always语句块中,verilog语⾔⽀持两种类型的赋值:阻塞赋值和⾮阻塞赋值。阻塞赋值使⽤“=”语句;⾮阻塞赋值使
⽤“<=”语句。注意,千万不要将这两种赋值⽅法与assign赋值语句混淆起来,assign赋值语句根本不允许出现在always语句块中。
位于begin/end块内的多条阻塞赋值语句是串⾏执⾏的,这⼀点同标准的程序设计语⾔是相同的。但是多条⾮阻塞赋值语句却是并⾏执⾏的,这些⾮阻塞赋值语句都会在其中任何⼀条语句执⾏完成之前开始执⾏。这正是硬件电路的特点,因为实际的逻辑门电路都是独⽴运转的,⽽不是等到其他门电路运转结束之后⾃⼰才开始运转。
下⾯我们以描述移位寄存器的两种⽅法为例来讲述两种赋值类型的区别。在下⾯的这种描述中,第⼀个触发器中的数据被移到第⼆个触发器中,第⼆个触发器中的数据被移到第三个触发器中……如此继续下去,直到最后⼀个触发器中的数据被移出该寄存器为⽌。
1
module
shiftreg (
input大意失荆州
clk,
2
input
sin,高校毕业生就业服务管理系统
3
outout
reg
[
3
:
]q);
//
这是正确使⽤⾮阻塞赋值的实例 4
always
@(
podge
clk)
5
begin
6
q[
]
<=
黄家驹经典歌曲大全sin;
//
穹顶之下电影
⾮阻塞赋值:<=
7
q[
1
]
<=
q[
];
8
q[
2
]
<=
q[
1
]
9
q[
孩子的缺点3
]
<=
q[
2
//
这⾥写作q <= {q[2:0],sin};更简单更好⼀些
11
end
12
endmodule
⾮阻塞赋值语句的功能是使得所有语句右侧变量的值都同时被赋给左侧的变量。因此,在上⾯的实例中,q[1]得到的是q[0]的原始值,⽽⾮sin的值(在第⼀条语句中,sin的值被赋给了q[0])。这正是我们期望得到的实际硬件电路。当然,我们可以把上边的四条语句合并写成⼀条简短的语句:q<={q[2:0],sin}。
阻塞赋值语句的功能更接近于传统的程序设计语⾔,但是阻塞赋值语句并不是准确的硬件⼯作模型。下⾯考虑使⽤阻塞赋值语句来实现同⼀模块可以得到什么结果。在始终clk的上升沿,verilog将会把sin的值赋给q[0],然后q[0]的新值被赋给q[1],如此继续执⾏下去。最终所有的四个寄存器都会得到相同的值:sin的值。
本部分内容⽤意在于:讲述使⽤always语句块对时序逻辑电路进⾏建模的时候,如何使⽤⾮阻塞赋值。如果设计者能够充分的灵活应⽤,⽐如倒转上例中四条语句的顺序,那么使⽤阻塞赋值语句仍然能实现相应的功能,但是与使⽤⾮阻塞赋值的⽅法相⽐,这种⽅法并不会带来任何好处,相反还暗藏了巨⼤的风险。
最后需要注意的是:每个always语句块都隐含表⽰⼀个独⽴的逻辑电路模块。因此,对于特定的reg类型的变量,只能在⼀个always语句块中对其进⾏赋值;否则就可能会出现两个硬件模块同时从同⼀个输出端⼝输出数据的情况,这种情况⼀般称为短路输出(shorted output)。
过程赋值语句多⽤于对reg型变量进⾏复制,过程赋值有阻塞复制和⾮阻塞赋值两种。⾮阻塞赋值的符号为:<=
阻塞赋值符号为:=
(1)⾮阻塞赋值的例⼦:
reg c,b;
clk)
begin
b <= a;
c <= b;
end
(2)阻塞赋值的例⼦:
reg c,b;
always @ (podge clk)
begin
b = a;
c = b;
end
上述例⼦中,使⽤⾮阻塞赋值⽅法,其中的每个<=都可以理解为⼀个寄存器。⽽在同⼀个时钟下⾯采
⽤的⾮阻塞赋值⽅法,模块内所有寄存器都同时随时钟跳变。这是硬件处理的精髓,也是时序电路中⼤量使⽤⾮阻塞赋值的原因。
在实际书写verilogHDL代码的过程中,对于always中reg型变量,如果不是处理组合逻辑,尽量不使⽤阻塞赋值的⽅法。这主要是基于代码的可综合性考虑的,因为在verilog HDL代码编译的时候,对于有些从后编译的编译器,阻塞赋值会找成时序上与预想的不⼀致。对于以上阻塞赋值的例⼦,采⽤⾮阻塞⽅法应该写为
>如果芸知道

本文发布于:2023-07-16 22:40:06,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1084308.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:赋值   阻塞   语句   逻辑   时序   硬件
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图