verilog阻塞非阻塞赋值在always语句中的表现
通常书上说组合逻辑要用阻塞赋值,时序逻辑要用非阻塞赋值,但偏偏有些人写代码喜欢在组合逻辑里边用非阻塞,时序逻辑里边用阻塞,有时还混用,看的让人头大,今天我就专门写个博客记录一下这个阻塞非阻塞在组合逻辑和时序逻辑中的效果,以后我头大的时候还能回来看看。。。
不多bb,直接放代码和仿真图
测试文件
module test(
input clk,
input rst_n,
output reg a,
output reg b,
output reg c,
output reg d,
output reg aa,
output reg bb,
output reg cc,
output reg dd
);
always @(posedge clk or negedge rst_n)begin
if(rst_n == 'b0)begin
a <= 'b0;
aa <= 'b0;
end
else begin
a <= 'b1;
aa <= a;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n == 'b0)begin
b = 'b0;
bb = 'b0;
end
else begin
b = 'b1;
bb = b;
end
end
always @(*)begin
if(rst_n == 'b0)begin
c = 'b0;
cc = 'b0;
end
else begin
c = 'b1;
cc = c;
end
end
always @(*)begin
if(rst_n == 'b0)begin
d <= 'b0;
dd <= 'b0;
end
else begin
d <= 'b1;
dd <= d;
end
end
endmodule
激励文件
module tb;
reg clk;
reg rst_n;
wire a;
wire b;
wire c;
wire d;
wire aa;
wire bb;
wire cc;
wire dd;
initial begin
clk = 0;
rst_n = 0;
#100
rst_n = 1;
end
always #5 clk = ~clk;
test test_inst(
.clk (clk ),
.rst_n (rst_n ),
.a (a ),
.b (b ),
.c (c ),
.d (d ),
.aa (aa ),
.bb (bb ),
.cc (cc ),
.dd (dd )
);
endmodule
modelsim仿真结果

总结
从波形图可以发现:
always @(*)
描述的是组合逻辑,不管里边用阻塞赋值(=)还是非阻塞赋值(<=),都是阻塞的效果。而
[email protected](posedge clk or negedge rst_n)
是时序逻辑,其中阻塞赋值和非阻塞赋值是起作用的,阻塞赋值可以理解成一堆组合逻辑连接了一个D触发器的结构,非阻塞可以看成时流水线结构。