<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
在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
else begin
testout <= testd;
end
end
end
endmodule
例1综合后的结果为
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
例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
else begin
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. 非阻塞式赋值用于时序逻辑建模。
(谢谢,偷懒了,害人不浅啊 已更新)
用户425250 2013-12-24 19:14
用户199800 2009-4-11 15:18
sunke9_998892717 2009-4-10 08:03
用户1441579 2009-4-1 17:34
用户1113192 2007-11-25 09:25
用户123067 2007-11-24 22:11
用户1071875 2007-10-24 11:48
阻塞和非阻塞例子写的有点问题,都成一样了
还有就是阻塞能用在时序逻辑里?
用户1113192 2007-10-18 18:35
不好意思。各位从我的163的博客里直接摘过来的,图片看不到,不好意思。我重新上传了图片。给大家个直观的印象