用一个例子来学习阻塞赋值和非阻塞赋值

Posted noticeable

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用一个例子来学习阻塞赋值和非阻塞赋值相关的知识,希望对你有一定的参考价值。

阻塞赋值与非阻塞赋值

阻塞赋值的一般表达式为:目标变量名=驱动表达式  阻塞赋值是一种理想化的数据传输,赋值立即发生,不存在延时行为

非阻塞赋值一般表达式为:目标变量名<=驱动表达式   非阻塞赋值比较接近真实的电路工作状态,应为他从综合的角度考虑到了延时和并行性。

 

在过程启动中,非阻塞赋值使三条语句同时运行,而阻塞赋值是按顺序方式完成更新的数据的。

 

 

 

 

新建工程,编写示例代码

 

module block_nonblock(clk,rst_n,a,b,c,out );
input clk,rst_n,a,b,c;


output reg [1:0]out;//out=a+b+c>2,所以out应该为2位

reg [1:0] d;//定义一个中间变量
//d=a+b;
//out=d+c
always@(posedge clk or negedge rst_n)
if(!rst_n)

out=2\'b0;

else begin
d=a+b;
out=d+c;
end

endmodule

 

 

 

 从RTL 视图可以看出整个运行过程是顺序执行的。

改变

d=a+b;
out=d+c;的赋值顺序,再观察RTL视图,会发现两者之间是有区别的,这说明顺序决定着输出的结果。

 

 

 

将赋值语句改为非阻塞赋值。

 

观察RTL视图,会发现两者是有明显不同。

 

同样的改变

d<=a+b;
out<=d+c;的赋值顺序,再观察RTL视图,会发现两者之间是没有区别的,这说明顺序并没有决定输出的结果。

 

由RTL图理论上可以看出两种赋值语句的不同,下面编写testbench进行仿真。

`timescale 1ns/1ns
module block_nonblock_tb;
`define clock_period 20

reg clock,rst_n,a,b,c;
wire [1:0] out ;
block_nonblock block_nonblock0(clock,
rst_n,
a,
b,
c,
out    );//这里采用一一对应的调用方式

initial clock=1\'b0;
always#(`clock_period/2) clock=~clock;//产生时钟信号
initial begin
rst_n=1\'b0;
a=0;b=0;c=0; //赋值激励信号
#(`clock_period*200+1)

rst_n=1\'b1;
a=0;b=0;c=1; 
#(`clock_period*200)
a=0;b=1;c=0; 
#(`clock_period*200)
a=0;b=1;c=1; 
#(`clock_period*200)
a=1;b=0;c=0; 
#(`clock_period*200)
a=1;b=0;c=1; 
#(`clock_period*200)
a=1;b=1;c=0; 
#(`clock_period*200)
a=1;b=1;c=1; 
#(`clock_period*200)
#(`clock_period*200)
$stop;
end

endmodule

 

 设定文件路径后按前面的四个程序进行前仿。

 

 

d=a+b;
out=d+c;

 

out=d+c;
d=a+b;

 


d<=a+b;
out<=d+c;

 

out<=d+c;
d<=a+b;

 


通过仿真可以看出四种情况的异同,至此阻塞赋值和非阻塞赋值就可以通过实际例子来理解了。

以上是关于用一个例子来学习阻塞赋值和非阻塞赋值的主要内容,如果未能解决你的问题,请参考以下文章

阻塞赋值和非阻塞赋值有何区别

verilog阻塞赋值和非阻塞赋值的区别

verilog中为啥非阻塞赋值要用绝对时延

在 verilog中的非阻塞赋值在啥时候赋值时刻结束?

verilog中阻塞赋值和非阻塞赋值的区别

verilog中时序逻辑和非阻塞赋值的内在联系是啥? 都说时序逻辑用非阻塞赋值,这是啥决定的?