为什么 Verilog 模拟器以不同的方式处理这些情况?
1)
always #1 clk =! clk;
initial
begin
@(posedge clk)
start <= 1;
end
initial
begin
clk <= 1;
start <= 1;
end
文献说,在一种情况下,clk和start信号将同时设置,并且clk只能在下一个边沿捕获start信号。这就是它的工作原理。
但是为什么第二种情况与第一种情况不同呢?毕竟非阻塞赋值也应该同时设置。但它并不像第一种情况那样工作。但如果你这样写,那就和第一种情况一样了。
2)
initial
begin
clk = 1;
start <= 1;
end
示例 1)
module test();
reg clk=0;
reg start=0;
reg flag=0;
always #1 clk =! clk;
initial
begin
#5;
@(posedge clk)
start <= 1;
end
always@(posedge clk)
if(start)
flag<=1;
endmodule
module test();
reg clk=0;
reg start=0;
reg flag=0;
initial
begin
#5;
clk <= 1;
start <= 1;
end
always@(posedge clk)
if(start)
flag<=1;
endmodule
模拟结果
您的代码示例不遵循同步逻辑的推荐编码风格。这会导致模拟竞争条件。
不同的代码示例应该会产生不同的结果。
您正在混合编码风格。您应该在
always
块中生成具有阻塞分配的时钟。由于 start
和 flag
与 clk
同步,因此它们都应该使用非阻塞分配 (<=
) 并与时钟对齐 (@(posedge clk)
):
module test();
reg clk=0;
reg start=0;
reg flag=0;
always #1 clk = !clk;
initial
begin
repeat (3) @(posedge clk);
start <= 1;
end
always @(posedge clk)
if (start) flag <= 1;
endmodule