Uvm Test Termination

Download as odp, pdf, or txt
Download as odp, pdf, or txt
You are on page 1of 24
At a glance
Powered by AI
The key takeaways are that UVM simulations use phases to structure test execution and provide mechanisms like objections and timeouts to control test flow.

UVM simulations are structured with a top level module that imports the UVM package and instantiates the DUT. It then calls run_test() to start phase execution.

The main phases are run(), check(), report(). The run() phase has active and stop interrupt stages. Tasks can raise objections to control phase termination.

UVM Techniques for

Terminating Tests
Compiling designs & running UVM - overview

By default, when run_test() is done, $finish is called to terminate the


simulation.
PHASES (OVERVIEW)
UVM Phase Usage
Run() Phase Stages
run() phase execution flow diagram
Run() Phase Threads

1. Non-Stopping Threads
Non-Stopping threads are run() tasks that either execute their code without
issuing a stop command or are run() tasks with a forever loop that never ends.
A run() task that does not make a call to global_stop_request() or that does not
raise any objections would be a non-stopping thread.

2. Stop-Request Threads
Stop-Request threads are run() tasks that call the global_stop_request()
command inside of the run() task. If there are no Objections-Raised threads, the
run() phase will immediately process the stop_request(), terminate the Active
Stage and start the Stop-Interrupt Stage if any of the enable_stop_interrupt bits
were set in any of the run() phase threads.
If there are any Objections-Raised threads, the global_stop_request()
command is largely ignored. For this reason, using the global_stop_request()
command is largely discouraged as a way to terminate the Active Stage of the
run() phase. It only takes is a single Objections-Raised thread to invalidate all
of the global_stop_request() commands in all of the Stop-Request threads.

3. Objections-Raised Threads
A run() task that calls uvm_test_done.raise_objection(), is
specifying that it "objects to the termination of the Active Stage of
the run() phase," until the objection is dropped using the
uvm_test_done.drop_objection() command. Dropping all
objections will issue an immediate and implicit stop_request(),
even if there is a free-running forever-loop in a Non-Stopping
thread.
4. Enabling Stop-Interrupts In Threads
To interrupt the stoppage of the run() phase requires that a thread set the
enable_stop_interrupt bit, typically at the beginning of the run() task.
Once the enable_stop_interrupt bit is set, the thread will also execute a
stop() task in the Stop-Interrupt Stage.
HOW UVM SIMULATIONS WORK

Briefly, in a top-level module, an engineer:


1. Imports the uvm_pkg.
2. Instantiates a Design Under Test (DUT) with design interface
that is used to tie the class-based testbench to the DUT.
3. Calls a UVM run_test() method.

import uvm_pkg::*;
package uvm_pkg;
`include "uvm.svh"
endpackage
uvm.svh file itself includes-

//`include "uvm_macros.svh"
`include "base/base.svh"
//`include "uvm_tlm/uvm_tlm.svh"
//`include "methodology/methodology.svh"

base.svh file actually includes 28 other files from the


src/base subdirectory-

Out of these 2 main files are:


`include "base/uvm_component.sv"
`include "base/uvm_globals.svh"

the uvm_component.sv file-


includes the very important uvm_root.svh file
uvm_root
This is how the uvm_top is created and it is all done by importing
the uvm_pkg in the top-level module and the construction of
uvm_top happens right after simulation starts at time 0. uvm_top is
constructed before we even execute the UVM phases; in fact, the
UVM phases are executed by calling the run_test() method from
this instance (object) of uvm_top. Now uvm_top is a fully
constructed object of type uvm_root, and it is now possible to call
any uvm_root method (including run_test()) just by using the
uvm_top handle.
run_test()
The run_test() method is also defined in the uvm_root class.
Most initial block calls to
run_test() do not reference this method with the uvm_top
handle name.
task run_test (string test_name="");
uvm_root top;
top = uvm_root::get();
top.run_test(test_name);
endtask
function void global_stop_request();
uvm_root top;
top = uvm_root::get();
top.stop_request();
endfunction
function void set_global_timeout(time timeout);
uvm_root top;
top = uvm_root::get();
top.phase_timeout = timeout;
endfunction
function void set_global_stop_timeout(time timeout);
uvm_root top;
top = uvm_root::get();
top.stop_timeout = timeout;
Endfunction

Example 11 - Abbreviated base/uvm_globals.svh file


A call to run_test(), as shown in Example 10, calls the run_test() task
defined in Example 11. The run_test() task declares a handle called top
of the uvm_root class type. Then the uvm_root::get() method is called,
which will return the local static uvm_root handle, m_inst, and store it
into the top handle declared in the task (the uvm_root::get() method
ensures that only one uvm_root object will ever be created), and using
the top handle, the local run_test() calls the top.run_test() method in
the uvm_top object, which starts up all the UVM simulation phases.

import uvm_pkg::*; ---> creates the uvm_top top-level testbench


object and includes important global commands including: run_test(),
global_stop_request(), set_global_timeout(),
set_global_phase_timeout().
Users of the uvm_pkg have access to these commands and more without
being required to construct any class objects.
HOW UVM SIMULATIONS RUN

run_test() command starts all of the UVM phases.

Choosing A Test To Run:

The run_test() command must be passed a valid test name


that has been registered in the UVM
factory. There are two ways to pass a valid test name to the
run_test() command, (1) coded into the
top module or (2) passed to the UVM testbench through
the command line switch +UVM_TESTNAME.
UVM Testbench Coding Mistake
Proper Use of global_stop_request() Command
HOW UVM SIMULATIONS STOP

global_stop_request() - is a commonly used convenience


function that calls uvm_top.stop_request(). It is used to
terminate the Active Stage if there are no raised objections.

set_global_timeout() - is a convenience function that calls


uvm_top.phase_timeout = timeout.

set_global_stop_timeout()-is a convenience function that calls


uvm_top.stop_timeout= timeout.
Timeouts

When the run() phase starts, a parallel timeout timer is also started.
If the timeout timer reaches one of the specified timeout limits before
the run() phase completes, the run() phase will timeout and:
All run() tasks will be immediately disabled.
1. A timeout message will be issued.
2. Execution of the post-run() phases will begin.
There are two timeout counters that may become active during the
run() phase and their timeout limits
are kept in the variables uvm_top.phase_timeout and
uvm_top.stop_timeout.
The phase_timeout is the time that the entire run() phase
(ActiveStage and Stop-Interrupt Stage) is allowed to run before
timing out. The phase_timeout is often referred to as the
global_timeout limit. If the phase_timeout time limit is reached,
a UVM_ERROR will be reported.

The default value for the phase_timeout limit is set from the
`UVM_DEFAULT_TIMEOUT macro and has a default timeout
value of 9200 seconds. This value can be shortened by using the
set_global_timeout() command.
As part of the run() phase, various components of a test might
execute stop() tasks in the Stop-Interrupt Stage. The maximum
execution time of the stop() tasks is stored in the stop_timeout
limit and can be controlled by the set_global_stop_timeout()
command. The default stop_timeout value is also 9200 seconds.
The stop_timeout is often referred to as the global_stop_timeout
limit.

You might also like