I have a fundamental verilog event region question that I want clarification on.
The following piece of code (#1) results in the simulator hanging :
module top();
reg clk;
always clk <= #5 ~clk;
initial begin
clk = 0;
$monitor($time, " Monitor clk=%0d", clk);
#50;
$finish;
end
endmodule // top
However, if I change the delay to be an inter-assignment delay, I get a successful clock generation. What gives ?
module top(); //Successful clock generation
reg clk;
always #5 clk <= ~clk;
initial begin
clk = 0;
$monitor($time, " Monitor clk=%0d", clk);
#50;
$finish;
end
endmodule // top
In reply to DVJoe:
Hi,
You can generate clock with an intra-assignment delay with some active event as shown below.
module top();
reg clk;
always @(clk)
clk <= #5 ~clk;
initial begin
clk = 0;
$monitor($time, " Monitor clk=%0d", clk);
#50;
$finish;
end
endmodule // top
Putta Satish
In reply to puttasatish:
Non-blocking assignments is not a good way to write clock generator—you get extra events, and you have a potential race condition. If the initial starts executing before the always, the @(clk) will hang.
DVJoe, your first example hangs at time 0 because you have an always construct with no blocking statements. It goes into an infinite because time never has a chance to advance.
Your second always construct has a simple procedural blocking delay. It is not an intra-assignment delay. Time must advance by 5 for each loop of the always. The non-blocking assignment (NBA) is superfluous. Use a blocking assignment
always #5 clk = !clk;
always clk = #5 !clk; // this is intra-assigment (blocking) delay