-1
always @(clk) begin #10 clk <= ~clk;end       //works
always @(clk) begin #10 clk = ~clk;end        //doesn't work

Works means execution re-enters the always block, behaves like a oscillator.
Does not work mean it execute only once.

I've read Scheduling semantics part in Verilog Standard, as I understand it now, in a time step, all statements in the process are placed in the hierarchical event queue at the same time, until the process is suspended when the timing control statement in the process is encountered. The statements are then sorted and sorted. If the statements are in a begin end block, the statements need to be sorted in the order in which they appear.

As I understand it, both blocking and non-blocking assignments can generate a flapping clock because the timing control statement in the process is detected before the assignment is updated.

Is the evaluation of events in a time step done sentence by sentence? Or there's something wrong with my understanding.

Why can a non-blocking update event trigger a sensitive event at the same time step? Could You tell me how evaluation and update events enter the hierarchical event queue?

Mikef
  • 1,572
  • 2
  • 10
  • 21

1 Answers1

2

To better understand this, you need to unroll the statement in the always loop.

initial #0 clk = 0; // I'm assuming you have this code already. 
initial begin
    @(clk) #10 clk <= ~clk;
    @(clk) #10 clk <= ~clk;
    @(clk) #10 clk <= ~clk;
...
end

This works because clk is set to 0 after encountering the first @clk. It waits 10 time units and then executions the nonblocking assignment statement. The next @(clk) is encountered before the nonblocking assignment updates the value of clk.

In the second case,

initial #0 clk = 0; // I'm assuming you have this code already. 
initial begin
    @(clk) #10 clk = ~clk;
    @(clk) #10 clk = ~clk;
    @(clk) #10 clk = ~clk;
...
end

Again,clk is set to 0 after encountering the first @clk. But since you now have a blocking assignment statement, the update to clk occurs first, and then you encounter the @(clk). So it waits for a change on clk that never happens.

The key thing about event controls they have to be encountered in the procedural thread of execution before any change to the event expression happens. Note that I added a #0 to make sure the the @ is seen first. Without the delay, there is a race condition. There is still a race condition when the original code was modeled with an always construct, but most users do not see this because simulators tend to start always processes before initial processes.

In your case, there is no need for an event control. You can simply write:

always #10 clk = ~clk;

Even better is

initial begin
   clk = 0; // make sure that a posedge does not occur at time 0.
   forever #10 clk = ~clk;
end
dave_59
  • 39,096
  • 3
  • 24
  • 63
  • Thank you for answering my question.My current understanding is that the statements in the begin block are added to the active event queue one by one, such as non-blocking Rvalue evaluation, blocking assignment, etc., and the execution is also in the queue order until a timing control statement is reached, at which point the process will be suspended, or in the case of time control, the process will wait for sensitive events. Is #0 used in your example to ensure that x is not assigned until @ is detected, from the point of view of event control @ detection as an active event? – chen zhang May 08 '23 at 07:31
  • Verilog's standard does not specify how a sequence of events from an event step enters the event queue, or what happens if @ is encountered during execution – chen zhang May 08 '23 at 07:34
  • initial begin #0 x=0; x=1; end The result of this statement is x=1, which seems to confirm my idea that x=0 is first added to the inactive event area, since there are no active events, it is activated into the active area and executed, and then x=1 is added to the active area and assigned a value – chen zhang May 08 '23 at 07:40
  • @chenzhang, I added a note about your #0 delay comment to my answer. You last comment is more involved and probably needs to be asked as a separate question. – dave_59 May 08 '23 at 16:32