Introduction to the Easier UVM Coding Guidelines
AbbreviationsAPI – Application Programming Interface
BFM – Bus-Functional Model
DUT – Design Under Test
OOP – Object-Oriented Programming
OVM – Open Verification Methodology (a predecessor of UVM)
TLM – Transaction Level Modeling (or Transaction Level Model)
UVM – Universal Verification Methodology
VIP – Verification Intellectual Property
Introduction, Principles, and Goals
Easier UVM is a set of vendor-neutral coding guidelines accompanied by a code generator that creates UVM code compliant to those guidelines. Easier UVM was created to help individuals and project teams learn and then become productive with UVM as quickly as possible and to reduce the burden of supporting UVM code within a company or organization.
SystemVerilog is a very large and complex language, and the UVM is a large and complex base class library. This poses a challenge for adopters, because there are often many ways to do the same thing. By choosing a particular approach users may find themselves in a pitfall, straying from industry best practice, or creating non-interoperable code. UVM itself exists in part to address this issue by providing a standard base class library for building class-based verification environments. But UVM gives you several ways to do the same thing, partly because of the need for backward compatibility with legacy methodologies. Backward compatibility is itself a good thing, but having too much choice can be a bad thing while you are still learning a complex methodology, and having a variety of coding styles can increase the burden of maintaining and supporting a UVM code base. Easier UVM was specifically created to address this issue by recommending one way to do it.
In devising the Easier UVM coding guidelines, we have had to make specific choices as to how to do things. The guidelines are more prescriptive than either the official UVM Class Reference or the UVM User Guide: this document gives some very specific recommendations about which UVM features to use and exactly how to use them. In some cases, we have been able to recommend best practice as commonly agreed upon across the industry. In other cases we have had to make a rather arbitrary choice to favor one way of doing things rather than another. It was generally felt more useful to provide clear guidance rather than to present alternatives, but that is not to say that alternative approaches would not be equally valid. In a few cases we have added a side-note to point out alternative approaches and to explain the rationale for the approach taken.
By reducing the number of coding patterns, by recommending specific coding conventions, and by automatically generating the initial framework for the verification environment, Easier UVM makes it easier to create a code base of maintainable and reusable UVM code. Easier UVM summarizes best practice based on experience in industrial projects. In some cases Easier UVM has been shown to save something like 6 weeks coding effort at the start of a project (depending on the details of the project), to help avoid pitfalls, to make code more reusable, and to help unify the way UVM is used across a company. Because the Easier UVM code generator itself is available under an open source license, you are even free to modify the code generator for your own purposes.
Easier UVM is meant to be taken as a set of coding guidelines or biases. Easier UVM alone will not address every issue you are going to face as you build a complex verification environment, and for that reason, every rule in Easier UVM can have exceptions. While all the code produced from the Easier UVM code generator is compliant to the guidelines, you can choose to follow the Easier UVM coding guidelines exactly or you are free to bend or adapt the guidelines to suit your own requirements. Because of this, we have not tried to distinguish between hard rules and soft guidelines in the list of guidelines. The SystemVerilog language and UVM itself are the standards.
A lot of the code that you will add to the basic framework produced by the code generator will be project-specific. For example, scoreboards can often become highly complex, application-specific, and hard-to-write, in some cases dwarfing the boilerplate code. Although Easier UVM is designed to make things easier, SystemVerilog and UVM are still very challenging to learn and use, so please do not think that Easier UVM will remove the need to attend a formal training class or reduce the need to spend time on self-study. You still need to have a solid understanding of what you are doing, but once you have completed your formal training, Easier UVM will give you a way to apply that knowledge as you start working on your first real project.
The Structure of a UVM Verification Environment
UVM is a methodology for building class-based verification environments in SystemVerilog, taking advantage of object-oriented programming techniques to help with code reuse. Reuse is right at the heart of UVM: if you are not planning to reuse verification code right from the start, then you may have missed the point of UVM.
The building blocks of a UVM verification environment are objects, that is, instances of classes, as opposed to the modules, processes, and functions familiar to Verilog or VHDL users. The significance of using objects is that they can be replaced at run-time, giving a huge amount of flexibility when it comes to reusing verification components and tests without tampering with the original source code. You can take an existing VIP (an item of Verification Intellectual Property) and replace subcomponents, alter the sequence of transactions it generates, or extend its behavior without touching (or copying) the source code and without the original author of the VIP having needed to anticipate your changes in any way other than having followed good coding guidelines. This is achieved using some OOP (Object-Oriented Programming) tricks.
Easier UVM recognizes three main types of user-defined object, plus a few other less important ones. The three main object types are the component, the sequence item, and the sequence (where the corresponding classes are uvm_component, uvm_sequence_item, and uvm_sequence, respectively), while the less important ones include configuration and callback objects. Components are structural, that is, they are instantiated at the start of simulation (strictly speaking, during the build phase), whereas sequence items and sequences usually represent test stimulus and are dynamic, that is, they are instantiated on-the-fly at run time. As long as the coding guidelines are followed, any of these objects can be replaced with modified or extended versions at the time they are created.
Easier UVM defines coding templates for the component, sequence item and sequence. Each of these coding templates is simple and regular, and the three kinds of template are mutually consistent wherever possible. There are coding guidelines for the way the lines are ordered within each class and naming conventions for user-defined names, all of which makes your code look consistent and makes it easier for other people to find their way around.
Each of these three kinds of object is instantiated by making a call to a factory method, which allows the original object to be substituted with a replacement in a way that need not have been anticipated by the original author. Using the UVM factory consistently in this way is one of the keys to being able to exploit OOP in UVM.
Each component instance can have an associated configuration object, which contains configuration information (i.e. parameters) specific to that component instance. Configuration objects (and other configuration information) are inserted into the configuration database in a top-down fashion, typically from the test or an environment, and are then accessible to components lower in the hierarchy. This configuration mechanism is very convenient in that a configuration object can be randomized (with in-line constraints) using a single call, and very flexible in that the same configuration object can be accessed from multiple components where appropriate.
Aside from using regularized coding templates, the factory, and configuration, there are also the issues of the overall organisation of the verification environment, connecting the verification environment to the DUT, the generation of reusable stimulus, the collection of functional coverage information, message reporting, and the end-of-test mechanism. Easier UVM provides specific guidelines in each of these areas.
Easier UVM Coding Guidelines
Introduction to the Easier UVM Coding Guidelines
Summary of the Easier UVM Coding Guidelines
Detailed Explanation of the Easier UVM Coding Guidelines
Easier UVM Glossary
Easier UVM Coding Guidelines - Download
Easier UVM - Deeper Explanations
Coverage-Driven Verification Methodology
Requests, Responses, Layered Protocols and Layered Agents
How to Access a Parameterized SystemVerilog Interface from UVM
Easier UVM Code Generator
Easier UVM Code Generator - Download
Easier UVM Code Generator - Tutorial Part 1: Getting Started
Easier UVM Code Generator - Tutorial Part 2: Adding User-Defined Code
Easier UVM Code Generator - Tutorial Part 3: Adding the Register Layer
Easier UVM Code Generator - Tutorial Part 4: Hierarchical Verification Environments
Easier UVM Code Generator - Tutorial Part 5: Split Transactors
Easier UVM Code Generator - Frequently Asked Questions (FAQ)
Easier UVM Code Generator - Reference Guide
Easier UVM Video Tutorial
Introducing Easier UVM
Easier UVM - The Big Picture
Key Concepts of the Easier UVM Code Generator
Running Easier UVM in EDA Playground
Easier UVM - Components and Phases
Easier UVM - Configuration
TLM Connections in UVM
Easier UVM - Transaction Classes
Easier UVM - Sequences
Easier UVM - Tests
Easier UVM - Reporting
Easier UVM - Register Layer
Easier UVM - Parameterized Interfaces
Easier UVM - Scoreboards
The Finer Points of UVM Sequences (Recorded Webinar)
UVM Run-Time Phasing (Recorded Webinar)
A YouTube playlist with all the above videos and more
Easier UVM Paper and Poster
Easier UVM - Coding Guidelines and Code Generation - as presented at DVCon 2014
Easier UVM Q&A Forum
Easier UVM Google Group
Easier UVM Examples Ready-to-Run on EDA Playground
Minimal example with driver
Minimal example with coverage in a subscriber as well as driver and monitor.
Minimal example with register sequence and register block
Example with four interfaces/agents, two of which use a register model.
Minimal example with dual-top modules and split transactors
Minimal example showing a UVM sequence getting information from the config database
Minimal example showing features of objections and the command line processor
Minimal example showing the reporting features of UVM.
Example that drops an objection when coverage exceeds some threshold
Example that sends a response transaction from the driver back to the uvm_reg_adapter
Example that uses a frontdoor sequence to pass a response object back to the register sequence that called read/write
Example of a parameterized interface generated from an Easier UVM interface template file
Example that pulls in a user-defined parameterized interface
Example of a reference model with the Syosil scoreboard
Back to the full list of UVM Resources