Easing the use of APIs for verification IP stimuli
How to leverage a simpler, standardized approach to describing generic and reusable stimulus sequences for verification IP.
Given the increasing complexity of system design, there is a pressing need for standalone, pre-verified, built-in verification infrastructures. Verification IP (VIP) is an integral part of these infrastructures for block and system-level verification as it helps reduce the cycles spent on complex designs.
Stimulus generation is an important aspect of verification for creating both the simple and the complex scenarios used to hit functional bugs in a design. Stimulus-generation application program interfaces (APIs) in VIP help you write stimuli without much protocol knowledge that can in turn be combined into complex protocol scenarios for testing.
In general, VIP stimulus APIs should provide:
- Easy to write stimulus;
- Reusable stimulus from the block to system level;
- Reusable stimulus across various protocols;
- Protocol independence;
- Protocol functionality-specific APIs to achieve more complex protocol scenarios; and
- Minimal random behavior.
Ease-of-use is an essential characteristic. VIP should include Universal Verification Methodology (UVM) sequence components at various abstraction levels for generating stimulus using protocol-specific bus functional models (BFMs).
Although these protocol-specific sequence components consist of various SystemVerilog constraints that help in the generation of constrained random stimulus, they are not that easy to use. They lack the flexibility to support reuse of stimulus API sequences from one protocol to another, at various abstraction levels, and from the block to system levels.
What we require are generic, easy-to-use APIs that help us write stimuli quickly without worrying about protocol intricacies, that provide horizontal and vertical reuse of stimuli, and that are sufficiently flexible to generate portable stimuli for use across various verification platforms.
The solution lies in high-level APIs that support writing stimulus at the abstract read/write command level. Abstract read/write APIs help us to write instruction-level stimuli (more akin to software applications) that are easily reusable from the block to system level.
To understand this better, let’s first consider the difficulties that arise during stimulus generation and then describe a recommended approach for designing a generic reusable stimulus API sequence.
Difficulties in generating stimulus
Here are two scenarios that illustrate the difficulties faced in stimulus generation.
Scenario 1: Generating a coherent transaction on a cache coherent protocol interface
When creating a testbench environment for verifying a cache coherent interface, stimulus dependency on cache memory can complicate user sequences. You need to access cache memory at the start and end of each transaction. Beyond dependency on the local cache, there is dependency on setting the address region and domain (shareable or non-shareable) that is in general based on a system address map. For example, here are the steps you must take to perform a cache maintenance operation (CMO).
- Check the system address map to make sure the address lies correctly in one of the shareable regions.
- Access the master cache model to check the initial cache line state.
- Check the ordering for the same ID and cache line transactions in progress.
- Set a longer list of transaction attributes as per protocol legality.
- Perform the cache data/state update at the end of the transaction, as needed.
Though VIP for a cache coherent interface provides components such as a system address map, a cache model, and interface-specific sequence items, these are not enough to make it easy to generate stimulus. The user has to go through a lot of effort to access and modify various components while generating the transaction.
Scenario 2 – Running frames using a VIP on a display interface
To verify a display sink DUT, you would use display source VIP. From the display source, you might want to quickly run some frames at a particular resolution without knowing too much about the protocol. It is important that a VIP provides easy-to-use APIs for doing that quickly.
Easy-to-use stimulus API sequences
Now let’s look at how a stimulus API sequence should be structured to make it easy to use. Here, we will introduce a new category of stimulus APIs.
Stimulus API sequences consist of user-level stimulus APIs and basically represent a user interface. Implementation of these APIs should be separated from the API sequence and should be part of the stimulus controller. This helps in separating out protocol-specific logic from the user interface sequence.
There are various categories of APIs that could be part of a stimulus API sequence, but two stand out. Generic higher-abstraction APIs help you write quick stimuli without going into protocol intricacies. Protocol functionality-specific APIs help you generate deep protocol-specific scenarios.
Generic higher-abstraction APIs
Generic APIs are abstracted at a higher level and do not require the user to deal with protocol intricacies. They are further grouped into the following sub-categories:
- Instruction-level read/write APIs
- Abstract writes
- Abstract reads
- Transactional read/write APIs
- Makes use of generic Read-Write transaction item
- Barrier
- Any other API that defines a generic functionality
To verify a processor-based interface, you need to read or write a chunk of data in memory, preferably without worrying about protocol intricacies and a huge list of attributes associated with the protocol-specific transaction items. The first stimulus-generation requirement is for a generic read/write instruction-level API. Figure 5 shows a generic transaction item for passing generic read/write transaction information to the read/write API. This sequence item encapsulates a request to read or write a selected number of bytes in the system memory.
The read/write API is used for conducting basic reads and writes as if from a program running on a processor. It provides a basic interface, letting the stimulus controller choose the most appropriate bus protocol transaction.
The API methods have only a handful of simple arguments (command, address, and data) with no direct dependency on bus-specific attributes. Bus-specific attributes will be determined based on common VIP components — such as the address map — and the attributes API.
The stimulus API sequence provides the following instruction level read/write APIs, as well as a read/write transaction API (with minimal arguments and no protocol dependencies).
The transactional read/write API, ‘execute_txn’, makes use of a generic item.
Such a generic read-write transaction item comprises these characteristics:
- Used to initiate read/write transactions.
- Can also be used to retrieve read/write transaction information for analysis purpose.
- Fields are easy to understand and very generic.
- No protocol intricacies are involved.
Protocol functionality-specific APIs
Along with the generic higher-abstraction APIs, you need protocol-specific APIs to generate various protocol-related scenarios. Protocol functionality-specific APIs have the following characteristics.
- Have flexibility to directly execute protocol-specific transactions.
- Are independent of a big list of sequence item attributes.
- Precise attributes required for API specific functionality are captured.
- Attributes APIs and common VIP objects capture the rest of the attributes.
Common VIP objects and attributes API
In generic, higher-abstraction APIs and protocol functionality-specific APIs, the top level transaction of a stimulus sequence includes many attributes that allow for precise control over bus activity but remains simple to use as the API is abstracted so that only minimal inputs are required.
The stimulus controller implements the execution of these generic APIs, starting with the highest abstraction level bus sequence item in the VIP BFM. To do this, the stimulus controller needs to obtain and set values for all other transaction attributes that are not provided as inputs to the generic-instruction read/write or protocol-specific APIs. These attributes come either through common VIP objects or attributes APIs. Figure 7 shows the steps in API logic to create and generate a bus-specific sequence item through the VIP BFM.
Transaction attribute values taken through an attributes API are not available either from generic/protocol API or common VIP objects. Once a value is set using an attributes API, it is used in multiple transactions until changed again.
Common VIP objects — such as system address map, cache memory model, and generic slave memory — are generic objects and used across multiple protocols.
These generic objects help you define things consistently across multiple protocols. These are also used when extracting particular protocol-specific attribute values, such as system address map, slave id, protection type, and more.
There are a few other transaction attributes that are not extracted from the common VIP objects. A separate attributes API (set/get methods for each attribute) is provided in the stimulus sequence that can be set once and used by multiple transactions until changed again. If not set, then the default value is used for the attribute.
Conclusion
A typical VIP BFM provides stimulus APIs for stimulus generation. Reusable stimulus API sequences provide generic and more abstract APIs as well as protocol-specific APIs. This not only meets a pressing need for easy-to-use stimulus APIs as part of VIP packages, but also helps VIP developers design stimulus API sequences for their VIP.
Further reading
If you want to learn more about how to make your verification work easier and more effective using Verification IP, there are also several existing papers, and more coming, at the Mentor Graphics website, including Extending a Traditional VIP to Solve PHY Verification Challenges and Verifying Display Standards – A Comprehensive UVM Based Verification IP Solution.