具有自触发功能的clk发生器中的Verilog阻塞/非阻塞分配

时间:2014-07-23 07:48:19

标签: verilog blocking nonblocking

为什么以下代码不是自触发的?

module osc1 (clk);
output clk;
reg clk;
initial #10 clk = 0;
always @(clk) #10 clk = ~clk;

always
begin
$monitor("%0d clk=%0d\n",$time,clk);
#100 $finish;
end
endmodule

输出:

# 0 clk=x
# 10 clk=0
# 20 clk=1

当使用非阻塞分配时,它通常正常工作 即,always @(clk) #10 clk <= ~clk;

输出:

# 0 clk=x 
# 10 clk=0 
# 20 clk=1
# 30 clk=0
# 40 clk=1
# 50 clk=0 
# 60 clk=1 
# 70 clk=0
# 80 clk=1
# 90 clk=0

提前感谢。

1 个答案:

答案 0 :(得分:2)

它与verilog调度程序有关。

@将等待新事件,它将忽略任何过去的事件。在同一时间步骤内,执行顺序很重要。

clk = ~clk是阻止分配,意味着clk将在安排下一个@之前更新。 <{1}}活动将被遗漏。

clk是一种非阻止分配,意味着{/ 1}}会在安排下一个clk <= ~clk后更新。将感知clk事件。


自触发块在实践中并不常见。 @块不需要具有敏感性列表。它们应该在块内至少有一个可达到的时间阻塞延迟(例如clkalways);否则有一个零时间无限循环并且模拟挂起。

时钟发生器通常植入类似于:

@(_list_)

或者

#(_timeunit_)