![]() Verification transactions call for highter abstractionBy Sean W. Smith Today's system designs are almost always centered on processing complex transactions, but verifying such designs at the level of individual signals, bits and bytes with Verilog or VHDL testbenches is rapidly becoming impractical. Transaction verification tasks are best handled in a robust software environment using object-oriented techniques. Transaction-based verification is the technique of abstracting the verification problem to a higher level. The specific behavior of individual signals, bits and bytes is modeled and hidden so that verifying the functional behavior of the higher-level functions, which are called transactions, can be accomplished more effectively. Looking at a memory controller, one can equate a "transaction" to a memory burst read or write. In a networking scenario, a transaction might be the transmission or reception of one or more frames. For a CPU, a transaction might be a sequence of instructions or even an entire program. Transactions can be nested to create even more complex scenarios and functions for complex systems. The verification of individual signals, bits and bytes is still important, but that mundane task is hidden from the typical user through a more robust software environment. Object-oriented techniques and programming languages provide tremendous power, flexibility and extensibility that aren't available to the verification engineer using procedural programming languages such as Verilog, VHDL or C. Data-driven verification raises the abstraction level when dealing with data stored in memory, including data grouping and data addressing. Traditional memory models and verification techniques deal with absolute addresses of individual memories and don't consider the integration of many memories into the system address space.
For example, traditional techniques might deal with bytes or bits of data as a physical memory, rather than addressing a situation in which eight 8-bit memories are used to create a logical 64-bit memory. But data-driven verification addresses those techniques, and it provides many other desirable features that allow the verification engineer to ensure the data's correctness and still maintain a high-level, abstract view of the memory in question. Object orientation Objected-oriented programming has become a mainstream software engineering practice. It advocates design extensibility, reusability and modularity. As digital systems have become more complex, applying such techniques to functional verification environments has become more practical and desirable. Verisity's "e" language is a powerful and effective tool for modeling system behavior, creating complex object-oriented testbench environments and generating complex stimuli. The object-oriented language extends the object features found in such languages as Java, Smalltalk and C++ to make them more applicable to hardware description. Three key features make e an effective object-oriented language for hardware verification. First is the ability to describe time, temporal events and complex temporal relationships. Second is the provision of seamless support for concurrency of execution, which is a key feature needed by any hardware description language. Finally, the language includes a generator a complex solver as the core technology used to provide stimulus to the device under test. The solver generates all random variables in the system, based on constraints that can be applied to the system in a top-down manner. The e language lets the user easily generate events and then launch and synchronize time-consuming methods to those events. Additional support for complex temporal expressions makes protocol checking easier than in HDLs. To handle concurrency, e provides the equivalent of Verilog "always" blocks as well as the functionality of "fork/ join" blocks. Multiple threads can also execute in parallel, and temporal expressions and semaphores can be used for synchronization. Most verification engineers would likely consider the generator its most striking and useful feature. All variables, by default, are random, but there are directives in e that cause variables not to be random. Furthermore, constraints using the "keep" command can be applied to limit the scope of random variables. Using these object-oriented features, the verification engineer can build a complex hierarchy of classes that abstracts minute details from the test writer and allows the user to concentrate on creating robust test cases. Using a hierarchy of object-oriented abstractions, the engineer can build from simple reads and writes to bursts. The concept of bursts can be raised to the data level to represent packets or other system information. Combining abstractions of timing, concurrency and generation in conjunction with system-level abstraction lets the engineer rapidly describe the use of the system by the external world. The Denali Memory Modeler provides features needed for transaction- and data-driven verification. Memories are one of the most important components in any digital system, and they account for the majority of transistors in most designs. Most memory and ASIC vendors provide some basic Verilog models for their external or embedded memories. Still, replacing those memories with something faster, more feature-rich and more robust is one of the first items to tackle when constructing a new verification environment. For that task, Denali memory objects are modeled in C and link to the simulation through the programming language interface (PLI) or object model interface (OMI). In addition to sparse memory implementation for efficient memory usage during simulation, the C-based modeling paradigm enables a rich set of features for transaction and data-driven verification. Key verification features are implemented in C, eliminating extra simulation cycles for such controls as loading, saving and comparing memory images from file, or combining heterogeneous memories into a single system memory view using combinations of width expansion, depth expansion, interleaving and masking of physical memories. While those additional functions are typically beyond the scope of handwritten or vendor-supplied memory models, they are critical and enable verification engineers to raise the level of abstraction universally for all memory types, eliminating the need to reinvent the wheel for every new type or instance of memory. All of the techniques and functions are globally accessible and are applicable across all supported memory types. All of those features can be accessed with a graphical user interface, Verilog PLI calls or C functions, and they are all well-adapted to the object-oriented programming paradigm. The functions or Verilog PLI calls can be used to create classes in an object-oriented language such as e. The user then simply instantiates one e Denali object for each physical or system memory, and seamlessly accesses all of the features using the class' methods. A simple class definition makes it possible to treat a memory model like any other object using the e language. For example, loading a memory with an object file requires only a simple method call. Denali models also provide a C language interface that offers many features to Specman, Vera and C users. A feature that is extremely useful is memory event callbacks. Every time a transaction occurs to the memory, a method call can be issued to e announcing that the instance, address and operation type were just performed. Employing memory event callbacks in e can yield powerful new checks that are difficult to issue otherwise. For example, the checks might verify logical-to-physical address translation, verify that no additional memory transactions were unnecessarily generated over the course of a test, or verify that no memory transactions were dropped or eliminated. Sean W. Smith is Asic Design and Verification Engineer at Cisco Systems Inc. (Research Triangle Park, N.C.).
|
| ||||||||||||||||