| Preface | p. xix |
| Acknowledgments | p. xxi |
| Introduction | p. 1 |
| Background | p. 3 |
| What is Functional Verification? | p. 4 |
| Why Focus on SystemVerilog? | p. 5 |
| A Tour of the Handbook | p. 5 |
| For Further Reading | p. 6 |
| SystemVerilog and Verification (The Why and How) | p. 7 |
| Why SystemVerilog? | p. 9 |
| Overview | p. 10 |
| SystemVerilog as a Verification Language | p. 11 |
| Main Benefits of Using SystemVerilog | p. 13 |
| Drawbacks of Using SystemVerilog | p. 13 |
| SystemVerilog Traps and Pitfalls | p. 14 |
| SystemVerilog is not Verilog | p. 14 |
| Errors and run-time crashes | p. 15 |
| Five languages in one! | p. 15 |
| The assertions language | p. 15 |
| The constraint language | p. 16 |
| The coverage language | p. 18 |
| SystemVerilog features not discussed | p. 19 |
| Summary | p. 20 |
| For Further Reading | p. 20 |
| OOP and SystemVerilog | p. 23 |
| Overview | p. 24 |
| The Evolution of OOP and SystemVerilog | p. 25 |
| Assembly programming: The early days | p. 25 |
| Procedural languages: The next big step | p. 25 |
| OOP: Inheritance for functionality | p. 26 |
| OOP: Inheritance for interface | p. 28 |
| A word or two about "interface" | p. 28 |
| The Evolution of Functional Verification | p. 29 |
| Verification through inspection | p. 29 |
| Verification through randomness | p. 29 |
| The emergence of hardware verification languages | p. 30 |
| OOP: A current trend in verification | p. 31 |
| OOP: A possible next step | p. 31 |
| OOP and SystemVerilog | p. 32 |
| Data abstraction through classes | p. 32 |
| A DMA descriptor example | p. 32 |
| Access control | p. 33 |
| Constructors | p. 34 |
| Member methods and variables | p. 35 |
| Inheritance for functionality | p. 36 |
| Inheritance for code interface | p. 37 |
| What's a header file? | p. 39 |
| Packages | p. 40 |
| Separating HDL and testbench code | p. 42 |
| Wiggling wires: the interface concept | p. 42 |
| Building and using interfaces | p. 44 |
| Summary | p. 46 |
| For Further Reading | p. 46 |
| A Layered Approach | p. 47 |
| Overview | p. 48 |
| A Whiteboard Drawing | p. 50 |
| An "ends-in" approach | p. 51 |
| Refining the whiteboard blocks | p. 52 |
| The "Common-Currency" Components | p. 52 |
| The Component Layer in Detail | p. 53 |
| The connection layer | p. 54 |
| The agent layer | p. 56 |
| The transaction layer | p. 57 |
| The Top-Layer Components | p. 58 |
| What is a Test? | p. 60 |
| The Test Component | p. 62 |
| The Test Irritator | p. 64 |
| A Complete Test | p. 65 |
| Summary | p. 67 |
| For Further Reading | p. 67 |
| An Open-Source Environment with SystemVerilog | p. 69 |
| Teal Basics | p. 71 |
| Overview | p. 72 |
| Teal's Main Components | p. 72 |
| Using Teal | p. 74 |
| A simple test | p. 74 |
| Logging Output | p. 74 |
| Using Test Parameters | p. 77 |
| Accessing Memory | p. 79 |
| A memory example | p. 80 |
| Constrained Random Numbers | p. 84 |
| Required initialization | p. 84 |
| Using random numbers | p. 85 |
| Working with Simulation Events | p. 86 |
| Summary | p. 87 |
| Truss: A Standard Verification Framework | p. 89 |
| Overview | p. 90 |
| General Considerations | p. 91 |
| SystemVerilog considerations | p. 91 |
| Keeping it simple | p. 92 |
| Major Classes and Their Roles | p. 93 |
| Key test algorithm: The "dance" | p. 94 |
| The verification_component Virtual Base Class | p. 97 |
| Detailed Responsibilities of the Major Components | p. 98 |
| The testbench class | p. 99 |
| Watchdog timer | p. 101 |
| Test class | p. 102 |
| Test Component and Irritator Classes | p. 106 |
| The test component virtual base class | p. 106 |
| An AHB example | p. 108 |
| Test-component housekeeping functionality | p. 109 |
| The irritator virtual base class | p. 110 |
| Using the irritator | p. 112 |
| Summary | p. 113 |
| Truss Flow | p. 115 |
| Overview | p. 116 |
| About truss_verification_top.sv | p. 116 |
| The Test Component Dance | p. 119 |
| The Irritator Dance | p. 121 |
| Compiling and Running Tests | p. 122 |
| The truss run script | p. 123 |
| Switches | p. 124 |
| Using "-f" files | p. 125 |
| The First Test: A Directed Test | p. 125 |
| The Second Test: Adding Channels and Random Parameters | p. 127 |
| The channel pseudo-templated classes | p. 128 |
| Building the second test | p. 129 |
| Building the second test's test_component | p. 131 |
| Adjusting the second test's parameters | p. 132 |
| The Remaining Tests: Mix-and-Match Test Components | p. 135 |
| Summary | p. 136 |
| Truss Example | p. 137 |
| Overview | p. 138 |
| Directory Structure | p. 138 |
| Theory of Operation | p. 140 |
| Running the Simple ALU Example | p. 142 |
| Points of Interest | p. 142 |
| Power-on Reset | p. 143 |
| Driver and Monitor Protocol | p. 144 |
| The alu_test_component | p. 145 |
| Checking the Chip | p. 146 |
| Completing the Test | p. 147 |
| Summary | p. 149 |
| Using OOP for Verification (Best Practices) | p. 151 |
| Thinking OOP | p. 153 |
| Overview | p. 154 |
| Sources of Complexity | p. 155 |
| Essential complexity vs. implementation complexity | p. 155 |
| Flexibility vs. complexity | p. 156 |
| Apparent simplicity vs. hiding inherent complexity | p. 159 |
| Example: How hiding complexity can create confusion | p. 159 |
| Example: How apparent simplicity leads to later problems | p. 160 |
| Team dynamics | p. 162 |
| Team roles | p. 162 |
| Using a "code buddy" | p. 163 |
| Creating Adaptable Code | p. 163 |
| Achieving adaptability | p. 163 |
| Why is adaptability tricky? | p. 164 |
| Architectural Considerations to Maximize Adaptability | p. 165 |
| Changes are easy-or just plain impossible | p. 166 |
| Where is adaptation likely to happen? | p. 167 |
| Separating Interface from Implementation | p. 168 |
| Code Interface, Implementation, and Base Classes | p. 169 |
| Summary | p. 170 |
| For Further Reading | p. 171 |
| Designing with OOP | p. 173 |
| Overview | p. 174 |
| Keeping the Abstraction Level Consistent | p. 174 |
| Using "Correct by Construction" | p. 176 |
| The Value of Packages | p. 178 |
| Data Duplication-A Necessary Evil | p. 180 |
| Designing Well, Optimizing Only When Necessary | p. 181 |
| Using the Protocol, Only the Protocol | p. 182 |
| Verification Close to the Programming Model | p. 183 |
| The Three Parts of Checking | p. 184 |
| Separating the Test from the Testbench | p. 186 |
| Summary | p. 187 |
| For Further Reading | p. 188 |
| OOP Classes | p. 189 |
| Overview | p. 190 |
| Defining Classes | p. 191 |
| How Much Electricity? | p. 191 |
| Classes | p. 192 |
| Packages | p. 192 |
| Pointers and virtual functions | p. 192 |
| Global Services | p. 193 |
| Package it up! | p. 193 |
| Static methods | p. 194 |
| Singletons-A Special Case of Static Methods | p. 194 |
| Packages or static methods? | p. 195 |
| Other considerations | p. 196 |
| Class Instance Identifiers | p. 197 |
| Strings as identifiers | p. 197 |
| Static integers as identifiers | p. 197 |
| Combination identifiers | p. 198 |
| Class Inheritance for Reuse | p. 198 |
| A BFM base-class example | p. 199 |
| A BFM agent class | p. 200 |
| Reusing the BFM class | p. 200 |
| Class Inheritance for Code Interfaces | p. 201 |
| Inheritance for a verification component | p. 201 |
| Inheritance for a payload code interface | p. 202 |
| Summary | p. 203 |
| For Further Reading | p. 204 |
| OOP Connections | p. 205 |
| Overview | p. 206 |
| How Tight a Connection? | p. 207 |
| Types of Connections | p. 209 |
| Peer-to-peer connections | p. 209 |
| Master-to-slave and push-vs.-pull connections | p. 209 |
| Two Tight Connection Techniques | p. 211 |
| Using pointers | p. 211 |
| Using inheritance | p. 212 |
| Threads and Connections | p. 214 |
| Events-explicit blocking interconnects | p. 214 |
| Hiding the thread block in a method | p. 216 |
| Fancier Connections | p. 217 |
| Listener or callback connections | p. 218 |
| Channel connections | p. 219 |
| Action object connections | p. 220 |
| Summary | p. 221 |
| For Further Reading | p. 222 |
| Coding OOP | p. 223 |
| Overview | p. 224 |
| "If" Tests-A Necessary Evil | p. 224 |
| "If" tests and abstraction levels | p. 225 |
| "If" tests and code structure | p. 226 |
| Repeated "if" expressions | p. 227 |
| "If" tests and factory functions | p. 228 |
| A factory function example | p. 229 |
| Coding Tricks | p. 232 |
| Coding only what you need to know | p. 232 |
| Reservable resources | p. 233 |
| The register: an int by any other name | p. 234 |
| Using data members carefully | p. 234 |
| Coding Idioms | p. 236 |
| The singleton idiom | p. 237 |
| Public nonvirtual methods: Virtual protected methods | p. 238 |
| Enumeration for Data, Integer for Code Interface | p. 240 |
| What's in a Name? | p. 241 |
| Keeping class name the same as file name | p. 241 |
| Keeping class and instance names related | p. 241 |
| Coding with Style | p. 242 |
| Proceeding with caution | p. 243 |
| General syntax conventions | p. 243 |
| Identifying local and protected members | p. 244 |
| Summary | p. 245 |
| For Further Reading | p. 246 |
| Examples (Putting It All Together) | p. 247 |
| Block-Level Testing | p. 249 |
| Overview | p. 250 |
| Theory of Operation | p. 251 |
| Verification environment | p. 252 |
| Verification IP | p. 253 |
| UART VIPs | p. 253 |
| Wishbone VIP | p. 254 |
| The verification dance | p. 255 |
| Running the UART Example | p. 255 |
| Points of Interest | p. 256 |
| Configuration | p. 256 |
| VIP UART package | p. 257 |
| VIP UART configuration class | p. 258 |
| Randomization of parameters | p. 258 |
| UART 16550 configuration class | p. 260 |
| Configuring the Chip | p. 261 |
| Register access | p. 262 |
| The wishbone_memory_bank and wishbone_driver | p. 263 |
| Traffic Generation | p. 265 |
| The generator_agent and uart_bfm_agent classes | p. 265 |
| The Checker | p. 267 |
| Checking the data | p. 268 |
| Connecting It All Together | p. 270 |
| The testbench | p. 270 |
| Building the channels | p. 271 |
| Building the configuration and interface port | p. 271 |
| Building the component-layer objects | p. 273 |
| The wishbone objects | p. 274 |
| The test component | p. 275 |
| The uart_basic_test_component::do_randomize() method | p. 277 |
| The basic data test | p. 278 |
| More Tests | p. 280 |
| Summary | p. 280 |
| Chip-Level Testing | p. 281 |
| Overview | p. 282 |
| Theory of Operation | p. 282 |
| Verification environment | p. 283 |
| Running the UART Example | p. 284 |
| The quad_uart_test_components Test | p. 284 |
| The quad_uart_irritators Test | p. 286 |
| UART irritator class | p. 286 |
| The test | p. 288 |
| The quad_uart_vectors Test | p. 292 |
| The block_uart Test | p. 293 |
| Summary | p. 293 |
| Things to Remember | p. 295 |
| Use SystemVerilog and Layers! | p. 296 |
| An Open-Source Approach | p. 296 |
| OOP-Best Practices | p. 297 |
| Examples-Copy and Adapt! | p. 298 |
| Conclusion to the Conclusion | p. 298 |
| Index | p. 301 |
| Table of Contents provided by Ingram. All Rights Reserved. |