FPGA学习 -通过波形图来看阻塞赋值和非阻塞赋值的区别

本文章采用阻塞赋值和非阻塞赋值对比的方式来讨论二者的区别,利用简单的例程+波形图直观查看细小差别。

1.模块文件:

module block_nonblock(clk50M,rst_n,a,b,c,out);

input clk50M;
input rst_n;
input a;                 //实现a+b+c=out,拆分成两部。一步是定义d且d=a+b,另一布是out=c+d
input b;
input c;
output reg [1:0]out;     //out最大是3,所以两位足够

reg [1:0] d;             //只要用到这个d,就增加了一步寄存a+b的过程(肯定意味着延时)

always@(posedge clk50M or negedge rst_n) begin
	if(!rst_n)
		out=2'd0;
	else begin
		d=a+b;           //情况1;情况2(out=d+c;d=a+b;);情况3(d<=a+b;out<=d+c;);情况4(out<=d+c;d<=a+b;)
		out=d+c;
	end
end

endmodule

        注: 情况1:阻塞赋值顺序;

                情况2:阻塞赋值逆序;

                情况3:非阻塞赋值顺序;

                情况4:非阻塞赋值逆序;

2.testbench文件: 

`timescale 1ns/1ps
`define clock_period 20 

module block_nonblock_tb;

	reg clk;
	reg rst_n;
	reg a;
	reg b;
	reg c;
	wire [1:0] out;

	block_nonblock block_nonblock0(
	.clk50M(clk),
	.rst_n(rst_n),
	.a(a),
	.b(b),
	.c(c),
	.out(out)
	);

	initial clk=1;
	always #(`clock_period/2) clk=~clk;
	initial begin
		rst_n=0;
		a=0;
		b=0;
		c=0;
		#201;
		rst_n=1;
		#(`clock_period*200);
		a=0;b=0;c=0;
		#(`clock_period*200);
		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

3.RTL电路图:

 

 

 

前两幅图可以看出,阻塞赋值时,语句顺序不同电路也会不同。后两幅图非阻塞赋值时,语句顺序改变时,电路稳定不变化。

4.波形图:

这是非阻塞赋值顺序情况3的波形图。可以看到由于d寄存器的缘故,如果d变化那么out将在下一拍发生变化(由于那个寄存器的缘故,使得out运算只与前一时刻的运算结果有关,而与当前无关,所以虽然顺序为out<=d+c;d<=a+b;,但是out只认上一个always@(posedge clk)中发生的事也就是只取决于上一个d和c。)。而且d和out所有的变化都不是在检测到时钟上升沿的一瞬间,是由于后仿真接近实际情况,会有电路延时。

5.非阻塞赋值的优化手段(从算法入手):

为什么out延时一拍才输出?就是因为多加了一句d<=a+b(从电路图上看,就是多加了一个寄存器),如果想要去掉这个延时,只需out<=a+b+c(即去掉这个寄存器)。这样a+b+c就完全是一个组合逻辑,不存在延迟。

6.总结:

在设计电路时应该避免设计阻塞赋值。因为阻塞赋值时,“语句顺序”的不同会生成不同的电路,这就造成了电路是一种不太确定的状态,顺序不同电路就会不同。

推荐采用非阻塞赋值,语句是并行的,而且不论“语句顺序”怎么样,电路结构都是唯一确定的。如果想优化设计,只需从算法上修改。

 

 

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值