代码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相加。
所以改进用组合逻辑。