difference between $display, $write, $strobe and $monitor

In SystemVerilog and Verilog, simulation system tasks are widely used to print signal values, debug designs, and observe behaviour during simulation. Among these, $display, $write, $strobe, and $monitor are the most commonly used output system tasks.

Although they look similar, they behave very differently with respect to timing, formatting, and execution. Understanding these differences is extremely important for debugging RTL, writing testbenches, and preparing for VLSI interviews.

1. $display

$display prints the specified message immediately when the statement is executed and automatically moves to the next line after printing.

Key Characteristics

  • Executes at the current simulation time in active region
  • Automatically adds a newline
  • Prints values as they are at that moment

Syntax

$display("Time=%0t a=%0d b=%0d", $time, a, b);

2. $write

$write is similar to $display, but does NOT automatically add a newline.

Key Characteristics

  • Executes at the current simulation time in active region
  • No automatic newline

Syntax

$write("a=%0d ", a);
$write("b=%0d\n", b);

3. $strobe

$strobe prints the values at the end of the current simulation time step, after all non-blocking assignments (NBA) are updated. It executes in postponed region.

This makes $strobe extremely useful for accurate final-value observation.

Key Characteristics

  • Executes only once at the end of the current time slot. When all processes in that time instant have executed.
  • Displays final updated values
  • Avoids race-condition confusion

Syntax

$strobe("Time=%0t a=%0d b=%0d", $time, a, b);

4. $monitor

$monitor continuously monitors the specified signals and automatically prints values whenever any monitored signal changes. It also gets executed in postponed region.

It runs implicitly until disabled.

Key Characteristics

  • Executes whenever a signal changes
  • Prints updated values automatically
  • Only one $monitor can be active at a time

Syntax

$monitor("Time=%0t a=%0d b=%0d", $time, a, b);

Example:

Let’s take a simple example to see the differences between $display, $write, $strobe and $monitor.

module tasks_example;

  reg a, b;

  initial begin
    a = 0; b = 0;
    $monitor("MONITOR: Time=%0t a=%0b b=%0b", $time, a, b);

    #5 a = 1;
    $display("DISPLAY: Time=%0t a=%0b b=%0b", $time, a, b);

    #5 b = 1;
    $write("WRITE: Time=%0t ", $time);
    $write("a=%0b b=%0b\n", a, b);

    #5 begin
      a <= 0;
      b <= 0;
      $strobe("STROBE: Time=%0t a=%0b b=%0b", $time, a, b);
    end

    #5 $finish;
  end

endmodule

Output:

MONITOR: Time=0 a=0 b=0
DISPLAY: Time=5 a=1 b=0
MONITOR: Time=5 a=1 b=0
WRITE: Time=10 a=1 b=1
MONITOR: Time=10 a=1 b=1
MONITOR: Time=15 a=0 b=0
STROBE: Time=15 a=0 b=0
$finish called from file "testbench.sv", line 24.
$finish at simulation time                   20
           V C S   S i m u l a t i o n   R e p o r t

Observation:

Time Slot
----------------------------------
Active Events     -> $display, $write
NBA Updates       -> <= assignments
Post-NBA          -> $strobe
Signal Change     -> $monitor
----------------------------------