例解阻塞赋值&非阻塞赋值

发布时间:2022-09-27 16:00

例解阻塞赋值&非阻塞赋值
先简单介绍一下阻塞赋值与非阻塞赋值:
1.非阻塞(Non_Blocking)赋值方式( 如 b <= a; )

  1. 块结束后才完成赋值操作。
  2. b的值并不是立刻就改变的。
  3. 这是一种比较常用的赋值方法。(特别在编写可综合模块时)
    2.阻塞(Blocking)赋值方式( 如 b = a; )
  4. 赋值语句执行完后,块才结束。
  5. b的值在赋值语句执行完后立刻就改变的。
  6. 可能会产生意想不到的结果。
    总结:
  7. 时序电路建模时,用非阻塞赋值。
  8. 锁存器电路建模时,用非阻塞赋值。
  9. 用 always 块建立组合逻辑模型时,用阻塞赋值。
  10. 在同一个 always 块中建立时序和组合逻辑电路时,用非阻塞赋值。
  11. 在同一个 always 块中不要既用非阻塞赋值又用阻塞赋值。
  12. 不要在一个以上的 always 块中为同一个变量赋值。
  13. 用$strobe 系统任务来显示用非阻塞赋值的变量值
  14. 在赋值时不要使用 #0 延迟
    代码说明:
    1.阻塞赋值形式1

module block1(clk,a,b,c);
input [2:0]a;
input clk;
output reg [2:0]b,c;

always@(posedge clk)
	begin
		b=a;
		c=b;				
	end

endmodule
例解阻塞赋值&非阻塞赋值_第1张图片
block1综合后RTL视图
2.阻塞赋值形式2
module block2(clk,a,b,c);
input [2:0]a;
input clk;
output reg [2:0]b,c;

always@(posedge clk)
	begin
		c=b;
		b=a;				
	end

endmodule
例解阻塞赋值&非阻塞赋值_第2张图片
block2综合后RTL视图
3.非阻塞赋值形式1
module no_block1(clk,a,b,c);
input [2:0]a;
input clk;
output reg [2:0]b,c;

always@(posedge clk)
	begin
		b<=a;
		c<=b;				
	end

endmodule
例解阻塞赋值&非阻塞赋值_第3张图片
no_block1综合后RTL视图
4.非阻塞赋值形式2
module no_block2(clk,a,b,c);
input [2:0]a;
input clk;
output reg [2:0]b,c;

always@(posedge clk)
	begin
		c<=b;
		b<=a;				
	end

endmodule
例解阻塞赋值&非阻塞赋值_第4张图片
no_block2综合后RTL视图
在modelsim中仿真tb文件:
`timescale 1ns/1ns
module compare_tb;
reg [2:0]a;
reg clk;
wire [2:0]b1,b2,b3,b4,c1,c2,c3,c4;

block1 u0(
    .clk(clk),
    .a(a),
    .b(b1),
    .c(c1)
);
block2 u1(
    .clk(clk),
    .a(a),
    .b(b2),
    .c(c2)
);
no_block1 u2(
    .clk(clk),
    .a(a),
    .b(b3),
    .c(c3)
);
no_block2 u3(
    .clk(clk),
    .a(a),
    .b(b4),
    .c(c4)
);

initial begin
	clk=0;
	forever #10 clk=~clk;	
end 

initial begin
	a=3'd1;
	#100;
	a=3'd3;
	#100;
	a=3'd6;
	#100;
	a=3'd7;
	#200;
	$stop;	
end

endmodule
例解阻塞赋值&非阻塞赋值_第5张图片
对于block1使用阻塞赋值建模,因为always语句@符号后敏感事件使用边沿触发,所以b,c都是D触发器输出。由于是阻塞赋值,a赋值给b后,语句c=b;也立即会执行。
对于block2也是用阻塞赋值,但是顺序颠倒,begin-end是顺序执行,首先执行c=b;b的值是就是进入always语句时的值,即上升沿到来前的值,综合后RTL视图如图所示。
对于no_block1使用非阻塞赋值,进入always语句后,会使用各个变量的原始值将表达是右边值计算后并暂存,语句结束后b,c同时被更新。c<=b;用的是b的前一个值。
对于no_block2非阻塞赋值,顺序颠倒后对综合生成的电路无影响。
因此,阻塞赋值语句对语句的顺序具有依赖性,用它对时序电路建模存在一定风险,所以对时序逻辑电路建议使用非阻塞赋值。

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号