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?

