FPGA学习笔记4-阻塞辅助和非阻塞赋值的区别(小梅哥)

代码1及对应RTL视图
module block_nonblock(Clk,Rst_n,a,b,c,out);

	input Clk;
	input Rst_n;
	input a,b,c;
	output reg [1:0]out;

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

endmodule

代码2及对应RTL视图
module block_nonblock(Clk,Rst_n,a,b,c,out);

	input Clk;
	input Rst_n;
	input a,b,c;
	output reg [1:0]out;

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

endmodule

代码3及对应RTL视图
module block_nonblock(Clk,Rst_n,a,b,c,out);

	input Clk;
	input Rst_n;
	input a,b,c;
	output reg [1:0]out;

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

endmodule

代码4 及对应RTL视图
module block_nonblock(Clk,Rst_n,a,b,c,out);

	input Clk;
	input Rst_n;
	input a,b,c;
	output reg [1:0]out;

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

endmodule

对比四种RTL视图,只有代码一的RTL视图不一样。

testbench文件

`timescale 1ns/1ns

`define clock_period 20

module block_nonblock_tb;

	reg Clock;
	reg Rst_n;
	reg a,b,c;
	
	wire [1:0]out;
	
	block_nonblock block_nonblock0(
	Clock,
	Rst_n,
	a,
	b,
	c,
	out);
	
	initial Clock = 1;
	always#(`clock_period/2)Clock=~Clock;
	
	initial begin
		Rst_n = 1'b0;
		a = 0;
		b = 0;
		c = 0;
		#(`clock_period*200+1);
		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
接下来修改block_nonblock.v文件,模拟电路延时
`timescale 1ns/1ns
`define tp 1
module block_nonblock(Clk,Rst_n,a,b,c,out);

	input Clk;
	input Rst_n;
	input a,b,c;
	output reg [1:0]out;

	reg [1:0] d;
	
	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		out = #`tp 2'b0;
	else begin
		d <= #`tp a + b;
		out <= #`tp c + d;
		
		
	end

endmodule

可以看到a为0,b为1的时候,d并不是马上变成1,而是有一个电路延时。

通过模拟的电路延迟,使我们在看波形的时候更容易理解。因为实际情况一定会有电路延迟。

后仿真验证

放大要观察的部分,这一次d从0变成1,是由于上升沿到来,检测到b为1,a为0,c为0,即d的值为0。d的值并没有马上变成0,而是有一段延迟。

结论

非阻塞的这两行代码,并没有先后顺序。

out的值,只跟前一时刻的c ,d有关。

代码改进,用组合逻辑

这是没有改进前的效果,此时a=0,  b=1, c=0。检测到上升沿之后,d的值变成1,但是out值还是变成了0,知道下一个上升沿,out的值才变成1。  

造成这一拍的延迟的原因:a与b的和,通过d触发器,再跟c相加。

所以改进用组合逻辑。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值