阻塞赋值和非阻塞赋值
来源:互联网 发布:淘宝客成交计入权重吗 编辑:程序博客网 时间:2024/06/05 14:59
10
11
12
过程赋值语句多用于对reg型变量进行复制,过程赋值有阻塞复制和非阻塞赋值两种。
非阻塞赋值的符号为:<=
阻塞赋值符号为:=
(1)非阻塞赋值的例子:
reg c,b;
always@(posedge
clk) begin
b <= a;
c <= b;
end
(2)阻塞赋值的例子:
reg c,b;
always @ (posedge clk)
begin
b = a;
c = b;
end
上述例子中,使用非阻塞赋值方法,其中的每个<=都可以理解为一个寄存器。而在同一
个时钟下面采用的非阻塞赋值方法,模块内所有寄存器都同时随时钟跳变。这是硬件处理
的精髓,也是时序电路中大量使用非阻塞赋值的原因。
在实际书写verilogHDL代码的过程中,对于always中reg型变量,如果不是处理组合逻
辑,尽量不使用阻塞赋值的方法。这主要是基于代码的可综合性考虑的,因为在verilog
HDL代码编译的时候,对于有些从后编译的编译器,阻塞赋值会找成时序上与预想的不
一致。对于以上阻塞赋值的例子,采用非阻塞方法应该写为
reg c,b;
always @ (posedge clk)
begin
b <= a;
c <= a;
end
实现电路和原方法一样。
而在always用于组合逻辑中,采用阻塞赋值表明未使用寄存器。
如
reg a,A,B,f_a;
always @ (a or A or B)
begin
f_a = a ?A : B;
end
以下是使用阻塞和非阻塞赋值应遵循的一些基本原则,这些原则有利于防止竞态(race condition)的发生。
(1)当用always块来描述组合逻辑(combinationallogic)时,应当使用阻塞赋值。
(2)对于时序逻辑(sequentiallogic)的描述和建模,应当使用非阻塞赋值。
(3)在同一个always模块中,最好不要混合使用阻塞赋值和非阻塞赋值,对同一变量
既进行阻塞赋值,又进行非阻塞赋值,在综合时会出错。所以always中要么全部使用非
阻塞赋值,要么把阻塞赋值和非阻塞赋值分在不同的always中书写。
(4)尽量不要再在多个不同的always块中对同一变量赋值。
(5)使用$strobe显示使用非阻塞赋值的变量。
在Verilog HDL中,有两种过程性赋值方式,即阻塞式(blocking)和非阻塞式(non-blocking)。这两种赋值方式看似差不多,其实在某些情况下却有着根本的区别,如果使用不当,综合出来的结果和你所想得到的结果会相去甚远。
Tip:所谓过程性赋值就是指在initial或always语句内的赋值,它只能对寄存器数据类型的变量赋值。
阻塞式
(blocking) 的操作符为 “ = ” 非阻塞式(non-blocking)
的操作符为 “ <= ”首先,我们通过两个例子来看看这两种赋值方式的区别,这里使用的综合工具为Qt ii。
例1:非阻塞式赋值
module
test_non_blocking
(
input
clk, input
testa, input
testb, input
testc, input
testd, output
reg testout );
reg testreg;
always @ (posedge clk)
begin
testreg<= testb | testc;
begin
if(testa) begin
testout<= testreg & testd;
end
elsebegin
testout<= testd;
end
end end
endmodule
例1综合后的结果为
例2:阻塞式赋值
module
test_blocking
(
input
clk, input
testa, input
testb, input
testc, input
testd, output
reg testout );
reg testreg;
always @ (testa,testb.testc,testd)
begin
testreg = testb |testc;
begin
if(testa) begin
testout= testreg & testd;
end
elsebegin
testout= testd;
end
end end
endmodule
例2综合后的结果为:
分析:
可以看到,例1和例2的code写法完全一样,只是在always语句块中使用了不同的赋值方式,就导致综合出来的结果不同。
在例1中,是非阻塞式赋值方式,非阻塞式赋值的赋值对象总是在当前仿真时刻结束时被赋值,所以,当在对语句2中的testout赋值这一时刻,
testreg 值还没有得到语句1中的新值,而是原来的值(即上一个时刻的值)。 而在例2中,使用了阻塞式赋值方式,就是在always语句块中是一句一句执行的。在执行语句2之前,语句1就已经执行完成,testreg被赋好了新值,所以语句2中的testreg值取的是新值。
建议:
1.
阻塞式赋值用于组合逻辑建模; 2.
非阻塞式赋值用于时序逻辑建模。
- 阻塞赋值和非阻塞赋值
- 阻塞赋值和非阻塞赋值
- 阻塞赋值和非阻塞赋值
- 阻塞赋值和非阻塞赋值
- 阻塞赋值和非阻塞赋值
- 阻塞赋值和非阻塞赋值
- 阻塞赋值和非阻塞赋值
- 阻塞赋值和非阻塞赋值
- 阻塞赋值和非阻塞赋值
- 阻塞赋值和非阻塞赋值
- 阻塞赋值和非阻塞赋值
- 阻塞赋值和非阻塞赋值学习笔记
- verilog中阻塞赋值和非阻塞赋值的区别
- 阻塞(=)赋值和非阻塞(<=)赋值
- 关于阻塞赋值和非阻塞赋值的…
- Verilog中阻塞赋值和非阻塞赋值区别
- Verilog中的阻塞赋值和非阻塞赋值
- 阻塞与非阻塞赋值
- Ubuntu安装新版GCC并启用C++11
- 你知道我是是么
- Using the Input Subsystem, Part II
- javascript 事件监听以及冒泡
- 欢迎您在新浪博客安家
- 阻塞赋值和非阻塞赋值
- 考尔型电路设计中求连分式商的Matl…
- can't lanch the Modelsim-Altera …
- 自己编程第一次实现中断
- enum与typedef enum的用法
- 2014年03月19日
- 英语词典中的一些符号 意思
- 将博客搬至CSDN
- Error (10028): Can't resol…