verilog 阻塞赋值与非阻塞赋值

良好的代码风格推荐:

1.组合逻辑尽量采用阻塞逻辑

2.时序逻辑尽量采用非阻塞赋值

3.同一个always模块中尽量不要混用组合逻辑和时序逻辑。

4.阻塞逻辑是 =  ,语句按顺序执行,后一语句等待前一语句执行完之后才执行,所以称之为阻塞

5.非阻塞逻辑是 <=  ,语句同时执行,所以通常称之为非阻塞

下面给出两个例子说明:

1.对于组合逻辑

用阻塞赋值得到如下程序:

module non_blocking(
input a,
input b,
input c,
input d,
output out
    );

	reg t1,t2,out;

	always@(a or b or c or d) begin
		t1=a & b;
		t2=c & d;
		out=t1 | t2;	
	end

endmodule

当a,b,c,d同时由0变为1时,out变为1,按顺序执行,没有延时。

用非阻塞赋值得到如下程序:

module non_blocking(
input a,
input b,
input c,
input d,
output out
    );

	reg t1,t2,out;
	always@(a or b or c or d or t1 or t2) begin
		t1<=a & b;
		t2<=c & d;
		out<=t1 | t2;	
	end	

endmodule

用非阻塞赋值,敏感列表中必须添加t1和t2,因为这三句语句同时执行,第三句并不是等前两句执行完才执行。

上面两行代码得到的仿真图形都如下所示:

2.对于时序逻辑

实现移位寄存器,用阻塞逻辑得到如下程序:

module block1(q0,q1,q2,q3,din,clk);

input clk,din; 
output reg q0,q1,q2,q3;

always @(posedge clk)
begin  	
    q3=q2; //注意赋值语句的顺序
    q2=q1;
    q1=q0;
    q0=din;
end 
endmodule

对于阻塞逻辑,只要颠倒上面赋值顺序,便不能按照我们的想法实现移位寄存器。

对于非阻塞逻辑得到如下程序:

module block4(q0,q1,q2,q3,din,clk);

input clk,din; 
output reg q0,q1,q2,q3;

always @(posedge clk)
begin 	
    q3<=q2;
    q1<=q0;
    q2<=q1;
    q0<=din;
end  
endmodule

颠倒顺序不影响结果。

重要!!!!!!!

阻塞赋值和非阻塞赋值是指一个begin...end中的语句是按顺序执行还是同时执行,与延时没有关系!!

组合逻辑和时序逻辑的重要区别是时钟信号在不在敏感列表中!!

猜你喜欢

转载自blog.csdn.net/yanxiaopan/article/details/82495275