Wait statements and Functions

I’ve created an example to ilustrate my problem (runnable in EDA playground).

I need to wait for a counter to reach a certain value before i continue executing a process in simulation.
I access the counter trough the return value of a function call.
But some how, it does not work.

My expectation is to read in terminal at some point:

"***** After 2nd wait *****"

but that never happens as long as i am reading the value trough the fuction.
If i read it directly, that means using

wait(cnt == 8);

instead of

wait(func_rd_cnt() == 8);

then it does work.

Please tell me where my error is, thank you,

Example code:


module top();
  byte cnt;
  bit clk;

  always #5 clk = ~clk;

  always @ (posedge clk)
    cnt <= cnt + 1;

  function byte func_rd_cnt();
    return cnt;
  endfunction
  
  initial
    begin
      $display("***** Before wait *****");
      wait(cnt == 4);
      $display("***** After 1st wait *****");
      $display("** the function returns %d", func_rd_cnt());
      wait(func_rd_cnt() == 8);
      $display("***** After 2nd wait *****");
    end

  initial #100 $finish;
  initial $monitor("cnt - %0d", cnt);    
endmodule

In reply to stefaniemcg:

https://verificationacademy.com/forums/systemverilog/can-we-have-function-callwithout-arguments-within-wait-statement-systemverilog

In reply to cgales:

You’ll have to shine some light on it, cuz i still don’t get it.

From IEEE 1800-2012 LRM in 9.4.2 Event control:

Nonvirtual methods of an object and built-in methods or system functions for an aggregate type are allowed in event control expressions as long as the type of the return value is singular and the method is defined as a function, not a task.

In my case, i would argue that I am calling a function whose return value is singular.
Is it not?

I still don’t know what the problem is.

In reply to stefaniemcg:

From Dave’s answer: If not a class method, then only changes to the inputs to the function trigger re-evaluation of the wait expression.

Since your function has no inputs, the function call is never re-evaluated.

This works, but it is a dummy solution:
If someone can suggest a better solution, please do.
In the example from LRM the function has no input, so there may be a better solution.


module top();
  byte cnt;
  bit clk;

  always #5 clk = ~clk;

  always @ (posedge clk)
    cnt <= cnt + 1;

  function byte func_rd_cnt(bit dummy=1);
    return cnt;
  endfunction
  
  initial
    begin
      $display("***** Before wait *****");
      wait(cnt == 4);
      $display("***** After 1st wait *****");
      $display("** the function returns %d", func_rd_cnt());
      wait(func_rd_cnt(clk) == 8);
      $display("***** After 2nd wait *****");
    end

  initial #100 $finish;
  initial $monitor("cnt - %0d", cnt);    
endmodule

In reply to stefaniemcg:

You have to explain why you can’t use ‘cnt’ directly and need to use a function.

From my understanding if you took function inside wait, there should be only two condition if function is true then value is '1' otherwise '0'. But in your case always '0', thats why not triggered better to use your other approach cnt == 8. I have attach the solution : [amir_sharfu_approach](https://www.edaplayground.com/x/MrfD) Kindly take a look once.

Other approach is polling of cnt value, means use do-while loop.