Working of $monitor

Hi All,

When testing the following code

module tb;  
  bit clk ; 
  
  int unsigned sig ;
  
  always #5 clk = !clk;
  
  always@(posedge clk) begin
    sig <= sig + 1;
  end  
  
  initial $monitor("At T:%0t sig is %0d",$time,sig);
  
  initial #30 $finish();
endmodule

I observe that $monitor executes at time 0 units.

As per LRM

When a $monitor task is invoked with one or more arguments, the simulator sets
up a mechanism whereby each time a variable or an expression in the argument 
list changes value—with the exception of the $time,$stime, or $realtime system 
functions—the entire argument list is displayed at the end of the time step as
if reported by the $display task. If two or more arguments change value at the
same time, only one display is produced that shows the new values.

(1) Since sig remains at default value of 0 (there is no change in it’s value), why does $monitor execute at time 0 ?

(2) From the above LRM quote, what is the meaning of with the exception of the $time,$stime, or $realtime system functions ?

Thanks

Strictly speaking, you are correct. The simulator really shouldn’t display anything at time 0. If you really want to know why, you should ask the simulator vendor. If you want to avoid seeing a message at time 0, use $display in a clocked “always” block instead of $monitor. That is the recommended approach.

$monitor is not sensitive to the $time argument, which means you will not get a message only when the simulation time changes. You see that in your output. You don’t get a message at time 1, 2, 3, 4. You only get a message when “sig” changes.

There is additional information in that paragraph:

A call to $monitoron shall produce a display immediately after it is invoked, regardless of whether a value change has taken place; this is used to establish the initial values at the beginning of a monitoring session. By default, the monitor flag is turned on at the beginning of simulation.

I interpret this to mean that the initial call to $monitor will also produce a display immediately after it is invoked.

1 Like

Thanks @cgales.

I had a strong intuition that it wasn’t a tool related issue ( since all had the same output )

I believe simulation would advance only in steps of 5N units ( where N >= 0 )

i.e 0 units ( due to initial block ) , 5 units , 10 units , 15 units etc ( due to always ##5 … )

The LRM needs a bit of clarification here. All output from $monitor gets scheduled in the postponed event region-- it is not immediate. (see Section 4.4.2.9 Postponed events region). The LRM should be corrected to say

A call to $monitor or $monitoron shall produce a display in the postponed event region immediately after it is invoked, …

SystemVerilog is defined in terms of a discrete event simulation algorithm, which means that simulation time is merely a bookkeeping measure. It is solely used to maintain the relative ordering of events.