$monitor in SystemVerilog

module ex;
  class test;
      task run;
       static int i;
        begin
          for(i=1;i<=5;i++)
            begin
              $monitor("moni :: %d",i);
            end
        end
      endtask
  endclass
  
  initial
    begin
      test t = new;
      t.run;
    end  
endmodule

If I run the above code, the $monitor is printing only one time like moni :: 6

module ex;
  task run;
    static int i;
    begin
      for(i=1;i<=5;i++)
        begin
          $monitor("moni :: %d",i);
        end
    end
  endtask
  
  initial
    begin
      run;
    end  
endmodule
  • If I run this above code, $monitor is printing for 5 times for i = 1,2,3,4,5.

Can anyone please explain what is happening in both cases.

In reply to RanjithSurya:

Please use code tags to make your code more readable. I have added them for you.

I believe you are seeing incorrect behavior from a particular tool, and this Mentor sponsored public forum is not for discussing tool specific issues.

$monitor sets up a background process to print at the end of a time-slot when any argument has a change. Since there are no delays in either testcase, there is only one end of time-slot, time 0, thus only one line of output.

In reply to dave_59:

Hi Dave ,

If I were to change the code ::


      task run;
       integer i;
        begin
          for(i=1;i<=5;i=i+1)
            begin
              i = 1'bx;
              $monitor("moni :: %d",i);
            end
          //  i = 1'bx; // Either I write here OR above
	end
      endtask
 
  initial
    begin
      run;
    end  

Shouldn’t I not get any output since i hasn’t changed ( initial and final value are x ) ?

In reply to himanshu valecha:

I would not spend too much time on $monitor, it is only useful for very simple debugging,

The first time slot you execute $monitor is considered a change, so you always get a lest one line of output. Then the next time it gets printed you see what changed.