UVM Objections

UVM objections are a crucial mechanism for controlling the simulation time, particularly within the run_phase. They allow components to signal that they are still active and need the simulation to continue. When all objections are dropped, the simulation advances to the subsequent phases (extract, check, and final).In the Universal Verification Methodology (UVM), objections are used to manage the synchronization of different components within a testbench. They allow hierarchical status communication among components, which is helpful in deciding when to end a phase or the entire test.

UVM Objection Diagram

Here’s a diagram to illustrate the objection mechanism in UVM:

+-------------------+
|   Build Phase     |
+-------------------+
          |
          v
+-------------------+
|  Run Phase        |
+-------------------+
          |
          v
+-------------------+
|  Extract Phase    |
+-------------------+
          |
          v
+-------------------+
|   Check Phase     |
+-------------------+
          |
          v
+-------------------+
|  Report Phase     |
+-------------------+

Key Concepts of UVM Objections

  1. Raising and Dropping Objections: Components can raise objections to indicate that a certain activity is in progress and should not be interrupted. Once the activity is completed, the objection is dropped.
  2. Hierarchical Objections: Objections can be raised and dropped hierarchically, meaning that a parent component can manage objections for its child components.
  3. Phase Objections: Each phase in UVM has a built-in objection mechanism. Components raise objections at the beginning of an activity and drop them at the end, allowing the phase to end only when all objections are dropped.

Why Use Objections?

  • Dynamic Simulation Control: Objections provide a way to dynamically control the simulation duration based on the activity of different components.
  • Synchronization: They help synchronize the execution of different parts of the testbench, ensuring that all necessary operations are completed before the simulation ends.
  • Testbench Automation: Objections automate the process of ending the simulation, removing the need for manual time limits or other workarounds.

How Objections Work:

  1. Raising an Objection: A component raises an objection using phase.raise_objection(this);. This tells the UVM scheduler that the component is still active and the simulation should not proceed to the next phase.

  2. Dropping an Objection: When a component has completed its work, it drops its objection using phase.drop_objection(this);. This signals to the UVM scheduler that the component is finished.

  3. Objection Counter: Each phase maintains an internal counter of raised objections. The phase will not advance until this counter reaches zero (i.e., all objections have been dropped).

Diagram 1: Basic Objection Mechanism

+-----------+     Raise     +--------------+     Drop     +-----------+
| Component |------------>| Phase        |------------>| Component |
| (Active)  |             | (Objections) |             | (Finished)|
+-----------+             +--------------+             +-----------+
                                 ^
                                 |
                                 | Objection Counter
                                 | (Increments on raise, decrements on drop)

 

Example Code:

class my_driver extends uvm_driver#(my_transaction);
  `uvm_component_utils(my_driver)

  task run_phase(uvm_phase phase);
    seq_item_port.get_next_item(req); // Get a transaction

    phase.raise_objection(this); // Raise objection before driving

    drive_transaction(req); // Drive the transaction onto the interface

    phase.drop_objection(this); // Drop objection after driving

    seq_item_port.item_done(); // Signal transaction completion
  endtask : run_phase
  //...
endclass

Diagram 2: Objection Lifecycle in run_phase

+-----------------+     +-----------------+     +-----------------+     +-----------------+
| Get Transaction |---->| Raise Objection |---->| Drive Transaction|---->| Drop Objection  |
+-----------------+     +-----------------+     +-----------------+     +-----------------+
        ^                                                                      |
        |______________________________________________________________________|

Objection Hierarchy:

Objections are hierarchical. When a component raises an objection, it implicitly raises an objection on all its parent components up to the top-level environment. This ensures that the entire testbench waits for all active components to finish.

Diagram 3: Hierarchical Objections

        Top Environment (Objections)
            /   |   \
       Env 1 (Objections)  Env 2 (Objections)
      /   \
Driver 1 (Raises Objection) Monitor 1

If Driver 1 raises an objection, objections are also raised on Env 1 and the Top Environment.

Objection Timeout:

It’s crucial to implement objection timeouts to prevent simulations from hanging indefinitely if a component fails to drop its objection. You can set a timeout using the phase.set_objection_timeout() method.

Example with Timeout:

task run_phase(uvm_phase phase);
  phase.set_objection_timeout(100ns); // Set a timeout of 100ns

  phase.raise_objection(this);

  // ... simulation activity ...

  phase.drop_objection(this);
endtask

If the objection is not dropped within 100ns, the simulation will issue an error and terminate.

Example Code for UVM Objections

Here’s an example of how to use objections in a UVM sequence:

class wr_rd_seq extends uvm_sequence#(mem_seq_item);
  `uvm_component_utils(wr_rd_seq)

  task pre_body();
    // Raise objection if started as a root sequence
    if(starting_phase != null) starting_phase.raise_objection(this);
  endtask

  task body();
    `uvm_do_with(req, wr_en == 1);
    `uvm_do_with(req, rd_en == 1);
  endtask

  task post_body();
    // Drop objection if started as a root sequence
    if(starting_phase != null) starting_phase.drop_objection(this);
  endtask
endclass

Advanced UVM Objection Concepts

Virtual Functions: Allow dynamic binding of methods at runtime. Constructors and Destructors: Initialize and clean up objects. Static Members: Shared by all instances of a class. Interfaces: Define a set of methods that a class must implement. Packages: Organize classes and interfaces into reusable modules.

Benefits of Using UVM Objections

  • Improved Synchronization: Ensures that all components are synchronized during execution.
  • Enhanced Flexibility: Allows for dynamic control over the testbench.
  • Better Test Management: Facilitates the management of test phases and end-of-test conditions.