在verilog HDL语言中的阻塞赋值和非阻塞赋值究竟有啥不同?同一变量在不同的过程块中(同时触发)又是如
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在verilog HDL语言中的阻塞赋值和非阻塞赋值究竟有啥不同?同一变量在不同的过程块中(同时触发)又是如相关的知识,希望对你有一定的参考价值。
在always语句块中,verilog语言支持两种类型的赋值:阻塞赋值和非阻塞赋值。阻塞赋值使用“=”语句;非阻塞赋值使用“<=”语句。注意,千万不要将这两种赋值方法与assign赋值语句混淆起来,assign赋值语句根本不允许出现在always语句块中。位于begin/end块内的多条阻塞赋值语句是串行执行的,这一点同标准的程序设计语言是相同的。但是多条非阻塞赋值语句却是并行执行的,这些非阻塞赋值语句都会在其中任何一条语句执行完成之前开始执行。这正是硬件电路的特点,因为实际的逻辑门电路都是独立运转的,而不是等到其他门电路运转结束之后自己才开始运转。
下面我们以描述移位寄存器的两种方法为例来讲述两种赋值类型的区别。在下面的这种描述中,第一个触发器中的数据被移到第二个触发器中,第二个触发器中的数据被移到第三个触发器中……如此继续下去,直到最后一个触发器中的数据被移出该寄存器为止。
1 module shiftreg (input clk,
2 input sin,
3 outout reg [3:0]q);//这是正确使用非阻塞赋值的实例
4 always @(posedge clk)
5 begin
6 q[0] <= sin;//非阻塞赋值:<=
7 q[1] <= q[0];
8 q[2] <= q[1]
9 q[3] <= q[2];
10 //这里写作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)。
关于你的第二个问题,虽然没有说完,但是我大概了解你的意思了。verilog中并不允许在两个always@语句中赋值同一个变量,道理就和不能把两个与门输出端接到一起一样。这时有三个解决方法:1.把其中一个always语句变为另一个模块,并在主程序中引用。2.利用中间变量,也就是增加寄存器的方法把需要重复赋值的变量存起来,再统一调用。3.更改语言进行编写,换用没有类似问题的语言,如VHDL,SYSTEM VERILOG等。 参考技术A always里用阻塞赋值,assign里用非阻塞赋值。
阻塞赋值在一个时间片内寄存器的值保持原来的值,当时间片结束时同时更新
阻塞赋值和非阻塞赋值
为尽量避免在综合布局布线后的仿真中出现冒险竞争现象,在编写Verilog代码时必须牢记以下8个原则:
1,时序电路建模时,用非阻塞赋值。
2,锁存器电路建模时,用非阻塞赋值。
3,用always块建立组合逻辑模型时,用阻塞赋值。
4,在同一个always块中建立时序和组合逻辑电路时,用非阻塞赋值。
5,在同一个always块中不要既用非阻塞赋值又用阻塞赋值。
6,不要在一个以上的always块中为同一个变量赋值。(新手几乎都会犯的错误,Vivado在综合时会报critical warning: multiple-driver)
7,用$strobe系统任务来显示用非阻塞赋值的变量值。
8,在赋值时不要使用 #0 延迟。
参考《Verilog数字系统设计教程 第四版 夏宇闻》
以上是关于在verilog HDL语言中的阻塞赋值和非阻塞赋值究竟有啥不同?同一变量在不同的过程块中(同时触发)又是如的主要内容,如果未能解决你的问题,请参考以下文章