Figure 4: Simulation Phases of the OVM
Next, the pre_run() phase allows the test to further customize and configure verification components and/or the design under test (DUT) prior to executing the test in the run() phase. At the conclusion of run(), which is a task, three reporting phases are executed: extract() allows results to be gathered from specific components, check() validates the results to determine the pass/fail status of the test, and report() lets each component
report its results and status to a log fi le or the display, using the message severity and formatting routines.
It is possible to define user-, project-, or company-specific phases and insert these into the default list. This ensures they are run on every component at the appropriate time during the simulation. The execution of phases is managed automatically throughout the environment at every level of the hierarchy.
The OVM does not require instantiation of individual components, as in the following example.
my_a = new("a",this); // hard-coded instantiation/allocation
Instead, the OVM facilitates reuse and customization through a class factory, which is a standard object-oriented technique allowing components to be instantiated and initialized on-the-fly from a central location as follows.
cmp = create_component("red", "a"); // flexible instantiation
All components in the OVM are extended from ovm_component, which is the return type of the create_component() method of the class factory. Thus, the return value must be cast to the specific component (my_a) that, by default, is now of type a_c, as it was in the original code. The class factory also allocates and initializes the component before returning it. The advantage of using the class factory is that it may be overridden to customize the environment.
ovm_factory::set_inst_override("top.a", "red", "green");
The set_type_override() method tells the class factory to return a component of type blue whenever a red is requested. The environment coded in this example now has a component of type blue for my_a (and any other instance of the red class), allowing a different set of behaviors without changing the environment code, simply because the environment was written to allow this flexibility. The use of TLM interfaces between components
facilitates this capability by enforcing the encapsulation of communication. As long as blue has the same interfaces as red, the rest of the environment is perfectly compatible. Similarly, the type returned by the class factory may also be overridden on a per-instance bases using set_inst_override().
One of the keys to reuse is being able to customize and configure components based on their context. The OVM manages this process by allowing components to specify configuration information for their children. During the execution of the post_new() phase, each component is responsible for checking whether its internal properties have been so configured, and, if they have, it sets those properties to the configured values. The build process continues top-down, allowing each component to modify the configuration and/or instantiation of its child components.
class my_env extends ovm_env;
function void build(); // called from post_new()
set_config_int("b", "is_active", 0);
class block extends ovm_component;
bit is_active = 1;
function void build();
cmp = create_component("driver", "d");
In this example, the environment directs the configuration for the block to set its is_active bit to 0. All OVM components are responsible for getting their own configuration information, so in its build process, the block component checks to get the value of is_active from the global table. If a value is found, it is used; otherwise, the default value is used. Configuration values may be set for int, string, and ovm_object parameters, so this
simple text-based interface (including wildcarding of names) can be used to set the configuration value for any information required, depending on the component being used.
In this case, the block is set to be inactive (is_active == 0). The block component continues its build process by using this configuration information to control the configuration and set up of its children. In this case, it uses the value of is_active to control whether to instantiate a driver component. This single block component may now be reused and controlled in many different environments, each of which may choose to activate the driver or not. By designing components to provide such flexibility, it becomes straightforward to create (or purchase) a library of verification components that may be reused without altering its internal contents.
Sequential Layered Stimulus
A third way that the OVM facilitates the customization of particular tests is through the specification of the actual stimuli that will be executed. The OVM enables the rapid creation of interesting transaction stimulus patterns without requiring detailed knowledge of the verification environment infrastructure. This important feature allows non-verification experts to quickly create interesting test scenarios that can be reused across multiple tests, verification environment topologies, and projects. Sequential stimulus can range from a purely directed approach to a constrained-random approach that allows constraint layering via class factories, such as that described above. Once defined, stimulus sequences can be reused as a subset of other stimulus sequences in order to create larger and more interesting test scenarios. Various scenarios can be executed in order to exercise the design with interesting mixes of the stimulus sequences. Complex protocols can be modeled by layering sequences in a hierarchical fashion that provides clean abstraction for each level of the hierarchy. For large verification environments, multiple interfaces can be controlled and coordinated from a central mechanism; known as a virtual sequence.
Successful verification projects require more than a standard language. A sophisticated methodology is needed to build leading-edge testbenches, ensure interoperability, and promote verification reuse. With several widely used but incompatible verification methodologies available, the industry has been clear in its desire for cooperation among EDA vendors to end the "methodology wars."
The co-development and endorsement by Mentor and Cadence give the OVM credibility and viability as the answer to the industry's concerns. The OVM is clearly the only interoperable, open, and proven verification methodology. With the release of the OVM, there is no longer a methodology war raging. The OVM is already the clear winner.
Copyright © 2008 All company or product names are the registered trademarks or trademarks of their respective owners.