8.5. Simulation Control: $finish vs $stop
Proper simulation control is essential for automated testing workflows and interactive debugging.
8.5.1 $finish - Terminate Simulation
​
Purpose: Completely terminate simulation and exit the simulator
​​
Syntax: `$finish;` or `$finish(n);` where n ∈ {0, 1, 2}
​
Verbosity Levels:
-
0: Silent exit (no diagnostic message)
-
1: Display time and location (default)
-
2: Display time, location, and memory/CPU statistics
​
Use Cases:
-
Normal test completion
-
Automated regression tests
-
Timeout conditions
-
Critical errors
Verilog
module finish_levels_demo;
initial begin
$display("Demonstrating $finish verbosity levels:");
// Example 1: Silent finish (for clean scripts)
if ($test$plusargs("QUIET")) begin
$display("Test completed.");
$finish(0); // No simulator diagnostic
end
// Example 2: Normal finish (default)
if ($test$plusargs("NORMAL")) begin
$display("Test completed normally.");
$finish; // or $finish(1) - shows time/location
end
// Example 3: Detailed finish (for debugging)
if ($test$plusargs("DETAILED")) begin
$display("Test completed with full diagnostics.");
$finish(2); // Shows memory/CPU stats
end
end
endmodule
8.5.2 $stop - Pause Simulation
Purpose: Pause simulation and enter interactive debug mode
Syntax: `$stop;` or `$stop(n);` where n ∈ {0, 1, 2}
Characteristics:
-
Simulation can be RESUMED (in interactive simulators)
-
Enters simulator command prompt
-
Allows signal inspection and debugging
Use Cases:
-
Setting breakpoints during development
-
Examining signals at critical points
-
Interactive debugging sessions
-
Conditional debug stops
Verilog
module stop_debug_demo;
reg [7:0] address, data;
reg write_enable, error_flag;
integer transaction_count;
initial begin
// Initialize
address = 0;
data = 0;
write_enable = 0;
error_flag = 0;
transaction_count = 0;
// Perform transactions
repeat (10) begin
#10;
address = address + 1;
data = $random;
write_enable = 1;
transaction_count = transaction_count + 1;
// Conditional breakpoint
if (address == 8'h05) begin
$display("BREAKPOINT: Address 0x05 reached");
$display("Current data = 0x%h", data);
$stop(1); // Pause for inspection
end
#10 write_enable = 0;
// Error detection breakpoint
if (data == 8'hFF) begin
$display("WARNING: Special data pattern detected!");
error_flag = 1;
$stop(1); // Pause to debug
end
end
$display("Completed %0d transactions", transaction_count);
$finish;
end
endmodule
8.5.3 Practical Patterns
​
Pattern 1: Timeout Watchdog
Verilog
module timeout_watchdog;
reg done;
integer max_cycles;
initial begin
done = 0;
max_cycles = 10000;
// Main process
fork
// Process that should complete
begin
#500 done = 1;
end
// Watchdog timer
begin
#max_cycles;
if (!done) begin
$display("ERROR: Simulation timeout after %0d cycles!", max_cycles);
$display("Process did not complete in expected time.");
$finish(2); // Exit with diagnostics
end
end
join
if (done) begin
$display("Process completed successfully at time %0t", $time);
$finish(0);
end
end
endmodule
Pattern 2: Pass/Fail with Appropriate Exit
Verilog
module test_with_status;
integer pass_count, fail_count, total_tests;
initial begin
total_tests = 100;
pass_count = 0;
fail_count = 0;
// Run tests
repeat (total_tests) begin
if (run_single_test())
pass_count = pass_count + 1;
else
fail_count = fail_count + 1;
#10;
end
// Report and exit with appropriate status
$display("\n========================================");
$display("TEST SUMMARY");
$display("========================================");
$display("Total : %0d", total_tests);
$display("Passed: %0d", pass_count);
$display("Failed: %0d", fail_count);
$display("========================================");
if (fail_count == 0) begin
$display("✓ ALL TESTS PASSED");
$finish(0); // Clean exit for scripts
end else begin
$display("✗ %0d TEST(S) FAILED", fail_count);
$finish(1); // Exit with info (non-zero implies failure)
end
end
function run_single_test;
begin
run_single_test = ($random % 100) < 95; // 95% pass rate
end
endfunction
endmodule
Pattern 3: Interactive Debug Checkpoints
Verilog
module debug_checkpoints;
reg [31:0] checkpoint_data [0:9];
integer i;
initial begin
// Phase 1: Initialization
$display("=== CHECKPOINT 1: Initialization ===");
for (i = 0; i < 10; i = i + 1)
checkpoint_data[i] = i * 10;
if ($test$plusargs("DEBUG"))
$stop(1); // Pause if debug mode
// Phase 2: Processing
$display("=== CHECKPOINT 2: Processing ===");
for (i = 0; i < 10; i = i + 1)
checkpoint_data[i] = checkpoint_data[i] + $random;
if ($test$plusargs("DEBUG"))
$stop(1); // Pause if debug mode
// Phase 3: Verification
$display("=== CHECKPOINT 3: Verification ===");
for (i = 0; i < 10; i = i + 1)
$display("Data[%0d] = 0x%h", i, checkpoint_data[i]);
if ($test$plusargs("DEBUG"))
$stop(1); // Pause if debug mode
$display("=== SIMULATION COMPLETE ===");
$finish;
end
endmodule
Usage:
​
vsim top (runs without stops)
vsim top +DEBUG (stops at each checkpoint)
8.5.4 Comparison Summary

