Alberto Evasio Allara, STMicroelectronics Riccardo Oddone, Cadence Design Systems Introduction
Current and upcoming requirements to exhaustively verify a design under development can create significant challenges for verification, system and design engineers to quickly get from development to production. Further increasing the complexity of the whole verification effort is the need to build an environment able to reproduce the external world, to guarantee the design has been fully verified in all possible conditions before tape-out.
Although the introduction of the Open Verification Methodology (OVM) and tool suites to support it closed the major gaps for the design verification engineers, the OVM would not have been enough if it could not build a self-adaptive environment, able to replicate all dynamics necessary to satisfactorily cover all system requirements.
The OVM provides a built-in mechanism to statically configure verification components. The verification parameters can be used to control the verification environment topology as well as trigger specific behaviors. In some cases the configuration of the verification environment cannot be predefined at build time. In such cases, the verification components need to adapt their configuration, and hence their behavior, dynamically. For example, the verification environment configuration might be based on the register configuration of the design under verification (DUV)
This document describes an approach to enhance the OVM with run-time configuration capabilities. Static Configurability
The OVM class library implements a technology to configure the structure and the behavior of a verification component and its sub-hierarchies.
The configuration functions set_config_* provide a name-based approach for setting fields within sub-components before creating them during the build phase.
The configuration of a verification component can be captured in an instance of a configuration descriptor implemented as a simple specialization of an ovm_transaction object. Each of the internal parameters can be randomized and its values controlled by a set of constraints.
An example of a configuration object is shown in Code 1. Code 1: example of static configuration
In this example the OVM verification component (OVC) my_env uses a configuration descriptor named my_cfg. Such an object contains three parameters that will be used by the component to program a specific behavior of the OVC. The registration of the configuration descriptor with the ovm_component_utils* macro allows it to statically assign a value to this object before the execution of the building phase.
This capability is extremely useful during the development of tests at the block level because it allows the randomization of a configuration immediately followed by the creation of a verification object that behaves according to this configuration. Run-Time Configurability
There are applications where the behavior of a verification component cannot be predefined statically at build time but must change at run-time during the simulation. One example of such an application is the verification of a read/write channel for an HD Drive. The functionalities of such devices are controlled by a set of software-programmable registers and their value may change based on sectors processed from the media.
The same OVM configuration functions can be used for run-time configuration. In this scenario each verification component must include code to explicitly extract the configuration data. An example of a monitor is shown in Code 2. Code 2: example of a code that extracts the configuration at run-time
The run task of this example implements a standard structure of a monitor, an infinite loop that contains the code to collect the monitor transactions. At the beginning of each iteration the verification component extracts the configuration and adapts its behavior accordingly.
The set_config_object/get_config_object mechanism does not require any explicit connection between generation and use of a configuration. A drawback of the solution in Code 2 is the overhead generated by the continuous extraction of configuration descriptors even if the configuration does not change during the simulation.
This overhead can be removed by replacing the “pull” mechanism in Code 2 with a “push” mechanism based on the use of analysis ports. The configuration in this case is stored into the OVC at the ovm_env level. Any sub-components that need to use the configuration information can include a handle to the configuration object directly connected to the configuration object allocated at the top level of the OVC. The only difference with respect to the set_config_object/get_config_object mechanism is that an explicit connection between generation and use of the configuration is needed. Code 3 shows how this mechanism works.
Code 3: run-time configurability through an analysis port
Code 3 defines an OVC that includes a configuration descriptor (conf). The implementation of the write function required by the analysis port copies the my_cfg packet into the local UVC copy. Configurability at System Level
At system level the configuration of verification components depends, in many cases, on the internal register configuration of the DUV. The configuration mechanisms described in the previous sections can be successfully applied at the top level as shown in Figure 1.
Figure 1: run-time configuration mechanism at system level
The run-time configuration mechanism should include at least a register interface OVC to propagate the register programming to the DUV and a run-time configuration component dedicated to convert the DUV configuration into specific OVCs configurations. The sequence of the operations is:
- A sequence of register packets is sent to the register interface OVC.
- The sequence is converted by the register interface OVC into physical signals to program the DUV.
- The internal monitor of the register interface OVC collects the register packets and sends them externally through an analysis port.
- The analysis port is connected to a run-time configuration component, which includes a register map model mirroring the internal registers of the DUV. The register map model allows the physical registers to be converted back into logical fields.
- The logical fields are used by the run-time configuration component to create and populate the configuration objects of any other OVCs. Such configurations can be propagated either through set_config_object statements or through analysis ports as it has been shown in the previous sections.
Code 4 is a snippet of code with an example implementation of a run-time configuration component OVC. Code 4: Run-time configuration component code
The example in Code 4 implements, in particular, the write function that intercepts the register packets generated by the register interface OVC through an analysis port. The information is used to update an internal model of the register map (named rmap) whose content is used to convert register names into configuration parameters. In the code, every time there is an update of the register configuration the write function calls the methods config_ovc1 and config_ovc2 respectively. These methods are dedicated to create new configuration objects that are populated with the information extracted by the register map. config_ovc1 in particular forwards the configuration with the set_config_object mechanism while the config_ovc2 method shows the use of an analysis port.
Notice that at every register access the configuration of the OVCs is propagated. In some cases such overhead can be too high. A possible solution is to switch off the instantaneous propagation of the configuration (update_at_every_register_change=0) and drive the propagation of the configuration by the occurrence of an event triggered by the test. ovm_event (provided by the OVM) allows the identification of an event by its name and can be easily configured at build time. The only drawback of this solution is related to the fact that the propagation of the configuration must be explicitly activated by the test. Conclusion
This article builds on the configuration mechanisms of OVM-based verification components. Based on the static configuration approach supported by the OVM, this article has proposed a reasonably flexible approach that allows defining configuration descriptors for OVCs. This approach allows run-time OVC configuration changes, implements the ultimate objective to have an adaptive verification environment, and enables more exhaustive verification, by stressing the DUV under changes that represent normal behavior in the real world application.
If properly implemented, the described approach can be easily reused across different designs and also scale from block-level verification up to the whole SOC. Acknowledgments
Most of the ideas contained in this paper come from the discussions among the verification engineers of the data-storage division of STMicroelectronics and the verification specialists of the Cadence Core Competency team. In particular, the authors want to thank Gregory Augier, Matteo Barbati, Fabio Brognara, Brice Cossalter, Alain Mellan, Phu Huynh, Rohit Jindal and Everest Zuffetti for the contribution they bring to this topic.