The system tasks $stop and $finish both stop a simulation, but for different purposes: $stop pauses it so that you can look around, and $finish ends it for good.

A simulation normally ends by itself when there is nothing left to do: every initial block has executed its last statement and no more events are scheduled. Most testbenches, however, contain processes that never run out of events, such as a clock generator always #5 clk = ~clk; or a forever loop. Without an explicit $finish, such a simulation would keep advancing time forever.

8 min read | Beginner Level

What You'll Learn

  • How $stop pauses a simulation for interactive debugging
  • How $finish ends a simulation, and what its optional argument prints
  • How testbenches use $finish for end-of-test reports and timeout watchdogs
  • Common mistakes that make a simulation hang or end too early
States of a simulation: Running moves to Paused on $stop, where an interactive prompt is shown and the state is kept; a simulator-specific resume command returns from Paused to Running; Running moves to Finished on $finish or when no more events are left, and the simulator exits to the operating system; a quit or finish command also moves from Paused to Finished

$stop

$stop suspends the simulation, much like a breakpoint in a software debugger. Simulation time stops advancing and the simulator shows its interactive prompt. All signal values are kept, so you can inspect variables, look at waveforms or change values, and then continue the run from exactly the same point.


$stop([N]);

// where N is
// 0   :   Prints nothing
// 1   :   Prints simulation time and location
// 2   :   Prints simulation time, location, and statistics about the memory
//         and central processing unit (CPU) time used in simulation

Without an argument, $stop behaves as $stop(1). The command to resume a paused simulation is specific to each simulator, often something like run or cont typed at the prompt, so check your simulator's manual.


module tb;

  reg [3:0] counter;

  initial begin
    counter = 0;
    #10 counter = counter + 1; // Increment after 10 time units
    $display("Counter value before stop: %b", counter);

    $stop; // Simulation pauses here

    // This line will not execute until the simulation is resumed
    #10 counter = counter + 1;
    $display("Counter value after stop: %b", counter);
  end
endmodule

The counter is incremented at 10 ns and its value is printed. The simulation then pauses at $stop, at time 10. Nothing else happens until you resume it; then the counter is incremented again at 20 ns and printed. The output looks like this, with the exact pause message depending on the simulator:

Counter value before stop: 0001
(simulator prints the stop time and location, and waits at its prompt)
Counter value after stop: 0010

Quick Check

While the simulation is paused at $stop, does simulation time keep advancing?

Show Answer

No. Simulation time stays at 10 for as long as the simulation is paused, no matter how long you spend at the prompt. Simulation time only advances while the simulator is processing events.

$finish

$finish ends the simulation completely: the simulator stops, closes its output files, and returns control to the operating system. It is used when a test has finished, or when the testbench detects an error so serious that continuing makes no sense. It takes the same optional argument as $stop.


$finish([N]);

// where N is
// 0   :   Prints nothing
// 1   :   Prints simulation time and location
// 2   :   Prints simulation time, location, and statistics about the memory
//         and central processing unit (CPU) time used in simulation

module tb;

  initial begin

    // Some simulation code...
    #10 $display("Waited to 10 units");

    // Terminate simulation and print a diagnostic message
    $finish(1);

    // This delay will never be executed in simulation because it will be
    // terminated by the line before
    #100;
  end

endmodule

The message is printed at time 10, and the simulation ends right there with a short note giving the time and location of the $finish. The #100 after it is never reached. $finish ends the whole simulation, not just the block that calls it, so every other initial and always block stops too.

Quick Check

A testbench has two initial blocks. One calls #50 $finish; and the other calls #100 $display("done");. Is "done" printed?

Show Answer

No. The simulation ends at 50, so the second block never reaches time 100.

Ending a Test with $finish

In a self-checking testbench, $finish usually comes right after the final report, in the block that runs the stimulus:


initial begin
  run_all_tests;                      // Task with the stimulus and checks
  if (errors == 0)
    $display ("TEST PASSED");
  else
    $display ("TEST FAILED: %0d errors", errors);
  $finish;
end

A second block acts as a watchdog. If the design hangs, for example because a handshake never completes, the main block never reaches its $finish, and the watchdog ends the simulation with an error instead of letting it run forever:


initial begin
  #1_000_000;                         // Longer than any test should take
  $display ("ERROR: Timeout at %0t, test did not finish", $time);
  $finish;
end

Timeouts in Nightly Regressions

A regression starts thousands of simulations on a compute farm. One test that hangs would block a machine and a license for hours. Every testbench therefore has a watchdog timeout, and the regression system additionally kills any job that runs longer than a fixed limit. A test that ends through its watchdog is reported as a failure, so the hang gets investigated instead of going unnoticed.

Difference between $stop and $finish

$stop is a tool for debugging, while $finish is the normal way to end a testbench or a simulation run.

$stop$finish
FunctionalityPauses the simulation, allowing for inspection and debuggingEnds the simulation completely
ResumptionAfter $stop, you can continue from where you left offAfter $finish, you must restart the entire simulation to run it again
Tool LicenseDoes not release any licenses, allowing for a continued session.Releases licenses and exits the simulator environment.
Typical usePause at an interesting point while debugging interactivelyEnd of test, timeout watchdog, fatal error

Synthesis result: None. $stop and $finish are simulation-only system tasks and are ignored by synthesis tools. They only appear in testbenches and behavioral models.

Conditional Breakpoints

When a bug appears only after millions of cycles, an engineer can add a temporary line such as if (fifo_count == DEPTH) $stop; to the testbench. The simulation runs at full speed until the interesting moment, then pauses, and the engineer inspects the state at the prompt. Before the change is committed, the $stop is removed, because it would make batch runs wait for input.

Common Beginner Mistakes

Mistake #1: Forgetting $finish in a testbench with a clock

Wrong: always #5 clk = ~clk; with stimulus that simply ends
Right: End the stimulus block with $finish;

Why? The clock always has another event scheduled, so the simulation never runs out of events and never ends by itself.

Mistake #2: Leaving $stop in a testbench used in batch runs

Wrong: A $stop left over from debugging in a test that runs in a regression
Right: Use $finish to end tests, and remove $stop after debugging

Why? In a batch run there is nobody at the prompt. Depending on the simulator, $stop either waits for input forever, blocking the machine until the job is killed, or exits without the end-of-test report.

Mistake #3: Putting the final report after $finish

Wrong:


$finish;
$display ("TEST PASSED");   // Never printed

Right: Print the report first, then call $finish

Why? $finish ends the simulation immediately, so no statement after it executes.

Mistake #4: A zero-delay infinite loop

Wrong: always clk = ~clk;
Right: always #5 clk = ~clk;

Why? Without a delay, the always block loops forever at time 0, and simulation time never advances. The $finish waiting at a later time is never reached, so the simulator appears to hang. Every always block needs a delay or an event control.

Practice Exercise

Challenge: Which Block Ends the Test?

Predict the complete output of this testbench and the time at which it ends. Then change one number so that the test passes.


module tb;
  reg done = 0;

  initial begin
    #300 done = 1;
  end

  initial begin
    wait (done);
    $display ("T=%0t TEST PASSED", $time);
    $finish;
  end

  initial begin
    #200;
    $display ("T=%0t ERROR: Timeout", $time);
    $finish;
  end
endmodule
Hint

Find the earliest time at which any block reaches a $finish.

Solution
T=200 ERROR: Timeout

The watchdog reaches its $finish at 200, before done is set at 300, so the test ends with a timeout and "TEST PASSED" is never printed. Increasing the watchdog delay to more than 300, for example #1000, lets the second block print T=300 TEST PASSED and end the simulation at 300. The watchdog never fires, because $finish stops it too.

Summary

In this tutorial, you learned:

  • $stop pauses the simulation at the interactive prompt, keeping all values so the run can be resumed
  • $finish ends the whole simulation immediately and exits the simulator
  • Both accept an optional argument 0, 1 or 2 that controls the diagnostic message, with 1 as the default
  • A testbench with a free-running clock needs $finish, and a watchdog $finish protects against hangs
  • The final report must be printed before $finish, and $stop should not be left in batch tests
  • Both tasks are simulation-only and ignored by synthesis
Did you find what you were looking for?

Quiz

Test Your Knowledge

1 of 5 Score: 0 / 5