自触发的clk生成器中的Verilog阻止/非阻止分配 [英] Verilog blocking/nonblocking assignment in clk generator with self triggered
问题描述
为什么下面的代码不是自触发的?
Why the following code is not self-triggered?
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;
when used non-blocking assignment it works normally
i.e., 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
提前谢谢.
推荐答案
它与verilog计划程序有关.
It has to do with the verilog scheduler.
@
将等待一个新事件,它将忽略任何过去的事件.在同一时间步中,执行顺序很重要.
@
will wait for a new event, it will ignore any past events. Within the same time step, execution order matters.
clk = ~clk
是一项阻塞分配,这意味着clk
将在之前安排下一个@
之前进行更新. clk
事件将丢失.
clk = ~clk
is a blocking assignment, meaning clk
will be update before scheduling the next @
. The clk
event will be missed.
clk <= ~clk
是非阻塞分配,这意味着clk
将在安排下一个@
之后进行更新. clk
事件将被感知.
clk <= ~clk
is a non-blocking assignment, meaning clk
will be update after scheduling the next @
. The clk
event will be sensed.
在实践中,自触发块不是很常见. always
块不需要具有敏感度列表.它们在该块内应至少具有一个可达到的时间阻塞延迟(例如@(_list_)
,#(_timeunit_)
);否则将出现零时无限循环,并且模拟会挂起.
Self triggering blocks are not very common in practice. always
blocks are not required to have a sensitivity list. They should have at least one reachable time blocking delay (e.g. @(_list_)
, #(_timeunit_)
) within the block; else there is a zero time infinite loop and the simulation hangs.
时钟发生器通常植入类似于以下内容的东西:
Clock generator are usually implanted something similar to:
reg clk;
initial begin
#10 clk = 0;
forever #10 clk = ~clk;
end
或
reg clk;
always #10 clk = (clk===1'b0);
这篇关于自触发的clk生成器中的Verilog阻止/非阻止分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!