FPGA入门笔记005——阻塞赋值和非阻塞赋值的区别

发布时间 2023-11-21 16:40:02作者: Yamada_Ryo

定义一个示例模组,代码如下:

module block_nonblock(
	Clk,
	Rst_n,
	a,
	b,
	c,
	out
);
	
	input Clk;
	input Rst_n;
	input a,b,c;
	output reg[1:0]out;
	
	//out = a + b + c,out最大为3,所以设置为两位;
	
	//d = a + b;
	//out = d + c;
	
	reg [1:0]d;

阻塞赋值:

阻塞赋值1:

功能代码如下:

	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		out = 2'b0;
	else begin
		d = a + b;
		out = d + c;
	end

RTL视图如下:

微信截图_20231121143145

阻塞赋值2:

功能代码如下:

	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		out = 2'b0;
	else begin
		out = d + c;	//更改代码顺序
		d = a + b;
	end

RTL视图如下:

微信截图_20231121143624

可以看见,当代码顺序不同时,RTL视图也不同,其out的结果和代码顺序有关。

非阻塞赋值

非阻塞赋值1:

功能代码如下:

	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		out <= 2'b0;
	else begin
		out <= d + c;
		d <= a + b;
	end

RTL视图如下:

微信截图_20231121143948

非阻塞赋值2:

功能代码如下:

	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		out <= 2'b0;
	else begin
		d <= a + b;	//更改代码顺序
		out <= d + c;
	end

RTL视图如下:

微信截图_20231121144134

可以看见,当代码顺序不同时,RTL视图相同,其out的输出结果和代码顺序无关。

后仿真结果如下:

微信截图_20231121162147

当时钟信号处于上升沿1时:

a=0,b=1,随后d经过一段时间的延时从00->01;

d=00,c=0,随后out经过一段时间的延时从01->00;

当时钟处于上升沿2时:

a=0,b = 1,随后d不变;

d=01,c=0,随后out经过一段时间的延时从00->01;

所以非阻塞赋值时,其out的输出结果只与时钟信号处于上升沿时 d 的状态和 c 的状态有关。