A Practical Guide to Adopting the Universal Verification Methodology (UVM)
What is the Universal Verification Methodology (UVM) ........................................................................................................... 9 1.1 Verification Planning and Coverage-Driven Verification ........................................................................................... 9 1.2 Multi-Language and Methodologies ...................................................................................................................... 11 1.3 What is Unique about This Book? .......................................................................................................................... 11 1.4 How to Use This Book ............................................................................................................................................. 11 1.4.1 How to Run the Examples.......................................................................................................................... 12 1.4.2 Conventions in This Book........................................................................................................................... 12 1.4.3 Abbreviations............................................................................................................................................. 13 UVM Overview ........................................................................................................................................................................ 15 2.1 UVM Testbench and Environments ...................................................................................................................... 15 2.2 Interface UVCs ...................................................................................................................................................... 16 2.2.1 Data Items.................................................................................................................................................. 16 2.2.2 Driver/Bus Functional Model (BFM) .......................................................................................................... 16 2.2.3 Sequencer .................................................................................................................................................. 16 2.2.4 Monitor ...................................................................................................................................................... 16 2.2.5 Collector .................................................................................................................................................... 17 2.2.6 Agents ........................................................................................................................................................ 17 2.2.7 The Environment ....................................................................................................................................... 18 2.2.8 Testbench................................................................................................................................................... 18 2.3 System and Module UVCs..................................................................................................................................... 19 2.3.1 Software UVCs ........................................................................................................................................... 19 2.4 The SystemVerilog UVM Class Library .................................................................................................................. 20 2.4.1 UVM Utilities ............................................................................................................................................... 21 2.4.1.1 The UVM Factory .............................................................................................................................. 21 2.4.1.2 Transaction-Level Modeling (TLM) ................................................................................................... 22 Object-Oriented Programming (OOP) ..................................................................................................................................... 23 3.1 Introduction .......................................................................................................................................................... 23 3.2 Designing Large Software Applications ................................................................................................................ 23 3.3 What is an Object in OOP? ................................................................................................................................... 24 3.4 Distributed Development Environment................................................................................................................ 24 3.5 Separation of Concerns ........................................................................................................................................ 24 3.6 Classes, Objects, and Programs ............................................................................................................................ 24 3.7 Using Generalization and Inheritance .................................................................................................................. 25 3.8 Creating Compact Reusable Code ........................................................................................................................ 26 3.9 Polymorphism in OOP........................................................................................................................................... 27 3.10 Downcast ............................................................................................................................................................ 28 3.11 Class Libraries ..................................................................................................................................................... 28 3.12 Static Methods and Attributes............................................................................................................................ 29 3.13 Parameterized Classes ........................................................................................................................................ 29 3.14 Packages and Namespaces ................................................................................................................................. 30 3.15 Unified Modeling-Language Diagrams ............................................................................................................... 31 3.16 Software Design Patterns ................................................................................................................................... 32 3.16.1 Software Design Anti-Patterns................................................................................................................. 32 3.17 Why Isn’t the Existing OOP Methodology Enough? ........................................................................................... 32 3.18 Aspect-Oriented Programming ......................................................................................................................... 33 Summary.......................................................................................................................................................................... 33 UVM Library Basks ................................................................................................................................................................... 34 4.1 Using the UVM Library.......................................................................................................................................... 34
4.1.1 Hello World Example ................................................................................................................................. 34 4.1.2 Guidelines for Using the UVM Library ....................................................................................................... 35 4.2 Library Base Classes .............................................................................................................................................. 35 4.3 The uvm_object Class ........................................................................................................................................... 36 4.3.1 UVM Field Automation .............................................................................................................................. 37 4.3.2 uvm_object Definition Guidelines ............................................................................................................. 37 4.3.3 UVM Object Automation Usage Examples ................................................................................................ 38 4.3.4 Using UVM Field Automation .................................................................................................................... 40 4.4 The uvm_component Class .................................................................................................................................. 40 4.4.1 Simulation Phase Methods ........................................................................................................................ 40 4.4.2 Hierarchy Information Functions ............................................................................................................... 42 4.4.3 uvm_top Component............................................................................................................................... 44 4.5 UVM Configuration Mechanism ......................................................................................................................... 45 4.6 Transaction-Level Modeling in UVM....................................................................................................................... 47 4.6.1 Key TLM Concepts in UVM ........................................................................................................................ 48 4.6.1.1 Modeling Transactions .................................................................................................................... 48 4.6.1.2 TLM Ports and Exports .................................................................................................................... 48 4.6.1.3 Connecting Ports to Exports ........................................................................................................... 50 4.6.1.4 Connecting Ports to Ports and Exports to Exports.......................................................................... 50 4.6.1.5 Using uvm_tlm_fifo ........................................................................................................................ 51 4.6.1.6 Analysis Ports and Exports .............................................................................................................. 52 4.6.1.7 `uvm_*imp_decl Macros .............................................................................................................. 54 4.7 UVM Factory ........................................................................................................................................................... 55 4.8 UVM Message Facilities .......................................................................................................................................... 58 4.8.1 UVM Message APIs .................................................................................................................................... 58 4.8.2 Guidelines for Using UVM Messages ......................................................................................................... 59 4.8.3 Modifying Message Verbosity ................................................................................................................... 59 4.9 Callbacks ............................................................................................................................................................... 60 4.9.1 Using Callbacks .......................................................................................................................................... 60 4.9.1.1 Developer ....................................................................................................................................... 60 4.9.1.2 User................................................................................................................................................. 61 4.9.2 Guidelines for Using Callbacks ................................................................................................................... 61 4.9.2.1 Developer Guidelines ..................................................................................................................... 61 4.9.2.2 User Guidelines............................................................................................................................... 61 4.9.3 The Report Catcher Built-In Callback ......................................................................................................... 62 Summary.......................................................................................................................................................................... 62 Interface UVCs ......................................................................................................................................................................... 63 5.1 Stimulus Modeling and Generation ...................................................................................................................... 63 5.1.1 Modeling Data Items ................................................................................................................................... 63 5.1.2 Defining Control Fields .............................................................................................................................. 64 5.1.3 Inheritance and Constraint Layering.......................................................................................................... 65 5.1.4 Using Empty Constraint Blocks for Tests .................................................................................................... 66 5.1.5 A Simple Data Item Test ............................................................................................................................. 66 5.2 Creating the Driver ................................................................................................................................................. 67 5.2.1 The SystemVerilog Interface and Virtual Interface .................................................................................... 68 5.3 Creating the Sequencer ........................................................................................................................................ 70 5.3.1 Key Randomization Requirements............................................................................................................. 70 5.3.2 A Non-UVM Generator .............................................................................................................................. 71
5.3.3 The UVM Sequencer .................................................................................................................................... 72 5.4 Connecting the Driver and Sequencer.................................................................................................................... 73 5.4.1 Basic Sequencer and Driver Interaction .................................................................................................... 73 5.4.2 Querying for the Randomized Item ........................................................................................................... 74 5.4.3 Supporting Pipeline Protocols ................................................................................................................... 74 5.4.4 Sending Processed Data Back to the Sequencer ....................................................................................... 75 5.5 Creating the Collector and Monitor...................................................................................................................... 75 5.5.1 Connecting the Collector and Monitor ...................................................................................................... 77 5.6 Modeling Topology with UVM .............................................................................................................................. 78 5.7 Creating the Agent ................................................................................................................................................ 79 5.7.1 Using connect() to Connect Components .................................................................................................... 81 5.7.2 Agent Configuration..................................................................................................................................... 81 5.8 Creating the UVM Verification Component ............................................................................................................ 81 5.8.1 The Environment Class .............................................................................................................................. 82 5.8.2 Point-to-Point Environments ..................................................................................................................... 83 5.8.3 The UVM Configuration Mechanism ......................................................................................................... 84 5.8.3.1 Making the UVC Reusable .............................................................................................................. 84 5.8.3.2 Configuration Requirements............................................................................................................. 85 5.8.3.3 UVC Configuration Object............................................................................................................... 85 5.8.3.4 Reconfiguring a Device ................................................................................................................... 87 5.8.4 Setting the Agent Virtual Interface ............................................................................................................ 87 5.9 Creating UVM Sequences ..................................................................................................................................... 89 5.9.1 User-Defined Sequences ........................................................................................................................... 90 5.9.1.1 Sequence and Sequence Item Macros ........................................................................................... 92 5.9.2 Predefined Sequences ............................................................................................................................... 93 5.9.2.1 uvm_random_sequence ................................................................................................................. 93 5.9.2.2 uvm_exhaustive_sequence ............................................................................................................ 93 5.9.2.3 uvm_simple_sequence ................................................................................................................... 94 5. 10 Configuring the Sequencer’s Default Sequence ................................................................................................ 94 5.10.1 Controlling the Sequencer and Generated Sequences ............................................................................ 94 5.10.2 Overriding Sequence Items and Sequences ............................................................................................ 95 5.10.3 Building a Reusable Sequence Library ..................................................................................................... 95 5.11 Coordinating End-of-Test .................................................................................................................................... 96 5.11.1 UVM Objection Mechanism .................................................................................................................... 96 5.11.2 End-of-Test Objection Mechanism Usage ................................................................................................ 97 5.11.3 Tracing Objection Information ................................................................................................................. 98 5.11.3.1 Querying the Objection Status ..................................................................................................... 98 5.11.3.2 Trace Objection Information ......................................................................................................... 98 5.11.4 Setting Drain Time ................................................................................................................................... 98 5.11.5 Identifying Lack of Progress ..................................................................................................................... 99 5.11.5.1 Using the Heartbeat Mechanism .................................................................................................. 99 5.11.5.2 Heartbeat Example ..................................................................................................................... 100 5.12 Implementing Protocol-Specific Coverage and Checks .................................................................................... 101 5.12.1 Placing Coverage Groups ....................................................................................................................... 102 5.12.1.1 Transaction Coverage.................................................................................................................. 102 5.12.1.2 Timing-Related Coverage ............................................................................................................ 103 5.12.2 Implementing Checks ............................................................................................................................ 103 5.12.3 Enabling and Disabling Coverage and Checks........................................................................................ 104
5.12.3.1 Using the checks_enable and coverage_enable Flags ................................................................ 104 5.12.3.2 Fine Granularity for Enabling and Disabling ............................................................................... 105 5.12.4 Implementing Checks and Coverage in Interfaces................................................................................. 105 5.13
Handling Reset............................................................................................................................................. 105 5.13.1 Reset Methodology for Interface UVCs ................................................................................................. 106 5.13.1.1 Propagating a Reset to the Interface UVC.............................................................................. 106 5.14 Packaging Interface UVCs ................................................................................................................................. 107 5.14.1 Interface UVC Directory Structure ......................................................................................................... 108 5.14.2 File Naming Conventions ....................................................................................................................... 108 5.14.3 UVC Packages......................................................................................................................................... 109 Summary........................................................................................................................................................................ 109 Automating UVC Creation ..................................................................................................................................................... 110 6.1 UVC Development Flow ...................................................................................................................................... 110 6.2 Code Generators ................................................................................................................................................. 111 6.3 Compliance Checklist .......................................................................................................................................... 113 6.4 Automated Compliance Checking ...................................................................................................................... 113 Summary........................................................................................................................................................................ 114 Simple Testbench Integration ................................................................................................................................................ 115 7.1 Testbenches and Tests ........................................................................................................................................ 115 7.1.1 The Testbench Class ................................................................................................................................. 115 7.1.2 The Test Classes ....................................................................................................................................... 116 7.1.2.1 Where Is My Test? ........................................................................................................................ 116 7.1.2.2 Why Not Use Program Blocks? ....................................................................................................... 116 7.2 Creating a Simple Testbench............................................................................................................................... 116 7.2.1 Instantiating UVCs in a Testbench ........................................................................................................... 116 7.3 Testbench Configuration ..................................................................................................................................... 119 7.3.1 UVC Configurable Parameters ................................................................................................................. 119 7.3.2 UVC Configuration Mechanism................................................................................................................ 119 7.3.3 Using a Configuration Class ..................................................................................................................... 120 7.4 Creating a Test .................................................................................................................................................... 121 7.4.1 Creating the Base Test ............................................................................................................................. 121 7.4.2 Creating a Test Library Using a Base Test ................................................................................................. 122 7.4.3 Test Selection ........................................................................................................................................... 122 7.5 Creating Meaningful Tests .................................................................................................................................. 123 7.5.1 Constraining Data Items .......................................................................................................................... 123 7.5.1.1 Creating a Test-Specific Frame ...................................................................................................... 124 7.5.2 Sequences and Sequencer Control ........................................................................................................... 125 7.5.2.1 Controlling the Number of Sequences Created by uvm_random_sequence ................................. 125 7.5.2.2 Creating and Adding a New Sequence.......................................................................................... 125 7.5.2.3 Creating Nested Sequences .......................................................................................................... 126 7.5.2.4 Setting the Default Sequence ....................................................................................................... 126 7.5.2.5 Sequence Libraries and Reuse ...................................................................................................... 127 7.5.2.6 Disabling a Sequencer .................................................................................................................. 128 7.5.2.7 Directed-Test Style Interface......................................................................................................... 129 7.6 Virtual Sequencers and Sequences .................................................................................................................... 130 7.6.1 The Virtual Sequencer ............................................................................................................................. 130 7.6.2 Creating a Virtual Sequence .................................................................................................................... 131 7.6.3 Controlling Other Sequencers ................................................................................................................. 132
7.6.4 Connecting a Virtual Sequencer to Sub-Sequencers ............................................................................... 132 7.7 Checking for DUT Correctness ............................................................................................................................ 133 7.7.1 Scoreboards ............................................................................................................................................. 133 7.7.1.1 UART Controller Scoreboard Example .......................................................................................... 134 7.7.1.2 Creating the Scoreboard ............................................................................................................... 134 7.7.1.3 Adding TLM Ports to uvm_scoreboard ......................................................................................... 134 7.7.1.4 TLM Write Implementation .......................................................................................................... 135 7.7.1.5 Adding the Scoreboard to the Environment ................................................................................. 135 7.8 Implementing a Coverage Model ..................................................................................................................... 135 7.8.1 Selecting a Coverage Method .................................................................................................................. 136 7.8.2 Implementing a Functional Coverage Model .......................................................................................... 136 7.8.2.1 Enabling and Disabling Coverage .................................................................................................. 136 Summary........................................................................................................................................................................ 137 Stimulus Generation Topics ................................................................................................................................................... 138 8.1 Fine Control Sequence Generation..................................................................................................................... 138 8.2 Executing Multiple Sequences Concurrently ...................................................................................................... 140 8.2.1 Using fork/join and `uvm_do in the Body of a Sequence ........................................................................ 140 8.2.2 Starting Several Sequences in Parallel ..................................................................................................... 140 8.3 Using p_sequencer ............................................................................................................................................. 141 8.4 Using the pre_body( ) and post_body( ) Methods ............................................................................................. 141 8.5 Controlling the Arbitration of Items ................................................................................................................... 141 8.6 Interrupt Sequences ........................................................................................................................................... 142 8.7 Protocol Layering ................................................................................................................................................ 143 8.7.1 Layering of Protocols ............................................................................................................................... 143 8.7.2 Layering and Sequences .......................................................................................................................... 144 8.7.2.1 Layering Inside One Sequencer .................................................................................................... 145 8.7.2.2 Layering of Several Sequencers .................................................................................................... 145 8.7.3 Styles of Layering ..................................................................................................................................... 146 8.7.3.1 Basic Layering ............................................................................................................................... 146 8.7.3.2 One-to-One, One-to-Many, Many-to-One, Many-to-Many .......................................................... 147 8.7.3.3 Different Configurations at Pre-Run Generation and Run Time ................................................... 147 8.7.3.4 Timing Control .............................................................................................................................. 147 8.7.3.5 Data Control.................................................................................................................................. 148 8.7.3.6 Controlling Sequences on Multiple Sequencers ........................................................................... 148 8.7.4 Using Layered Sequencers ....................................................................................................................... 148 Summary........................................................................................................................................................................ 151 Register and Memory Package .............................................................................................................................................. 152 9.1 Register-Related Terminology ............................................................................................................................. 152 9.2 Register Package Overview ................................................................................................................................. 153 9.2.1 Register Packages Usage Flow ................................................................................................................. 153 9.2.2 uvm_rgm Hook-Up and Data Flow .......................................................................................................... 154 9.2.3 The Register Database (RGM_DB) ........................................................................................................... 154 9.2.4 Randomization and Injection ................................................................................................................... 155 9.2.4.1 The Register Sequencer and Sequences ....................................................................................... 155 9.2.4.2 The Bus Interface UVC .................................................................................................................. 155 9.2.5 Monitoring ............................................................................................................................................... 155 9.2.5.1 The Interface UVC Monitor ........................................................................................................... 155 9.2.5.2 The Module UVC ........................................................................................................................... 155
9.3
Using the uvm_rgm Package .............................................................................................................................. 156 9.3.1 Defining the Register and Memory Models............................................................................................. 156 9.3.2 Creating an IP-XACT File .......................................................................................................................... 156 9.3.2.1 XML Structure ............................................................................................................................... 156 9.3.2.2 IP-XACT Structure ......................................................................................................................... 156 9.3.2.3 IP-XACT Vendor Extensions........................................................................................................... 157 9.3.2.4 Leveraging XML and IP-XACT Editors ............................................................................................ 158 9.3.2.5 Building the Register-Model Procedurally .................................................................................... 158 9.3.3 Creating uvm_rgm SystemVerilog Classes ............................................................................................... 158 9.3.3.1 Using the IP-XACT Utility .............................................................................................................. 159 9.3.3.2 The Generated SystemVerilog Code ............................................................................................. 160 9.3.3 Extending the Auto-Generated uvm_rgm Classes ........................................................................... 162 9.4 Connecting uvm_rgm Components in a Testbench ............................................................................................ 162 9.4.1 Connecting Register Components to a Testbench ................................................................................... 162 9.4.2 Adding the Necessary Infrastructure to the Bus Master Sequencer ....................................................... 163 9.4.3 Instantiation and Connection to the Testbench ...................................................................................... 165 9.4.4 Reset Handling ......................................................................................................................................... 166 9.5 Controlling Register Scenarios ............................................................................................................................ 167 9.5.1 Register Operations ................................................................................................................................. 167 9.5.2 Register Read/Write Sequences .............................................................................................................. 168 9.5.2.1 Read-Modify-Write Sequence ...................................................................................................... 169 5.9.3 Multi-Register Sequence Operations ....................................................................................................... 169 9.5.4 Sequences Reuse ..................................................................................................................................... 170 9.6 Using uvm_rgm for Checking.............................................................................................................................. 170 9.6.1 Using the Shadow Model for Checking.................................................................................................... 170 9.6.2 Advanced Register Checking .................................................................................................................... 171 9.6.2.1 Get Register Functions ................................................................................................................ 171 9.7 Updating the Register Database Model.............................................................................................................. 171 9.7.1 Updating the Module UVC....................................................................................................................... 172 9.8 Collecting Coverage of Register Activities .......................................................................................................... 172 9.8.1 Using uvm_rgm Automatic Coverage Facilities ....................................................................................... 173 9.8.2 User-Defined Coverage ............................................................................................................................ 173 9.9 Controlling Coverage-Sampling Time ................................................................................................................. 174 Summary........................................................................................................................................................................ 174 System UVCs and Testbench Infearation ............................................................................................................................... 175 10.1 Introduction ...................................................................................................................................................... 175 10.2 Module and System UVC Architecture ............................................................................................................. 177 10.2.1 Reuse in Module and System UVCs ....................................................................................................... 177 10.2.2 Module UVC Architecture...................................................................................................................... 177 10.2.3 System UVC Architecture ....................................................................................................................... 178 10.3 Sub-Components of Module and System UVCs ................................................................................................ 178 10.3.1 Monitor.................................................................................................................................................. 179 10.3.1.1 Scoreboard.................................................................................................................................. 180 10.3.1.2 Coverage ..................................................................................................................................... 181 10.3.1.3 Reference Model ........................................................................................................................ 181 10.3.2 Memory Blocks and Register Files ......................................................................................................... 182 10.3.3 Active Stand-In Mode ............................................................................................................................ 182 10.3.4 The Module UVC Class ........................................................................................................................... 182
10.4
Module UVC Configuration ............................................................................................................................... 182 10.4.1 Standard Configuration Modes.............................................................................................................. 183 10.4.2 Module UVC Reconfiguration ................................................................................................................ 184 10.5 The Testbench................................................................................................................................................... 184 10.5.1 The UART Controller Testbench Strategy ............................................................................................... 185 10.5.1.1 Configuration and Reconfiguration Mode .................................................................................. 186 10.5.1.2 The System-Level Virtual Sequence ............................................................................................ 186 10.5.1.3 Register Operations .................................................................................................................... 187 10.5.2 Virtual Sequencer and Register Sequencer ................................................................................................... 187 10.5.3 Interface UVC Extensions............................................................................................................................... 188 10.6 Sequences......................................................................................................................................................... 188 10.6.1 Developing Reusable Sequences ........................................................................................................... 188 10.7 Coverage ........................................................................................................................................................... 189 10.7.1 Module UVC Coverage ........................................................................................................................... 189 10.7.2 System-Level Coverage .......................................................................................................................... 191 10.7.2.1 Adding Coverage Definitions to System UVCs..................................................................... 192 10.8 Stand-In Mode .................................................................................................................................................. 192 10.9 Scalability Concerns in System Verification ...................................................................................................... 193 10.9.1 Randomization and Stimuli Creation ..................................................................................................... 193 10.9.1.1 Recycle Allocated Items .............................................................................................................. 194 10.9.1.2 Avoid Redundant Randomization ............................................................................................... 194 10.9.2 Coverage ................................................................................................................................................ 194 10.9.2.1 Grouping Coverage ..................................................................................................................... 194 10.9.2.2 Determining the Appropriate Tradeoff ....................................................................................... 194 10.9.3 Messages ............................................................................................................................................... 194 10.10 Module UVC Directory Structure .................................................................................................................... 195 Summary........................................................................................................................................................................ 195 The Future of UVM ................................................................................................................................................................ 196 11.1 Commercial UVM Verification IP ...................................................................................................................... 196 11.2 Class Library Enhancements ............................................................................................................................. 196 11.2.1 Register Package .................................................................................................................................... 197 11.2.2 Run-Time Phases................................................................................................................................. 197 11.2.3 Multi-Language Integration ................................................................................................................... 197 11.3 Multi-Domain UVM .......................................................................................................................................... 198 Summary........................................................................................................................................................................ 199
What is the Universal Verification Methodology (UVM) The Universal Verification Methodology (UVM) is a complete methodology that codifies the best practices for efficient and exhaustive verification. One of the key principles of UVM is to develop and leverage reusable verification components—also called UVM Verification Components (UVCs). The UVM is targeted to verify small designs and large-gate-count, IP-based system-on-chip (SoC) designs. The UVM has all of the verification features and capabilities your management may ask for to justify its use. ● It is mature—The UVM code is based on the Open Verification Methodology (OVM) library, with some modifications made on top of the proven OVM code. ● It is open—It is an emerging Accellera standard (and targeted for the IEEE) delivered in an open-source format. ● It is compatible and portable—It is tested to work on all major commercial simulators. On the technical side, UVM delivers a common objected-oriented UVM verification component (UVC) use model and ensures that all UVM-compliant UVCs will inter-operate, regardless of origin or language implementation. Key features of the UVM include:
DataDesign—Provides, viamethodologyandlibrary code, the ability to cleanly partition your verification environment into a set of specific data items and components. In addition, UVM provides many built-in capabilities that simplify activities such as textually printing and graphically viewing objects, hierarchically setting and getting data values in objects, and automating commonplace activities such as copying, comparing, and packing items. Together, this allows engineers to focus on what the objects contain and how they work, instead of the mundane supporting code.
Stimulus Generation—Provides classes and infrastructure to enable fine-grain control of sequential data streams for module- and system-level stimulus generation. Users can randomize data based on the current state of the environment, including the design under test (DUT) state, interface, or previously-generated data. The UVM provides built-in stimulus generation, which can be customized to include user-defined hierarchical transactions and transaction stream creation
Building and Running the Testbench—Creating a complete testbench (verification environment) for an SoC containing different protocols, interfaces, and processors is becoming more and more difficult. UVM base classes provide automation and help streamline usage of the UVM. A well-defined build flow allows creation of hierarchical reusable environments. A common configuration interface enables users to customize run-time behavior and testbench topology without modifying the original implementation, which is key for facilitating reuse.
Coverage Model Design and Checking Strategies—Enabling best-known practices for incorporating functional coverage, and physical and temporal, protocol, and data checks into a reusable UVC.
User Example—Including a golden System Verilog example, which is based on an easy-to-understand, yet complete protocol called the XBus. The example includes tests, sequences, testbench structures, and derived UVCs using the methodology and base classes.
1.1
Verification Planning and Coverage-Driven Verification
The ultimate goal of the UVM is to help you find more bugs earlier in the design process. In over 14 years of working with customers who have been building verification environments, we have learned that the best way uncover unanticipated bugs is by using controlled randomness. In fact, we have seen more users have ultimate success in finding unanticipated bugs using controlled randomness than any other verification technique. In many technical engagements, we would work with users who had already verified their design and we would ask them, “Will you let us try to find a bug
in a week?” Most engineers agreed right away. But how can you find bugs in a system that you are not familiar with, that was tested for a long period of time by capable engineers who are much more experienced in the specific verification requirements of the project than you? As you can probably guess, the solution is randomness! We would consult the local
engineers, abstract a protocol and system attributes that can be randomized, and let the random solver do the rest. Success was inevitable. UVM also provides the best framework to achieve coverage-driven verification (CDV). CDV combines automatic test generation, self-checking testbenches, and coverage metrics to significantly reduce the time spent verifying a design. The purpose of CDV is to:
Ensure thorough verification using up-front goal setting Eliminate the effort and time spent manually creating hundreds of tests Use run-time self-checking to simplify error analysis and debugging, and to receive error notifications as early as possible
The CDV flow is different from the traditional directed-testing flow. With CDV, you start by setting verification goals using an organized planning process. You then create a smart verification environment—one that generates random legal stimuli and sends it to the DUT. Coverage monitors are added to the environment to measure progress and identify non-exercised functionality. Checkers are added to identify undesired DUT behavior. Finally, simulations are launched when both the coverage model and testbench are implemented. Then a more complete verification can be achieved.
Using CDV, you can thoroughly verify your design by changing testbench parameters or changing the randomization seed. Test constraints can be added on top of the smart infrastructure to guide stimulus generation to meet verification goals sooner. Ranking technology allows you to identify the tests and seeds that contribute to the verification goals, and to remove redundant tests from a test-suite regression. Figure 1-1 is a graphical representation of this flow. CDV environments support both directed and automated testing. The recommended approach is to focus first on automated testing and let it do most of the work, before devoting effort to writing time-consuming, deterministic tests intended to reach specific scenarios that are too difficult to reach randomly. Proper planning can enable significant efficiencies and high visibility into the verification process. Creating an executable verification plan containing concrete metrics enables you to accurately measure your progress and thoroughness throughout a design and verification project. Using this proven method, sources of coverage can be planned, observed, ranked, and reported at the feature level. Using an abstracted, feature-based approach (and not relying on implementation details) results in a more readable, scalable, and reusable verification plan. You can find out more about this well-defined process and relevant automation capabilities in various vendor-specific materials.
Figure 1-1 Hie Verification Planning and Execution Flow
1.2
Multi-Language and Methodologies
Multi-language design and verification is usually not a project or corporate goal, but it is a fact of life and it provides an opportunity for companies to share and leverage more proven verification assets. No one really starts a new project with the goal of writing a multi-language verification environment from scratch. But many users want to save time by leveraging available verification code without rewrites. Depending on whether you already have multiple internal VIP components implemented in multiple languages, or if you may run into this requirement in the future, you probably need to consider a multi-language methodology now. With the number of acquisitions and joint-development activities in the industry today, we have seen that many users who have never dealt with reuse before now find it a common and necessary activity. UVM uses Transaction-Level Modeling (TLM) APIs to facilitate transaction-level communication between verification components written in SystemVerilog as well as between components written in other languages such as e and SystemC. Using the same API in all languages, it reduces the need to learn and bridge between facilities with different semantics. However, TLM is just the basics of multi-language (ML) interoperability. The UVM uses TLM for all standard languages. Examples of multi-language usage for both TLM 1.0 and TLM 2.0 are demonstrated in the Cadence OVM contribution and in Cadence product releases. Other facilities required for practical multi-language simulation include: a central configuration mechanism, traffic randomization and coordination, messages, and more.
1.3
What is Unique about This Book?
For some users, books are the preferred way to build knowledge; they provide an easy entry point for learning a topic. This book is based on many years of experience in multiple application domains and saves the users the expensive trial-and-error process to adopt a solution that works. It provides real-life tips and guidelines for successful methodology deployment, and suggests effective coding habits you can adopt from the beginning. The book does not cover the entire class library features, but focuses on the important ones that enable the concepts that make UVM users successful. When users go through multiple deployments of UVM, guidelines that looked insignificant at first can make a big difference. For example, it is important to establish a standard directory structure for reusable components. While the nature of the directory structure is always arguable, experience shows that this seemingly-small matter can have a huge impact on team collaboration. Another example is the need for consistency. While some guidelines look less critical for a single user or small scale projects, they quickly grow into real pain points during collaboration, or when training new engineers.
1.4
How to Use This Book
A typical verification team consists of multiple contributors with different skill sets and responsibilities. The different roles of developers and environment users require different depths of verification knowledge. The organization of this user guide is based on the way a typical verification team divides its responsibilities:
UVC developers create the reusable testbench infrastructure.
Environment users (or integrators) write tests for and configure the testbench infrastructure created by the developers to meet project-specific verification goals. We also differentiate between testbench
integrators who instantiate and configure testbenches and test writers who create the tests on top of an . already-assembled testbench.
In some companies the UVC developer, testbench integrator and the test writer are the same person. To gain a thorough understanding of UVM, we highly recommend that you read this entire book regardless of your individual role. However, the organization of the book allows environment users to quickly learn what they need to know without having to read and understand all of the methodology. This book is structured as follows:
To
Learn
About
Read
The structure of UVM testbenches and components
Chapter 2 “UVM Overview”
The basics of object-oriented programming
Chapter 3 “Object-Oriented Programming (OOP)”
The mechanics and basic facilities of the UVM library
Chapter 4 “UVM Library Basics"
The basic concepts and components that make up a standard
Chapter 5 “Interface UVCs”
reusable interface environment A technology and development flow that expedites UVC
Chapter 6 “Automating UVC Creation”
development and usage The creation of simple testbenches—collections of reusable
Chapter 7 “Simple Testbench Integration”
components with additional glue logic Note This is about initial interface UVC integration concepts and usage. Chapter 10 “System UVCs and Testbench Integration” covers the complete integration and how to leverage the register package and other testbench elements in a reusable way. Various techniques for sequence and randomization control
Chapter 8 “Stimulus Generation Topics”
A methodology and automation to enable productive and
Chapter 9 “Register and Memory Package”
reusable register-related verification logic How to wrap device-specific logic and reuse it in block,
Chapter
10
"System
UVCs
subsystem and system integration
Integration”
An overview of both the short-term and longer term areas in
Chapter 11 “The Future of UVM”
and
Testbench
which the UVM will likely be enhanced
1.4.1
How to Run the Examples
The main example used throughout this book is the development of a testbench for a UART Controller device. This design and testbench are based on the UART module testbench from the UVM Reference Flow, available in the contributions area of www.uvmworld.org. The UVM Reference Flow applies the UVM to the block and cluster verification in a SoC design. The smaller examples are also downloadable from www.uvmworId.org and are available in the contributions area, listed as UVM Book Examples. Each chapter has its own directory, and example numbers are on the files. The examples are self contained and easy to run. To run the examples with IUS, use the following command: % irun -f run.f
example-name.sv
Some examples provided in the example files are not fully described in the chapters. These are still a good source of reference. A complete list of examples is provided at the beginning of this book (see page xiii). We encourage you to download the reference flow and examples, review them, run them, and experiment with them.
1.4.2
Conventions in This Book
This book uses typeface variations to help you locate and interpret information easily. These type variations are explained in the following table.
Table 1-1 Typographical Conventions Typeface
courier font courier bold
Represents The Courier font indicates code. For example, the following line is UVM code:
uvm object utils(uart config reg) In examples, Courier bold highlights important lines of code to which you should pay attention. // Control field - does not translate into signal data rand
apb_delay_enum delay
kind; The italic font represents either user-defined variables or titles of books. In this example, exampk-name is the beginning of the filename for your SystemVerilog file:
italic
% irun -f run.f example-name.sv %
1.4.3
Abbreviations
The following table documents the abbreviations used in this book.
Abbreviation
Definition
AHB
Advanced High-performance Bus
AMBA
Advanced Microcontroller Bus Architecture
AOP
Aspect-Oriented Programming
APB
AMBA Advanced Peripheral Bus
API
Application Programming Interface
ATM
Asynchronous Transfer Mode
AVM
Advanced Verification Methodology
BFM
Bus Functional Model
CDV
Coverage-Driven Verification
CPU
Central Processing Unit
DMA
Direct Memory Access
DUT
Device Under Test
eRM
e Reuse Methodology
ESL
Electronic System Level
FPGA
Field-Programmable Gate Array
HDL
Hardware Description Language
HVL
High-Level Verification Language
HW
Hardware
IES
Incisive® Enterprise Simulator
IP
Intellectual Property
LRM
Language Reference Manual
ML
Multi-Language
OOP
Object-Oriented Programming
OSCI
Open SystemC Initiative
Abbreviation
Definition
AHB
Advanced High-performance Bus
AMBA
Advanced Microcontroller Bus Architecture
AOP
Aspect-Oriented Programming
APB
AMBA Advanced Peripheral Bus
API
Application Programming Interface
ATM
Asynchronous Transfer Mode
AVM
Advanced Verification Methodology
BFM
Bus Functional Model
OVM
Open Verification Methodology; see Preface for more information
PCI-E
Peripheral Component Interconnect Express
RDB
Register Database
RTL
Register Transfer Level
RVM
Reuse Verification Methodology
SC
SystemC
SoC
System-on-Chip
SV
SystemVerilog
Sw
Software
TCP
Transmission Control Protocol
TLM
Transaction-Level Modeling
UART
Universal Asynchronous Receiver/Transmitter
URM
Universal Reuse Methodology
UML
Unified Modeling Language
UVC
Universal Verification Component
VIF
Verification Interface
VIP
Verification IP
VMM
Verification Methodology Manual
UVM Overview This chapter provides an overview of the structure of UVM testbenches and components. This chapter describes: How to use the UVM to create SystemVerilog testbenches The recommended architecture of a UVM verification component
2.1
UVM Testbench and Environments
A UVM testbench is composed of reusable UVM-compliant universal verification components (UVCs). A UVM-compliant UVC is an encapsulated, ready-to-use and configurable verification environment intended for an interface protocol, a design sub-module, or even for software verification. Each UVC follows a consistent architecture and contains a complete set of elements for sending stimulus, as well as checking and collecting coverage information for a specific protocol or design. The interface UVC is applied to the device under test (DUT) to verify implementation of the design protocol logic or as a means to program the DUT For example, in bus UVCs, the UVC can emulate a central processing unit (CPU) that programs a direct memory access (DMA) device. Module UVCs contain internal verification logic for a subsystem or a module and enable the subsystem verification in a larger system. UVM-compliant UVCs expedite creating efficient testbenches for the DUT, and are structured to work with any hardware description language (HDL) and high-level verification language (HVL), including Verilog, VHDL, e, System Verilog, and SystemC.
Figure 2-1 UVM Testbench Example Figure 2-1, UVM Testbench Example, shows an example of a verification environment with three UVM-compliant interface UVCs and a module UVC. These UVCs might be stored in a company repository and reused for multiple verification environments. The UVCs are instantiated and configured for a desired operational mode. The verification environment also contains a multi-channel sequence mechanism (a virtual sequencer) that synchronizes the timing and the data between the different interfaces and allows fine control of the test environment for a particular test. For example, a virtual sequencer can ask the BUS interface UVC to execute the configure_dut sequence, and then ask external interface
UVCs to drive traffic for some time while polling the DUT status through the DUT The repository block on the right illustrates a company UVC repository that can contain internally implemented or commercial UVCs which can be leveraged by all verification projects.
2.2
Interface UVCs
The interface UVCs standard structure includes the following elements:
2.2.1
Data Items
Data items represent stimulus transactions that are input to the DUT, Examples include networking packets, bus transactions, and instructions. The fields and attributes of a data item are derived from the data items specification. For example, the Ethernet protocol specification defines valid values and attributes for an Ethernet data packet. In a typical test, many data items are generated and sent to the DUT. By intelligently randomizing data item fields using SystemVerilog constraints, you can create a large number of meaningful tests and maximize coverage.
2.2.2
Driver/Bus Functional Model (BFM)
A driver is an active entity which emulates logic that drives the DUT. A typical driver repeatedly pulls data items generated by a sequencer (advanced generator) and drives it to the DUT by sampling and driving the DUT signals. For example, a driver controls the read/write signal, address bus, and data bus for a number of clock cycles to perform a write transfer. (If you have created a verification environment in the past, you probably have implemented driver functionality.)
2.2.3
Sequencer
A sequencer is an advanced stimulus generator that controls the items provided to the driver for execution. By default, a sequencer behaves similarly to a simple stimulus generator and returns a random data item upon request from the driver. This default behavior allows you to add constraints to the data item class in order to control the distribution of randomized values. Unlike generators that randomize arrays of transactions or one transaction at a time, a sequencer includes many important built-in features. A partial list of the sequencer’s built-in capabilities includes: Ability to react to the current state of the DUT for every data item generated Capture of the order between data items in user-defined sequences, which forms a more structured and meaningful stimulus pattern Enabling time modeling in reusable scenarios Support for declarative and procedural constraints for the same scenario System-level synchronization and control of multiple interfaces
2.2.4
Monitor
A monitor is a passive entity that samples DUT signals but does not drive them. Monitors collect coverage information and perform checking. Even though reusable drivers and sequencers drive bus traffic, they are not used for coverage and checking—monitors are used instead. A monitor performs the following functions: Collects transactions (data items). A monitor extracts signal information from a bus and translates the information into a transaction that can be made available to other components and to the test writer. Note that this activity might be performed by a collector component that is described below.
Extracts events. The monitor detects the availability of information (such as a transaction), structures the data, and emits an event to notify other components of the availability of the transaction. A monitor also captures status information so it is available to other components and to the test writer. Performs checking and coverage Checking typically consists of protocol and data checkers to verify that the DUT output meets the protocol specification. Coverage is also collected in the monitor. Optionally prints trace information
Note We recommend splitting the monitor activity into signal- and transaction-level activities. This is done by splitting the monitor class into a low-level collector class and a high-level monitor that does transaction-level coverage and checking. See more information about the collector in “Collector” on page 17. On a protocol-by-protocol basis, an environment can instantiate a separate monitor per device (for example, a monitor per master or slave in an AHB bus), or a single bus monitor. A bus monitor handles all the signals and transactions on a bus, while an agent monitor handles only signals and transactions relevant to a specific device. Typically, drivers and monitors are built as separate entities (even though they may use the same signals) so they can work independently of each other. However, you can reuse code that is common between a driver and a monitor to save time.
Note To enable an agent to operate passively when only the monitor is present, do not make monitors depend on drivers for information.
2.2.5
Collector
In use models such as transaction-level modeling or acceleration, the signal-level activity is abstracted away completely, or placed into the accelerator box. In addition, advanced protocols include transaction-level state machines, which need to be checked and covered. When driving stimuli, the UVM enforces a good separation between the transaction level (sequencer) and the signal-level activity (driver). The collector enables a similar separation for the monitoring path. The collector is also a passive entity. It follows the specific protocol in order to collect bits and bytes and form transactions. An analysis port is used to send the collected transaction to the monitor, where coverage and checking are performed. While not mandatory, We recommend that you dedicate the monitoring path to a monitor and a collector. Figure 2-2, Monitor-Collector Interaction, demonstrates the interaction between the monitor and the collector.
Note UVM 1.0 EA does not currently include a separate collector class. TLM:uvm_analysis_imp
Monitor
Data transfer
Collector
TLM:uvm_analysis_port
Figure 2-2 Monitor-Collector Interaction
2.2.6
Agents
Sequencers, drivers, monitors, and collectors can be reused independently, but this requires the environment
integrator to learn the names, roles, configuration, and hookup of each of these entities. To reduce the amount of work and knowledge required by the test writer, UVM recommends that environment developers create a more abstract container called an agent. Agents can emulate and verify DUT devices. They encapsulate a driver, sequencer, monitor, and collector (when applicable). UVCs can contain more than one agent. Some agents are proactive (for example, master or transmit agents) and initiate transactions to the DUT, while other agents (slave or receive agents) react to transaction requests. Agents should be configurable so that they can be either active or passive. Active agents emulate devices and drive transactions according to test directives. Passive agents only monitor DUT activity.
2.2.7
The Environment
The environment (env) is the top-level component of the UVC. It contains one or more agents, as well as other components such as a bus monitor. The env contains configuration properties that enable you to customize the topology and behavior to make it reusable. For example, active agents can be changed into passive agents when the verification environment is reused for system verification. Figure 2-3, Typical Interface UVC, illustrates the structure of a reusable verification environment. Notice that a UVM-compliant UVC may contain an environment-level monitor. This bus-level monitor performs checking and coverage for activities that are not necessarily related to a single agent. An agents monitors can leverage data and events collected by the global monitor. UVM Environment Master Agent Config
Master Agent
name has...
Slave Agent Config
Slave Agent
Config Sequencer
Sequencer Monitor
Monitor
Bus Monitor checks coverage
Collector
uvm_driver Driver
DUT
uvm_driver Driver
Collector
bus
Figure 2-3 Typical Interface UVC The environment class (uvm_env) is designed to provide a flexible, reusable, and extendable verification component. The main function of the environment class is to model behavior by generating constrained-random traffic, monitoring DUT responses, checking the validity of the protocol activity, and collecting coverage. You can use derivation to specialize the existing classes to their specific protocol. This book describes the process and infrastructure that UVM provides to replace existing component behavior with IP-specific behavior.
2.2.8
Testbench
A testbench is an environment that instantiates the rest of the reusable verification components. Interface, system, and SW environments are instantiated, configured, and connected in a testbench component. If the next generation of a device uses exactly the same interfaces of an existing device, the testbench can be re-applied and reused. But usually the
testbench is specific to the DUT and to the project, and is typically not reused in vertical reuse scenarios. Refer to Figure 2-1 to see the integration of multiple UVCs in a UVM testbench.
2.3
System and Module UVCs
As already discussed, an interface UVC captures protocol-related verification aspects. But where would you place a device-specific set of verification aspects? For example, where would you place end-to-end coverage of multiple interfaces? Or a DUT-specific checker? For these purposes, a module UVC is needed. A module UVC is an environment that contains verification logic for a specific module or subsystem. It assists in verifying this subsystem, as it is vertically reused in a larger environment. A system UVC makes use of interface, module, and software UVCs (UVCs that can dynamically control software execution). A system UVC might not contain its own agents, in which case it merely instantiates other UVCs and connects them to create a larger verification environment. System UVCs are targeted at system verification—for example, a CPU, bridge, or a cell phone. Relatively small system UVCs sometimes are called module UVCs. A system UVC typically makes use of other UVCs, including: Interface UVCs for connecting to the system interfaces Other module or system UVCs, which are subsystems or modules of the current system being verified Any system UVC can he reused in a larger system verification environment. The system UVC architecture is similar to the interface UVC architecture and contains: A collector for signals that connect to the DUT. A monitor that is fed by the collector and other interface UVCs’monitors. Virtual (multiple channel) sequencers connected to the sequencers of the interface and subsystem UVCs. While interface UVC sequencers control a single interface, a virtual sequencer controls multiple sequencers and orchestrates the system-level scenario. Its sequence library defines multiple-channel sequences, which simultaneously control all of the system interfaces. A scoreboard—an untimed reference model that allows end to end checking. The scoreboard receives input from the interface UVCs and compares the DUT responses to the testbench prediction for the same input. We recommend using a scoreboard in the system UVC. An address map and register files. Most systems use memory and registers, which can be modeled using a register package. With UVM, you will have a pointer to the register database address map and register files.
2.3.1
Software UVCs
Verification poses requirements such as How can you ensure that an interrupt occurred while visiting all the software states? Or, How can you steer the simulation to visit this specific HW/SW corner cases? SW UVCs arc- elegant solutions for requirements such as these. A SW UVC expands the coverage-driven verification (CDV) capabilities of a testbench to control and monitor software. The software UVC provides run-time control to the execution of driver routines. It can control the type, time, and parameters of routine calls, and can collect desired coverage for software state variables. Virtual sequences can be used to seamlessly control HW interfaces and SW execution. Coverage monitors can collect coverage for HW, SW and their associations.
Note We do not cover SW UVCs in this book, if you are interested in additional information regarding these, please contact a Cadence representative. Figure 2-4, Typical System-Level UVM Testbench, shows how interface, module, and system UVCs can be reused to compose a specific verification environment, including HW/SW co-verification. Later in this book we cover the details of how to develop this type of environment.
Figure 2-3 Typical System-Level UVM Testbench
2.4
The SystemVerilog UVM Class Library
The SystemVerilog UVM Class Library provides all of the building blocks you need to quickly develop well-constructed, reusable, verification components and test environments (see Figure 2-5). The library consists of base classes, utilities, and macros. Components may be encapsulated and instantiated hierarchically and are controlled through an extendable set of phases to initialize, run, and complete each test. These phases are defined in the base class library but can be extended to meet specific project needs. See the UVM Class Reference for more information.
Figure 2-5 (Partial) UVM Class Hierarchy The advantages of using the SystemVerilog UVM Class Library include: A robust set of built-in features—The SystemVerilog UVM Class Library provides many features that are required
for verification, including complete implementation of printing, copying, test phases, factory methods, and more.
Correctly-implemented UVM concepts—Each component in the block diagram in Figure 2-3 is derived from a corresponding SystemVerilog UVM Class Library component. Figure 2-6, Typical UVM Environment Using UVM Library Classes, shows the same diagram using the derived SystemVerilog UVM Class Library base classes. Using these base-class elements increases the readability of code since each components role is predetermined by its parent class. UVC Environment (uvm_env) uvm_agent Config name has...
uvm_agent
uvm_agent
uvm_agent
Config
Config
uvm_monitor
uvm_sequencer sequences
uvm_monitor
uvm_sequencer sequences
uvm_collector
uvm_driver uvm_driver
uvm_collector
uvm_driver uvm_driver
uvm_monitor checks coverage
DUT
Figure 2-6 Typical UVM Environment Using UVM Library Classes
2.4.1
UVM Utilities
The SystemVerilog UVM Class Library also provides various utilities to simplify the development and use of verification environments. These utilities support debugging by providing a user-controllable messaging utility. They support development by providing a standard communication infrastructure between verification components (TLM) and flexible verification environment construction (UVM factory). The SystemVerilog UVM Class Library provides global messaging facilities that can be used for failure reporting and general reporting purposes. Both messages and reporting are important aspects of ease of use.
2.4.1.1
The UVM Factory
The factory method is a classic software design pattern used to create generic code, deferring to run time the exact specification of the object that will be created. In functional verification, introducing class variations is frequently needed. For example, in many tests you might want to derive from the generic data item definition and add more constraints or fields to it; or you might want to use the new derived class in the entire environment or only in a single interface; or perhaps you must modify the way data is sent to the DUT by deriving a new driver. The factory allows you to substitute the verification component without having to change existing reusable code. The SystemVerilog UVM Class Library provides a built-in central factory that allows: Controlling object allocation in the entire environment or for specific objects, Modifying stimulus data items, as well as infrastructure components (for example, a driver) Use of the UVM built-in factory reduces the effort of creating an advanced factory or implementing factory methods in class definitions. It facilitates reuse and adjustment of predefined verification IP in the end-user’s environment. One of the
biggest advantages of the factory is that it is transparent to the test writer and reduces the object-oriented expertise required from both developers and users. See “UVM Factory” on page 55 for more information and examples of the UVM factory.
2.4.1.2
Transaction-Level Modeling (TLM)
UVM components communicate by way of standard TLM interfaces, which improves reuse. Using a SystemVerilog implementation of TLM in UVM, a component may communicate, by way of its interface, to any other component which implements that interface. Each TLM interface consists of one or more methods used to transport data. TLM specifies the required behavior (semantic) of each method but does not define their implementation. Classes inheriting a TLM interface must provide an implementation that meets the specified semantic. Thus, one component may be connected at the transaction level to others that are implemented at multiple levels of abstraction. The common semantics of TLM communication permit components to be swapped in and out without affecting the rest of the environment. See “Transaction-Level Modeling in UVM” on page 47 for more information.
Object-Oriented Programming (OOP) Unless you are an OOP expert, we encourage you to review this chapter and make sure you understand the terminology. While you can learn the UVM library and pick up the details as you go along, it is more efficient to build some OOP foundations before going through the verification methodology and the use model. Many books have been written about OOP; this brief chapter covers only the basics of OOP. Our goals are to show the motivation behind OOP, introduce basic concepts, and demonstrate these concepts using simple SystemVerilog examples in a HW verification context. This chapter includes: Distributed development environments Polymorphism in OOP Libraries and inheritance reuse UML block diagrams SW design patterns Why OOP isn’t enough Aspect-Oriented Programming
3.1
Introduction
In the early days of software engineering there were epic struggles with project complexity, growth, and the challenge of managing large development teams. Object-Oriented Programming (OOP) introduced a revolution to the software community to help deal with these problems. OOP focuses on modularity, change tolerance, code reuse, ease of understanding, and distributed development. Most projects today use object-oriented concepts. Since C++ introduced OOP, user experience has generated more knowledge about how best to make use of OOP. There is a lot of agreement and even more debate about OOP. Which features should be encouraged? Does C++ define which features are object-oriented? As reuse and verification IP become prevalent in hardware verification, OOP is applicable. In fact, functional verification provides ideal conditions for reuse, as standard protocols, systems, and even tests and interesting sequences of transactions take advantage of OOP.
3.2
Designing Large Software Applications
Traditionally, a program is seen as a collection of functions. This works well for small applications, but hinders reusing a subset of the program or making use of distributed parallel development process in which different engineers own different aspects of the program. So how can we design a large application? OOP suggests using a “divide and conquer” approach in which applications are a set of related, interacting objects. For example, an application that emulates traffic would involve cars, drivers, and traffic lights, instead of designing an application for the complete traffic system, we should focus on separate modules to capture cars, drivers, and traffic light operations. The same is true for a testbench or verification project. Instead of focusing on the complete application, we focus on data items or protocol-specific components that eventually comprise the testbench.
3.3
What is an Object in OOP?
An object is an entity that holds data and methods that operate on that data. Each object can be viewed as an independent little machine or actor with a distinct role or responsibility. In our traffic emulation example, the cars, drivers, and traffic lights are all objects.
3.4
Distributed Development Environment
One of the challenges in OOP is defining the objects and the interaction between them. This initial agreement is key for allowing individuals and teams to collaborate. The objects provide services via an agreed upon public interface (contract). Other objects can use this public API. The objects internal implementation can be independently developed and refined. Languages provide information-hiding facilities to limit object use to its public methods. Figure 3-1 demonstrates two developers working in an OOP environment, using an agreed-upon interface between separate objects.
Figure 3-1 OOP Interface Objects Enable Parallel Development
3.5
Separation of Concerns
Can we use the same objects to create other systems? Or copy one object and leverage it in a different system? This requires building independent objects. No functionality overlap should exist between the objects. For instance, our traffic emulation example may also include a race track. In a typical race track, there are no traffic lights, no turn signals, and the cars are much faster. If the implementation of a car assumes the existence of traffic lights, it cannot take part in a race track system that has no traffic lights. In the same vein, a functional verification example can have a packet that should not send itself or commit to a specific protocol/driver. If it does, it cannot be used in an environment that requires a different driving protocol or protocol layering,
3.6
Classes, Objects, and Programs
A class defines the abstract characteristics (attributes) and behavior (methods) of an object. It is a blueprint that allows creating one or more objects of the same type. For example, there might be a class for cars that defines all of the things a car object can contain. Then, a particular make of car, say a ... Plorsche, is a sub-class (specialization) of the car class, with its own particular attributes above and beyond a general car class. Finally, a car object is a particular instance of a car with specific color and engine attributes, such as a silver Plorsche coupe. There could be many Plorsche cars that share these attributes; all these would be objects of the Plorsche sub-class, or specialization, of cars. Objects hold run-time data and are used as a building block of a program. A program or application instantiates objects and triggers their interaction. Figure 3-2 below illustrates how a program is made of class object instantiations.
Figure 3-2 Program and Object Interaction class car; // class definition local lock my_lock; // internal implementation local engine my_engine; task void run(); // public interface task void open(); endclass: car module top; car my_car = new; // object of instance creation my_car.run(); endmodule: top
Note
SystemVerilog classes are different from the Verilog module instances in their dynamic nature. The module
instances, their number, and hierarchy are created at the time of elaboration in Verilog, and are static throughout the simulation. Objects can be created during run time upon request. This allows for the creation of modular and optimized data structures. In functional verification, the build process of a testbench is dynamic, which makes it more flexible. It uses procedural flow control to instantiate the needed testbench structure. Dynamic objects are used to represent data items such as packets, frames or transactions that are created during run time, as required, and often take into account other environment variable values.
3.7
Using Generalization and Inheritance
Humans perceive the world using generalization. An abstract notion of a car means: four wheels, an engine, at least two doors, a steering wheel, and so on. This ability to abstract allows us to organize data and enables efficient communication. For example, you can say “I drove my car to work yesterday” and listeners would understand without the need for you to define a car, and talk about the specific car you drove, or the way that you “drive.” These details are unnecessary to understanding the intent of your simple statement. Object-oriented programming allows us to do the same thing with software design. You can define a generic class notion and, using inheritance, create specializations of that abstract class. A sports car could be a specialization of the generic car notion. As well as having all car attributes, it has more horsepower, better handling, and often attracts attention. A user can express the desired functionality—for example, drive() a car—without knowing the specific details of what driving means in a specific car. Using inheritance allows objects with sufficiently similar interfaces to share implementation code. A parent class that should never be instantiated—meaning it exists only for modeling purposes to enable reuse and abstraction—is declared as a virtual class.
Changing the car abstract type changes all of the derived types.
car engine wheels run() open()
//define virtual classes Virtual class car; ... Endclass Virtual class truck Extends car; ... endclass
sports_car
truck
sedan
retractable_roof
cargo_area
four_doors
open_roof()
open_tailgate()
open_trunk() Virtual class
Flerrari
Plorsche
open_roof()
open_roof()
Implements its own unique method for open_roof()
Figure 3-3 Using Inheritance and Generalization Example 3-1 Generalization and Inheritance virtual class car; // note that car is a virtual class local lock my_lock; local engine my_engine; task run(); endtask task open(); endtask endclass: car virtual class sports_car extends car; task run () ; ... endtask; endclass: sports_car class plorsche extends sports_car; task run () ; ... endtask; // plorsche’s runt() endclass: plorsche
3.8
Creating Compact Reusable Code
If you have an overlap between objects, consider creating an abstract class to hold the common functionality and derive a class to capture the variation. This will reduce the amount of code needed for development and maintenance. For example, request and response packets may have similar attributes, but the data generated in the request is collected at the response, and vice versa.
Request byte data[ ] byte delay bit legal_par calc_par() ls_consist() constraints1
Response byte data[ ] byte delay bit legal_par calc_par() ls_consist() constraints2
Overlap
Figure 3-4 The Overlap between Request and Response Request byte data[ ] byte delay bit legal_par calc_par() ls_consist() Request constraint1
Response constraint2
Figure 3-5 Using an Abstract Class to Model the Request and Response
3.9
Polymorphism in OOP
Programs may require manipulating sets of objects in a procedural way. For example, you might want to have an abstract handle to car, and in a loop call the run() method of all the cars in an array. Each car class has a different run() method implementation. The ability to execute run() on an abstract class and have the specific run() executed is called “polymorphism.” The programmer does not have to know the exact type of the object in advance. Example 3-2 below demonstrates how Plorsche and Flerrari cars are derived from an abstract sport car class. Polymorphism allows the print() task of the program to hold a pointer to the virtual class array that may consist of both Plorsche and Flerrari cars, but execute the correct print() function for each item. Example 3-2 Inheritance and Polymorphism 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
typedef enum {RED, BLUE, BLACK, WHITE} color_t; virtual class sports_car; rand color_t color; virtual function void print(); // virtual keyword $display("I’m a %s sports car", color.name()); endfunction endclass: sports_car class plorsche extends sports_car; virtual function void print(); $display("I’m a %s plorsche", color.name()); endfunction endclass: plorsche class flerrari extends sports_car; virtual function void print(); $display(”I’m a %s flerrari", color.name ()); endfunction endclass: flerrari module top; ... task print_all(sports_car cars[]); for (int i=0;i=0; transmit_delay transmit_delay == 0; 15 (delay_kind == SHORT) -> transmit_delay inside { [1:10] }; 16 (delay_kind == MEDIUM) -> transmit_delay inside { [11:29] }; 17 (delay_kind == LONG) -> tramsmit_delay inside { [30:100] }; 18 (delay_kind == MAX) -> transmit_delay == 100};
19 //UVM utilities and automation macros for data items 20 `uvm_object_utils_begin( apb_transfer); 21 `uvm_field_int(addr, UVM_DBFAULT); 22 `uvm_field_int(data, UVM_DEFAULT); 23 `uvm_field_enum(apb_direction_enum, direction, UVM_DEFAULT); 24 `uvm_field_enum(apb_dly_enum, delay_kind, UVM_DEFAULT| UVM_NOCOMPARE | UVM_NOPACK); 26 `uvm_field_int(transmit_delay,UVM_DEFAULT | UVM_NOCOMPARE | UVM_NOPACK); 28 `uvm_object_utils_end 29 // Constructor - required OVM syntax 30 function new (string name="apb_transfer" ); 31 super.new (name) ; 32 endfunction : new 33 endclass : apb_transfer Using this method allows you to create more abstract tests. For example, you can specify distribution as: constraint c_delay_kind_dist { delay_kind dist {ZERO:=2, SHORT:=1, MEDIUM:=1, LONG:=1, MAX:=2};} When creating data items, keep in mind what range of values are often used or which categories are of interest to that data item. Then add knobs to the data items to simplify control and coverage of these data item categories.
Notes
Control knobs that are added for generation and coverage purposes should not be compared, packed or unpacked since they are not sent to the DUT. We do not discuss here data-item attributes that are added for coverage purpose only, such as adding a start_time and an end_time to cover a transfer processing time. These attributes are best captured by the monitor to enable passive operation mode and are discussed in the coverage section below.
5.1.3
Inheritance and Constraint Layering
for a specific test, you might want to adjust the randomness, disable existing constraints or further change the generation using additional constraints. This is achieved using class inheritance. You create a new class which extends from the original class. All the original fields, methods and constraints are available in the extended class. You override an existing constraint by adding a constraint with the same constraint name. Or you can add a constraint with a different name to specify additional constraints: class short_delay_transfer extends apb_transfer; // further constrain the transmit_delay constraint c_short_delay {transmit_delay < = 3 ; } endclass : short_delay_transfer
Note In the code snippet above, the constructor and UVM automation macros have been omitted for brevity. In future examples, the constructor and macros will be shown only when needed. Please remember to include a constructor and UVM automation macros for all components and data items derived from uvm_object. In this example, the constraint block in the class short_delay_transfer will be solved together with the constraint blocks from the class apb_transfer during randomization, and the value of transmit_delay will be constrained between 0 and 3. In a larger environment, you will often want to replace apb_transfers with short delay transfers. The UVM factory greatly simplifies the replacement of a type with a derived type such as short_delay_transfer. This is one of the major reasons for using the factory. Such constraint layering requires usage of the UVM factory.
To enable this type of extensibility: Make sure constraint blocks are organized so that users are able to override or disable constraints for a random variable without having to rewrite a large constraint block. Note Many users find that writing a larger number of short constraint blocks is easier than a small number of long constraint blocks. Do not use the protected or local keywords to restrict access to properties that may be constrained by the user. This will limit your ability to constrain them with an inline constraint. Use descriptive names for constraints. This will make it easier for users not familiar with the original definition to understand and override constraints in derived types.
5.1.4
Using Empty Constraint Blocks for Tests
A user can leave in a class an empty constraint block that later can be filled with constraints by the test writer. This technique is not System Verilog-compliant, but is supported by all of the simulators. Using an empty constraint block is an ad hoc layering technique. As well as not being part of the language reference manual (LRM), it has the limitations of not supporting instance overrides; not supporting multiple extensions, as no new class is created; and no ability to turn off or override existing constraint blocks. Further, you can only compile one set of constraints at a time, so it makes it difficult to manage for all but the smallest projects. We recommend using the factory solution over external implementation of constraint blocks. For more information on the factory, see “UVM Factory" on page 55.
5.1.5
A Simple Data Item Test
When you have captured your data item with its control knobs and constraints, you can write a simple test to create, randomize and print a few items to verify the results you expect are produced. Example 5-3 Test for the apb_transfer Data Item 1 2 3 4
module test; // import the UVM library and include the UVM macros import uvm_pkg::*; `include "uvm_macros.svh" // include the data item class `include "apb_transfer.sv"
5 6 7 8 9 10 11 12 13 14 15
apb_transfer my_xfer; initial begin my_xfer = apb_transfer::type_id::create("my_xfer"); repeat (5) begin if (!my_xfer.randomize()) `uvm_fatal ("RANDFAIL", "Can not randomize my_xfer") my_xfer.print(); end endmodule : test
Notes To run this test on the Cadence IES simulator, first set UVM_HOME to the location of your UVM library installation, then run the following command: % irun $UVM_HOME/src/uvm_pkg.sv -incdir $UVM_HOME/src test.sv This simple test will also verify that you have access to the UVM library and macros. If you forgot to specify a field with the uvm_field_* macros, it will not be printed. Check your constraints by randomizing with additional constraints:
if(!my_xfer.randomize() with { addr inside {{‘hOOOO:’hFFFF]); direction == APB_WRITE; }) ... additional code ... As well as looking at the generated values, try to look at the distribution of the values. Some constraint sets can create an undesired bias to the generated values. It is useful to define a transaction coverage group and use it for such analysis. Randomize and cover the transaction multiple times in a loop and review the generation result. Do you have too many reads vs. write transfers? Is the length delay between transactions reasonable? Are the generate transaction kinds evenly distributed? Fix the constraints needed to achieve the desired results.
5.2
Creating the Driver
When data items are generated, the drivers role is to drive them to the bus following the interface protocol The driver obtains data items from the sequencer for execution. Once the driver is finished sending the data item, it may return a value back to the sequencer. For example, the sequencer can randomize a read bus transaction and send it to the driver for delivery to the DUT. The driver performs the read operation on the bus and returns the result value back to the sequencer. The SystemVerilog UVM Class Library provides the uvm_driver base class, from which all driver classes should be extended. The uvm_driver class is parameterized by both the request type (the data that is randomized by the sequencer) and the response (the DUT result that goes back to the sequencer). Built-in TLM ports are provided to communicate with the sequencer. To create a driver: Derive a driver class from the uvm_driver base class. It is parameterized with the request and response data item type(s), so ensure that your driver class provides types for these parameters. Declare a virtual interface in the driver to connect the driver to the DUT interface. Add the UVM infrastructure and automation macros for class properties to provide implementations for print(), copy(), compare(), and so on. In the run() task, get the next data item from the sequencer and drive it on the virtual interface. Refer to “Configuring the Sequencer’s Default Sequence” on page 94 for a description of how a sequencer, driver, and sequences synchronize with each other to generate constrained random data. The example below defines an AMBA advanced peripheral bus (APB) master driver. The example derives apb_master_driver from uvm_driver (parameterized to use the apb_transfer transaction type) and uses the methods in the seq_item_port object to communicate with the sequencer. As always, include a constructor and the `uvm_component_utils macro to register the driver type with the common factory. Example 5-4 APB Master Driver Definition 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
class apb_master_driver extends uvm_driver #(apb_transfer); // Virtual interface used to drive and view HDL signals virtual apb_if vif; // UVM utility and automation macros for general components `uvm_component_utils(apb_master_driver) // Constructor function new (string name, uvm_component parent); super.new(name, parent); endfunction : new // Additional class methods extern virtual task run(); extern virtual protected task get_and_drive () ; extern virtual protected task reset_signals(); extern virtual protected task drive_transfer(apb_transfer trans) endclass : apb_mastex_driver task apb_master_driver::run(); fork
18 19 20 21
get_and_drive() ; reset_signals() ; join endtask : run
22 23 24 25 26 27 28 29
task apb_master_driver::get_and_drive(); forever begin // Get the next data item from sequencer (may block). seq_item_port.get_next_item(req); drive_transfer(req);// Execute the item seq_item_port.item_done(req); // Return the request. end endtask : get_and_drive
task apb_master_driver::drive_transfer (input apb_transfer trans); ... // Add your logic here. endtask : drive_transfer Line 1: Derive the driver from uvm_driver. By parameterizing the driver with a class type, it will have a built-in variable named req of the type apb_transfer (the data item). This is the data type you will retrieve from the sequencer. 30 31 32
Notes By default, the response field accepts the same type as the request field. So this driver accepts apb_transfer types and returns apb_transfers back to the sequencer. For a different request and response type, use: class apb_driver extends uvm_driver #(apb_transfer_req, apb_transfer_res); Your driver class can optionally provide a second parameter for the type of response sent back to the sequencer. If you chose not to provide a second parameter, the response type will be the same as the request type. In this example, we are providing only a single parameter for the request type. Line 5: Add the UVM component utilities macro. Line 7: The constructor for uvm_components has two arguments: a string name and a reference to the component’s parent.
Note In the data item section, we had several fields registered with macros. It is common for components to have a small number of fields. And in many instances, there are no fields registered at all. Line 25: Call get_next_item() to get the next data item for execution from the sequencer. Line 27: Signal the sequencer that the execution of the current data item is done. Line 31: Add your application-specific logic to the drive_transfer() method to execute the data item. When first developing the UVC, you may want to only print the transaction until you have integrated a SystemVerilog interface. More flexibility exists on connecting the drivers and the sequencer. See “Connecting the Driver and Sequencer” on page 73. We recommend that you use extern virtual protected tasks in the driver; this allows a concise view of the drivers API. We also recommend that you place the external implementation of these in the same file. This allows a quick review of the class interfaces without introducing too many files. A driver should not randomize parameters and, as much as possible, the traffic control should be reserved for the sequencer. This allows reusing the test logic, even if the driver does not exist (for example, when verifying the TLM model). Timing and injection-related parameters, such as delay between data items or timing-related error injection, should be randomized by the sequencer and delivered to the driver as part of the request.
5.2.1
The SystemVerilog Interface and Virtual Interface
The driver interacts with the DUT using a virtual interface. The SystemVerilog interface construct is used to bundle the DUT signals that will be connected to the UVM testbench. The interface definition is part of the reusable UVC. SystemVerilog interfaces are defined outside a module boundary, are instantiated in a module, and the interface signals
are references via a “operator (interface. sig_name). In addition to signals, the interface can contain assertions, parameters, functions, tasks, module ports(modports) and clocking blocks. The example code below shows a simple interface declaration for an APB bus. Example 5-5 APB Interface Definition interface apb_if (input pclock, input preset); // APB Bus Protocol Signals logic [31:0] paddr; logic prwd; logic [31:0] pwdata; logic penable; logic [15:0] psel; logic [31:0] prdata; logic pslverr; logic pready; // Control flags bit has_checks =1; bit has_coverage = 1; // Checking and coverage (via assertions) would follow here endinterface : apb_if The pclock and the preset are ports as they are always input to the interface UVC. This makes the interface more modular and simplifies the connectivity especially if interface arrays are used. An interface cannot be instantiated inside of a class. Instead, SystemVerilog provides an additional keyword “virtual” which enables you to place a reference to an interface inside of a class. This allows you to instantiate an interface and connect it up to the signals of your DUT and then in your driver make a reference to the instantiated interface. A SystemVerilog virtual interface provides the mechanism for connecting abstract signals to the actual signals. A virtual interface can be referenced inside classes anywhere inside the dynamic testbench. The virtual interface must be connected to an actual interface instance and signals are referenced using a hierarchical reference to the virtual interface. The syntax for a virtual interface inside a class is shown in Example 5-4 on page 67 but repeated here for you: class apb_master_driver extends uvm_driver; virtual apb_if vif; // Virtual interface declaration // UVM macros // Constructor // user methods endclass : apb_master_driver The drive_transfer task then accesses the DUT signals through this virtual interface: 1 task apb_master_driver::drive_transfer(apb_transfer trans); 2
int slave_index;
3
if(trans.transmit_delay>0)
4
repeat(trans.transmit_delay) @(posedge vif.pclock);
5
//Driver the address phase of the transfer
6
slave_index =cfg.get_slave_psel_by_addr(trans.addr);
7
vif.paddr