参考思路:在b站看到一节课很好,这里附上链接,来源【零数电基础学FPGA】第二课:阻塞非阻塞赋值介绍、testbench及仿真
以下代码均来自上述课程。
阻塞赋值与非阻塞赋值的理解
testbench内容
`timescale 1ns / 1ps
module testbench();
reg clk = 1'b0;
reg a,b;
always #10 clk = !clk;
initial
begin
a = 1'b0;
b = 1'b1;
end
//例化
test test1(
.clk(clk),
.a(a),
.b(b)
);
endmodule
Verilog设计文件内容
module test(
input clk,
input a,
input b,
output reg y1,
output reg y2
);
reg m1 = 1'b0;
reg m2 = 1'b0;
always @(posedge clk)
begin
m1 = a+ b;
y1 = m1;
end
always @(posedge clk)
begin
m2 <= a+ b;
y2 <= m2;
end
endmodule
设计中共写了两个always块,分别是阻塞和非阻塞,这种方式起到了对比的作用。
下图是vivado的仿真图。

在第一个clk上升沿的时候,首先分析m1和y1的变化情况。
因为当前a=0,b=1,因为是阻塞赋值,只有当m1=a+b运行结束后(此时m1的值为1),才会运行y1=m1,这时候y1的值为1。
always @(posedge clk)
begin
m1 = a+ b;
y1 = m1;
end

在第一个clk上升沿的时候,接着分析m2和y2的变化情况。
always @(posedge clk)
begin
m2 <= a+ b;
y2 <= m2;
end
因为当前a=0,b=1,因为是非阻塞赋值,首先我们需要先计算非阻塞赋值符号右侧。
此时a + b = 1,m2此时为0。当赋值语句结束后,才会把右边的值赋值给左边的变量。
所以在第一个clk的时候,m2为1,y2为0。
在第二个clk上升沿的时候,我们再分析m2和y2的变化情况
此时a + b = 1,m2此时为1。当赋值语句结束后,才会把右边的值赋值给左边的变量。
所以在第二个clk的时候,m2为1,y2为1。
本文详细解析了Verilog中阻塞与非阻塞赋值的区别,通过实例展示了它们在testbench中的行为,并结合Vivado仿真,说明了两者在时序上的不同。

47

被折叠的 条评论
为什么被折叠?



