top of page

8.1. Display Functions: $display vs $monitor vs $strobe vs $write

Understanding when and how to use different display functions is crucial for effective debugging and verification.

8.1.1 $display - Immediate One-Time Print

Executes once when encountered, prints immediately with automatic newline.

​

It is executed in Active Region.

​

Syntax: $display("format", arguments);

Best for:

​

  • Debug messages at specific execution points

  • Test result reporting

  • General logging and status messages

Example:

 Verilog

module display_demo;

  reg [7:0] data;

  initial begin

    $display("========== Simulation Start ==========");

    data = 8'hA5;

    $display("Time: %0t ns | Data initialized: 0x%h (%b)", $time, data, data);

    #10 data = 8'hFF;

    $display("Time: %0t ns | Data updated: 0x%h (%b)", $time, data, data);

    $display("========== Simulation End ==========");

  end

endmodule

/* Output:

========== Simulation Start ==========

Time: 0 ns | Data initialized: 0xa5 (10100101)

Time: 10 ns | Data updated: 0xff (11111111)

========== Simulation End ==========

*/

8.1.2 $monitor - Automatic Change Detection
 

Continuously monitors variables and automatically prints whenever ANY of its arguments change.

It is executed in postponed region.

​

Syntax: $monitor("format", arguments);

​

Important Notes:

​

  • Only ONE `$monitor` should be active at a time (new monitor replaces old one)

  • Use `$monitoroff` to temporarily disable

  • Use `$monitoron` to re-enable monitoring

  • Automatically prints at time 0 with initial values

​

Best for:

​

  • Tracking signal changes throughout simulation

  • Monitoring state machine transitions

  • Observing bus protocol activity

Example:

 Verilog

module monitor_demo;

  reg [2:0] state;

  reg clk, reset;

  initial begin

    // Set up monitoring

    $monitor("Time=%0t | Clk=%b | Reset=%b | State=%b (%0d)", 

             $time, clk, reset, state, state);

    // Initialize

    clk = 0; reset = 1; state = 0; 

    // Stimulus

    #5 reset = 0;

    #5 state = 1;

    #5 clk = 1;

    #5 state = 2; clk = 0; 

    #5 $monitoroff;    // Disable monitoring

    #5 state = 3;       // This change won't be printed 

    #5 $monitoron;      // Re-enable monitoring

    #5 state = 4;       // This will be printed

  end

endmodule

/* Output:

Time=0 | Clk=0 | Reset=1 | State=000 (0)

Time=5 | Clk=0 | Reset=0 | State=000 (0)

Time=10 | Clk=0 | Reset=0 | State=001 (1)

Time=15 | Clk=1 | Reset=0 | State=001 (1)

Time=20 | Clk=0 | Reset=0 | State=010 (2)

Time=35 | Clk=0 | Reset=0 | State=100 (4)

*/

8.1.3 $strobe - End-of-Timestep Print
 

Executes in the postponed region at the END of the current time step, after ALL assignments (blocking and non-blocking) have completed.
 

Syntax: $strobe("format", arguments);
 

Critical Use Case: Capturing values after non-blocking assignments (NBA) region.
 

Why it matters: Non-blocking assignment region don't take effect immediately; they're scheduled to update after the active region. Using $display shows OLD values (As it is executed in active region), while `$strobe` shows UPDATED values (As it is executed in postponed region).

Example 1 - Demonstrating the Difference:

 Verilog

module strobe_vs_display;

  reg a, b;

  initial begin

    a = 0; b = 0;

    #10;

    a <= 1;  // Non-blocking: scheduled for end of timestep

    b = 1;   // Blocking: immediate update

    $display("$display => Time:%0t | a=%b, b=%b", $time, a, b);

    $strobe ("$strobe  => Time:%0t | a=%b, b=%b", $time, a, b);

  end

endmodule

/* Output:

$display => Time:10 | a=0, b=1  (a shows OLD value)

$strobe  => Time:10 | a=1, b=1  (a shows NEW value)

*/

Example 2 - Flip-Flop Verification:

 Verilog

module dff_test;

  reg clk, d, q;

  // D Flip-Flop behavior

  always @(posedge clk)

    q <= d;  // Non-blocking assignment

  initial begin

    clk = 0; d = 0; q = 0;

    // Test 1: Set d=1 and clock

    d = 1;

    #5 clk = 1; 

    $display("Display: q = %b (incorrect!)", q);  // Shows 0

    $strobe ("Strobe : q = %b (correct!)", q);    // Shows 1 

    #5 clk = 0;

  end

endmodule

8.1.4 $write - Print Without Newline

​

Same as `$display` but WITHOUT automatic newline character. It is also executed in Active region.

​

Syntax: $write("format", arguments);

​

Best for:

​

  • Building custom formatted output on same line

  • Creating progress indicators

  • Constructing tables dynamically

Example:

 Verilog

module write_demo;

  integer i;

  initial begin

    // Example 1: Progress bar

    $write("Testing: [");

    for (i = 0; i < 10; i = i + 1) begin

      #5 $write("_");

    end

    $display("] Complete!");

    // Example 2: Custom table

    $display("\n+------+-------+-------+");

    $display("| Time | Data  | Valid |");

    $display("+------+-------+-------+");

    $write  ("| %0t  ", $time);

    $write  ("| 0x%h ", 8'hAB);

    $display("| %b   |", 1'b1);

    $display("+------+-------+-------+");

  end

endmodule

Output:

 Verilog

Testing: [ _ _ _ _ _ _ _ _ _ _ ] Complete!

+------+-------+-------+

| Time | Data  | Valid |

+------+-------+-------+

| 50   | 0xab  | 1     |

+------+-------+-------+

Decision Matrix: Which Function to Use?

$function.png

System task & function

$random: Random Number Generation

© Copyright 2025 VLSI Mentor. All Rights Reserved.©

Connect with us

  • Instagram
  • Facebook
  • Twitter
  • LinkedIn
  • YouTube
bottom of page