UVM Phases
UVM phases are the backbone of the UVM simulation lifecycle. They provide a standardized, deterministic order of execution for different parts of the testbench, ensuring consistent and predictable behavior. Understanding UVM phases is crucial for writing robust and reliable verification environments.
Why UVM Phases?
- Standardization: Phases provide a well-defined order of execution, making it easier to understand and debug complex testbenches.
- Automation: The UVM scheduler automatically executes the phases in the correct order, reducing manual intervention.
- Synchronization: Phases help synchronize the execution of different components in the testbench.
- Reusability: Phases enable the creation of reusable verification components that can be easily integrated into different testbenches.
Types of UVM Phases:
UVM defines two main categories of phases:
-
Build Phases: These phases are responsible for constructing the testbench hierarchy. They execute in a bottom-up fashion.
-
Run-Time Phases: These phases are responsible for the actual simulation and verification process. They execute in a top-down fashion.
Key UVM Phases
Your Roadmap
1. Build Phases (Bottom-Up)
This is the primary phase for constructing the testbench hierarchy. Components are instantiated, connections are made, and configurations are applied.
Functions: build_phase()
, connect_phase()
, end_of_elaboration_phase()
Diagram 1: Build Phase Execution (Bottom-Up)
Top Environment
/ | \
Env 1 Env 2 Env 3
/ \ / \ / \
Comp 1 Comp 2 Comp 3 Comp 4 Comp 5 Comp 6
Execution Order: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 (Top Environment)
- Diagram:
+-------------------+ | Build Phase | +-------------------+ | v +-------------------+ | Construct & Init | +-------------------+
2. Run-Time Phases (Top-Down)
These phases execute in the following order:
connect_phase
: This phase establishes connections between components, such as connecting ports and exports.end_of_elaboration_phase
: This phase is called after all connections are made and before the simulation starts. It’s typically used for final setup and configuration.start_of_simulation_phase
: This phase is called at the very beginning of the simulation.run_phase
: This is the main phase for running the simulation. It’s where sequences are executed, drivers drive stimulus, and monitors collect data.
- Functions:
run_phase()
- Diagram:
+-------------------+ | Run Phase | +-------------------+ | v +-------------------+ | Generate Stimulus | | Check Responses | +-------------------+
extract_phase
: This phase is used to extract data from the simulation, such as coverage information.
- Functions:
extract_phase()
- Diagram:
+-------------------+ | Extract Phase | +-------------------+ | v +-------------------+ | Extract Data | +-------------------+
check_phase
: This phase is used to check the results of the simulation and report any errors.- Functions:
check_phase()
- Diagram:
+-------------------+ | Check Phase | +-------------------+ | v +-------------------+ | Perform Checks | +-------------------+
final_phase
: This phase is called at the very end of the simulation. It’s typically used for final cleanup and reporting.- Functions:
report_phase()
- Diagram:
+-------------------+ | Report Phase | +-------------------+ | v +-------------------+ | Generate Report | +-------------------+
-
Diagram 2: Run-Time Phase Execution (Top-Down)
Top Environment / | \ Env 1 Env 2 Env 3 / \ / \ / \ Comp 1 Comp 2 Comp 3 Comp 4 Comp 5 Comp 6 Execution Order: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 (Top Environment) (But each component executes connect_phase, end_of_elaboration_phase, etc. before moving to the next phase.)
Diagram 3: Overall UVM Phase Execution
+-----------------+ +-----------------------------------------------------------------+ | Build Phases |---->| Run-Time Phases | +-----------------+ +-----------------------------------------------------------------+ | build_phase | | connect_phase -> end_of_elaboration_phase -> start_of_simulation_phase| | (Bottom-Up) | | -> run_phase -> extract_phase -> check_phase -> final_phase | +-----------------+ +-----------------------------------------------------------------+ ^ | | Simulation Time
Detailed UVM Phase Diagram
plaintext+------------------+ | Build Phase | +------------------+ | v +------------------+ | Run Phase | +------------------+ | v +------------------+ | Extract Phase | +------------------+ | v +------------------+ | Check Phase | +------------------+ | v +------------------+ | Report Phase | +------------------+
Phase Jumping:
UVM provides mechanisms for jumping between phases or skipping phases altogether. This is typically done using the
phase.raise_objection()
andphase.drop_objection()
methods within therun_phase
.Example of raising and dropping objections in run_phase:
task run_phase(uvm_phase phase); phase.raise_objection(this); // Raise objection to keep simulation running // Perform simulation activities (e.g., run sequences) seqr.start_item(seq); seqr.finish_item(seq); phase.drop_objection(this); // Drop objection to allow simulation to finish endtask
Example Code for UVM Phases
Here’s an example of how to implement these phases in a UVM testbench:
class my_env extends uvm_env; `uvm_component_utils(my_env) function void build_phase(uvm_phase phase); super.build_phase(phase); // Build components endfunction task run_phase(uvm_phase phase); super.run_phase(phase); // Generate stimulus and check responses endtask function void extract_phase(uvm_phase phase); super.extract_phase(phase); // Extract data endfunction function void check_phase(uvm_phase phase); super.check_phase(phase); // Perform checks endfunction function void report_phase(uvm_phase phase); super.report_phase(phase); // Generate report endfunction endclass
Benefits of UVM Phases
- Modularity: Different tasks are separated into distinct phases, making the testbench more modular.
- Reusability: Testbenches can be reused for different designs with minimal changes.
- Scalability: Facilitates the creation of large and complex verification environments.
- Synchronization: Ensures that all components are synchronized during execution.
Key Considerations:
- Phase Synchronization: Ensure that different components in your testbench are properly synchronized using phases and objections.
- Phase Domains: UVM supports phase domains, which allow you to create separate sets of phases for different parts of your testbench.
- Objections: Objections are used to control the duration of the run_phase. A component raises an objection to indicate that it is still active and drops the objection when it is finished. The simulation ends when all objections have been dropped.