awill
awill

Reputation: 135

wait($time >1000); cannot work in system-verilog?

I use this code to wait for a specific simulation time

initial begin
    $display("A");
    wait($time>1000);
    $display("B");
end

the simulation result is:

A

I didnot see B printed.

If I use following code, it works.

while($time <1000) #1;

Is it because vcs needs to judge the wait condition once any viriable in the condition statement changes, $time is changing too frequently so vcs doesnot allow this usage?

@Tudor 's answer enlighten me. I tried @Tudor 's code with some modification. It turns out when wait(func(arglist)); vcs only retry to evaluate the function when arglist changes. Because $time has no args, vcs will only evaluate $time the 1st time, won't retry.

module top;
  int the_time = 0;
  int  in_arg = 0;

  function int the_time_f(int in);
    return the_time;
  endfunction // the_time_f

  initial begin
    $display("A");

// This works because 'the_time' is a variable
//wait(the_time > 10);

// This doesn't work because 'the_time_f' is a function


wait(the_time_f(in_arg) >10);
    $display("B at %t", $time);
      end

  initial begin
    #10ns;
    the_time = 11;
    #10ns;
    in_arg = 1;
    #20ns;
    $finish();
  end
endmodule // top

got following result

A
B at 20ns

Upvotes: 1

Views: 6532

Answers (2)

dave_59
dave_59

Reputation: 42698

In an event control @(expression) or wait(expression) that suspends a process, SystemVerilog scheduling semantics requires an event to evaluate the expression (called an evaluation event. See section 4.3 Event Simulation of the 1800-2012 LRM) If an expression includes a function, only the arguments to that function are visible to cause an event evaluation (There is an exception for class methods in at a write to any member of the object in the method call will cause an event) See section 9.4.2 Event control

In an event driven simulation, the value of time is just an attribute of the current time slot, it is never an event. The simulator processes all events for the current time slot in a queue, and when that queue is empty, it advances time to the next time slot queue. So it might simulate time slots 0,5,7,10, skipping over the unmentioned times. Using your while loop, that would create a time sot for every consecutive time unit between 0 and 1000 - extremely inefficient.

So just use

#(1000); // wait for 1000 relative time units 

Upvotes: 4

Tudor Timi
Tudor Timi

Reputation: 7573

This seems to be a gray area in the standard. In section 9.4 Procedural timing controls of the IEEE Std 1800-2012 Standard, it's mentioned that event control can be either implicit (changed of nets or variables) or explicit (fields of type event). $time is a system function, not a variable. I've also tried using a function for the wait and it also doesn't work:

module top;
  int the_time = 0;

  function int the_time_f();
    return the_time;
  endfunction // the_time_f

  initial begin
    $display("A");

    // This works because 'the_time' is a variable
    //wait(the_time > 10);

    // This doesn't work because 'the_time_f' is a function
    wait(the_time_f() > 10);
    $display("B");
  end

  initial begin
    #10ns;
    the_time = 11;
    #20ns;
    $finish();
  end
endmodule // top

Waiting on a change of a variable works fine, but waiting for a change on a function's return value doesn't work. IMHO, the compiler should have flagged this as a compile error (same for using $time) since it seems to just ignore the statement.

Upvotes: 4

Related Questions