UVM Phases
The phases are an important concept in uvm that applies to all testbench components.
- Each testbench component is derived from uvm_component that has predefined phases. They are represented as callback methods. Hence, the user may implement these callbacks.
- Each component can not move to the next phase unless the current phase execution is completed for all the components. This provides proper synchronization between all the components.
- UVM phases are executed in a certain order and all are virtual methods.
- Few phases that consume simulation time for execution are implemented as tasks and other phases that do not consume any simulation time are implemented as functions.
- Main categories in UVM phases.
a. Build phases: Used to configure or construct the testbench.
b. Run-time phases: Time-consuming testbench activity like running the test case.
c. Clean up phases: Collect and report the results of the simulation.
How does UVM phase execution start?
The run_test() method is required to call from the static part of the testbench. This will trigger up the UVM testbench. It is usually called in the initial block from the top-level testbench module. The run_test() method call to construct the UVM environment root component and then initiates the UVM phasing mechanism.
Build phases
To construct a testbench, it is necessary to build component objects first and then are connected to form a hierarchy, The build phase category consists
a. build_phase
b. connect_phase
c. end_of_elaboration_phase
Phase Type |
Phase Name |
Description |
Execution approach |
function |
build_phase |
Build or create testbench component |
Top to down |
function |
connect_phase |
Connect different testbench component using the TLM port mechanism |
Bottom to top |
function |
end_of_elaboration_phase |
Before simulation starts, this phase is used to make any final adjustment to the structure, configuration, or connectivity of the testbench. It also displays UVM topology. |
Bottom to top |
Run-time phases
Once testbench components are created and connected in the testbench, it follows run phases where actual simulation time consumes. After completing, start_of_simulation phase, there are two paths for run-time phases. The run_phase and pre_reset phase both start at the same time.
a. run_phase
b. pre_reset, reset, post_reset, pre_configure, configure, post_configure, pre_main, main, post_main, pre_shutdown, shutdown, post_shutdown phases.
Phase Type |
Phase Name |
Description |
Execution approach |
function |
start_of_simulation_phase |
Used to display testbench topology or configuration. |
Bottom to top |
a. run_phase
Phase Type |
Phase Name |
Description |
task |
run_phase |
Used for the stimulus generation, checking activities of the testbench, and consumes simulation time cycles. The run_phase for all components are executed in parallel. |
b. Other phases that run parallel to run_phase
Phase Type |
Phase Name |
Description |
task |
pre_reset |
Used to add any activity or functionality before reset as power-up signal goes active |
task |
reset |
Used to generate a reset and put an interface into its default state. |
task |
post_reset |
Used to add any activity that is required immediately after reset |
task |
pre_configure |
After the reset is completed, this phase is used to prepare DUT for configuration programming. Ex: It may be used as a last chance to update information before it is passed to the DUT. |
task |
configure |
Used to program the DUT and any memories in the testbench to keep it ready for the start of the test case. |
task |
post_configure |
Used to wait for the response after configuring DUT or wait for a certain DUT state so that the main test stimulus can be started. |
task |
pre_main |
Used to ensure that all required components are ready to generate stimulus. |
task |
main |
Used to apply generated stimulus to the DUT. Most of the time, stimuli are handled using sequences. This phase completed either all stimuli are exhausted or a timeout occurred. |
task |
post_main |
Used to take care of any finalization of the main phase |
task |
pre_shutdown |
This phase is a buffer for any DUT stimuli that have to take care before the shutdown phase. |
task |
shutdown |
Used to ensure that the effects of stimuli are driven to DUT during main_phase and that any resultant data has drained away. This phase may also be used to execute any time-consuming sequences that read status registers. |
task |
post_shutdown |
Used to perform any final activity before existing time-consuming simulation phases. |
Clean up phases
The clean-up phases are used to collect information from functional coverage monitors and scoreboards to see whether the coverage goal has been reached or the test case has passed. The cleanup phases will start once the run phases are completed. They are implemented as functions and work from the bottom to the top of the component hierarchy. The extract, check, and report phase may be used by analysis components.
Phase Type |
Phase Name |
Description |
Execution approach |
function |
extract |
Used to retrieve and process the information from functional coverage monitors and scoreboards. This phase may also calculate any statistical information that will be used by report_phase. |
Bottom to top |
function |
check |
Checks DUT behavior and identity for any error that occurred during the execution of the testbench. |
Bottom to top |
function |
report |
Used to display simulation results. It can also write results to the file. |
Bottom to top |
function |
final |
Used to complete any outstanding actions that are yet to be completed in the testbench. |
Top to down |
Why are phases introduced for UVM based System Verilog testbench but not for Verilog-based testbench?
All components are static in Verilog-based testbench whereas System Verilog introduced OOP (Object Oriented Programming) feature in the testbench. In Verilog, as modules are static, users don’t have to care about their creation as they would have already created at the beginning of the simulation. In the case of UVM based System Verilog testbench, class objects can be created at any time during the simulation based on the requirement. Hence, it is required to have proper synchronization to avoid objects/components being called before they are created, The UVM phasing mechanism serves the purpose of synchronization.
UVM Tutorials