The accepted answer is wrong - the always
is initially triggered by the assignment to 0 in the initial
block, so you have a perfectly valid question, which is why the always
block isn't triggering itself after it ran the first time (and it clearly did run, because clk
is set to 1).
Run the code below - you'll see that it works as expected if you change the blocking assignment to a non-blocking one, or if you use an intra-assignment delay instead of your delay control (clk = #5 ~clk
). So, this is a scheduling issue. You might intuitively expect that your process would only trigger once, because the eventual blocking assignment and the process evaluation effectively occur in the same delta, so the blocking assignment could potentially be lost. However, I can't see a specific justification in the LRM. The delay control turns into a future inactive event, and the scheduler eventually executes it, creating an update event, which updates clk
(you see this happen once). This should then create an evaluation event for the process, because it's sensitive to clk
, but it's not doing this. The scheduling section is (very) woolly, and doesn't really cover this. Mentor would probably give you their version of what's going on if you ask them. VHDL avoids this issue by making all signal assignments non-blocking.
module tb();
reg clk1, clk2, clk3;
initial begin
$monitor($time,, "clk1 = %b; clk2 = %b, clk3 = %b", clk1, clk2, clk3);
clk1 = 1'b0;
clk2 = 1'b0;
clk3 = 1'b0;
#100 $finish;
end
always @*
#5 clk1 = ~clk1;
always @*
#5 clk2 <= ~clk2;
always @(clk3)
clk3 <= #5 ~clk3;
endmodule