Verilog学习笔记——阻塞赋值与非阻塞赋值

阻塞:在本语句中“右式计算”和“左式更新”完全完成之后,才开始执行下一条语句;

非阻塞:当前语句的执行不会阻塞下一语句的执行,等式右边会在当前进程开始时更新,并在当前进程结束时对等式左边赋值。(这里的“进程”指的是,所有always块在当前时钟沿并行运行一次)

阻塞赋值语句是完全完成一条语句后,才执行下一次语句;非阻塞赋值语句是所有赋值语句同时进行。
在这里插入图片描述
如图,共有6个阻塞和非阻塞赋值,在功能性上(不考虑物理层面的延时),使用阻塞赋值的信号,不管其控制信号是由阻塞赋值还是非阻塞赋值得到的,均与控制信号在同一时刻跳变,即无延时。使用非阻塞赋值的信号,如果其控制信号是由阻塞赋值得到的,且正好在触发点(即上升沿处),则其与其控制信号在同一时刻跳变,即无延时;如果其控制信号是由非阻塞赋值得到的,不管是否正在处于出发点,则其都会比其控制信号慢一拍,即有延时。

控制信号由阻塞赋值得到的,受其控制的信号最快可以与其在同一时刻跳变;(无延时)
控制信号有非阻塞赋值得到的,受其控制的信号分两种情况得到:

  1. 由阻塞赋值得到,受其控制的信号最快可以与其在同一时刻跳变(无延时);
  2. 由非阻塞赋值得到,受其控制的信号最快只能在下一拍作出响应(有延时)。

实验代码

block_AND_non_block.v

module block_AND_non_block(
	input clk,
	input rst_n,
	
	input flag,
	input in,
	
	output block_out1,
	output block_out2,
	output block_out3,
	output reg non_block_out1,
	output reg non_block_out2,
	output reg non_block_out3
);

	assign block_out1 = (flag) ? in : 1'b0;
	assign block_out2 = (non_block_out1) ? in : 1'b0;
	assign block_out3 = (non_block_out2) ? in : 1'b0;
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n) begin
			non_block_out1 <= 1'b0;
		end else if(flag) begin
			non_block_out1 <= in;
		end else
			non_block_out1 <= 1'b0;
	end
	
	always@(posedge clk or negedge clk or negedge rst_n)begin
		if(!rst_n) begin
			non_block_out2 <= 1'b0;
		end else if (non_block_out1) begin
			non_block_out2 <= in;
		end else 
			non_block_out2 <= 1'b0;
	end
	
	always@(posedge clk or negedge clk or negedge rst_n)begin
		if(!rst_n) begin
			non_block_out3 <= 1'b0;
		end else if (non_block_out2) begin
			non_block_out3 <= in;
		end else 
			non_block_out3 <= 1'b0;
	end
	
endmodule

测试代码

block_AND_non_block_tb.v

`timescale  1ns/1ns
module block_AND_non_block_tb();
	reg clk;
	reg rst_n;
	
	reg flag;
	reg in;
	
	wire block_out1;
	wire block_out2;
	wire block_out3;
	wire non_block_out1;
	wire non_block_out2;
	wire non_block_out3;
	
block_AND_non_block uu1(
	.clk(clk),
	.rst_n(rst_n),
	.flag(flag),
	.in(in),
	.block_out1(block_out1),
	.block_out2(block_out2),
	.block_out3(block_out3),
	.non_block_out1(non_block_out1),
	.non_block_out2(non_block_out2),
	.non_block_out3(non_block_out3)
);

initial begin
	clk = 1'b0;
	rst_n = 1'b0;
	in = 1'b0;
	flag = 1'b0;
	
	#10 
	rst_n = 1'b1;
	
	#20
	flag = 1'b1;
	in = 1'b1;
	#20
	in = 1'b1;
	#20
	in = 1'b0;
	#20
	in = 1'b1;
	#20
	in = 1'b0;
	flag = 1'b0;
	
	#20
	in = 1'b1;
	
	#100
	$stop;
end

always #10 clk = ~clk;

endmodule

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值