® VCS /VCSi™ User Guide Version Y-2006.06-SP2 March 2008 Comments? E-mail your comments about Synopsys documentation to vcs_support@synopsys.
Copyright Notice and Proprietary Information Copyright © 2008 Synopsys, Inc. All rights reserved. This software and documentation contain confidential and proprietary information that is the property of Synopsys, Inc. The software and documentation are furnished under a license agreement and may be used or copied only in accordance with the terms of the license agreement.
Contents 1. Getting Started What VCS Supports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-3 Main Components of VCS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-3 VCSi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-6 Preparing to Run VCS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-6 Obtaining a License . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2. Modeling Your Design ii Avoiding Race Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-2 Using and Setting a Value at the Same Time . . . . . . . . . . . . 2-2 Setting a Value Twice at the Same Time . . . . . . . . . . . . . . . . 2-3 Flip-Flop Race Condition . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-4 Continuous Assignment Evaluation . . . . . . . . . . . . . . . . . . . . 2-5 Counting Events. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Avoiding Circular Dependency . . . . . . . . . . . . . . . . . . . . . . . . . . 2-33 Designing With $lsi_dumpports for Simulation and Test . . . . . . . 2-34 Dealing With Unassigned Nets . . . . . . . . . . . . . . . . . . . . . . . 2-35 Code Values at Time 0. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-36 Cross Module Forces and No Instance Instantiation . . . . . . . 2-36 Signal Value/Strength Codes . . . . . . . . . . . . . . . . . . . . . . . . . 2-38 3.
iv Performance Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-23 Using Local Disks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-23 Managing Temporary Disk Space on UNIX . . . . . . . . . . . . . . 3-24 Compile-Time Options That Impede or Accelerate VCS . . . . 3-25 Compiling for Debugging or Performance . . . . . . . . . . . . . . . 3-27 64-32-Bit Cross-Compilation and Full 64-Bit Compilation . . . . .
Resolving ‘include Compiler Directives . . . . . . . . . . . . . . 3-48 Configurations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Configuration Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . Hierarchical Configurations . . . . . . . . . . . . . . . . . . . . . . . The -top Compile-Time Option . . . . . . . . . . . . . . . . . . . . . Limitations of Configurations . . . . . . . . . . . . . . . . . . . . . . 3-48 3-49 3-51 3-52 3-53 4.
5. Using the Discovery Visual Environment Overview of DVE Window Configuration . . . . . . . . . . . . . . . . . . . 5-2 DVE Panes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-4 Managing DVE Windows. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-4 Managing Target Panes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-4 Docking and Undocking Windows and Panes . . . . . . . . . . . . Dragging and Dropping Docked windows . . . . . . . .
+vpdfile to Set the Output File Name. . . . . . . . . . . . . . . . . . . 6-26 +vpdfilesize to Control Maximum File Size . . . . . . . . . . . . . . 6-26 +vpdignore to Ignore $vcdplus Calls in Code . . . . . . . . . . . . 6-27 +vpddrivers to Store Driver Information . . . . . . . . . . . . . . . . . 6-27 +vpdnoports to Eliminate Storing Port Information . . . . . . . . 6-28 +vpdnocompress to Bypass Data Compression . . . . . . . . . . 6-28 +vpdnostrengths to Not Store Strength Information. . . .
Generating Source Files From VCD Files . . . . . . . . . . . . . . . 7-17 Writing the Configuration File. . . . . . . . . . . . . . . . . . . . . . . . . 7-18 The vcsplit Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-23 The vcsplit Utility Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-23 The vcd2vpd Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-26 The vcd2vpd Utility Syntax. . . . . . . . . . . . . . . . . .
Navigating the Design and Displaying Design Information . . 9-2 Showing and Retrieving Simulation Information . . . . . . . . . . 9-4 Setting, Displaying and Deleting Breakpoints . . . . . . . . . . . . 9-7 Displaying Object Data Members . . . . . . . . . . . . . . . . . . . . . 9-9 Setting and Printing Values of Variables . . . . . . . . . . . . . . . . 9-9 Traversing Call-stacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-9 Showing and Terminating Threads . . . . . . . . . .
Debugging Simulation Mismatches . . . . . . . . . . . . . . . . . . . . 11-10 The Static Race Detection Tool . . . . . . . . . . . . . . . . . . . . . . . . . . 11-13 12. Delays and Timing Transport and Inertial Delays . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-2 Different Inertial Delay Implementations . . . . . . . . . . . . . . . . 12-4 Enabling Transport Delays. . . . . . . . . . . . . . . . . . . . . . . . . . . 12-7 Pulse Control. . . . . . . . . . . . . . . . . . . . . . . . .
Disabling CELLTYPE Checking in SDF Files . . . . . . . . . . . . 13-15 The SDF Configuration File . . . . . . . . . . . . . . . . . . . . . . . . . . Delay Objects and Constructs . . . . . . . . . . . . . . . . . . . . . SDF Configuration File Commands . . . . . . . . . . . . . . . . . SDF Example with Configuration File. . . . . . . . . . . . . . . . 13-16 13-17 13-18 13-25 Understanding the DEVICE Construct . . . . . . . . . . . . . . . . . . . . 13-28 Handling Backannotation to I/O Ports . . . . .
Negative Timing Checks for XYZ. . . . . . . . . . . . . . . . . . . . . . 14-2 The $setuphold Timing Check Extended Syntax . . . . . . . . . . 14-7 Negative Timing Checks for Asynchronous Controls. . . . . . . 14-10 The $recrem Timing Check Syntax . . . . . . . . . . . . . . . . . . . . 14-11 Enabling Negative Timing Checks. . . . . . . . . . . . . . . . . . . . . . . . 14-13 Other Timing Checks Using the Delayed Signals . . . . . . . . . . . . 14-14 Checking Conditions . . . . . . . . . . . . .
Using LMTV SmartModel Window Commands . . . . . . . . . . . . . . 16-10 Entering Commands Using the SWIFT Command Channel . . . . 16-13 Using the CLI to Access the Command Channel. . . . . . . . . . 16-15 Loading Memories at the Start of Runtime . . . . . . . . . . . . . . . . . 16-15 Compiling and Simulating a Model . . . . . . . . . . . . . . . . . . . . . . . 16-16 Changing the Timing of a Model . . . . . . . . . . . . . . . . . . . . . . 16-16 17. Using the PLI Writing a PLI Application . .
Support for the vpi_register_systf Routine. . . . . . . . . . . . . . . 17-31 PLI Table File for VPI Routines . . . . . . . . . . . . . . . . . . . . . . . 17-32 Integrating a VPI Application With VCS . . . . . . . . . . . . . . . . . 17-32 Writing Your Own main() Routine . . . . . . . . . . . . . . . . . . . . . . . . 17-34 18. DirectC Interface xiv Using Direct C/C++ Function Calls . . . . . . . . . . . . . . . . . . . . . . . 18-3 How C/C++ Functions Work in a Verilog Environment . . . . .
int vc_is4stVector(vc_handle). . . . . . . . . . . . . . . . . . . . . . int vc_is2stVector(vc_handle). . . . . . . . . . . . . . . . . . . . . . int vc_width(vc_handle) . . . . . . . . . . . . . . . . . . . . . . . . . . int vc_arraySize(vc_handle) . . . . . . . . . . . . . . . . . . . . . . . scalar vc_getScalar(vc_handle) . . . . . . . . . . . . . . . . . . . . void vc_putScalar(vc_handle, scalar). . . . . . . . . . . . . . . . char vc_toChar(vc_handle) . . . . . . . . . . . . . . . . . . . . . . .
int vc_getMemoryInteger(vc_handle, U indx). . . . . . . . . . 18-62 void vc_putMemoryInteger(vc_handle, U indx, int) . . . . . 18-64 void vc_get4stMemoryVector(vc_handle, U indx, vec32 *). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18-64 void vc_put4stMemoryVector(vc_handle, U indx, vec32 *). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18-66 void vc_get2stMemoryVector(vc_handle, U indx, U *) . . . 18-67 void vc_put2stMemoryVector(vc_handle, U indx, U *) .
Verilog Design Containing SystemC Leaf Modules . . . . . . . . . . . 19-6 Input Files Required. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-7 Generating the Wrapper for SystemC Modules . . . . . . . . . . . 19-8 Instantiating the Wrapper and Coding Style. . . . . . . . . . . . . . 19-11 Controlling Time Scale and Resolution in a SystemC Module Contained in a Verilog Design . . . . . . . 19-13 Compiling a Verilog Design Containing SystemC Modules . .
Transaction Level Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-31 Interface Definition File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-33 Generation of the TLI Adapters . . . . . . . . . . . . . . . . . . . . . . . 19-36 Transaction Debug Output. . . . . . . . . . . . . . . . . . . . . . . . . . . 19-37 Instantiation and Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-38 Supported Data Types of Formal Arguments. . . . . . . . . . . . .
OpenVera Assertions Post-Processing . . . . . . . . . . . . . . . . . . . . 20-24 OVAPP Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20-25 Building and Running a Post-Processor . . . . . . . . . . . . . . . . 20-26 OVA Post-Processing CLI Commands . . . . . . . . . . . . . . . . . 20-31 Using Multiple Post-Processing Sessions . . . . . . . . . . . . . . . 20-32 Multiple OVA Post-Processing Sessions in One Directory . . 20-32 Viewing Output Results . . . . . . .
Use Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Enabling Verilog Parameter Expansion . . . . . . . . . . . . . . Limitations on the Input . . . . . . . . . . . . . . . . . . . . . . . . . . Recommended Methodology . . . . . . . . . . . . . . . . . . . . . . Caveats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20-63 20-64 20-64 20-66 20-66 Post-processing Flow. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Use Model . . .
Preprocessor Directives . . . . . . . . . . . . . . . . . . . . . . . . . . Top Level Constructs . . . . . . . . . . . . . . . . . . . . . . . . . . . . Program Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "Hello World!" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21-6 21-7 21-7 21-8 The Template Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21-9 Multiple Program Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xxii Using Encrypted Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21-44 Testbench Functional Coverage . . . . . . . . . . . . . . . . . . . . . . . . . 21-45 Coverage Models Using Coverage Groups . . . . . . . . . . . . . . 21-46 Measuring Coverage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21-49 Controlling Coverage Collection Globally . . . . . . . . . . . . . . . 21-51 Unified Coverage Reporting. . . . . . . . . . . . . . . . . . . . . . . . . .
Example Testbench . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21-71 Running OpenVera Testbench with OVA . . . . . . . . . . . . . . . . 21-74 Running OpenVera Testbench with SVA . . . . . . . . . . . . . . . . 21-74 Running OpenVera Testbench with SVA and OVA Together . 21-75 OpenVera-SystemVerilog Testbench Interoperability . . . . . . . . . 21-75 Scope of Interoperability . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21-76 Importing OpenVera types into SystemVerilog . .
Testbench Optimization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21-99 NTB Performance Profiler . . . . . . . . . . . . . . . . . . . . . . . . . . . 21-99 Enabling the NTB Profiler. . . . . . . . . . . . . . . . . . . . . . . . . 21-100 Performance Profiler Example . . . . . . . . . . . . . . . . . . . . . 21-100 VCS Memory Profiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Use Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Force and Release on SystemVerilog Variables . . . . . . . . . . Automatic Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Multiple Drivers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Release Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Integer Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unpacked Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Structures . . . . . . . . . . . . . . . . . . . .
The $root Top-Level Global Declaration Space . . . . . . . . . . . 22-54 New Data Types for Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . 22-56 Instantiation Using Implicit .name Connections . . . . . . . . . . . 22-58 Instantiation Using Implicit .* Connections. . . . . . . . . . . . . . . 22-58 New Port Connection Rules for Variables . . . . . . . . . . . . . . . 22-59 Ref Ports on Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22-60 Interfaces. . . . .
Conditions for Sequences . . . . . . . . . . . . . . . . . . . . . . . . Specifying That Sequence Match Within Another Sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using the End Point of a Sequence . . . . . . . . . . . . . . . . . Level Sensitive Sequence Controls . . . . . . . . . . . . . . . . . 23-12 23-13 23-13 23-14 Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Formal Arguments in a Property . . . . . . . . . . . . . .
Tcl Commands For SVA And OVA Functional Coverage Reports. . . . . . . . . . . . . . . . . . . . . . . . . . . . 23-49 The assertCovReport Report Files . . . . . . . . . . . . . . . . . . . . The report.index.html File. . . . . . . . . . . . . . . . . . . . . . . . . The tests.html File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The category.html File . . . . . . . . . . . . . . . . . . . . . . . . . . . The hier.html File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-20 Dynamic Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The new[ ] Built-In Function . . . . . . . . . . . . . . . . . . . . . . . The size() Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The delete() Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Assignments to and from Dynamic Arrays . . . . . . . . . . . .
Scope Resolution Operator :: . . . . . . . . . . . . . . . . . . . . . . super keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-54 24-55 Casting. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-56 Chaining Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-58 Accessing Class Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-62 Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Controlling Constraints. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-102 Disabling Random Variables . . . . . . . . . . . . . . . . . . . . . . . . . 24-105 In-line Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-108 In-line Constraint Checker . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-109 Random Number Generation. . . . . . . . . . . . . . . . . . . . . . . . . 24-111 Seeding for Randomization . . . . . . . . . . . . . . . . . . . . . . . . .
sort() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-166 rsort() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-166 Array locator methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . find() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . find_index(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . find_first() . . . . . . . . . . . . . . . . . . . . . . . . . . .
Reclaiming Named Events . . . . . . . . . . . . . . . . . . . . . . . . 24-186 Event Comparison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-187 Clocking Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-188 Clocking Block Declaration . . . . . . . . . . . . . . . . . . . . . . . . . . 24-188 Input and Output Skews . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-193 Hierarchical Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . .
Event Expression/Structure . . . . . . . . . . . . . . . . . . . . . . . . . . 24-213 Null Comparison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-213 Not Yet Implemented . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-214 Coverage. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-214 The covergroup Construct . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-215 Defining a Coverage Point . . . . . . . . . . . . . . . . .
UCLI Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CLI Interface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Incremental Profiling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . Only Active Memory Reported . . . . . . . . . . . . . . . . . . . . . 24-247 24-247 24-248 24-248 VCS NTB (SV) Dynamic Memory Profile Report . . . . . . . . . . 24-249 The Direct Programming Interface (DPI) . . . . . . . . . . . . . . . . . . . 24-251 Limitations . .
Preventing Mangling of Top-Level Modules . . . . . . . . . . . . . . Appendix A. 25-24 VCS Environment Variables Simulation Environment Variables. . . . . . . . . . . . . . . . . . . . . . . . A-2 Optional Environment Variables . . . . . . . . . . . . . . . . . . . . . . . . . A-3 Appendix B. xxxvi Compile-Time Options Options for Accessing Verilog Libraries . . . . . . . . . . . . . . . . . B-4 Options for Incremental Compilation . . . . . . . . . . . . . . . . . . .
Options for Profiling Your Design. . . . . . . . . . . . . . . . . . . . . . B-37 Options for File Containing Source File Names and Options B-38 Options for Compiling Runtime Options into the simv Executable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-39 Options for Pulse Filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . B-40 Options for PLI Applications . . . . . . . . . . . . . . . . . . . . . . . . .
TetraMAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Make Accessing an Undeclared Bit an Error Condition . . Treat Output Ports As Inout Ports . . . . . . . . . . . . . . . . . . Allow Inout Port Connection Width Mismatches. . . . . . . . Specifying a VCD File. . . . . . . . . . . . . . . . . . . . . . . . . . . . Memories and Multi-Dimensional Arrays (MDAs) . . . . . . Specifying a Log File . . . . . . . . . . . . . . . . . . . . . . . . . . . . Hardware Modeling . . . . . . .
Options for Controlling $gr_waves System Task Operations. C-17 Options for VCD Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C-18 Options for Specifying Min:Typ:Max Delays . . . . . . . . . . . . . C-19 Options for Flushing Certain Output Text File Buffers . . . . . . C-20 Options for Licensing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C-21 General Options. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Compiler Directive for Including a Source File . . . . . . . . . D-8 Compiler Directive for Setting the Time Scale . . . . . . . . . D-9 Compiler Directive for Specifying a Library . . . . . . . . . . . D-9 Compiler Directive for Maintaining The File Name and Line Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D-10 xl Unimplemented Compiler Directives . . . . . . . . . . . . . . . . . . . D-10 System Tasks and Functions. . . . . . . . . . . . . . . . . . . . . . . . . . .
System Tasks for Probabilistic Distribution . . . . . . . . . . . . . . D-38 System Tasks for Resetting VCS . . . . . . . . . . . . . . . . . . . . . . D-38 General System Tasks and Functions . . . . . . . . . . . . . . . . . . Checks for a Plusarg . . . . . . . . . . . . . . . . . . . . . . . . . . . . SDF Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Counting the Drivers on a Net . . . . . . . . . . . . . . . . . . . . . Depositing Values. . . . . . . . . . . . . . .
acc_getmem_size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-22 acc_getmem_word_int. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-23 acc_getmem_word_range . . . . . . . . . . . . . . . . . . . . . . . . . . . E-24 Access Routines for Multidimensional Arrays . . . . . . . . . . . . . . . E-25 tf_mdanodeinfo and tf_imdanodeinfo. . . . . . . . . . . . . . . . . . . E-26 acc_get_mda_range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
acc_lsi_dumpports_limit. . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-47 acc_lsi_dumpports_misc . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-48 acc_lsi_dumpports_off . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-49 acc_lsi_dumpports_on . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-50 acc_lsi_dumpports_setformat . . . . . . . . . . . . . . . . . . . . . . . . E-52 acc_lsi_dumpports_vhdl_enable . . . . . . . . . . . . . . . . . . . . . .
xliv vcsSpSetPliProtectionFlag. . . . . . . . . . . . . . . . . . . . . . . . . . . E-80 vcsSpWriteChar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-81 vcsSpWriteString . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-83 Access Routine for Signal in a Generate Block. . . . . . . . . . . . . . E-84 acc_object_of_type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E-84 VCS API Routines . . . . . . . . . . . . . . . . . . . . . . . . .
1 Getting Started 1 VCS® is a high-performance, high-capacity Verilog® simulator that incorporates advanced, high-level abstraction verification technologies into a single open native platform. VCS enables you to analyze, compile, and simulate Verilog design descriptions. It also provides you with a set of simulation and debugging features to validate your design. These features provide capabilities for source-level debugging and simulation result viewing.
VCS is also integrated with other third-party tools via the programming language interface (PLI). Also, the DirectC Interface enables interaction between Verilog designs and applications written in C or C++. VCS is integrated with many third party tools such as testbench tools, memory model generation tools, acceleration and emulation systems, and graphical user interfaces.
What VCS Supports VCS provides fully featured implementations of the following: • The Verilog language as defined in the IEEE Standard Hardware Description Language Based on the Verilog Hardware Description Language (IEEE Std 1364-1995) and the Standard Verilog Hardware Description Language (IEEE Std 1364-2001). • The SystemVerilog 3.1a language (with some exceptions) as defined in SystemVerilog 3.1a Accellera’s Extensions to Verilog.
• OpenVera Assertions (OVA) — provides an easy and concise way to describe sequences of events, and facilities to test for their occurrence. VCS natively compiles OVA. For details on OVA, see Chapter 20, "Using OpenVera Assertions" and the OpenVera Language Reference Manual: Assertions volume. Many of the implemented SystemVerilog assertions constructs are functionally comparable to OpenVera assertion constructs.
• DirectC Interface — this interface allows you to directly embed user-created C/C++ functions within your Verilog design description. This results in a significant improvement in ease-of-use and performance over existing PLI-based methods. VCS atomically recognizes C/C++ function calls and integrates them for simulation, thus eliminating the need to manually create PLI files.
VCSi VCSi is offered as an alternate version of VCS. VCS and VCSi are identical except that VCS is more highly optimized, resulting in greater speed. VCS and VCSi are guaranteed to provide the exact same simulation results. VCSi implementation requirements are summarized as follows: 1. There are separate licenses for VCSi. 2. VCSi is invoked using the vcsi command, instead of the vcs command. Note: Hereafter, all references to VCS in this manual pertain to VCSi as well.
Obtaining a License You must have a license to run VCS. To obtain a license, contact your local Synopsys Sales Representative. Your Sales Representative will need the hostid for your machine. To start a new license, do the following: 1. Verify that your license file is functioning correctly: % lmcksum -c license_file_pathname Running this licensing utility ensures that the license file is not corrupt. You should see an "OK" for every INCREMENT statement in the license file.
- Using multiple port@host in the $LM_LICENSE_FILE can cause previous VCS releases, which use pre FLEX-LM6.1 daemons, not to work.
% set path=($VCS_HOME /bin\ $VCS_HOME/‘$VCS_HOME/bin/vcs -platform‘/bin\ $path) Make sure the path environment variable is set to a bin directory containing a make or gmake program. • LM_LICENSE_FILE environment variable The definition can either be an absolute path name to a license file or to a port on the license server. Separate the arguments in this definition with colons in UNIX. For example: % setenv LM_LICENSE_FILE 7182@serveroh:/u/net/serveroo/ eda_tools/license.
You can specify a different location with the VCS_CC environment variable or with the -cc compile time option. -v Displays the version number and exits. -lib Displays the library mapping. -help Lists the options to show_setup. VCS Workflow The process of using VCS to simulate a design consists of the following tasks: • Compiling the Simulation Executable • Running a Simulation This approach simulates faster and uses less memory than interpretive simulators.
Note: For information on coverage features, see the VCS /VCS MX Coverage Metrics User Guide. Figure 1-1 illustrates the VCS workflow.
Figure 1-1 Basic VCS Compilation and Simulation Flow Verilog Code (mem.v, cpu.v) Step1: Compilation % vcs mem.v cpu.
Compiling the Simulation Executable After setting up your environment and preparing your source files, you are ready to compile a simulation executable. To create this executable, named simv by default, use the following VCS command line: vcs source_files [source_or_object_files] options where: source_files The Verilog, OpenVera assertions, or OpenVera testbench source files for your design. The file names must be separated by spaces. source_or_object_files Optional C files (.c), object files (.
Basic Compile-Time Options This section outlines some of the basic compile-time options you can use to control how VCS compiles your Verilog source files. Detailed descriptions and usage instructions for all compile-time options are available in Chapter 3, "Compiling Your Design" and Appendix B, "Compile-Time Options". -cm [line|cond|fsm|tgl|path|branch] Specifies compiling for the specified type or types of coverage. The arguments specify the types of coverage: line Compile for line or statement coverage.
+define+macro=value+ Defines a text macro in your source code to a value or character string. You can test for this definition in your Verilog source code using the ‘ifdef compiler directive. -f filename Specifies a file name that contains a list of absolute pathnames for Verilog source files and compile-time options. +incdir+directory Specifies the directory or directories that VCS searches for include files used in the `include compiler directive. More than one directory may be specified, separated by +.
+notimingcheck Suppresses timing check system tasks during compilation. This option can moderately improve simulation performance. The extent of this improvement depends on the number of timing checks that VCS ignores. -ntb Enables the use of the OpenVera Testbench language constructs described in the OpenVera Language Reference Manual: Native Testbench. -ova_file filename Identifies an OVA file as input. This option is not required if the OVA file name contains a .ova extension. -P pli.
-sverilog Enables the use of SystemVerilog code. +v2k Enables language features in the IEEE 1364-2001 standard. -v filename Specifies a Verilog library file, in which VCS looks for the modules and UDP instances that are instantiated, but not defined, in the source code. +vc[+abstract][+allhdrs][+list] Enables the direct call of C/C++ functions in your source code using the DirectC interface.
On Solaris, HP, and Linux machines, VCS can generate object files from your Verilog source files and does so by default. This is sometimes called native code generation. On these machines, if you enter the -gen_asm or -gen_c compile-time options, VCS generates corresponding intermediate assembly or C files and then assembles or compiles these intermediate files into object files. On DEC Alpha, and IBM RS/6000 AIX, VCS always generates intermediate C files.
% simv -l log +notimingcheck Basic Runtime Options This section outlines some of the basic runtime options you can use to control how VCS compiles your Verilog source files. Detailed descriptions and usage instructions for all runtime options are available in Chapter 4, "Simulating Your Design" and Appendix C, "Simulation Options". Here: -cm line|cond|fsm|tgl|path|branch Specifies monitoring for the specified type or types of coverage.
+notimingcheck Disables timing check system tasks in your design. Using this option at runtime can improve the simulation performance of your design, depending on the number of timing checks that this option disables. -ova_cov Enables functional coverage reporting. -ova_report Generates an OVA report file in addition to printing results on screen. The default file name and location is simv.vdb/report/ ova.report but you can specify a different name and location as an argument to this option.
• Using the PDF files in the NanoSim installation To access the Discovery AMS documentation in Synopsys Documentation on the Web: 1. Go to www.synopsys.com. 2. Click on SOLVNET. 3. Click on Documentation on the Web. 4. Click the Go button next to Browse. 5. Click on NanoSim. 6. Click on the document titles: - Discovery AMS NanoSim-VCS User Guide, or - Discovery AMS Enhanced NanoSim-VCS User Guide Clicking on the user guide titles displays the user guide in HTML format.
Making a Verilog Model Protected and Portable After you have successfully verified your design using VCS, you can use the Verilog Model Compiler (VMC) to make the design portable and protected. VMC enables you to secure your design and distribute it to your partners and internal or external customers without a Non Disclosure Agreement (NDA). VMC is a model development tool used to generate portable models, starting with Verilog source and producing compiled SWIFT models.
2 Modeling Your Design 1 Verilog coding style is the most important factor that affects the simulation performance of a design. How you write your design can make the difference between a fast error-free simulation, and one that suffers from race conditions and poor performance. This chapter describes some Verilog modeling techniques that will help you code designs that simulate most efficiently with VCS.
• Memory Size Limits in VCS • Using Sparse Memory Models • Obtaining Scope Information • Avoiding Circular Dependency • Designing With $lsi_dumpports for Simulation and Test Avoiding Race Conditions A race condition is defined as a coding style for which there is more than one correct result. Since the output of the race condition is unpredictable, it can cause unexpected problems during simulation. It is easy to accidentally code race conditions in Verilog.
end initial begin #10 if (a) $display("may not print"); end endmodule The solution is to delay the $display statement with a #0 delay: initial begin #10 if (a) #0 $display("may not print"); end You can also move it to the next time step with a non-zero delay. Setting a Value Twice at the Same Time In this example, the race condition occurs at time 10 because no ordering is guaranteed between the two parallel initial blocks.
Flip-Flop Race Condition It is very common to have race conditions near latches or flip-flops. Here is one variant in which an intermediate node a between two flip-flops is set and sampled at the same time: module test(out,in,clk); input in,clk; output out; wire a; dff dff0(a,in,clk); dff dff1(out,a,clk); endmodule module dff(q,d,clk); output q; input d,clk; reg q; always @(posedge clk) q = d; // race! endmodule The solution for this case is straightforward.
Note that the following change does not resolve the race condition: always @(posedge clk) #1 q = d; // race! The #1 delay simply shifts the original race by one time unit, so that the intermediate node is set and sampled one time unit after the posedge of clock, rather than on the posedge of clock. Avoid this coding style. Continuous Assignment Evaluation Continuous assignments with no delay are sometimes propagated earlier in VCS than in Verilog-XL.
if (state0) // do something end The modification of state may propagate to state0 before the if statement, causing unexpected behavior. You can avoid this by using the nonblocking assignment to state in the procedural code as follows: state <= 0; if (state0) // do something This guarantees that state is not updated until the end of the time step, that is, after the if statement has executed.
Time Zero Race Conditions The following race condition is subtle but very common: always @(posedge clock) $display("May or may not display"); initial begin clock = 1; forever #50 clock = ~clock; end This is a race condition because the transition of clock to 1 (posedge) may happen before or after the event trigger (always @(posedge clock)) is established. Often the race is not evident in the simulation result because reset occurs at time zero.
Optimizing Testbenches for Debugging Testbenches typically execute debugging features, for example, displaying text in certain situations as specified with the $monitor or $display system tasks. Another debugging feature, which is typically enabled in testbenches, is writing simulation history files during simulation so that you can view the results after simulation. Among other things, these simulation history files record the simulation times at which the signals in your design change value.
Conditional Compilation Use ‘ifdef, ‘else, and ‘endif compiler directives in your testbench to specify which system tasks you want to compile for debugging features. Then, when you compile the design with the +define compile-time option on the command line (or when the ‘define compiler directive appears in the source code), VCS will compile these tasks for debugging features.
Later in the development cycle of the design, you can compile the design without the +define+postprocess compile-time option and VCS will not compile these system tasks into the testbench. Doing so enables VCS to simulate your design much faster. Advantages and Disadvantages The advantage of this technique is that simulation can run faster than if you enable debugging features at runtime. When you use conditional compilation VCS has all the information it needs at compile-time.
An example of the $test$plusargs system function is as follows: initial if ($test$plusargs("postprocess")) begin $vcdpluson(0,design_1); $vcdplustraceon(design_1); $vcsplusdeltacycleon; $vcdplusglitchon; end In this technique you do not include the +define compile-time argument on the vcs command line. Instead you compile the system tasks into the testbench and then enable the execution of the system tasks with the runtime argument to the $test$plusargs system function.
No matter whether you enter the +a, +ab, or +abc plusarg, when you simulate the executable, VCS always displays the following: <<< Now a >>> To avoid this pitfall, enter the longest plusarg first.
Using the $test$plusargs system function forces VCS to consider the worst case scenario — plusargs will be used at runtime — and VCS generates the simv executable with the corresponding overhead to prepare for these plusargs. The more fixed information VCS has at compile-time, the more VCS can optimize simv for efficient simulation. On the other hand, the more user control at runtime, the more overhead VCS has to add to simv to accept runtime options, and the less efficient the simulation.
Here both the +define+comppostprocess compile-time option and the +runpostprocess runtime option are required for VCS to write the VPD file. This technique allows you to avoid recompiling just to prevent VCS from writing the file during the next simulation and also provides you with a way to recompile the testbench, later in the development cycle, to exclude these system tasks without first editing the source code for the testbench.
To avoid these debugging problems, and to increase simulation performance, do the following when writing new models: 1. If you need values to propagate in and out of a port, declare it as an inout port. If you don’t need this bidirectional behavior, declare it as an input or output port. 2. Compile the modules with these ports under the ‘noportcoerce compiler directive. Creating Models That Simulate Faster When modeling your design, for faster simulation use higher levels of abstraction.
VCS is optimized for simulating sequential devices. Under certain circumstances VCS infers that an always block is a sequential device and simulates the always block much faster. This section describes the coding guidelines you should follow to make VCS infer an always block as a sequential device. When writing an always block, if you cannot follow the inferencing rules for a sequential device there are still things that you should keep in mind so that VCS simulates the always block faster.
Avoid Unaccelerated Primitives VCS cannot accelerate tranif1, tranif0, rtranif1, rtranif0, tran, and rtran switches. They are defined in IEEE Std 1364-2001 page 86. Avoid Calls to User-defined Tasks or Functions Declared in Another Module VCS cannot accelerate user-defined tasks or functions declared in another module. For example: module bottom (x,y); . . . always @ y top.
Inferring Faster Simulating Sequential Devices VCS is optimized to simulate sequential devices. If VCS can infer that an always block behaves like a sequential device, VCS can simulate the always block much faster. The IEEE Std 1364-2001 defines always constructs on page 149. Verilog users commonly use the term always block when referring to an always construct. VCS can infer whether an always block is a combinatorial or sequential device. This section describes the basis on which VCS makes this inference.
Using either blocking or nonblocking procedural assignment statements in the always block does not prevent VCS from inferring a sequential device, but in VCS blocking procedural assignment statements are more efficient. Synopsys recommends zero delay nonblocking assignment statements to avoid race conditions. IEEE Std 1364-2001 describes blocking and nonblocking procedural assignment statements on pages 119-124.
@ (posedge clk) q <=d; Even though clk is in an event control, it is not in the sensitivity list event control. • VCS does not infer the following latch to be a sequential device: always begin wait clk; q <= d; @ d; end There is no sensitivity list event control. • VCS infers the following latch to be a sequential device: always @ (clk or d) if (clk) q <= d; The sequential controls, clk and d, are in the sensitivity list event control.
The following code examples illustrate this rule: Example 1 VCS infers that the following always block is combinatorial, not sequential: always @ (a or b) y = a or b Here the sensitivity list event control is level sensitive and VCS assigns a value to y whether a or b are true or false.
Modeling Faster always Blocks Whether VCS infers an always block to be a sequential device or not, there are modeling techniques you should use for faster simulation. Place All Signals Being Read in the Sensitivity List The sensitivity list for an always block is the event control that immediately follows the always keyword.
Using the +v2k Compile-Time Option The following table lists the implemented constructs in Std 1364-2001 and whether you need the +v2k compile-time option to use them. Std 1364-2001 Construct Require +v2k comma separated event control expressions: always @ (r1,r2,r3) yes name-based parameter passing: modname #(.param_name(value)) inst_name(sig1,...
Std 1364-2001 Construct Require +v2k the power operator: r1=r2**r3; yes attributes: (* optimize_power=1 *) module dev (res,out,clk,data1,data2); yes generate statements yes localparam declarations yes Automatic tasks and functions task automatic t1(); requires the -sverilog compile-time option constant functions localparam lp1 = const_func(p1); yes parameters with a bit range parameter bit [7:0][31:0] P = {32'd1,32'd2,32'd3,32'd4,32'd5,32'd6,32'd7,32'd8}; requires the -sverilog compile-time o
Memory Size Limits in VCS The bit width for a word or an element in a memory in VCS must be less than 0x100000 (or 220 or 1,048,576) bits. The number of elements or words (sometimes also called rows) in a memory in VCS must be less than 0x3FFF_FFFE-1 (or 230 - 2 or 1,073,741,822) elements or words. The total bit count of a memory (total number of elements * word size) must be less than 8 * (1024 * 1024 * 1024 - 2) or 8,573,157,376.
In simulations, this memory model used 4 MB of machine memory with the /*sparse*/ pragma, 81 MB without it. There is a small runtime performance cost to sparse memory models: the simulation of the memory with the /*sparse*/ pragma took 64 seconds, 56 seconds without it. The larger the memory, and the fewer elements in the memory that your design reads or writes to, the more machine memory you will save by using this feature. It is intended for memories that contain at least a few MBs.
Obtaining Scope Information VCS has custom format specifications (IEEE Std 1364-2001 does not define these) for displaying scope information. It also has system functions for returning information about the current scope. Scope Format Specifications The IEEE Std 1364-2001 describes the %m format specification for system tasks for displaying information such as $write and $display. The %m specification tells VCS to display the hierarchical name of the module instance that contains the system task.
named block containing the task enabling statement for this other user-defined task. If the function call is in another user-defined function, the hierarchical name is the hierarchical name of the instance or named block containing the function call for this other user-defined function. If the function call is in a user-defined task, the hierarchical name is the hierarchical name of the instance or named block containing the task enabling statement for this user-defined task.
$display("%-i"); end endtask // displays "top.d1" function my_func; input taskin; begin $display("%m"); // displays "top.my_func" $display("%i"); // displays "top.d1.named" $display("%-i"); // displays "top.d1" end endfunction dev1 d1 (r1); endmodule module dev1(inport); input inport; initial begin:named reg namedreg; $display("%m"); // displays "top.d1.named" $display("%i"); // displays "top.d1.named" $display("%-i"); // displays "top.d1" namedreg=1; top.my_task(namedreg); namedreg = top.
Returning Information About the Scope The $activeinst system function returns information about the module instance that contains this system function. The $activescope system function returns information about the scope that contains the system function. This scope can be a module instance, or a named block, or a user-defined task, or a function in a module instance. When VCS executes these system functions it does the following: 1. Stores the current scope in a temporary location. 2.
$display("%i"); if ($activescope("top.d0.block","top.d1.named")) $display("%-i"); end endmodule The following is an example of a DirectC application that uses the $activeinst system function: extern void showInst(input bit[31:0]); module discriminator; task t; reg[31:0] r; begin showInst($activeinst); if($activeinst("top.c1", begin r = $activeinst; $display("for instance end end endtask declaration of C function named showInst $activeinst system function without arguments passed to the C function "top.
2. A nested begin block executes only if the current scope is either top.c1 or top.c3. 3. VCS displays whether $activeinst points to a zero or non-zero value. The C code is as follows: #include void showInst(unsigned str_arg) { const char *str = (const char *)str_arg; printf("DirectC: [%s]\n", str); } Function showInst declares the char pointer str and assigns to it the value of its parameter, which is the pointer in $activeinst in the Verilog code.
Avoiding Circular Dependency The $random system function has an optional seed argument. You can use this argument to make the return value of this system function the assigned value in a continuous assignment, procedural continuous assignment, or force statement.
For example: assign out = $random(); initial begin assign dr1 = $random(); force dr2 = $random(); dr3 = $random(in); These statements do not generate the warning message. You can tell VCS not to display the warning message by using the +warn=noRWSI compile-time argument and option. Designing With $lsi_dumpports for Simulation and Test This section is intended to provide guidance when using $lsi_dumpports with Automatic Test Pattern Generation (ATPG) tools.
Dealing With Unassigned Nets Consider the following example: module test(A); input A; wire A; DUT DUT_1 (A); // assign A = 1'bz; initial $lsi_dumpports(DUT_1,"dump.out"); endmodule module DUT(A); input A; wire A; child child_1(A); endmodule module child(A); input A; wire Z,A,B; and (Z,A,B); endmodule In this case, the top level wire A is undriven at the top level. It is an input which goes to an input in DUT_1, then to an input in CHILD_1 and finally to an input of an AND gate in CHILD_1.
The designer actually meant for a code of Z to be returned, input tristated. To achieve this code, the input A needs to be assigned a value of z. This is achieved by removing the comment from the line, // assign A = 1'bz;, in the above code. Now when the code is executed, VCS is able to identify that the wire A going into DUT_1 is being driven to a z. With the wire driven from the outside and not the inside, $lsi_dumpports returns a code of Z.
module top; middle u1 (a); endmodule module middle(a); input a; wire b; buf(b,a); endmodule First, there is no instance name specified for $lsi_dumpports. The syntax for $lsi_dumpports calls for an instance name. Since the user didn't instantiate module top in the test fixture, they are left specifying the MODULE name top. This will produce a warning message from VCS. Since top appears only once, that instance will be assumed.
$lsi_dumpports(test.u0.u1,"dump.out2"); end top u0 (a); endmodule module top(a); input a; middle u1 (a); endmodule module middle(a); input a; wire b; buf(b,a); endmodule By using the method in this example, the port a of instance u1 is driven from the outside, and when $lsi_dumpports checks for the drivers it reports a code of D as desired.
H high X unknown (don’t care) T tristate l low (2 or more DUT drivers active) Testbench Level (only z drivers from the DUT) h high (2 or more DUT drivers active Drivers Active on Both Levels 0 low (both input and output are active with 0 values) 1 high (both input and output are active with 1 values) ? unknown F tristate (input and output unconnected) A unknown (input 0 and output unconnected) a unknown (input 0 and output X) B unknown (input 1 and output 0) b unknown (input 1 and o
Modeling Your Design 2-40
3 Compiling Your Design 1 VCS compiles your design before simulation. You can use the vcs command to compile your designs. The resulting executable is called simv. There are several options and techniques that you can use to compile your design for high performance or easy debugging. Native code generation is default in VCS.
• Initializing Memories and Regs • Initializing Memories and Regs • Allowing Inout Port Connection Width Mismatches • Using Lint • Changing Parameter Values From the Command Line • Checking for X and Z Values in Conditional Expressions • Making Accessing an Out of Range Bit an Error Condition • Compiling Runtime Options Into the simv Executable • Performance Considerations • 64-32-Bit Cross-Compilation and Full 64-Bit Compilation • Using Radiant Technology • Library Mapping Files and
For a complete description of the syntax of the vcs command, see Appendix B, "Compile-Time Options". Incremental Compilation VCS compiles your source code on a module-by-module basis. By default, when you recompile the design, VCS recompiles only the modules that have changed since the last compilation. This is called incremental compilation. During compilation VCS creates a subdirectory named csrc to store the files generated by compilation.
Compile-time options that affect incremental compilation all begin with -M. For more details on these options, see “Options for Incremental Compilation” on page B-6. Triggering Recompilation VCS recompiles a module when you change its contents. The following conditions also trigger the recompilation of a module: • Change in the VCS version. • Changes in the command-line options. • Change in the target of a hierarchical reference. • Change in the ports of a module instantiated in the module.
Using Shared Incremental Compilation Shared incremental compilation allows a team of designers working on a large design to share the generated files for a design in a central location so that they do not have to recompile the parts of a design that have been debugged and tested by other members of the team.
The chip designer needs to know what debug features the board designer needs in the chip design. The chip designer meets the board designer and learns that the board designer needs to dump the signals in a memory submodule in the chip design, so the chip designer adds a $dumpvars system task to the chip design: $dumpvars(0,asic.
The board designer includes the -Mdir option to specify a directory where VCS writes the generated files for the board design but not the chip design. VCS also uses the generated files in this directory to create the simv executable for simulating the board design. If the board designer omits this option, VCS will write the generated files to a csrc directory in the board designer’s current directory.
Initializing Memories and Regs VCS has compile-time options for initializing all bits of memories and regs to the 0, 1, X, or Z value. These options are: +vcs+initmem+0|1|x|z Initializes all bits of all memories in the design. +vcs+initreg+0|1|x|z Initializes all bits of all regs in the design. Note: +vcs+initmem+, and +vcs+initreg+ options work only for Verilog portion of the design. The +vcs+initmem option initializes regular memories and multi-dimensional arrays of the reg data type.
• Assigning values to regs or memory elements at simulation time 0 when the value you assign is not the same as the value specified with the +vcs+initreg or +vcs+initmem option. For example: initial begin mem[1][1]=8’b00000001; . . . Allowing Inout Port Connection Width Mismatches By default it is an error condition if you connect a signal to an inout port and that signal does not have the same bit width as the inout port.
Without the +noerrorIOPCWM compile-time option, VCS displays the following error message and does not create the simv executable: Error-[IOPCWM] Inout Port connection width mismatch The following 8-bit expression is connected to 16-bit port "gk" of module "dev", instance "dev1". If you include the +noerrorIOPCWM compile-time option, VCS displays the following warning message and creates the simv executable: Warning-[IOPCWM] Inout Port connection width mismatch.
VCS displays this message when you attach an entire vector reg instead of a bit-select to an input terminal of a gate. In this message the text string GCWM is the ID of the message. You can use the ID to enable or disable the message. The syntax of the +lint option is as follows: +lint=[no]ID|none|all,... Here: no Specifies disabling lint messages that have the ID that follows. There is no space between the keyword no and the ID. none Specifies disabling all lint messages.
• Disable all lint messages. This is the default. +lint=none The syntax of the +lint option is very similar to the syntax of the +warn option for enabling or disabling warning messages. Another thing these options have in common is that some of their messages have the same ID.
• -pvalue • -parameters You specify a parameter with the -pvalue option. It has the following syntax: vcs -pvalue+hierarchical_name_of_parameter=value For example: vcs source.v -pvalue+test.d1.param1=33 You specify a file with the -parameters option. The file contains command lines for changing values. A line in the file has the following syntax: assign value path_to_the_parameter Here: assign Keyword that starts a line in the file. value New value of the parameter.
Note: The -parameters and -pvalue options do not work with a localparam or a specparam. Checking for X and Z Values in Conditional Expressions The -xzcheck compile-time option tells VCS to display a warning message when it evaluates a conditional expression and finds it to have an X or Z value.
VCS displays this warning every time it evaluates the conditional expression to have an X or Z value, not just when the signal or signals in the expression transition to an X or Z value. VCS does not display a warning message when a sub-expression has the value X or Z, but the conditional expression evaluates to a 1 or 0 value.
Filtering Out False Negatives By default, if a signal in a conditional expression transitions to an X or Z value and then to 0 or 1 in the same simulation time step, VCS displays the warning. Example 1 In this example, VCS displays the warning message when reg r1 transitions from 0 to X to 1 during simulation time 1.
Example 5 False Negative Example module test; reg r1; initial begin r1=1'b0; #1 r1<=1'b1; r1=1'bx; end always @ (r1) begin if (r1) $display("\n r1 true at %0t\n",$time); else $display("\n r1 false at %0t\n",$time); end endmodule If you consider these warning messages to be false negatives, use the nofalseneg argument to the -xzcheck option to suppress the messages. For example: vcs example.
r1 false at 1 r1 true at 1 If you compile and simulate example1 or example2 with the xzcheck compile-time option and the nofalseneg argument, VCS does not display the warning message. HSOPT Technology The HSOPT technology improves both the compile-time and runtime performance of VCS, reduces the amount of memory needed for both compilation and simulation, and reduces the size of the simv executable. HSOPT is an LCA feature requiring a special license. You enable HSOPT with the -hsopt compile-time option.
• designs with extensive use of timing such as delays, timing checks, and SDF back annotation, particularly to INTERCONNECT delays • designs compiled with -debug_all The designs that benefit the least from HSOPT are as follows: • shallow designs — those with only a few layers of hierarchy • designs without extensive use of timing HSOPT is developed for Verilog and SystemVerilog code (design, assertion, and testbench constructs) and supports the following adjacent technologies: • mixed HDL (VCS MX)
Making Accessing an Out of Range Bit an Error Condition By default it is a warning condition if your code assigns a value to, or reads the value of, a bit of a signal, or an element in a memory or multidimensional array, that was not in the declaration of the signal, memory, or array. For example: reg [1:0] r1; . . . initial r1[2] = 1; In this case, there is no bit 2 in the declaration of reg r1. VCS displays a warning message but continues to compile the code and link together the simv executable.
"source_file.v", line_number: signal[bit] Like the warning message, the error message includes the module name where the access occurs, the source file name, the line number, and the signal name and bit that is outside the declared range, or the memory or array and the undeclared element.
You can also enter the following runtime options on the vcs command line or in the file that you specify with the -f or -F compile-time option, so that VCS compiles them into the simv executable, BUT you must precede them with the +plusarg_save compile-time option: +cfgfile +vcs+dumpoff +vcs+dumpvarsoff +vcs+ignorestop +vcs+mipd+noalias +vcs+stop +vera_mload +vpddrivers +vpdfilesize +vpdnostrengths +vpdupdate +override_model_delays +vcs+dumpon +vcs+grwavesoff +vcs+learn+pli +vcs+nostdout +vera_load +vpdbuf
Several runtime options, such as -cm, -cm_dir, -cm_name, +notimingcheck, and +no_tchk_msg, are also compile-time options. When these options appear on the vcs command line or in the file that you specify with the -f or -F compile-time option, even if you precede them with the +plusarg_save option, VCS considers them to be compile-time options. So, there is no way to compile these runtime options into the simv executable.
If the csrc working directory is not located on a local disk, set the incremental compile directory so that it is. Or change to the local disk (cd local_disk) and run the compilation there. This ensures that VCS can quickly access the compilation directory. If the link step takes more than a few seconds on a small design, then you know that you’re accessing files over the network. Managing Temporary Disk Space on UNIX The temporary disk space partition (/tmp) causes errors if it becomes full.
Compile-Time Options That Impede or Accelerate VCS There are a number of compile-time options that enhance or reduce compilation and simulation performance. Consider looking for opportunities when you can use the options that speed up compilation or simulation and looking for ways to avoid the options that slow down compilation or simulation. Compile-Time Options That Slow Down Both Compilation and Simulation -debug Enables line stepping. +acc Enables PLI ACC capabilities.
+spl_read Treats output ports as inout ports. Compile-Time Options That Slow Down Compilation -gen_asm Generates assembly code instead of directly generating native code. Can increase compilation time up to 20%. -gen_c Generates C intermediate code instead of directly generating native code. Can increase compilation time as much as 3x. -comp64 Compiles in 64-bit mode for 32-bit simulation.
-O1 Applies fewer optimizations when generating C code intermediate files and compiling them. Applying fewer optimizations allows the C compiler to finish somewhat sooner but the design simulates somewhat slower without these optimizations. Compile-Time Options That Speed Up Both Compilation and Simulation +nospecify Tells VCS to ignore specify blocks. If you have extensive specify blocks this can increase both compilation and simulation speed.
% vcs -Mdir=csrc_debug -debug source.v This command line enables debugging capabilities but also results in a slower simulating simv executable. VCS writes the generated files for this simv executable in the directory csrc_debug. For faster simulation enter the following vcs command line: % vcs -Mdir=csrc_perf source.v This command line results in a faster simulating simv executable. VCS writes the generated files for this simv executable in the directory csrc_perf.
Note: • 64-bit machines have more capacity than 32-bit machines, but there is a performance trade-off. • The process of compiling on a 64-bit machine and simulating the executable on a 32-bit machine, generally known as Crosscompilation is not yet supported. • The 64-bit compilation and 64-32-bit cross-compilation processes are not available on all platforms, and not all features and capabilities of VCS work with them.
Error: malloc(400) returned 0: Not enough space error: out of virtual memory (swap space) error: calloc(16384,1) returned 0: Cannot allocate memory Error-[NOMEM] Out of virtual memory (swap space)! sbrk(0) returned 0x80f52ea0 datasize limit 2097148 KB memorysize limit 2097152 KB If you encounter one of these error messages, there are several alternative methods you can try that might help adapt to the memory requirements of your design.
• Avoid using debug options like -debug, -debug_all... switches. • In the pli.tab files, beware of ACC calls that call for global access (i.e. acc=rw:*) • Minimize the amount of dumping. Instead of dumping the whole design, try to limit the scope of dumping to particular modules. Note that an overhead is incurred if you compile in dumping using $test$plusargs, even if it is not enabled until runtime. • If dumping to a VPD file, use +nocelldefinepli+n to limit dumping to non-library modules.
Setting up the Compiler and Linker Before running the 64-32-bit cross-compilation, Synopsys recommends that you check the VCS Release Notes for currently supported compilers and linkers. In general, you can use gcc for compiling. The release notes also indicate the required library and assembler patches. Memory Setup In order to run the 64-32-bit cross-compilation process, make sure you are running on a machine with at least 8 GB of available memory.
Note that these are only experimental values and you may need to further adjust them to fit your particular situation. If you still have memory issues, try running the cross-compilation process with the +memopt option. Specifying the Compiler, Linker, and -comp64 Option When running the 64-32-bit cross-compilation process, you can specify the compiler and linker in either of two ways: • Using the path environment variable. • Using VCS compile-time options -cc and -ld.
Running a 64-Bit Compilation and Simulation If you are encountering memory issues at runtime, you can use the -full64 option. This option compiles a 64-bit binary executable for simulating in 64-bit mode. In this case, you need to use a 64-bit machine at both compile-time and runtime. Make sure you check the VCS Release Notes for all compatible platforms for running a 64-bit compilation.
Compiling With Radiant Technology You specify Radiant Technology optimizations at compile time. Radiant Technology has the following compile-time options: +rad Specifies using Radiant Technology +optconfigfile Specifies applying Radiant Technology optimizations to part of the design using a configuration file. See “Applying Radiant Technology to Parts of the Design” on page 3-36. Known Limitations Radiant Technology is not applicable to all simulation situations.
The only SystemVerilog constructs that work with Radiant Technology are SystemVerilog assertions that refer to signals with Verilog-2001 data types, not the new data types in SystemVerilog. Potential Differences in Coverage Metrics VCS supports coverage metrics with Radiant Technology and you can enter both the +rad and -cm compile-time options. However, Synopsys does not recommend comparing coverage between two simulation runs when only one simulation was compiled for Radiant Technology.
You specify the configuration file with the +optconfigfile compile-time option. For example: +optconfigfile+file name Note: The configuration file is a general purpose file that has other purposes, such as specifying ACC write capabilities. Therefore to enable Radiant Technology optimizations with a configuration file, you must also include the +rad compile-time option.
Here: module Keyword that specifies that the attributes in this statement apply to all instances of the modules in the list, specified by module identifier.
tree Keyword that specifies that the attributes in this statement apply to all instances of the modules in the list, specified by module identifier, and also apply to all module instances hierarchically under these module instances. depth An integer that specifies how far down the module hierarchy, from the specified modules, you want to apply Radiant optimization attributes. You can specify a negative value.
Configuration File Statement Examples The following are examples of statements in a configuration file. module statement example module {mod1, mod2, mod3} {noOpt, PortOpt}; This module statement example disables Radiant optimizations for all instances of modules mod1, mod2, and mod3, with the exception of port optimizations.
instance {mod1.mod2_inst1.mod3_inst1, mod1.mod2_inst1.rega} {noOpt}; In this example, the module statement disables Radiant optimizations for all instances of module mod1.
first tree statement example tree {mod1,mod2} {Opt}; This example is for a design with the following module hierarchy: module top module mod1 mod1_inst1 module mod11 mod11_inst1 module mod111 mod111_inst1 module mod12 mod12_inst1 module mod2 mod2_inst1 module mod3 mod3_inst1 module mod21 mod21_inst1 Radiant Technology optimizations apply to this part of the design module mod1111 mod1111_inst1 The statement enables Radiant Technology optimizations for the instances of modules mod1 and mod2 and for
down the hierarchy than the instances of the specified modules, mod1 and mod2. module top module mod1 mod1_inst1 module mod11 mod11_inst1 module mod12 mod12_inst1 module mod2 mod2_inst1 module mod3 mod3_inst1 module mod21 mod21_inst1 module mod111 mod111_inst1 Radiant Technology optimizations apply to this part of the design module mod1111 mod1111_inst1 A tree statement with a depth of 0 is the equivalent of a module statement.
counting up from there. (Leaf level module instances contain no module instantiation statements.
Library Mapping Files and Configurations Library mapping and configurations are an LCA (Limited customer Availability) feature and requires a special license. For more information contact your Synopsys Applications Consultant. Library mapping files are an alternative to the defacto standard way of specifying Verilog library directories and files with the -v, -y, and +libext+ext compile-time options and the ‘uselib compiler directive.
The following is an example of the contents of a library mapping file: library lib1 /net/design1/design1_1/*.v; library lib2 /net/design1/design1_2/*.v; Note: Path names can be absolute or relative to the current directory that contains the library mapping file. In this example library mapping file there are two logical libraries.
VCS assigns the source file dev.v to the default logical library called work. You can specify either absolute paths or relative paths to the source files. Overriding the Search Order in the Library Mapping File You can use the -liblist logical_library+... compile-time option to alter the search order VCS uses. If the library mapping file lists the lib1 logical library first, you can tell VCS to search lib2 first with the following VCS command line: vcs +v2k dev.v -libmap lib1.
Resolving ‘include Compiler Directives The source file in a logical library might include the ‘include compiler directive. if so, you can include the -incdir option on the line in the library mapping file that declares the logical library, for example: library gatelib /net/design1/gatelib/*.v -incdir /net/ design1/spec1lib, /net/design1/spec2lib; Note: The +incdir VCS compile-time option, on the vcs command line, overrides the -incdir option in the library mapping file.
• Specifies overrides to the logical library search order for all instances of specified cells You can define a configuration in a library mapping file or in any type of Verilog source file. Configurations can be mapped to a logical library just like any other type of cell. Configuration Syntax A configuration contains the following statements: config config_identifier; design [library_identifier.]cell_identifier; config_rule_statement; endconfig Where: config Is the keyword that begins a configuration.
endconfig Is the keyword that ends a configuration. The default Clause The default clause specifies the logical libraries in which to search to resolve a default cell instance. A default cell instance is an instance in the design that is not specified in a subsequent instance or cell clause in the configuration. You specify these libraries with the liblist keyword.
use Specifies that the instance is an instance of the specified cell in the specified logical library. The following are examples of instance clauses: instance top.dev1 liblist lib1 lib2; This instance clause tells VCS to resolve instance top.dev1 with the cells assigned to logical libraries lib1 and lib2; instance top.dev1.gm1 use lib2.gizmult; This instance clause tells VCS that top.dev1.gm1 is an instance of the cell named gizmult in logical library lib2.
particular instances in a subhierarchy, then you can define a configuration for a higher level of the design. Suppose, for example, a subhierarchy of a design was an eight-bit adder and you have RTL Verilog code describing the adder in a logical library named rtllib and you had gate-level code describing the adder in a logical library named gatelib. Now for some reason, you want the gate-level code used for the 0 (zero) bit of the adder and the RTL level code used for the other seven bits.
The -top compile-time option requires the +v2k or -sverilog compile-time option and the -new_dr compile-time option. If you have coded your design to have more than one top-level module you can enter more than one -top option, or you can append arguments to the option using the plus delimiter, for example: -top top_cfg+test+ Using the -top options tells VCS not to create extraneous top-level modules, one that you don’t specify.
Compiling and Elaborating Your Design 3-54
4 Simulating Your Design 1 You can simulate your design with VCS using several options and techniques, which allow you to focus on either performance or debugging. You can also use runtime options to save and restart the simulation as required.
Running and Controlling a Simulation This section describes how to simulate your design using the binary executable generated during compilation. Invoking a Simulation at the Command Line To invoke the simulation, enter the following at the command line: % executable [options] The options are more than one runtime options that enable you to control how VCS executes the simulation. For a complete list of VHDL and Verilog runtime options, see Appendix C, "Simulation Options".
2. Choose Simulator > Setup, then start simulation from the Simulation Setup dialog box. 3. Browse to the simulation executable or a VPD/VCD file and select a working directory. 4. Select start and waveform update options. 5. Click OK. For more information on DVE, see Chapter 5, "Using the Discovery Visual Environment".
Save and Restart VCS provides a save and restart feature that allows checkpoints of the simulation to be saved at arbitrary times. The resulting checkpoint files can be executed at a later time, causing simulation to resume at the point immediately following the save.
Example 4-1 Save and Restart Example % cat test.v module simple_restart; initial begin #10 $display("one"); $save("test.chk"); $display("two"); #0 // make the following occur at restart $display("three"); #10 $display("four"); end endmodule Now compile the example source file: % vcs test.v Now run the simulation: % simv VCS displays the following: one two $save: Creating test.chk from current state of simv... three four To restart the simulation from the state saved in the check file, enter: % test.
four Save and Restart File I/O VCS remembers the files you opened via $fopen and reopens them when you restart the simulation. If no file with the old file name exists, VCS opens a new file with the old file name. If a file exists having the same name and length at time of save as the old file, then VCS appends further output to that file. Otherwise, VCS attempts to open a file with file name equal to the old file name plus the suffix .N. If a file with this name exists, VCS exits with an error.
For example, if you load a memory image with $loadmemb at the beginning of the simulation and want to be able to restart from a checkpoint with a different memory image, you must add Verilog code to load the memory image after every $save call. This ensures that at the beginning of any restart the correct memory image is loaded before simulation begins. A reasonable way to manage this is to create a task to handle processing arguments, and call this task at the start of execution, and after each save.
Restarting at the CLI Prompt The $restart system task allows you to restart the simulation at the CLI prompt. Enter it with the name of the check file created by the $save system task. For example: C1 > $restart("checkfile1"); Specifying a Very Long Time Before Stopping Simulation You can use the +vcs+stop+time runtime option to specify the simulation time when VCS halts simulation. This works if the time value you specify is less that 232 or 4,294,967,296.
This difference is the first argument. You can let VCS do some of this work for you by using the following source code: module wide_time; time wide; initial begin wide = 64’d10_000_000_000; $display(“Hi=%0d, Lo=%0d”, wide[63:32], wide[31:0]); end endmodule VCS displays: Hi=2,Lo=1410065408 2. Divide the large time value by 232. In this example: 10, 000, 000, 000 ---------------------------------------------- = 2.33 4, 294, 967, 296 3. Round down this quotient to the whole number.
Passing Values From the Runtime Command Line The $value$plusargs system function can pass a value to a signal from the simv runtime command line using a plusarg. The syntax is as follows: integer = $value$plusargs("plusarg_format",signalname); The plusarg_format argument specifies a user-defined runtime option for passing a value to the specified signal. It specifies the text of the option and the radix of the value that you pass to the signal.
How VCS Prevents Time 0 Race Conditions At simulation time 0, VCS always executes the always blocks in which any of the signals in the event control expression, that follows the always keyword (the sensitivity list), initializes at time 0.
With other Verilog simulators there are two possibilities at time 0: • The simulator executes the initial block first, initializing reg rst, then the simulator evaluates the event control sensitivity list for the always block and executes the always block because the simulator initialized rst. • The simulator evaluates the event control sensitivity list for the always block, and so far reg rst has not changed value during this time step so the simulator does not execute the always block.
Runtime options that specify writing to a file slow down simulation. These runtime options are as follows: -a filename Appends all output of the simulation to the specified file as well as sends it to the standard output. -l filename Writes all output of the simulation to the specified file as well as to the standard output. Other runtime options that specify operations other than the default operations also slow down simulation to some extent.
For memory usage it reports the following: • The amount of memory and the percentage of memory used by the VCS kernel, the design, the SystemVerilog testbench program block, cosimulation applications using either the DPI or PLI, and the time spent writing a VCD or VPD file. • The amount of memory and the percentage of memory that each module definition uses. You can use this information to see where in your design you might be able to modify your code for faster simulation performance.
The Top Level View This view shows you how much CPU time was used by: • Any PLI application that executes along with VCS • VCS for writing VCD and VPD files • VCS for internal operations that can’t be attributed to any part of your design • The Verilog modules in your design • A SystemVerilog testbench program block, if used Example 4-2 Top Level View =========================================================================== TOP LEVEL VIEW =======================================================
If there was CPU time used by a PLI application, you could use a tool such as gprof or Quantify to profile the PLI application. The Module View This view shows you the module definitions whose instances use the most CPU time. It does not list module definitions whose module instances collectively use less than 0.5% of the CPU time.
• There are 10,000 instances of module FD2. The number of instances is a way to assess the CPU times used by these instances. For example, as in this case, a high CPU time with a correspondingly high number of instances tells you that each instance isn’t using very much CPU time. • The module header, the first line of the module definition, is in source file design.v on line 142.
• combinational logic including gates or built-in primitives and continuous assignment statements • user-defined tasks • user-defined functions • module instance ports • user-defined primitives (UDPs) • Any Verilog code protected by encryption Ports use simulation time particularly when there are expressions in port connection lists such as bit or part selects and concatenation operators. This view has separate sections for the Verilog constructs for each module definition in the module view.
Example 4-5 Module to Construct Mapping View =========================================================================== MODULE TO CONSTRUCT MAPPING =========================================================================== ___________________________________________________________________________ 1.
• An always block in this module definition used 27.44% of the TOTAL CPU time. Of all the CPU time consumed by all instances of the FD2 module, 44.14% is spent on this construct (44.14% of 62.17% = 27.44%). The always block is in source file design.v between lines 150 and 160. If there were another always block in module FD2 that used more than 0.5% of the CPU time, there would be another line in this section for it, beginning with the always keyword. • The module path delays in this module used 23.
The Instance View This view shows you the module instances that use the most CPU time. An instance must use more than 0.5% of the CPU time to be entered in this view. Example 4-6 Instance View =========================================================================== INSTANCE VIEW =========================================================================== Instance %Totaltime --------------------------------------------------------------------------test.lfsr1000_1.lfsr100_1.lfsr10_1.lfsr_1.en_ 1 ( 2 ) 0.
The Program to Construct Mapping View The program to construct mapping view lists the testbench constructs that use the most simulation time and list the percentage of the total simulation they use, and the percentage of the program’s simulation time each type of construct uses. It also lists the source fine and line number of the constructs declaration.
Example 4-8 Top Level Construct View ============================================================================== TOP-LEVEL CONSTRUCT VIEW -----------------------------------------------------------------------------Construct %Totaltime -----------------------------------------------------------------------------Combinational 28.14 Task 16.58 Program Task 9.87 Always 6.52 Program Function 5.82 queue.size 2.64 Port 2.01 Object new 1.92 Initial 0.89 Program Thread 0.79 Function 0.76 queue.name 0.09 queue.
Example 4-9 Top Level Construct View =========================================================================== CONSTRUCT VIEW ACROSS DESIGN =========================================================================== ___________________________________________________________________________ 1.Always --------------------------------------------------------------------------Module %TotalTime --------------------------------------------------------------------------FD2 27.
• Top Level View • Module View • The Program View The Top Level View This view shows you how much memory was used by: • Any PLI or DPI application that executes along with VCS • VCS for writing VCD and VPD files • VCS for internal operations (known as the kernel) that can’t be attributed to any part of your design.
In this example there is no DPI or PLI application and VCS does not write a VCD or VPD file. VCS used 1163834 bytes of memory, 56.66% of the total memory, to simulate the design. VCS used 890408 bytes of memory, 43.34% of the total memory, for internal operations, such as scheduling, that can’t be attributed to any part of the design. The designation KERNEL, is for these internal operations.
The Program View The program view shows the amount of memory used, and the percentage of memory used, by each testbench program. Example 4-12 Program View ============================================================================== PROGRAM VIEW ============================================================================== Program(index) Memory %Totalmemory No of Instances Definition -----------------------------------------------------------------------------test (1) 4459091 18.74 1 /u/design/test.
Simulating Your Design 4-28
5 Using the Discovery Visual Environment 2 This chapter introduces the Discovery Visual Environment (DVE) graphical user interface. It contains the following sections: • Overview of DVE Window Configuration • DVE Panes • Managing DVE Windows • Using the Menu Bar and Toolbar • Setting Display Preferences For complete information on the use of DVE, see the Discovery Visual Environment User Guide in your VCS / VCS MX installation.
Overview of DVE Window Configuration DVE has a completely flexible window model. This model is based on the concept of the TopLevel window. A TopLevel window contains a frame, menus, toolbars, status bar, and pane targets. Any number of TopLevel windows are possible. The default at startup is one. A DVE TopLevel window is a frame for displaying design and debug data.
Figure 5-1 DVE TopLevel Frame Initial View Hierarchy Browser Menu Bar Data Pane Status Bar Toolbar Source Window Target Window Control Tcl Command-line Interface Console Tabs Console Using the Discovery Visual Environment 5-3
DVE Panes A TopLevel window can contain any number of panes. A pane is a window that serves a specific debug purpose. Examples of panes are Hierarchy, Data, Assertion, Wave, List, Memory, and Schematic. Panes can be docked on any side ot a TopLevel window or left floating in the area in the frame not occupied by docked panes (called the workspace). Panes can also be opened in a new TopLevel frame. Managing DVE Windows A DVE TopLevel window can contain any number of DVE windows and panes.
Figure 5-2 Window targeting icons Darts indicate targeted windows are attached to the current window. No dart in targeted Wave window icon Target icons can have the following two states: • Targeted – Icon has a dart in it, which means an action that requires a new pane creates that pane in the current frame • Untargeted – icon has no dart in it, which means an action that requires a new pane creates a new TopLevel window that contains that pane. To open a pane in a new TopLevel window: 1.
Targets a new Wave pane in a new TopLevel window Wave Targets a List pane in a new TopLevel window. List Memory Targets a new Memory pane in a new TopLevel window. 2. Click a corresponding window icon in the toolbar to open a window of that type. It will not be attached to the current window and will open in a new TopLevel window. Docking and Undocking Windows and Panes You can use the Windows menu to dock and undock windows and panes.
Dark blue color of dock handle (dock handle is the train track that connects to the X icon) indicates that this docked window is active. This is the same for all dockable windows. An action must occur such as a click to make the window active. Dragging and Dropping Docked windows Left Click on the dock handle and drag and drop the window to a new dock location or to a non docked window. Right click on dock handle brings up a small popup menu: Undock Undock the active window.
• Select View>Go To Time, then enter a value in the Go To Time dialog box, and click Apply or OK. • Enter a value in the Time text field on the toolbar, then press Enter on your keyboard. See Figure 5-3 for an example.
Figure 5-3 Methods for Setting the Simulation Time Menu Bar: OR Select View>Go To Time, enter a value in the Go To Time dialog box, then click Apply or OK. Toolbar: Enter value in Time text field of the toolbar, then press the Enter key. Results: Waveform display moves to specified simulation time.
Setting Display Preferences You can set preferences to customize the display of DVE windows and panes. To customize the display: 1. In the TopLevel window, select Edit > Preferences. The Application Preferences dialog box displays the Global Settings category. 2. Select settings as follows: - Global Settings Select settings to set the font and font sizes to display in DVE windows The default is to log only UCLI commands. To also log GUI commands select the Log GUI commands in Console window checkbox.
Select whether to display the exit dialog box when closing DVE. - Debug Settings – Select signal compare parameters, value transition, exit dialog box and assertion window docking defaults, and first frame target setup options..
- Hierarchy Browser – Set the appearance and initial filter states.. - Data Pane – Set the appearance parameters, signal sorting, signal levels to display, and scroll bar conditions..
- Source window – Specify data and annotation loading options, line wrap, line number display, tab width, default editor, and automatic reload of changed source code..
- Schematic window – Set line colors for schematic objects in Schematic and Path Schematic windows.. - Select the Value Annotations subcategory and set the Port/Pin visibility and color..
- Waveform window – Set appearance parameters, signal levels to display, and marker value display settings.. - List window – Sepecify grid display, signal name truncation, signal levels to display, and column spacing settings..
- Coverage Settings – Set weights for display of line, condition, toggle, FSM, and cover metrics.. - Coverage Colors – Customize the color display of Source window cover states and the number of coverage ranges and their associated colors in the Color Settings window.
3. Click OK to save your selections and close the dialog box, Save to save your settings and keep the dialog box open, or Reset to return the default settings.
Using the Discovery Visual Environment 5-18
6 VPD and EVCD File Generation 1 VPD and EVCD files contain simulation history data. In Verilog simulation, $vcdplus system tasks create these files and name them vcdplus.vpd by default. You can use system tasks that include the vcdplus name in the tasks, for example, $vcdpluson, $vcdplusoff, and $vcdplusfilename, to manipulate VPD files. To generate an EVCD file, you can use the system tasks $dumports, and $lsi_dumpports.
• System Tasks and Functions • Runtime Options • VPD Methodology • EVCD File Generation Advantages of VPD VPD offers the following significant advantages over the standard VCD ASCII format: • Provides a compressed binary format that dramatically reduces file size as compared to VCD and other proprietary file formats. • The VPD compressed binary format dramatically reduces signal load time.
System Tasks and Functions VPD system tasks capture and save value change data in a binary format so that you can view the data in the Wave Window, Register Window, Source Window, and Logic Browser. You can include the following VPD system tasks in source files or enter them at the DVE interactive prompt. System Tasks to Generate a VPD File Note: The $vcdpluson and $vcdplusoff system tasks accept the same arguments as the Verilog $dumpvars system task.
scope Specifies the name of the scope in which to record signal value changes (default is all). signal Specifies the name of the signal in which to record signal value changes (default is all). Note: In the syntax, * indicates that the argument can have a list of more than one value (for scopes or signals). Example 1: Record all signal value changes. $vcdpluson; Example 2: Record signal value changes for scope test.risc1.alureg and all levels below it. $vcdpluson(test.risc1.
Example 2: Stop recording signal value changes for scope test.risc1.alu1. $vcdplusoff(test.risc1.alu1); Example 3: Stop recording signal value changes for test.risc1.alu1 and test.risc1.instreg.d1. $vcdplusoff(test.risc1.alu1, test.risc1.instreg.d1); Example 4: Stop recording signal value changes for scope test.risc1.alu1 and 39 levels below. In this example, 40 is a number large enough to ensure all lower levels are turned off. $vcdplusoff(40, test.risc1.
$vcdplusautoflushon When simulation stops, the $vcdplusautoflushon task automatically flushes to the VPD data file any value changes that have been reported by VCS but have not yet been written to the VPD data file. Syntax: $vcdplusautoflushon; $vcdplusautoflushoff The $vcdplusautoflushoff task turns off the automatic flush (enabled by the $vcdplusautoflushon task). Syntax: $vcdplusautoflushoff; $vcdplusfile The $vcdplusfile task specifies a VPD file name. If it does not specify a name, vcdplus.
System Tasks and Functions for Multi-Dimensional Arrays This section describes system tasks and functions that provide visibility into multi-dimensional arrays (MDAs). There are two ways to view MDA data: • The first method, which uses the $vcdplusmemon and $vcdplusmemoff system tasks, records data each time an MDA has a data change. • The second method, which uses the $vcdplusmemorydump system task, stores data only when the task is called.
dim1Lsb Name of the variable that contains the left bound of the first dimension. This is an optional argument. If there are no other arguments, then all elements under this single index of this dimension are recorded. dim1Rsb Name of variable that contains the right bound of the first dimension. This is an optional argument. Note: The dim1Lsb and dim1Rsb arguments specify the range of the first dimension to be recorded.
Note that MDA system tasks can take 0 or more arguments, with the following caveats: • No arguments: The whole design is traversed and all memories and MDAs are recorded. Note that this process may cause significant memory usage, and simulation drag. • One argument: If the object is a scope instance, all memories/ MDAs contained in that scope instance and its children will be recorded. If the object is a memory/MDA, that object will be recorded.
In order for VCS to provide memory data, it requires the +memcbk switch. VCS example: vcs -R -I mda.v +memcbk Memory declaration example: reg [1:0] mem [3:0]; Examples This section provides examples and graphical representations of various MDA and memory declarations using the $vcdplusmemon and $vcdplusmemoff tasks. Example 6-1 MDA and Memory Declaration Note that mem01 in this example is a three-dimensional array. It has 3x3x3 (27) locations; each location is 8 bits in length.
Figure 6-1 Diagram of example: reg [7:0] mem01 [1:3] [4:6] [7:9] Dimension 2 Dimension 1 5 4 [76543210] 1 6 Dimension 3 [76543210] [76543210] [76543210] [76543210] [76543210] 2 7 [76543210] [76543210] [76543210] 3 1 [76543210] [76543210] [76543210] [76543210] [76543210] [76543210] 2 8 [76543210] [76543210] [76543210] 3 1 [76543210] [76543210] [76543210] 9 [76543210] [76543210] [76543210] 2 Note: Unlimited dimensions can be used.
Example 6-2 $vcdplusmemon( mem01, addr1L ); $vcdplusmemon( mem01 ); // Records all elements of mem01 to the VPD file. addr1L = 2; $vcdplusmemon( mem01, addr1L ); // Records elements mem01[2][4][7] through mem01[2][6][9] The elements highlighted by the demonstrate Example 6-2.
Figure 6-2 Diagram of example: $vcdplusmemon( mem01, addr1L ); Starting bound: mem01[2][4][7] 5 4 [76543210] 1 6 [76543210] [76543210] [76543210] [76543210] [76543210] 2 7 Ending bound: [76543210] [76543210] [76543210] 3 1 [76543210] mem01[2][6][9] [76543210] [76543210] [76543210] [76543210] [76543210] 2 8 [76543210] [76543210] [76543210] 3 [76543210] 1 [76543210] [76543210] 9 [76543210] [76543210] [76543210] 2 3 Example 6-3 [76543210] [76543210] [76543210] $vcdplusmemon( mem01
Figure 6-3 $vcdplusmemon( mem01, addr1L, addr1R ); Starting bound: mem01[2][4][7] 5 4 [76543210] 1 6 [76543210] [76543210] [76543210] [76543210] [76543210] 2 7 [76543210] [76543210] [76543210] 3 1 [76543210] mem01[3][6][9] [76543210] [76543210] [76543210] [76543210] [76543210] 2 Ending bound: 8 [76543210] [76543210] [76543210] 3 [76543210] 1 [76543210] [76543210] 9 [76543210] [76543210] [76543210] 2 3 Example 6-4 [76543210] [76543210] [76543210] $vcdplusmemon( mem01, addr1L, ad
The elements highlighted by the demonstrate Example 6-4.
Example 6-5 $vcdplusmemon( mem01, addr1L, addr1R, addr2L, addr2R ) addr1L = 2; addr1R = 2; addr2L = 5; addr2R = 6; $vcdplusmemon( mem01, addr1L, addr1R, addr2L, addr2R ); // Records elements mem01[2][5][7] through mem01[2][6][9] The elements highlighted by the demonstrate Example 6-5.
Figure 6-5 $vcdplusmemon( mem01, addr1L, addr1R, addr2L, addr2R ); Starting bound: mem01[2][5][7] 5 4 [76543210] 1 6 [76543210] [76543210] [76543210] [76543210] [76543210] 2 7 Ending bound: [76543210] [76543210] [76543210] 3 1 [76543210] mem01[2][6][9] [76543210] [76543210] [76543210] [76543210] [76543210] 2 8 [76543210] [76543210] [76543210] 3 [76543210] 1 [76543210] [76543210] 9 [76543210] [76543210] [76543210] 2 3 Example 6-6 [76543210] [76543210] [76543210] Selected element
addr3L, addr3R ); // Either command records element mem01[2][5][8] The element highlighted by the demonstrates Example 6-6.
You can specify only once the complete set of multi-dimensional array elements to be dumped. You can specify multiple element subsets of an array using multiple $vcdplusmemorydump commands, but they must occur in the same simulation time. In subsequent simulation times, $vcdplusmemorydump commands must use the initial set of array elements or a subset of those elements. Dumping elements outside the initial specifications results in a warning message.
Source File (.v) // $vcdpluson; $vcdplustraceon; VPD File VCS PLI Source Execution Data 2. For viewing in post simulation mode, enter the appropriate trace task at the VCS command line. >$vcdpluson >$vcdplustraceon VPD File VCS Source File (.v) PLI Source Execution Data 3. For viewing in interactive mode in the DVE Source Window, Capture Line Data must be enabled (it is enabled by default).
Source Statement System Tasks Note: For VCS you must supply the -line option when creating the simulation executable. $vcdplustraceon The $vcdplustraceon task turns on line tracing. The VPD file saves line trace information. Syntax: $vcdplustraceon (,*); Here: level The number of hierarchy scope levels to descend to record line tracing (a zero value records all line tracing to the end of the hierarchy; default is 1 level).
Here: level The number of hierarchy scope levels to descend to stop recording line tracing (a zero value stops the recording of all line tracing to the end of the hierarchy; default is 1 level). System Tasks for Capturing Delta Cycle Information You can use the following VPD system tasks to capture and display delta cycle information in the Wave Window. $vcdplusdeltacycleon The $vcdplusdeltacycleon task enables reporting of delta cycle information from the VCS CLI or the Verilog source code.
$vcdplusdeltacycleoff The $vcdplusdeltacycleoff task turns off reporting of delta cycle information starting at the next sample time. Glitch detection is automatically turned off when VCS executes $vcdplusdeltacycleoff unless you have previously used $vcdplusglitchon/off. Once you use $vcdplusglitchon/ off, DVE allows you explicit control of glitch detection.
$vcdplusglitchoff The $vcdplusglitchoff task turns off checking for zero delay glitches. Glitch detection is automatically turned off when VCS executes $vcdplusdeltacycleoff unless you have previously used $vcdplusglitchon/off. Once you use $vcdplusglitchon/off, DVE allows you explicit control of glitch detection. Syntax: $vcdplusglitchoff; $vcdplusevent The $vcdplusevent task allows you to record a unique event for a signal at the current simulation time unit.
event_name A unique string which describes the event. This event name appears in the status bar of the Wave Window, Logic Browser, or Register Window when the mouse is placed on the event marker. severity A single character with legal values E, W, or I, which indicates the severity of the event. The severity of the event may be Error, Warning, or Information respectively. Colors associated with the severity level are set in the X Resource file.
Syntax: +vpdbufsize+nn Here nn is buffer size in megabytes. The minimum size is the size required to store two value changes per signal and the default size is the size required to store 15 value changes for each signal (but not less than 2 megabytes). Note: VCS automatically increases the buffer size as needed to comply with this limit. +vpdfile to Set the Output File Name The +vpdfile command allows you to specify the output file name.
File size is a direct result of circuit size, circuit activity, and the data being saved. Test cases show that VPD file sizes can range from a few megabytes to a few hundred megabytes. Many DVE users can share the same VPD history file, which may be a reason for saving all time value changes when you simulate a design. You can save one history file for the design and overwrite it on each subsequent run. Syntax: +vpdfilesize+nn Here nn is the file size in megabytes.
This option affects performance and memory usage for larger designs or longer runs. Syntax: +vpddrivers +vpdnoports to Eliminate Storing Port Information By default, VPD stores the port type for each signal. When you use this option, the Hierarchy Browser views all signals as internal and not connected to a port. The +vpdnoports option causes VPD to eliminate storing port information, which is used by the Hierarchy Browser to show whether a signal is a port and if so its direction.
+vpdnostrengths to Not Store Strength Information By default, VPD stores strength information on value changes to the VPD file. You can disable this feature by supplying the +vpdnostrengths command line option. Use of this option may lead to slight improvements in VCS performance. Syntax: +vpdnostrengths VPD Methodology The following information explains how to manage the DVE and VPD functions and how to to optimize simulation and analysis.
Conceptual Example of Using VPD System Tasks The example in Figure 6-7, shows the entry of the $vcdplus system tasks in Module B scope. The dump saves all the variables in Module B from time 100 to 300, all variables in module C from time 200 to 500, and a single variable in module D1.clk from time 600 to 900. Zero delay glitch detection is on while value change data is recorded throughout the simulation.
• Create a task in source: task sigon_instreg; begin $vcdpluson(test.risc1.instreg); end endtask Then call the task from source code. initial sigon_instreg; Or, enter the task name at the DVE interactive prompt. C1> sigon_instreg; • Use a shell command argument to enable task execution: vcs -f run.f +signal_on initial if ($test$plusargs("signal_on")) sigon_instreg; task sigon_instrg; begin $vcdpluson(test.risc1.
VPD On/Off PLI Rules Follow these basic rules while using VPD On/Off PLI system tasks: • You can insert the $vcdpluson and $vcdplusoff tasks in source code or enter it at the DVE interactive prompt. • The $vcdpluson and $vcdplusoff tasks accept one level but multiple scopes/signals as arguments. • The $vcdpluson and $vcdplusoff tasks, when applied to the same signals, toggle the recording on and off. The count for each signal is accumulative; (+,-). ..on/..on/..off leaves the signal recording on.
Performance Tips The following tips explain how to manage performance of VCS and VPD: • Normally you should save data for all signals that you may require for analysis. The time range should be such that it very likely contains the origin of the problem. • Generally, the bigger you make the RAM buffer size (via the +vpdbufsize option), the faster the simulation completes its run. The effects are so dependent on circuit and activity that rules-of-thumb do not apply.
• Saving statement execution for an entire design can increase simulation time by eight times or more. To limit performance degradation, limit the use of statement saves to certain scopes. Instead of saving statement execution from time 0, turn on tracing just prior to the time of a suspected problem and off after that time. • The file size increases from 200 to 500 percent when saving line execution data. • Glitch detection and delta cycle may significantly increase the size of the VPD file.
EVCD File Generation You can create an EVCD file for the entire design in the following ways: • Using the runtime option -dump_evcd • Using system tasks Using the runtime option -dump_evcd -dump_evcd writes an EVCD file for the instance/s specified as arguments to this option. You can specify more than one instance separated by “:” as shown below: % executable -dump_evcd /top/dev1/intr1:/top/dev1/intr2 The above example dumps the port information of the modules intr1 and intr2. .
Using System Tasks You can use $dumpports or $lsi_dumports system tasks to generate EVCD files. Using system tasks you can generate multiple EVCD files for various module instances of the design. See Appendix D,”Compiler Directives and System Tasks”.
7 VCD and VPD File Utilities 1 VCS comes with a number of utilities for processing VCD and VPD files. You can use these utilities to perform tasks like creating alternative VCD files, comparing the simulation data in two VCD, EVCD, or VPD files, easily viewing the data in a VCD file, and generating a VCD, EVCD, or VPD file that contains a selected subset of value changes found in a given input VCD, EVCD, or VPD file. Note: All the utilities are available in $VCS_HOME/bin.
• The vcd2vpd Utility • The vpd2vcd Utility • The vpdmerge Utility The vcdpost Utility You use the vcdpost utility to generate an alternative VCD file that has the following characteristics: • Contains value change and transition times for each bit of a vector net or register, recorded as a separate signal. This is called “scalarizing” the vector signals in the VCD file. • Avoids sharing the same VCD identifier code with more than one net or register.
$var wire 8 ! out1 [7:0] $end Therefore all the value changes and simulation times for signal out1 are for the entire signal and not just for the 0 bit. The vcdpost utility can create an alternative VCD file that defines a separate $var section for each bit of the vector signal.
Some back-end tools from other vendors fail when you input such a VCD file. You can use the vcdpost utility to create an alternative VCD file in which the identifier codes for all nets and registers, including the ones without value changes, are unique.
The vcdiff Utility The vcdiff utility compares two dump files and reports any differences it finds. The dump file can be of type VCD, EVCD or a VPD. Note: vcdiff utility cannot compare dump files of different type. Dump files consist of two sections: • A header section that reflects the hierarchy (or some subset) of the design that was used to create the dump file.
The vcdiff Utility Syntax The syntax of the vcdiff utility is as follows: vcdiff first_dump_file second_dump_file [-noabsentsig] [-absentsigscope scope] [-absentsigiserror] [-allabsentsig][-absentfile filename][-matchtypes] [-ignorecase] [-min time] [-max time] [-scope instance] [-level level_number] [-include filename] [-ignore filename] [-strobe time1 time2] [-prestrobe] [-synch signal] [-synch0 signal] [-synch1 signal] [-when expression] [-xzmatch] [-noxzmatchat0] [-compare01xz] [-xumatch] [-xdmatch] [-z
-allabsentsig Reports all absent signals. If this option is not present, by default, vcdiff reports only the first 10 absent signals. -ignorecase Ignores the case of scope/signal names when looking for absent signals. In effect, it converts all signal/scope names to uppercase before comparison. -matchtypes Reports mismatches in signal data types between the two dump files.
-ignore [file] Removes any signals/scopes contained in the given file from value change diffing. The file contains a set of full path specifications of signals and/or scopes, one per line. Note: The vcdiff utility applies the -scope/-level options first. It then applies the -include option to the remaining scopes/signals, and finally applies the -ignore option.
-when expression Reports differences only when the given when expression is true. Initially this expression can consist only of scalar signals, combined via and, or, xor, xnor, and not operators and employ parentheses to group these expressions. You must fully specify the complete path (from root) for all signals used in expressions. -synch signal Checks for differences only when the given signal changes value.
Options for Filtering Differences The following options filter out value change differences that are detected under certain circumstances. For the most part, these options are additive. -ignoretiming time Ignores the value change when the same signal in one of the VCD files has a different value from the same signal in the other VCD file for less than the specified time. This is to filter out signals that have only slightly different transition times in the two VCD files.
-compare01xz (EVCD only) Converts all signal state information to equivalent 4-state values (0, 1, x, z) before difference comparison is made (EVCD files only). Also ignores the strength information. -xzmatch Equates x and z values. -xumatch (9-state VPD file only) Equates x and u (uninitialized) values. -xdmatch (9-state VPD file only) Equates x and d (dontcare) values. -zdmatch (9-state VPD file only) Equates z and d (dontcare) values. -zwmatch (9-state VPD file only) Equates z and w (weak 1) values.
-showmasters (VCD, EVCD files only) Shows collapsed net masters. VCS can split a collapsed net into several sub-nets when this has a performance benefit. This option reports the master signals when the master signals (first signal defined on a net) are different in the two dump files. -limitdiffs number_of_diffs By default, vcdiff stops after the first 50 diffs are reported. This option overrides that default. Setting this value to 0 causes vcdiff to report all diffs.
The vcat Utility Syntax The vcat utility has the following syntax: vcat VCD_filename [-deltaTime] [-raw] [-min time] [-max time] [-scope instance_name] [-level level_number] [-include filename] [-ignore filename] [-spikes] [-noalpha] [-wrapsize size] [-showmasters] [-showdefs] [-showcodes] [-stdin] [-vgen] Here: -deltaTime Specifies writing simulation times as the interval since the last value change rather than the absolute simulation time of the signal transition.
10000 30 x z -raw Displays “raw” value changed data, organized by simulation time, rather than signal name. -min time Specifies a start simulation time from which vcat begins to display data. -max time Specifies an end simulation time up to which vcat displays data. -scope instance_name Specifies a module instance. The vcat utility displays data for all signals in the instance and all signals hierarchically under this instance.
-spikes Indicates all zero-time transitions with the >> symbol in the left-most column. In addition, prints a summary of the total number of spikes seen at the end of the vcat output. The following is an example of the new output: --- DF_test.logic.I_348.N_1 --0 x 100 0 120 1 >>120 0 4000 1 12000 0 20000 1 Spikes detected: 5 -noalpha By default vcat displays signals within a module instance in alphabetical order. This option disables this ordering.
-vgen Generates from a VCD file two types of source files for a module instance: one that models how the design applies stimulus to the instance, and the other that models how the instance applies stimulus to the rest of the design. See "Generating Source Files From VCD Files" on page 7-17. The following is an example of the output from the vcat utility: vcat exp1.vcd exp1.vcd: scopes:6 signals:12 value-changes:13 --- top.mid1.in1 --0 1 --- top.mid1.in2 --0 xxxxxxxx 10000 00000000 --- top.mid1.
Generating Source Files From VCD Files The vcat utility can generate Verilog source files that are one of the following: • A module definition that succinctly models how a module instance is driven by a design, that is, a concise testbench module that instantiates the specified instance and applies stimulus to that instance the way the entire design does. This is called testbench generation.
The name of the generated source file from testbench generation begins with testbench followed by the module and instance names in the hierarchical name of the module instance, separated by underscores. For example testbench_top_ad1.v. Similarly, the name of the generated source file from module generation begins with moduleGeneration followed by the module and instance names in the hierarchical name of the module instance, separated by underscores. For example moduleGeneration_top_ad1.v.
The following is an example of a configuration file: Example 7-1 Configuration File top.ad1 testbench //moduleGeneration module adder (out,in1,in2); input in1,in2; output [1:0] out; You can use a different name and location for the configuration file but if you do you must enter it as an argument to the -vgen option. For example: vcat filename.vcd -vgen /u/design1/vgen2.
#10 r1=1; #10 r2=1; #10 r1=0; #10 r2=0; #100 $finish; end passer pa1 (int1,int2,r1,r2); adder ad1 (result,int1,int2); endmodule module passer (out1,out2,in1,in2); input in1,in2; output out1,out2; assign out1=in1; assign out2=in2; endmodule module adder (out,in1,in2); input in1,in2; output [1:0] out; reg r1,r2; reg [1:0] sum; always @ (in1 or in2) begin r1=in1; r2=in2; sum=r1+r2; end assign out=sum; endmodule VCD and VPD File Utilities 7-20
Notice that the stimulus from the testbench module named test propagates through an instance of a module named passer before it propagates to an instance of a module named adder. The vcat utility can generate a testbench module to stimulate the instance of adder in the same exact way but in a more concise and therefore faster simulating module. If we use the sample vgen.cfg configuration file in Example 7-1 and enter the following command line: vcat filename.
This source file uses significantly less code to apply the same stimulus with the instance of module passer omitted. If we revise the vgen.cfg file to have vcat do module generation, the generated source file, moduleGeneration__top_ad1.
The vcsplit Utility The vcsplit utility generates a VCD, EVCD, or VPD file that contains a selected subset of value changes found in a given input VCD, EVCD, or VPD file (the output file has the same type as the input file). You can select the scopes/signals to be included in the generated file either via a command line argument, or a separate "include" file.
The include file must contain one scope or signal per line. Each presented scope/signal must be found in the input VCD, EVCD, or VPD file. If the file contains a scope, and separately, also contains a signal in that scope, vcsplit includes all the signals in that scope, and issues a warning. Note: If you use both -include and -scope options, vcsplit uses all the signals and scopes indicated. input_file Specifies the VCD, EVCD, or VPD file to be used as input.
If you specify an include_file and/or a selected_scope_or_signal, vcsplit includes all value changes of those signals/scopes that are present in the include_file and the selected_scope_or_signal but absent in ignore_file in the output file. If the ignore_file contains a scope, vcsplit ignores all the signals and the scopes in this scope. -level n Reports only n levels hierarchy from top or scope.
Limitations • MDAs are not supported. • Bit/part selection for a variable is not supported. If this usage is detected, the vector will be regarded as all bits are specified. The vcd2vpd Utility The vcd2vpd utility converts a VCD file generated using $dumpvars or any CLI or SCL dump commands to a VPD file.
-m Give translation metrics during translation. -q Suppress printing of copyright and other informational messages. +deltacycle Add delta cycle information to each signal value change. +glitchon Add glitch event detection data. +nocompress Turn data compression off. +nocurrentvalue Do not include object's current value at the beginning of each VCB.
Modifies the string identifier for the Test-Fixture half of the spilt signal. Default is "TF". +indexlast Appends the bit index of a vector bit as the last element of the name. vcd_file Specify the vcd filename or use "-" to indicate VCD data to be read from stdin. vpd_file Specify the VPD file name. You can also specify the path and the filename of the VPD file, else the VPD file will be generated with the specified name in the current working directory.
-q Suppress the copyright and other informational messages. -s Allow sign extension for vectors. Reduces the file size of the generated vcd_file. -x Expand vector variables to full length when displaying $dumpoff value blocks. -xlrm Convert upper case VHDL objects to lower case. +zerodelayglitchfilter Zero delay glitch filtering for multiple value changes within the same time unit. +morevhdl Translates the VHDL types of both directly mappable and those that are not directly mappable to verilog types.
+dumpports+instance Generate an EVCD file for the specified module instance. If the path to the specified instance contains escaped identifiers, then the full path must be enclosed in single quotes. -f cmd_filename Specify a command file containing commands to limit the design converted to VCD or EVCD. The syntax for this file is explained in the following section. The Command file Syntax Using a command file, you can: • generate a VCD file for the whole design or for the specified instance/s.
• All comments written after a command, must be preceded by a space. Example: dumpvars 1 adder4 //can write your comment here A command file can contain the following commands: dumpports instance [instance1 instance2 ....] Specify an instance for which an EVCD file has to be generated. You can generate an EVCD file for more than one instance by specifying the instance names separated by a space.
dumpvcdports [level] instance [instance1 instance2 ....] Specify an instance whose port values are dumped to a VCD file. [level] is a numeric value indicating the number of levels to traverse down the specified instance. If not specified, or if the value specified is "0", then the port values of all the instances under the specified instance will be dumped. You can generate a dump file for more than one instance by specifying the instance names separated by a space.
starttime start_time Specify the start time to start dumping the value change data to the VCD file. If this command is not specified the start time will be the start time of the VPD file. Note: Only one +start command is allowed in a command file. endtime end_time Specify the end time to stop dumping the value change data to the VCD file. If this command is not specified the end time will be the end time of the VPD file.
Wave Window in Figure 7-1, there are three signal groups for the same signals in different VPD files. Figure 7-1 DVE Wave Window with Signal Groups from Different VPD Files Signal group test is from a VPD file from the first half of a simulation, signal group test_1 is from a VPD file for the second half of a simulation, and signal group test_2 is from the merged VPD file.
-q Specifies quiet mode, disables the display of most output to the terminal. -hier Specifies that you are merging VPD files for different parts of the design, instead of the default condition, without this option, which is merging VPD files from different simulation times. -v Specifies verbose mode, enables the display of warning and error messages.
Limitations The verbose option -v may not display error or warning messages in the following scenarios: • If the reference signal completely or coincidentally overlaps the compared signal. • During hierarchy merging, if the design object already exists in the merged file. During hierarchy merging, the -heir option may not display error or warning messages in the following scenarios. • If the start and end times of the two dump files are the same.
VCD and VPD File Utilities 7-37
VCD and VPD File Utilities 7-38
8 Unified Command-Line Interface (UCLI) 2 The Unified Command-Line Interface (UCLI) enables consistent interactive simulation and post-processing using the UCLI interactive command language common to the following Synopsys verification technologies: • VCS • SystemVerilog • NTB (OpenVera Language) • DVE (Debug GUI) UCLI is compatible with Tcl 8.3.
• UCLI Interactive Commands • UCLI Command-Alias File • Operating System Commands Compilation and Simulation Options for UCLI The VCS compilation and simulation options for UCLI are: Compilation -debug Enables UCLI for interactive or post processing simulations. This option does not enable line stepping and setting of line breakpoints. -debug_all Enables UCLI for interactive simulations including line stepping, setting time, position, or trigger-type breakpoints, and the full debug mode.
-k keyFilename Records interactive commands used during a simulation to the file named KeyFilename, which can be used as the interactive command file in subsequent simulations. Using UCLI You can invoke UCLI as follows: 1. Compile a design with vcs using the -debug option. 2. Start the simulation with simv using the -ucli option. To compile and simulate a design so that it results in an interactive simulation using UCLI, do the following: Compilation % vcs [vcs_options] -debug file1.v [file2.v] [file3.
UCLI Interactive Commands The following is a list of the UCLI interactive commands: Tool Invocation Commands start exe_name [options] Invokes the simulation executable exe_name with the specified options. restart [options] Restarts simulations. Session Management Commands save [file_name] Saves simulation state in file file_name. restore [file_name] Restores a simulation state saved in file file_name.
run [-relative | -absolute time] [-posedge | -negedge | -change] [path_name] Advances simulation to a point specified by time or edge of signal path_name. finish Terminates a simulation, but remains in Tcl debug environment. Navigation Commands scope [-up [level] | active] [path_name] Shows or sets current scope to instance path_name. thread [thread_id][-active][-attach thread_id] Displays thread with ID thread_id or all threads when no ID is provided.
call [$cmd(...)] Calls a Verilog task. Tool Environment Array Commands senv [element] Displays the environment array element element. Breakpoint Commands stop [-file file_name] [-line num] [-instance path_name][-thread thread_id][-condition expression] Sets and displays breakpoints based on file file_name, source code line with number num, instance path_name, thread with ID thread_id or condition expression.
drivers path_name [-full] Displays drivers of object path_name. loads path_name [-full] Displays load on object path_name. Macro Control Routines do [-trace|-traceall] file_name [macro parameters][-trace|-traceall [on|off]] Reads macro file file_name. onbreak [commands] Executes one or more commands when a breakpoint, $stop task or Ctrl-c is encountered while executing a macro file. onerror [commands] Executes one or more commands when an error is encountered while executing a macro file.
Helper Routine Commands help -[full command] Displays information on all commands or specified command. alias [UCLI_command] Creates an alias alias for command UCLI command. config Displays current settings of all variables. Specman Interface Command sn Switches to Specman prompt.
UCLI Command-Alias File You can call UCLI commands with aliases defined in a command-alias file. You can either create this file or use the default command-alias file. Default Alias File The default alias file .uclirc in the VCS installation directory contains default aliases for UCLI commands. You can edit this file to add custom aliases for UCLI commands.
Unified Command-Line Interface 8-10
9 Using the Old Command Line Interface (CLI) 1 VCS provides the non-graphical debugger or CLI (Command Line Interface) for debugging your design. This chapter covers the following topics: • CLI Commands • Command Files • Key Files • Debugging a Testbench Using the CLI Note: There now is a Unified Command Line Interface for debugging commands. It is unified in that the same command line interface works for VCS, VCS MX, and Vera. It has more commands than the CLI.
CLI Commands You can use basic Command Language Interface (CLI) commands to perform the following tasks: • Navigate the design and display design information • Show and retrieve simulation information • Set, display and delete breakpoints • Display object data members • Set and print values of variables • Traverse call-stacks • Show and terminate threads • Access events Navigating the Design and Displaying Design Information help Displays the list of all commands and their meanings.
line Toggles line tracking. For example: cli> Line cli> Line line tracking is now ON. line tracking is now OFF. list [-n | n] Lists 10 lines starting with the current line. -n Lists n lines above the current position. n Lists n lines starting with the current line. print %[b|c|t|f|e|g|d|h|x|m|o|s|v] net_or_reg Shows the current value of net or register in the specified format. next Next line.
up Steps out of current automatic task or function. For example: cli_65 > step up Time break at time 100200 ##100250 [cpu.vr:79] breakpoint #1 break #50 Showing and Retrieving Simulation Information show [drivers|loads|ports|scopes|variables|break|?] drivers net_or_reg Shows the value and strength of the net or register. For nets it also shows the line number in the source code of the statement that is the source of the value that propagated to this net.
loads nid Displays the loads for the specified signal. For example: cli_23>show loads ramData ramData[7] (ram_test_top.dut.u3) ramData[6] (ram_test_top.dut.u3) ramData[5] (ram_test_top.dut.u3) ramData[4] (ram_test_top.dut.u3) ramData[3] (ram_test_top.dut.u3) ramData[2] (ram_test_top.dut.u3) ramData[1] (ram_test_top.dut.u3) ramData[0] (ram_test_top.dut.
show [allvariables|mailboxes|semaphores|threadsevent] allvariables Shows nets and registers in the current module and its parents. For example: cli> show allvariables listing variables for : memsys_test_top.vshell.\cpu::release_bus .unnamed$$_29 Int vtb_temp_int2 listing variables for : memsys_test_top.vshell.\cpu::release_bus listing variables for : memsys_test_top.vshell Wire SystemClock Wire \memsys.adxStrb Wire [7:0] \memsys.busAddr Wire [7:0] \memsys.busData Wire \memsys.busRdWr_N Wire \memsys.
mailboxes [m_id] Displays information about all mailboxes or the identified mailbox. semaphores [n_id] Displays information about all semaphores or the identified semaphore. For example: cli_33 > show semaphore semaphore id = 1 keys available 0 blocked threads: thread #2: memsys0.vr: 65 thread [t_id] Displays all threads or the identified thread and the status. For example: cli_32 > show thread thread #1 memsys_test_top.vshell.check_all [ready] memsys0.vr: 99 thread #2 memsys_test_top.vshell.
break -thread thread_id Sets breakpoint in the specified thread. break at file:lineno/lineno -thread thread_id Sets breakpoint at the line number of the file and thread mentioned. break at filename:lineno Sets a breakpoint in the identified file at the specified line number. break in class:task/function Sets a breakpoint in class at the identified task or function. For example: cli_55 > break in check_all set break #6 in check_all break in scope Sets a breakpoint in the specified scope.
Displaying Object Data Members print this In Vera code, prints the current object data members. For example: cli_141 > break in cpu::new set break #1 in cpu::new cli_142 > print this this = { localarb: cpu_id: 00000000 address: 69 data: 30 delay: 00000003 } Setting and Printing Values of Variables set variable = value Sets variable values. print variable Displays variable values. Traversing Call-stacks stack Prints task/function call traceback.
#1 in check_all at memsys0.vr:68 #2 in memsys_test at memsys0.vr:19 #3 in memsys_test_top.vshell upstack Goes up the call stack. For example: cli_131 > upstack #1 in check_all at memsys0.vr:68 downstack Goes down the call stack. For example: cli_132 > downstack #0 in \cpu::release_bus at cpu.vr:73 Showing and Terminating Threads show thread [thread_id] Prints information about the specified threads. For example: li_119 > show thread 2 thread #2 memsys_test_top.vshell.\cpu::release_bus [ready] cpu.
Accessing Events trigger(0|1|2|3|4, event variable) Triggers an event in the testbench according to the following: 0 -> Off 1 -> On 2 -> One shot 3 -> One blast 4 -> Handshake Command Files It is possible to create, in the working directory, a .vcsrc file containing CLI commands that VCS executes on entry to the CLI. This is useful for specifying alias commands to customize the command language. Any CLI command can appear in this file.
module top; reg a; reg [31:0] b; initial begin a = 0; b = 32’b0; #10 if (a) b = 32’b0; end endmodule % vcs +cli+2 a.v <> % simv -s $stop at time 0 cli_0 > scope Current scope is top cli_1 > show var Reg a Reg [31:0] b cli_2 > once #1 cli_3 > . Time break at time 1 breakpoint #1 tbreak ##1 cli_4 > print a a: 0 cli_5 > set a=1 cli_6 > print a a: 1 cli_7 > tbreak b cli_8 > . Value break time 10 breakpoint #2 tbreak top.
Key Files When you enter CLI commands (or commands in the DVE Interactive window), VCS by default records these commands in the vcs.key file that it writes in the current directory. The purpose of this file is to enable you to quickly enter all of the interactive commands from another simulation of your design by including the -i runtime option with this file as its argument. You can use the -k runtime option to specify a different name or location for the vcs.key file.
Non-Graphical Debugging With the CLI In order to use the CLI: • Enable it at compile time with the options +cli and -line. • Include the -s on the runtime command line (e.g. simv -s). For example: When compiling both the testbench and the design together, the command lines are: % vcs -ntb +cli -line sram.v sram.test_top.v sram.vr % simv -s When compiling the testbench separately from the design, the command lines are: % vcs -ntb_cmp +cli -line -ntb_sname sram_test sram.vr % vcs -ntb_vl +cli -line sram.
#include “port_bind.vr” #include “cpu.vr” program memsys_test { // Start of memsys_test cpu cpu0 = new (arb0, 0); cpu cpu1 = new (arb1, 1); init_ports(); reset_sequence(); check_all() ; } // end of program memsys_test // Don’t allow inputs to dut to float task init_ports () { printf(“Task init_ports\n”); @(posedge memsys.clk); memsys.request = 2’b00; memsys.busRdWr_N = 1’b1; memsys.adxStrb = 1’b0; memsys.reset = 1’b0; } task reset_sequence () { printf(“Task reset_sequence\n”); memsys.reset = 0; @1 memsys.
fork {// fork process for CPU 0 repeat(256) { randflag = cpu0.randomize(); cpu0.request_bus(); cpu0.writeOp(); cpu0.release_bus(); mailbox_put(mboxId, cpu0.address); mailbox_put(mboxId, cpu0.data); mailbox_put(mboxId, cpu0.delay); sync(ALL, CPU1done); trigger(OFF, CPU1done); cpu0.delay_cycle(); } } {// fork process for CPU 1 repeat(256) { mailbox_get(WAIT, mboxId, cpu1.address, CHECK); mailbox_get(WAIT, mboxId, cpu1.data, CHECK); mailbox_get(WAIT, mboxId, cpu1.delay, CHECK); cpu1.request_bus(); cpu1.
Use the following command line to run the simulation with debug: % simv -s The following is the output while using the CLI: Chronologic VCS simulator copyright 1991-2003 Contains Synopsys proprietary information. Compiler version 7.1_Beta2; Runtime version 7.1_Beta2; Oct 16 16:55 2003 $stop at time 0 cli_0 > break in memsys_test set break #1 in memsys_test cli_1 > break in check_all set break #2 in check_all cli_2 > break at memsys1.vr69: set break #3 at memsys1.vr:69 cli_3 > cont Constructing new CPU.
CPU 0 releases bus on arb0 Line break at time 2050 breakpoint #3 break at memsys1.vr:69 cli_6 >show mailboxes mailbox id: 1 data available: 1 data: -->1 blocked threads: NONE cli_7 > quit $finish at simulation time V C S S i m u l a t i o n 2050 R e p o r t Using the CLI, Example 2 Example 9-3 is a testbench containing semaphores. It is in the file memsys0.vr, which is a part of the Native Testbench tutorial example in your VCS installation under $VCS_HOME/doc/examples/ nativetestbench/tutorial.
} // end of program memsys_test // Don’t allow inputs to dut to float task init_ports () { printf(“Task init_ports\n”); @(posedge memsys.clk); memsys.request = 2’b00; memsys.busRdWr_N = 1’b1; memsys.adxStrb = 1’b0; memsys.reset = 1’b0; } task reset_sequence () { printf(“Task reset_sequence\n”); memsys.reset = 0; @1 memsys.reset = 1; @10 memsys.reset = 0; @1 memsys.
printf(“\nThe memory0 address is being repeated\n\n”); printf(“\n mem_add0[%b] is %b \n\n”, cpu0.address, mem_add0[cpu0.address]); } semaphore_get(WAIT, semaphoreId, 1); cpu0.request_bus(); cpu0.writeOp(); cpu0.release_bus(); cpu0.request_bus(); cpu0.readOp(); cpu0.release_bus(); semaphore_put(semaphoreId, 1); cpu0.delay_cycle(); } } {// fork process for CPU 1 repeat(256) { randflag = cpu1.randomize(); printf(“\n THE RAND MEM1 ADD IS %b \n\n”, cpu1.address); if (mem_add1[cpu1.address] !== cpu1.
cpu1.delay_cycle(); } } join } Use the following command line to compile the design and the testbench: % vcs -ntb +cli -f memsys.f memsys.test_top.v memsys0.vr Use the following command line to run the simulation with debug: % simv -s The following is the output while using the CLI: Chronologic VCS simulator copyright 1991-2003 Contains Synopsys proprietary information. Compiler version 7.1_Beta2; Runtime version 7.
Task init_ports Task reset_sequence Scope break at time 1250 breakpoint #2 break in memsys_test_top.vshell.check_all cli_5 >.
CPU 1 readOp: address 97 data f1 READ address = 097, data = 0f1 CPU 1 releases bus on arb1 Line break at time 5050 breakpoint #3 break at memsys0.vr:99 cli_6 > show semaphores semaphore id = 1 keys available 0 blocked threads: thread #3: memsys0.
Using the Old Command Line Interface (CLI) 9-24
10 Post-Processing • 2 Use the $vcdpluson system task to generate VPD files. For more details on this system task, see "System Tasks for VPD Files" in Appendix D. If you enable it, the VPD file contains simulation results from the design. The $vcdplustraceon system task records the order in which the source code lines are executed. Therefore, you can see the order in post processing. You can enter these system tasks either in your Verilog source code or at the CLI prompt using a different syntax.
• Line Tracing • Delta Cycle • Verilog HDL offers the advantage of having the ability to access any internal signals from any other hierarchical block without having to route it through the user interface. • You can generate an EVCD file using the $dumpports or $lsi_dumports system tasksSee “Verilog HDL offers the advantage of having the ability to access any internal signals from any other hierarchical block without having to route it through the user interface.” on page 10-4.
Syntax: $vcdplusevent(net_or_reg,"event_name", ""); eVCD You can use $dumpports or $lsi_dumports system tasks to generate EVCD files. Using system tasks you can generate multiple EVCD files for various module instances of the design. Line Tracing You can enable line tracing for the design using -debug_all or -debug as a compile-time option. The -debug_all option greatly degrades the simulation performance and therefore you should use it only for debugging.
Verilog HDL offers the advantage of having the ability to access any internal signals from any other hierarchical block without having to route it through the user interface.
11 Race Detection 1 VCS provides a dynamic race detection tool that finds race conditions during simulation and a static race detection too that finds race conditions by analyzing source code during compilation.
The Dynamic Race Detection Tool The dynamic race detection tool finds two basic types of race conditions during simulation: • read - write race condition This occurs when a procedural assignment in one always or initial block, or a continuous assignment assigns a signal’s value to another signal (read) at the same time that a procedural assignment in another always or initial block, or another continuous assignment assigns a new value to that signal (write).
In this example, at simulation time 5, different initial blocks assign 0 and 1 to signal a. When simulation time 5 is over you do not know if signal a’s value is 0 or 1. Finding these race conditions is important because in Verilog simulation you cannot control the order of execution of statements in different always or initial blocks or continuous assignments that execute at the same simulation time.
Therefore even when a Verilog design appears to be simulating correctly and you see the results you want, you should look for race conditions and remove them so that you will continue to see the same simulation results from an unrevised design well into the future. Also you should look for race conditions while a design is in development. VCS can help you find these race conditions by writing report files about the race conditions in your design.
Specifying the Maximum Size of Signals in Race Conditions You use the +race_maxvecsize compile-time option to specify the largest vector signal for which the dynamic race detection tool looks for race conditions. The syntax is as follows: +race_maxvecsize=size For example, if you enter the following vcs command line: vcs source.
Note: The race.unique.out is automatically created by the PostRace.pl Perl script after simulation. This script needs a perl5 interpreter. The first line of the script points to perl at a specific location, see "Modifying the PostRace.pl Script" on page 11-10. If that location at your site is not a perl5 interpreter, the script fails with syntax errors. The report describes read-write and write-write race conditions. The following is an example of the contents of a small race.
The following is the source file, with line numbers added, for this race condition report: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. module test; reg a,b,c,d; always @(a or b) c = a & b; always begin a = 1; #1 a = 0; #2; end always begin #1 a = 1; d = b | c; #2; end initial begin $display("%m c = %b",c); #2 $finish; end endmodule As stipulated in race.
• Also at simulation time 1 there is a procedural assignment to reg c on line 5 and the value of reg c is in an expression that is evaluated in a procedural assignment to another register on line 17. Races of No Consequence Sometimes race conditions exist, such a write-write race to a signal at the same simulation time, but the two statements that are assigning to the signal are assigning the same value.
-sig signal Specifies the signal that you want to examine for race conditions. You can only specify one signal and must not include a hierarchical name for the signal. If two signals in different module instances have the same identifier, the report lists race conditions for both signals. -minmax min max Specifies the minimum, or earliest, simulation time and the maximum, or latest, simulation time in the report -nozero Omits race conditions that occur at simulation time 0.
The following is an example of the command line: PostRace.pl -minmax 80 250 -f mydesign.race.out -o mydesign.race.out.post In this example the output file is named mydesign.race.out.post and reports on the race conditions between 80 and 250 time units. The post-process file is named mydesign.race.out. Modifying the PostRace.pl Script The first line of the PostRace.
When you have two VCD files, find their differences with the vcdiff utility. This utility is located in the vcs_install_dir/bin directory. The command line for vcdiff is as follows: vcdiff vcdfile1.dmp vcdfile2.dmp -options > output_filename If you enter the vcdiff command without arguments, you see usage information including the options.
Method 2: If the Number of Unique Races is Large If there are many lines in the race.unique.out file then there are a large number of unique race conditions. If so, one method of finding the critical race conditions is to do the following: 1. Look in the output file from the vcdiff utility for the simulation time of the first difference in simulation values. 2. Post process the race.out file looking for races at the time of the first simulation value difference.
b. Look for a race condition on that signal at that time. Enter: PostRace.pl -sig signal -minmax time time2 If there is a race condition at that time on that signal, it is a critical race condition. The Static Race Detection Tool It is possible for a group of statements to combine to form a loop such that the loop will be executed more than once by other Verilog simulators but only once by VCS. This is a race condition.
35 36 37 38 39 40 always @( A or C ) begin D = C; B = A; end assign C = B; The race.out.static file from the compilation of this source code follows: Race-[CLF] Combinational loop found "source.v", 35: The trigger ’C’ of the always block can cause the following sequence of event(s) which can again trigger the always block. "source.v", 37: B = A; which triggers ’B’. "source.v", 40: assign C = B; which triggers ’C’.
12 Delays and Timing 1 This chapter covers the following topics: • Transport and Inertial Delays • Pulse Control • Specifying the Delay Mode Delays and Timing 12-1
Transport and Inertial Delays Delays can be categorized into transport and inertial delays. Transport delays allow all pulses that are narrower than the delay to propagate through. For example, Figure 12-1 shows the waveforms for an input and output port of a module that models a buffer with a module path delay of seven time units between these ports. The waveform on top is that of the input port and the waveform underneath is that of the output port.
You can apply transport delays on all module path delays and all SDF INTERCONNECT delays backannotated to a net from an SDF file. For more details on SDF backannotation, see Chapter 15. Inertial delays, in contrast, filter out all pulses that are narrower than the delay. Figure 12-2 shows the waveforms for the same input and output ports when you have not enabled transport delays for module path delays.
Different Inertial Delay Implementations For compatibility with the earlier generation of Verilog simulators, inertial delays have two different implementations, one for primitives (gates, switches and UDPs), continuous assignments, and MIPDs (Module Input Port Delays) and the other for module path delays and INTERCONNECT delays backannotated from an SDF file to a net. For more details on SDF backannotation, see Chapter 15.
Figure 12-3 Gate Terminal Waveforms In the example illustrated in Figure 12-3, the following occurs: 1. At time 3 the input terminal changes to 0. This is the leading edge of a three time unit wide pulse. This event schedules a value change to 0 on the output terminal at time 8 because there is a #5 delay specification for the gate. 2. At time 6 the input terminal toggles to 1. This implementation keeps the scheduled transition on the output terminal at time 8 but alters the value change to a value of 1.
6. At time 14 the output is already 1 so there is no value change. The narrow pulse on the input between time 9 and 12 is filtered out. This implementation was devised for these narrow pulses. There is now no event scheduled for the output. 7. At time 15 the input toggles to 0 and this schedules the output to toggle to 0 at time 20.
Enabling Transport Delays Transport delays are never the default delay. You can specify transport delays on module path delays with the +transport_path_delays compile-time option. For this option to work you must also include the +pulse_e/number and +pulse_r/ number compile-time options. See "Pulse Control" on page 12-7. You can specify transport delays on a net to which you backannotate SDF INTERCONNECT delays with the +transport_int_delays compile-time option.
• Have VCS replace even narrower pulses with an X value pulse on the output and display a warning message. • Have VCS then filter out and ignore pulses that are even narrower that the ones for which it propagates an X value pulse and displays an error message. You specify pulse control with the +pulse_e/number and +pulse_r/number compile-time options for module path delays and the +pulse_int_e/number and +pulse_int_r/number compile-time options for INTERCONNECT delays.
You can use pulse control with transport delays (see "Pulse Control with Transport Delays" on page 12-9) or inertial delays (see "Pulse Control with Inertial Delays" on page 12-12). When a pulse is narrow enough for VCS to display a warning message and propagate an X value pulse, you can set VCS to do one of the following: • Place the starting edge of the X value pulse on the output, as soon as it detects that the pulse is sufficiently narrow, by including the +pulse_on_detect compile-time option.
You specify transport delays for INTERCONNECT delays on nets with the +transport_int_delays, +pulse_int_e/number, and +pulse_int_r/number options. You must include all three of these options. If you want VCS to propagate all pulses, no matter how narrow, specify a 0 percentage.
2. At time 29 the input port toggles to 0 ending a nine time unit wide value 1 pulse on the input port. 3. At time 30 the output port toggles to 1. The nine time unit wide value 1 pulse that began at time 20 on the input port is propagating to the output port because we have enabled transport delays and nine time units is more than 80% of the ten time unit module path delay. 4. At time 39 the input port toggles to 1 ending a ten time unit wide value 0 pulse. Also at time 39 the output port toggles to 0.
Pulse Control with Inertial Delays You can enter the +pulse_e/number and +pulse_r/number or +pulse_int_e/number and +pulse_int_r/number options without the +transport_path_delays or +transport_int_delays options. When you do you are specifying pulse control for inertial delays on module path delays and INTERCONNECT delays. There is a special implementation of inertial delays with pulse control for module path delays and INTERCONNECT delays.
Figure 12-5 shows the waveforms for the input and output ports for an instance of a module that models a buffer with a ten time unit module path delay. The vcs command line contains the following compile-time options: +pulse_e/0 +pulse_r/0 Specifying 0 percentages here means that the trailing edge of all pulses can change the second scheduled event on the output. Specifying 0 does not mean that all pulses propagate to the output because this implementation has its own way of filtering out short pulses.
3. At time 26 the input port toggles to 0. This cancels the current scheduled second event and replaces it by scheduling a transition to 0 at time 36. The first scheduled event is a transition to 0 at time 30 so the new second scheduled event isn’t really a transition on the output port. This is how this implementation filters out narrow pulses. 4. At time 29 the input port toggles to 1. This cancels the current scheduled second event and replaces it by scheduling a transition to 1 at time 39. 5.
In the example illustrated in Figure 12-6 the following occurs: 1. At simulation time 20 the input port transitions to 0. This schedules the first event on the output port, a transition to 0 at time 30. 2. At simulation time 30 the input port toggles to 1. This schedules the output port to toggle to 1 at time 40. Also at simulation time 30 the output port transitions to 0. It doesn’t matter which of these events happened first. At the end of this time there is only one scheduled event on the output. 3.
module_instance_name, Value = StE port_name ---> port_name = 10; 8. At time 60 the output transitions to 0. Pulse control sometimes blurs the distinction between inertial and transport delays. In this example the results would have been the same if you also included the +transport_path_delays option. Specifying Pulse on Event or Pulse on Detect Behavior Asymmetric delays, such as different rise and fall times for a module path delay, can cause schedule cancellation problems for pulses.
Here you include the +pulse_e/100 and +pulse_r/0 options. The scheduling problem is that the leading edge of the pulse on the input, at time 10, schedules a transition to 0 on the output at time 16; but the trailing edge, at time 11, schedules a transition to 1 on the output at time 15. Obviously the output has to end up with a value of 1 so VCS can’t allow the events scheduled at time 15 and 16 to occur in sequence; if it did the output would end up with a value of 0.
Figure 12-8 Using +pulse_on_event In most cases where the +pulse_e/number and +pulse_r/ number options already create X value pulses on the output, also including the +pulse_on_event option to specify pulse on event behavior will make no change on the output.
In this example, by including the +pulse_on_detect option, VCS causes the leading edge of the X value pulse on the output to begin at time 11 because of an unusual event that occured on the output between times 15 and 16 because of the rise at simulation time 11. Using pulse on detect behavior can also show you when VCS has scheduled multiple events for the same simulation time on the output by starting the leading edge of an X value pulse on the output as soon as VCS has scheduled the second event.
4. At time 16 the input toggles to 0 scheduling a second event on the output at time 20, a transition to 0. This event also is the trailing edge of a six time unit wide value 1 pulse so the first event changes to a transition to X. There is more than one event for different value changes on the output at time 20, so VCS begins the leading edge of the X value pulse on the output at this time. 5. At time 20 the output toggles to 0, the second scheduled event at this time.
Example 12-11 Conflicting Delay Modes ‘timescale 1 ns / 1 ns module design (out,in); output out; input in; wire int1,int2; assign #4 out=int2; buf #3 buf2 (int2,int1), buf1 (int1,in); specify (in => out) = 7; endspecify endmodule In Example 12-11, the module path delay is seven time units but the delay specifications distributed along that path add up to ten time units.
There are other modes that you can specify: • If you include the +delay_mode_unit compile-time option, VCS ignores the module path delays and changes the delay specification in all primitive instantiation and continuous assignment statements to the shortest time precision argument of all the ‘timescale compiler directives in the source code. (The default time unit and time precision argument of the ‘timescale compiler directive is 1 s).
13 SDF Backannotation 1 This chapter covers the following topics: • Using SDF Files • Compiling the ASCII SDF File at Compile-Time • Reading the ASCII SDF File During Runtime • INTERCONNECT Delays • Min:Typ:Max Delays • Using the Configuration File to Disable Timing • Using the timopt Timing Optimizer • Editing the timopt.
Using SDF Files The OVI Standard Delay File (SDF) specification provides a standard ASCII file format for representing and applying delay information. VCS supports the OVI versions 1.0, 1.1, 2.0, 2.1, and 3.0 of this specification. In the SDF format a tool can specify intrinsic delays, interconnect delays, port delays, timing checks, timing constraints, and pulse control (PATHPULSE).
Compiling the SDF file, when you compile your Verilog source files, creates binary data files that VCS reads when it executes a $sdf_annotate system task at runtime. VCS reads binary data files much faster than ASCII SDF files. The additional compile time will always be less than the time saved at run time. There are, however, limitations on your design when you compile an SDF file.
The syntax for the $sdf_annotate system task is as follows: $sdf_annotate ("sdf_file"[, module_instance] [,"sdf_configfile"][,"sdf_logfile"][,"mtm_spec"] [,"scale_factors"][,"scale_type"]); Where: "sdf_file" Specifies the path to the SDF file. module_instance Specifies the scope where backannotation starts. The default is the scope of the module instance that calls $sdf_annotate. "sdf_configfile" Specifies the SDF configuration file.
"scale_type" Specifies the delay value from each triplet in the SDF file for use before scaling. Possible values: "FROM_TYPICAL", "FROM_MIMINUM", "FROM_MAXIMUM", "FROM_MTM" (default).
input CK, D; specify (D *> out) = (1,2); (CK *> out) = (3); endspecify endmodule module leafB(out,D,CK); output out; input D; input CK; buf(out,D); endmodule The following is the SDF file, ex.sdf, for the Verilog model. (DELAYFILE (DESIGN "test") (VENDOR "") (DIVIDER .
) ) ) The following is the vcs command line that compiles both the Verilog source file and the SDF file: vcs +compsdf ex.v You do not have to specify the ex.sdf file, or any SDF table file, on the vcs command line. When VCS compiles the SDF file it creates binary data files in the simv.daidir directory. VCS reads these binary files when it executes the $sdf_annotate system task.
By default the +csdf+precompile option creates the precompiled SDF file in the same directory as the ASCII text SDF file and differentiates the precompiled version by appending "_c" to its extension. For example, if the /u/design/sdf directory contains a design1.sdf file, using the +csdf+precompile option creates the precompiled version of the file named design1.sdf_c in the /u/design/sdf directory.
For example, in the /u/designs/mydesign directory are the design.v and design.sdf files and the sdfhome directory. If you enter the following command line: vcs design.v +csdf+precompile +csdf+precomp+dir+sdfhome +csdf+precomp+ext+_precompiled VCS creates the design.sdf_precompiled file in the sdfhome directory. Now that the precompiled file is not in the default location and does not have the default filename extension, in subsequent compilations you must tell VCS its new location and name.
Reading the ASCII SDF File During Runtime You can use the ACC capability support that is part of the PLI interface to tell VCS to read the ASCII SDF file when it executes the $sdf_annotate system task. To do this, include the +oldsdf compile-time option and create a PLI table file that maps the $sdf_annotate system task to the C function sdf_annotate_call (automatically provided with VCS ) and indicates which modules will be annotated and what types of constructs will be annotated.
For example, the SDF annotation of module paths contained within the hierarchy of a module named myasic requires a PLI table such as this: $sdf_annotate call=sdf_annotate_call acc+=mp,prx:myasic+ If possible, take advantage of the %CELL wildcard scope to add the needed ACC capabilities to library cells only, which are often the only cells requiring SDF annotation: $sdf_annotate call=sdf_annotate_call acc+=mp, prx:%CELL For methodologies requiring delay annotation in the sub-hierarchy of cells, use: $sdf_a
end endmodule module leaf(in,out); input in; output out; buf(out,in); specify specparam mpath_d=1.0; (in => out) = (mpath_d); endspecify endmodule The following is the SDF file, ex2.sdf, for the Verilog model: (DELAYFILE (TIMESCALE 1 ns) (CELL (CELLTYPE “leaf”) (INSTANCE leaf1) (DELAY (ABSOLUTE (IOPATH in out (5)))))) In this file the SDF construct IOPATH corresponds to a Verilog module path delay. The delay value specified is 5.
0 0 x 5 0 0 $finish at simulation time 100 V C S S i m u l a t i o n R e p o r t Time: 100 ns CPU Time: 0.100 seconds; Data structure size: 0.0Mb Performance Considerations Because the compiler must make large quantities of information about the structure of the design available at run time in order to allow annotation, you must consider simulation efficiency when using SDF annotation.
Using the Shorter Delay in IOPATH Entries It is valid syntax in an SDF file to have two IOPATH entries for the same pair of ports but one entry for a rising edge on the input or inout port and another entry for a falling edge on the input or inout port.
VCS does not however backannotate the module path delay values as specified. Instead VCS backannotates the shorter of the corresponding delays in the two IOPATH entries.
If an SDF file backannotates delay values to an instance of a module that must be renamed, the CELLTYPE entry in the SDF file for the instance will contain the old identifier of the module, and ordinarily this would cause VCS to display the following error message: SDF Error: Instance instance_name is CELLTYPE of "new_module_identifier" not "old_module_identifier", ignoring In this situation, to avoid editing the SDF file, include the +sdf_nocheck_celltype compile-time option on the vcs command line.
Delay Objects and Constructs The mapping from SDF statements to simulation objects in VCS is fixed, as shown in Table 13-1.
Table 13-1 VCS Simulation Delay Objects/Constructs SDF Constructs VCS Simulation Object SKEWCONSTRAINT ignored SDF Configuration File Commands This section explains the commands used in SDF configuration files, with syntax and examples. approx_command: The INTERCONNECT_MPID keyword selects the INTERCONNECT delays in the SDF file that are mapped to MIPDs in VCS.
Syntax: INTERCONNECT_MIPD = MINIMUM | MAXIMUM | AVERAGE | LAST; Example: INTERCONNECT_MIPD=LAST; map_command: This command maps the SDF constructs to VCS Simulation Delay Objects. Note: Refer to Table 13-1: VCS Simulation Delay Objects/Constructs.
TYPICAL Annotates the typical delay value MAXIMUM Annotates the maximum delay value TOOL_CONTROL Delay value is determined by the command line options of the Verilog tool (+mindelays, +typdelays, or +maxdelays) The default for min_typ_max is TOOL_CONTROL.
FROM_MAXIMUM Scales from the maximum timing specification in the SDF file. FROM_MTM Scales directly from the minimum, typical, and maximum timing specifications in the SDF file. Syntax: SCALE_FACTORS = number : number : number ; SCALE_TYPE = FROM_MINIMUM | FROM_TYPICAL | FROM_MAXIMUM | FROM_MTM ; Example: SCALE_FACTORS=100:0:9; SCALE_TYPE=FROM_MTM; SCALE_FACTORS=1.1:2.1:3.1; SCALE_TYPE=FROM_MINIMUM; turnoff_command: The turnoff_command keyword globally specifies which delays the SDF annotator uses.
Syntax: TURNOFF_DELAY = FROM_FILE | MINIMUM | MAXIMUM | AVERAGE ; Example: TURNOFF_DELAY=FROM_FILE; modulemap_command: Redirects the delay object of IOPATH or TIMINGCHECK SDF statements for all instances of a specified module type to a different module path or timing check object in the same or lower scope. Syntax: MODULE verilog_id { list_of_module_mappings } ; Here, verilog_id is the name of a specific type of module (not instance name) specified in the corresponding Verilog description.
| path_declaration = IGNORE ; The SDF annotator uses hierarchical_path as the Verilog hierarchical path name of a submodule within module_type. The paths specified in the SDF file are mapped to module_type. This path applies to all path delays and timing checks specified for this module in the SDF file including those mapped with ADD and OVERRIDE. ADD Adds to the mapping specifications of the SDF file.
timing_check_condition: expression list_of_path_declaration: path_declaration ';' | list_of_path_declaration path_declaration ';' path_declaration: opt_if '(' list_of_path_in_td path_type list_of_path_out_td ')' | opt_if '(' list_of_path_in_td path_type '(' list_of_path_out_td ')' ')' opt_if: 'if' '(' expression ')' | ; opt_edge: timing_check_event_control | ; timing_check_event_control': 'posedge' | 'negedge' | 'edge' '[' edge_descriptor_list ']' edge_descriptor_list: edge_descriptor | edge_descriptor_list
identifier: verilog_id | identifier_head verilog_id identifier_head : verilog_id '.' | identifier_head verilog_id '.' number : "Any sized or unsized literal decimal, octal, binary, hex, or real number" verilog_id : "Any legal escaped or non-escaped Verilog identifier (excluding range selection portion in square brackets).
sub Y (w1,w2,in,in,ctrl,ctrl); sub W (out1,out2,w1,w2,ctrlw,ctrlw); initial begin $display(" i c ww oo"); $display("ttt n t 12 12"); $monitor($realtime,,,in,,ctrl,,w1,w2,,out1,out2); end initial begin ctrl = 0;// enable ctrlw = 0; in = 1'bx; //stabilize at x; #100 in = 1; // x-1 #100 ctrl = 1; // 1-z #100 ctrl = 0; // z-1 #100 in = 0; // 1-0 #100 ctrl = 1; // 0-z #100 ctrl = 0; // z-0 #100 in = 1'bx; // 0-x #100 ctrl = 1; // x-z #100 ctrl = 0; // z-x #100 in = 0; // x-0 #100 in = 1; // 0-1 #100 in = 1'bx; /
input ia,ib;output oa,ob; specify (ia *> oa) = 99.99; (ib *> ob) = 2.99; endspecify endmodule SDF File: test.sdf (DELAYFILE (SDFVERSION "3.0") (DESIGN "sdftest") (DATE "July 14, 1997") (VENDOR "Synopsys") (PROGRAM "manual") (VERSION "4.0") (DIVIDER .
MODULE sub { SCALE_TYPE=FROM_MTM; SCALE_FACTORS=1:2:3; MTM=MINIMUM; MAP_INNER = X; (i1 *> o1) = IGNORE; (i1 *> o1) = ADD { (ia *> oa); } (i1 *> o1) = ADD { (ib *> ob); } if (i2==1) (i2 *> o2) = ADD { (ib *> ob); } } Understanding the DEVICE Construct The DEVICE construct specifies the intrinsic delay of a cell or gate. When VCS reads a DEVICE construct, it backannotates the pin-topin delay generics throughout the cell.
• If DEVICE does not include an output port name, VCS assigns the value to all the pin-to-pin delay (tpd) generics in the cell. For example, if the DEVICE construct is DEVICE (1:2:3) VCS assigns the timing value to all the following generics: tpdIn1_Out1_R, tpdIn2_Out1_R, tpdIn1_Out2_R, tpdIn2_Out2_R, tpdIn1_Out1_F, tpdIn2_Out1_F, tpdIn1_Out2_F, and tpdIn2_Out2_F.
Handling Backannotation to I/O Ports SDF Reader might incorrectly handle the DEVICE construct for an output I/O port if the DEVICE construct does not include an output port name. Consider Figure 13-4; Port B is an I/O port of the instance U1 of type IO_CELL. If the DEVICE construct is DEVICE (1:2:3) VCS assigns the timing value to the generics tpdIn1_B_R, tpdIn2_B_R, tpdIn1_C_R, tpdIn2_C_R, tpdIn1_B_F, tpdIn2_B_F, tpdIn1_C_F, and tpdIn2_C_F.
To handle I/O ports, use the INTERCONNECT construct instead of the DEVICE construct. Using the INTERCONNECT Construct The INTERCONNECT construct represents the actual or estimated delay in the wire between devices. The following SDF specifies the loading for Figure 13-4: (INSTANCE CELLTYPE) (DELAY (ABSOLUTE (INTERCONNECT U1/B A (2:3:4)))) In the above statements, the interconnect must be reflected at the input of the next stage (which is actually the load or tester in this case).
The SDFPOLICY variable allows you to select the backannotation delay value. You can set this variable to MIN, MAX, or MINOMAX. The default value is MAX for backwards compatibility. If you specify a value other than MIN, MAX, or MINOMAX, VCS issues a warning and uses MAX as the default value. INTERCONNECT Delays INTERCONNECT entries in an SDF file are for backannotating delays to a net that connects two or more module instance ports.
Figure 13-1 Net with Multiple Drivers module stim module instance left1 lout1 module instance right1 rightin module instance bot1 botout lout2 net int The SDF file could specify different delays between output port lout1 and input port rightin and output port botout and input port rightin. The ports do not have to be on the same hierarchical level. An example for the entries that specify these different delays is as follows: (CELL (CELLTYPE "stim") (INSTANCE stim) (DELAY (ABSOLUTE (INTERCONNECT stim.
Note: In delay value lists in delay definition entries in an SDF file, you can list one, two, three, or six delay values. Lists of twelve values, that also specify delays for transitions to and from X are not yet implemented. The +multisource_int_delays compile-time option tells VCS to use a special algorithm for multisource INTERCONNECT delays.
Simultaneous Multiple Source Transitions When there are simultaneous transitions on more than one source port instance, the algorithm for the +multisource_int_delays option applies the shortest delay to all of these transitions instead of the one specified in the SDF file. For example, if the SDF file specifies the following: (CELL (CELLTYPE "stim") (INSTANCE stim) (DELAY (ABSOLUTE (INTERCONNECT stim.left1.bot1.botout stim.right1.rightin (2)) (INTERCONNECT stim.left1.lout1 stim.right1.
Figure 13-2 illustrates the following series of events: 1. At time 10 output port lout1 transitions to 1. Net int transitions therefore to X and there is a two time unit delay before this X value propagates through int to port rightin. 2. At time 15 port lout1 transitions to 0, net int transitions to 0 and port rightin transactions to 0 two time units later. 3. At time 25 both output ports lout1 and botout transitions to 1. So does net int.
Note: In delay value lists in delay definition entries in an SDF file, you can list one, two, three, or six delay values. VCS does not yet support lists of twelve values, that also specify delays for transitions to and from X. Min:Typ:Max Delays You can enter min:typ:max delay value triplets wherever you can enter a delay specification. For example: assign #(4:10:14) w1=r1; Here the minimum delay value is 4, the typical delay value is 10, and the maximum delay value is 14.
Include the +mindelays compile-time option to specify using the minimum delay of the min:typ:max delay value triplet either in delay specification or in the delay value in entries in an SDF file. Include the +maxdelays compile-time option to specify using the maximum delay. By default VCS uses the typical delays. You can specify using the typical delays with the +typdelays compile-time option.
Using the +allmtm compile-time option tells VCS to write three different compiled SDF files when VCS compiles the ASCII text SDF file. One has the minimum delays from the min:typ:max delay value triplets, another has the typical delays, and the third has the maximum delays. You specify which one to backannotate delays from at runtime with the +mindelays, +typdelays, or +maxdelays runtime options.
noIopath Specifies disabling the module path delays in the specified module instances. noSpecify Specifies disabling the specify blocks in the specified module instances. noTiming Specifies disabling the timing checks in the specified module instances. Using the timopt Timing Optimizer The timopt timing optimizer can yield large speedups for full-timing gate-level designs. Timopt makes its optimizations based on the clock signals and sequential devices that it identifies in the design.
Timopt then displays the percentage of identified sequential devices to which it can actually apply optimizations followed by messages about the optimization process. TIMOPT optimized 75 percent of the design Starting TIMOPT Delay optimizations Done TIMOPT Delay Optimizations DONE TIMOPT The next step is to simulate the design and see if the optimizations applied by timopt produce a satisfactory increase in performance.
Timopt will make the additional optimizations that it did not make because it was unsure of the signals and sequential devices in the timopt.cfg file that it wrote during the first compilation. 4. Look at the timopt.cfg file again: - If timopt wrote no new entries for potential clock signals or sequential devices, go to step 5. - If timopt wrote new entries but you make no changes to the new entries, go to step 5. - If you make modifications to the new entries, return to step 3. 5.
Editing the timopt.cfg File When editing the timopt.cfg file, first edit the potential sequential device entries. Edit the potential clock signal only when you have made no changes to the entries for sequential devices.
1. Remove the clock signal entries from the timopt.cfg file 2. Recompile the design with the same +timopt+clock_period compile-time option. Timopt will write new clock signal entries in the timopt.cfg file. Editing Clock Signal Entries The following is an example of the clock signal entries: clock { // test.badClock , // 1 test.goodClock // 2000 } {100ns}; These clock signals have a period of 100 ns or longer.
14 Negative Timing Checks 1 Negative timing checks are either $setuphold timing checks with negative setup or hold limits, or $recrem timing checks with negative recovery or removal limits.
• How VCS Calculates Delays • Using Multiple Non-Overlapping Violation Windows The Need for Negative Value Timing Checks Negative Timing Checks for XYZ The $setuphold timing check defines a timing violation window of a specified amount of simulation time before and after a reference event, such as a transition on some other signal like a clock signal, in which a data signal must remain constant. A transition on the data signal, called a data event, during the specified window is a timing violation.
Figure 14-1 Positive Setup and Hold Limits reference event clock data event data event data setup hold limit limit violation window 10 0 11 Here both the setup and hold limits have positive values. When this happens the violation window straddles the reference event. There are cases where the violation window cannot straddle the reference event at the inputs of an ASIC cell.
When this happens, use the $setuphold timing check in the top-level module of the cell to look for timing violations when signal values propagate to that sequential device. In this case, you need to use negative setup or hold limits in the $setuphold timing check.
Figure 14-3 Negative Setup Limit reference event clock data event data event data setup limit hold limit violation window 0 10 31 Here the $setuphold timing check is in the specify block of the top-level module of the cell. It specifies that there is a timing violation if there is a data event between 10 and 31 time units after the reference event on the cell boundary.
Figure 14-4 ASIC Cell with Long Propagation Delays on Data Events clock causes short delay data q clk d causes long delay The violation window shifts to the left when there are longer propagation delays on the data event. This left shift requires a negative hold limit: $setuphold (posedge clock, data, 31, -10, notifyreg); Figure 14-5 illustrates this scenario.
Here the $setuphold timing check is in the specify block of the toplevel module of the cell. It specifies that there is a timing violation if there is a data event between 31 and 10 time units before the reference event on the cell boundary. This is giving the data events a “head start” at the cell boundary, anticipating that the delays on the data events will allow the reference event to “catch up” at the sequential device inside the cell.
The following additional arguments are optional: timestamp_cond This argument specifies the condition which determines whether or not VCS reports a timing violation. In the setup phase of a $setuphold timing check, VCS records or “stamps” the time of a data event internally so that when a reference event occurs, it can compare the times of these events to see if there is a setup timing violation.
delayed_data_signal The name of the delayed version of the data signal. The following example demonstrates how to use the extended syntax: $setuphold(ref, data, -4, 10, notifr1, stampreg===1, , d_ref, d_data); In this example, the timestamp_cond argument specifies that reg stampreg must equal 1 for VCS to “stamp” or record the times of data events in the setup phase or “stamp” the times of reference events in the hold phase.
r 1 f ? ? ? ? * ? ? endtable endprimitive 0 0 r ? ? ? ? ? ? * : : : : : ? ? ? ? ? : : : : : 1 0 x ; ; ; ; ; In this example the DFF_UDP user-defined primitive is driven by the delayed signals dClk, dD, dRST, and the notifier reg. Negative Timing Checks for Asynchronous Controls The $recrem timing check is for checking how close asynchronous control signal transitions are to clock signals.
The $recrem Timing Check Syntax The $recrem timing check syntax is very similar to the extended syntax for $setuphold: $recrem(reference_event, data_event, recovery_limit, removal_limit, notifier, [timestamp_cond, timecheck_cond, delayed_reference_signal, delayed_data_signal]); reference_event Typically the reference event is the active edge on a control signal, such as a clear signal. Specify the active edge with the posedge or negedge keyword. data_event Typically the data event occurs on a clock signal.
timestamp_cond This argument specifies the condition which determines whether or not VCS reports a timing violation. In the recovery phase of a $recrem timing check, VCS records or “stamps” the time of a reference event internally so that when a data event occurs it can compare the times of these events to see if there is a recovery timing violation. If the condition specified by this argument is false, VCS does not record or “stamp” the reference event so there cannot be a recovery timing violation.
delayed_data_signal The name of the delayed version of the data signal, typically a clock signal. Enabling Negative Timing Checks To use a negative timing check you must include the +neg_tchk compile-time option when you compile your design. If you omit this option, VCS changes all negative limits to 0. If you include the +no_notifier compile-time option with the +neg_tchk option, you only disable notifier toggling.
Similarly, if you include the +neg_tchk compile-time option and then include the +notimingcheck runtime option instead of the compile-time option, you disable the $setuphold and $recrem timing checks that VCS compiled into the executable. At compile time VCS creates the signals that you specified in the delayed_reference_signal and delayed_data_signal arguments, and you can use them to drive sequential devices in the cell, but the +notimingcheck runtime option disables the delay on these “delayed” versions.
dff dff1(q, clk, d, rst); initial begin $monitor($time,,clk,,d,,q); rst = 0; clk = 0; d = 0; #100 clk = 1; #100 clk = 0; #10 d = 1; #90 clk = 1; #1 clk = 0; // width violation #100 $finish; end endmodule module dff(q, clk, d, rst); output q; input clk, d, rst; reg notif; DFF_UDP(q, d_clk, d_d, d_rst, notif); specify $setuphold(posedge clk, d, -10, 20, notif, , , d_clk, d_d); $setuphold(posedge clk, rst, 10, 10, notif, , , d_clk, d_rst); $width(posedge clk, 5, 0, notif); endspecify endmodule primitive DFF_UD
? ? endtable endprimitive ? * : ? : x ; In this example, if you include the +neg_tchk compile-time option, the $width timing check uses the delayed version of signal clk, named d_clk, and the following sequence of events occurs: 1. At time 311 the delayed version of the clock transitions to 1, causing output q to toggle to 1. 2. At time 312 the narrow pulse on the clock causes a width violation: "test1.v", 31: Timing violation in top.
If you include the +neg_tchk compile-time option and also the +old_ntc compile-time option, the $width timing check does not use the delayed version of signal clk and the following sequence of events occurs: 1. At time 301 the narrow pulse on signal clk causes a width violation: "test1.v", 31: Timing violation in top.dff1 $width( posedge clk:300, : 301, limit: 5); 2. Also at time 301 the notifier reg named notif toggles from X to 1.
The timing violation, as represented by the X value, is lost to the design. If a module path delay that is greater than ten time units was used for the module instance, the X value would not appear on the output at all. For this reason Synopsys does not recommend using the +old_ntc compile-time option. It exists only for unforeseen circumstances.
• If the operands in these expressions are the original reference and data signals and not the delayed versions, then you want VCS to evaluate these expressions when there are value changes on the original reference and data signals. To specify evaluating these expressions when the original reference and data signals change value, include the +NTC2 compile-time option.
• You compiled your design with the +neg_tchk compile-time option. • For all $setuphold timing checks the positive setup or hold limit is greater than the negative setup or hold limit. • For all $recrem timing checks the positive recovery or removal limit is greater than the negative recovery or removal limit. As documented in the OVI SDF3.
VCS uses the limits you specify in the $setuphold or $recrem timing check to calculate the delays on the delayed versions of the reference and data signals. For example: $setuphold(posedge clock,data,-10,20, , , , del_clock, del_data); This specifies that the propagation delays on the reference event (a rising edge on signal clock), are more than 10 but less than 20 time units more than the propagation delays on the data event (any transition on signal data).
Here: • The first $setuphold timing check specifies the delay on del_CP is more than 10 but less than 20 time units more than the delay on del_D. • The second $setuphold timing check specifies the delay on del_TI is more than 10 but less than 20 time units more than the delay on del_CP. • The third $setuphold timing check specifies the delay on del_CP is more than 4 but less than 8 time units more than the delay on del_TE.
In unusual and rare circumstances multiple $setuphold and $recrem timing checks, including those that have no negative limits, can make the delays on the delayed versions of these signals mutually exclusive. When this happens VCS repeats the following procedure until the signals are no longer mutually exclusive: 1. Sets one negative limit to 0. 2. Recalculates the delays of the delayed signals.
#45 in1=1; end initial begin clk=0; #50 clk = 1; #50 clk = 0; end endmodule module FD1 (d, cp, q); input d, cp; output q; wire q; reg notifier; reg q_reg; always @(posedge cp) q_reg = d; assign q = q_reg; specify $setuphold( posedge cp, negedge d, 40, 30, notifier); $setuphold( posedge cp, posedge d, 20, 10, notifier); endspecify endmodule The SDF file contains the following to backannotate negative delay values: (CELL (CELLTYPE "FD1") (INSTANCE top.
So the timing checks are now: $setuphold( posedge cp, negedge d, 40, -30, notifier); $setuphold( posedge cp, posedge d, 20, -10, notifier); The violation windows and the transitions that occur on signals top.fd1_1.cp and top.fd1_1.d are shown in Figure 14-4.
The $setuphold timing checks now specify: • A violation window for a falling edge on signal d between 40 and 30 time units before a rising edge on signal cp • A violation window for a rising edge on signal d between 20 and 10 time units before a rising edge on signal cp The testbench module top applies stimulus so that the following transitions occur: 1. A rising edge on signal d at time 45 2.
VCS alters the violation windows: - For the falling edge the window starts 40 time units before the reference event and ends at the reference event. - For the rising edge the window starts 20 time units before the reference event and also ends at the reference event. VCS alters the windows so that they overlap or converge. 2. During simulation, at time 50, the reference event, VCS displays the timing violation: "sourcefile.v", line_number_of_second_timing_check: Timing violation in top.
Negative Timing Checks 14-28
15 SAIF Support 2 The Synopsys Power Compiler enables you to perform power analysis and power optimization for your designs by entering the power command at the vcs prompt. This command outputs Switching Activity Interchange Format (SAIF) files for your design. SAIF files support signals and ports for monitoring as well as constructs such as generates, enumerated types, records, array of arrays, and integers.
Using SAIF Files VCS has native SAIF support so you no longer need to specify any compile-time options to use SAIF files. If you want to switch to the old flow of dumping SAIF files with the PLI, you can continue to give the option -P $VPOWER_TAB $VPOWER_LIB to VCS, and the flow will not use the native support. Note the following when using VCS native support for SAIF files: • VCS does not need any additional switches.
$toggle_start Instructs VCS to start monitoring switching activity. Syntax: $toggle_start(); $toggle_stop Instructs VCS to stop monitoring switching activity. Syntax $toggle_stop(); $toggle_reset Sets the toggle counter to 0 for all the nets in the current toggle region. Syntax: $toggle_reset(); $toggle_report Reports switching activity to an output file.
$read_lib_saif Allows you to read in a SDPD library forward SAIF file. It registers the state and path dependent information on the scope. It also monitors the internal nets of the design. Syntax: $read_lib_saif(); $read_rtl_saif Allows you to read in an RTL forward SAIF file. It registers synthesis invariant elements by reading forward SAIF file. By default, it doesn't register internal nets.
For more details on these task calls, refer to the Power Compiler User Guide. Note: The $read_mpm_saif, $toggle_set, and $toggle_count tasks in the PLI-based vpower.tab file are obsolete and no longer supported.
To generate an SDPD backward SAIF file using a forward SAIF file, do the following: initial begin $read_lib_saif(); $set_toggle_region(); // initialization of Verilog signals, and then: $toggle_start; // testbench $toggle_stop; $toggle_report(, timeUnit, ); end To generate a non-SDPD backward SAIF file without using SAIF files, do the following: initial begin $set_gate_level_monitoring("on"); $set_toggle_region(); // initialization of Verilog signals, and then: $
SAIF Support 15-7
SAIF Support 15-8
16 SWIFT VMC Models and SmartModels 1 VMC models are secure, protected, and portable models of Verilog designs. They contain no Verilog code. SmartModels are models from Synopsys that model devices from various vendors. SWIFT is the interface for both of these kinds of models. VCS enables you to instantiate both these kinds of models in your design and simulate them as part of your design. The steps you take are as follows: 1. Set the SWIFT environment variables. 2.
5. Compile the design with compile-time options for the SWIFT interface and then simulate your design.
All Platforms You must set the LMC_HOME environment variable to the directory where you installed the models. For example: setenv LMC_HOME /u/tools/swiftR41 Set the VCS_SWIFT_NOTES environment variable to 1. For example: setenv VCS_SWIFT_NOTES 1 Setting this environment variable enables the display of messages from models including messages that tell you if the model is correctly loaded.
HP Platform For the HP platform, set the SHLIB_PATH environment variable. If you have already set this environment variable for some other application, you can add to the definition of this environment variable as follows: setenv SHLIB_PATH ${LMC_HOME}/lib/hp700.lib:${SHLIB_PATH} If you haven’t already set this environment variable, enter the following setenv SHLIB_PATH ${LMC_HOME}/lib/hp700.
This command generates a Verilog template file named modelname.swift.v. For example, if you enter the following vcs command: vcs -lmc-swift-template xc4062xl_432 VCS writes the xc4062xl_432.swift.v file in the current directory. The Verilog template file contains a Verilog module definition that contains: • The special $vcs_swift user-defined system task for the SWIFT interface that enables you to use the command channel to the SWIFT interface to pass commands to the model and see messages from the model.
The modifications you can make are as follows: Reordering ports in the module header If, for example, the module header is as follows: module xyz (IO0, IO1, IO2, IO3, IO4); You can reorder the ports: module xyz (IO4, IO3, IO2, IO1, IO0); Concatenating ports in the module header You can concatenate ports in the module header, for example: module xyz ({IO4, IO3, IO2, IO1}, IO0); Doing so enables you to connect vector signals to the model as follows: wire [3:0] bus4; ... xyz xyz1( bus4, ...
Redefining Parameters The Verilog template file contains a number of parameters that are used for specifying model attributes. In some cases you can modify the parameter definition. For example, the template file contains the following parameter definition: parameter DelayRange = "MAX"; This parameter specifies using the maximum delays of min:typ:max delay triplets in the model. You can change the definition to "TYP" or "MIN".
For more information on SmartModel attributes that are parameters in the Verilog template file, see the SmartModel Library Simulator Interface Manual. Monitoring Signals in the Model Window SWIFT VMC models and SmartModels can have a window that enables you to see the values of certain signals inside the model. For some models you can also deposit values on these signals.
The following are examples of these regs in the Verilog template file: //Generating SmartModel Windows data reg [1:0] GEN_CCLK_SPEED; reg [4:0] LENGTH_CNT_WIDTH; reg [10:0] FRAME_SIZE; reg [12:0] DEVICE_FRAMES; reg [3:0] CRC_ERROR_CHK; reg SYNC_TO_DONE; reg [3:0] DONE_ACTIVE; reg [3:0] IO_ACTIVE; reg [3:0] DEVICE_STATE; reg CONFIGURATIONMODE; You enable and disable the monitoring of these window regs with the special $swift_window_monitor_on and $swift_window_monitor_off system tasks.
This example enables the monitoring of all window regs in the module instance for the model with the hierarchical name test.design.xc4062xl_432_1. Example 2 $swift_window_monitor_on("test.design.xc4062xl_432_1", "GEN_CCLK_SPEED","LENGTH_CNT_WIDTH"); This example enables the monitoring of the window regs GEN_CCLK_SPEED and LENGTH_CNT_WIDTH in the module instance test.design.xc4062xl_432_1.
equivalent to the $swift_window_monitor_on system task described in "Monitoring Signals in the Model Window" on page 16-8. Its syntax is as follows: $lm_monitor_enable(regname,instance_name, "window_element") $lm_monitor_disable Disables SmartModel windows for one or more window elements in a specified model instance. This system task is functionally equivalent to the $swift_window_monitor_off system task described in "Monitoring Signals in the Model Window" on page 16-8.
$lm_load_file Loads the memory contents of a file into an instance (the contents of this file are in a specific memory dump format). The instance can be either a programmable device or a memory model. Using this system task eliminates the write cycles required to set up the contents of the model. You can also use this system task to load a model control file (MCF) during simulation.
Note: VCS does not support two-dimensional windows for memory models and therefore has not implemented other LMTV window commands. Entering Commands Using the SWIFT Command Channel As an alternative to using the LMTV window commands, you can use the SWIFT command channel to pass commands to a SmartModel or a VMC model. The command channel works by assigning these commands and toggling the values of command channel regs declared in the Verilog template file.
The following is an example of an initial block that passes commands through the command channel: initial begin #1 circuit.model.cmd$str = "show doc"; circuit.model.do$model$cmd=1 ; // 1 #1 circuit.model.do$model$cmd=0 ; #1 circuit.model.cmd$str = "show timing unit"; circuit.model.do$model$cmd = 1; #1 circuit.model.do$model$cmd=0 ; #1 circuit.model.cmd$str = "show version"; circuit.model.
Using the CLI to Access the Command Channel You can also use the CLI to access the command channel during simulation. For example: cli_0> cli_1> cli_2> cli_3> cli_4> cli_5> set circuit.model.cmd$str = "show doc"; once #1; . set circuit.model.do$model$cmd=1; once #1; . Loading Memories at the Start of Runtime SmartModel memory models have an attribute called MemoryFile. You can use this attribute to load the contents of a file into these memories at runtime. To do so use a defparam statement.
Compiling and Simulating a Model If your design instantiates a SmartModel or a VMC model, you compile your design with the -lmc-swift compile-time option. Be sure to also include the Verilog template file on the vcs command line. For example: vcs -lmc-swift xc4062xl_432.swift.v test.v design.v This command line results in an executable file named simv.
17 Using the PLI 2 PLI is the programming language interface (PLI) between C/C++ functions and VCS. It helps to link applications containing C/C++ functions with VCS so that they execute concurrently. The C/C++ functions in the application use the PLI to read and write delay and simulation values in the VCS executable, and VCS can call these functions during simulation. VCS has implemented the TF and ACC routines for the PLI. It has also implemented the VPI procedural interface routine to some extent.
• Probabilistic distribution • Returning a string pointer to a parameter value • Extended VCD files • Line callbacks • Source protection • Signal in a generate block ACC routines, which access the values in a design, changing, for example, the delay values of module paths or the simulation values of individual signals, are more powerful that the TF routines which operate only on data passed to them. However, the ACC routines also have a greater performance cost.
• Using VPI Routines • Writing Your Own main() Routine Writing a PLI Application When writing a PLI application, you need to do the following: 1. Write the C/C++ functions of the application calling the TF and ACC routines that Synopsys has implemented to access data inside VCS. 2. Associate user-defined system tasks and system functions with the C/C++ functions in your application.
To use the debugging features, do the following: 1. Write a PLI table file, limiting the scope and operations of the ACC routines used by the debugging features. 2. Compile and simulate your design, specifying the table file. These procedures are not mutually exclusive. It is, for example, quite possible that you have a PLI application that you write and use during the debugging phase of your design.
• The function that VCS calls during compilation to check if the user-defined system task has the correct syntax. You can omit this check function. • The function that VCS calls for miscellaneous reasons such as the execution of $stop, or $finish, or other reasons such a value change. When VCS calls this function it passes a reason argument to it that explains why VCS is calling it. You can omit this miscellaneous function.
vcs_acc_user.h For PLI applications whose functions call the special ACC routines implemented exclusively for VCS. You will find these header files at $VCS_HOME/platform/lib, where platform is the platform you are using, such as sun_sparc_solaris_5.7. The header file for the VPI routines is $VCS_HOME/include/ vpi_user.h; see "Using VPI Routines" on page 17-29. The PLI Table File The PLI table file (commonly called the pli.
• The PLI specifications for the user-defined system task or system function. These specifications must include the call function. For user-defined system functions, they must also include the size of the return value. These specifications can also include the check and miscellaneous functions. There are a number of other PLI specifications, such as the one that allows the entering of the user-defined system task on the command line. You can also enter these specifications on a line in the PLI table file.
ACC_capabilities Specifications for ACC capabilities to be added, removed, or changed in various parts of the design hierarchy. For details on ACC capabilities, see "ACC Capabilities" on page 17-11.
PLI Specifications The valid PLI specifications are as follows: call=function Specifies the name of call function. This specification is required. check=function Specifies the name of check function. misc=function Specifies the name of misc function. data=integer Specifies the data value passed as first argument to call, check, and misc routines. The default is 0. Use this argument if you want more than one user-defined system task or system function to use the same call, check, or misc function.
maxargs=number Specifies the maximum number or arguments. nocelldefinepli Disables the dumping of value change and simulation time data, from modules defined under the ‘celldefine compiler directive, into the VPD file created by the $vcdpluson system task. You make this change in the line for the $xvcs system task in the virsims.tab, virsims_dki.tab, and virsims_pp.tab files in the $VCS_HOME/virsims_support/vcdplus directory.
Example 2 $value_passer size=0 args=2 call=value_passer persistent In this line, there is an associated user-defined system task (because it has a return size of 0). The system task takes two arguments. When VCS executes the $value_passer system task it calls the function named value_passer, and you can enter the system task on the CLI command line without including the +cli compile-time option.
• To specify the ACC capabilities that the debugging features of VCS can use. To do this, specify ACC capabilities alone on a line in a PLI table file, without an associated user-defined system task or system function. See "Specifying ACC Capabilities for VCS Debugging Features" on page 17-17 for more details. When you specify ACC capabilities, you specify both of the following: • The ACC capabilities you want to enable or disable.
+= Specifies adding the ACC capabilities that follow to the parts of the design that follow, as specified by module name, %CELL,%TASK, or * wildcard character. -= Specifies removing the ACC capabilities that follow from the parts of the design that follow, as specified by module name, %CELL,%TASK, or * wildcard character.
cbka or callback_all To be called when named and unnamed objects (such as primitive terminals) change value. frc or force Forces values on nets and registers. prx or pulserx_backannotation Sets pulse error and pulse rejection percentages for module path delays. s or static_info Enables access to static information, such as instance or signal names and connectivity information. Signal values are not static information. tchk or timing_check_backannotation Backannotates timing check delay values.
+ Specifies adding, removing, or changing the ACC capabilities for not only the instances of the specified modules but also the instances hierarchically under the instances of the specified modules.
acc+= rw,tchk:top,bot acc-=tchk:top This example adds the ACC capabilities for reading and writing to nets and registers, and for backannotating timing check delays, to these PLI functions, and enables them to do these things in all instances of modules top and bot. It then removes the ACC capability for backannotating timing check delay values from these PLI functions in all instances of module top.
Specifying ACC Capabilities for VCS Debugging Features The format for specifying ACC capabilities for VCS debugging features is as follows: acc=|+=|-=|:=capabilities:module_names[+]|%CELL|* Here: acc Keyword that begins a line for specifying ACC capabilities. =|+=|-=|:= Operators for adding, removing, or changing ACC capabilities. capabilities Comma separated list of ACC capabilities. module_names Comma-separated list of module identifiers.
The ACC capabilities and the interactive commands they enable are as follows: ACC Capability What it enables your PLI functions to do r or read For specifying “reads” in your design, it enables commands for doing the following (the actual CLI commands described are in parentheses): • Creating an alias for another CLI command (alias) • Displaying CLI help (? and help) • Specifying the radix of displayed simulation values (oformat) • Displaying simulation values (print) • Descending and ascending the modul
ACC Capability What it enables your PLI functions to do cbk or callback Commands for doing the following (the actual CLI commands described are in parentheses): • Setting a repeating breakpoint. In other words always halting simulation, when a specified signal changes value (always or break) • Setting a one shot breakpoint.
Example 2 The following specifications enable most interactive commands for most of the modules in a design. They then change the ACC capabilities preventing breakpoint and force commands in instances of modules in Verilog libraries and modules designated as cells with the ‘celldefine compiler directive.
One advantage to entering .o object files and .a libraries is that you do not have to recompile the PLI application every time you compile your design. Enabling ACC Capabilities As well as specifying ACC capabilities in only specific parts of your design (as described in "The PLI Table File" on page 17-6), VCS allows you to enable ACC capabilities throughout your design. It also enables you to specify selected write capabilities using a configuration file.
The level_number in this option specifies more and more ACC capabilities as follows: +acc+1 or +acc Enables all capabilities except value change callbacks and delay annotation. +acc+2 Above, plus value change callbacks. +acc+3 Above, plus module path delay annotation. +acc+4 Above, plus gate delay annotation. Enabling ACC Write Capabilities Using the Configuration File You specify the configuration file with the +optconfigfile compile-time option.
The entries in the configuration file override the ACC write-enabling entries in the PLI table file. The syntax of each type of statement in the configuration file to enable ACC write capabilities is as follows: set writeOnMem; or set noAccWrite; or module {list_of_module_identifiers} {accWrite}; or instance {list_of_module_instance_hierarchical_names} {accWrite}; or tree [(depth)] {list_of_module_identifiers} {accWrite}; Here: set Keyword preceding a property that applies to the entire design.
module Keyword specifying that the accWrite attribute in this statement applies to all instances of the modules in the list, specified by module identifier. list_of_module_identifiers Comma-separated list of module identifiers (also called module names). instance Keyword specifying that the accWrite attribute in this statement applies to all instances in the list. list_of_module_instance_hierarchical_names Comma-separated list of module instance hierarchical names.
Using Only the ACC Capabilities that You Need There are compile-time and runtime options that enable VCS and PLI applications to use only the ACC capabilities they need and no more than they need. The procedure to use these options is as follows: 1. Use the +vcs+learn+pli runtime option to tell VCS to keep track of, or learn, the ACC capabilities that are used by different modules in your design. VCS uses this information to create a secondary PLI table file, named pli_learn.
You should look at the contents of the pli_learn.tab file that VCS writes to see what ACC capabilities were actually used during simulation.
Signs of a Potentially Significant Performance Gain You might see one of following comments in the pli_learn.tab file: //!VCS_LEARNED: NO_ACCESS_PERFORMED This indicates that none of the enabled ACC capabilities were used during the simulation. //!VCS_LEARNED: NO_DYNAMIC_ACCESS_PERFORMED This indicates that only static information was accessed through ACC capabilities and there was no value change information during simulation.
When you recompile your design with the +applylearn compile-time option, it is important that you also re-enter all the compile-time options that you used for the previous compilation. For example, if in a previous compilation you specified a PLI table file with the -P compile-time option, specify this PLI table file again, using the -P option, along with the +applylearn option. Note: If you change your design after VCS writes the pli_learn.
• +multisource_int_delays or +transport_int_delays because interconnect delays need global ACC capabilities. If you enter the +applylearn compile-time option more than once on the vcs command line, VCS ignores all but the first one. Using VPI Routines To enable VPI capabilities in VCS, you must include the +vpi compile-time option. For example: vcs +vpi test.v -P test.tab test.c The header file for the VPI routines is $VCS_HOME/include/ vpi_user.h.
Object data model diagrams in the IEEE Verilog language reference manual specify that some VPI routines should be able to access data that is rarely needed. These routines and the data they can’t access are as follows: vpi_get_value - Cannot retrieve the value of var select objects (diagram 26.6.8 Variables) and func call objects (diagram 26.6.18 Task, function declaration). - Cannot retrieve the value of VPI operators (expressions) unless they are arguments to system tasks or system functions.
cbRelease cbAssign cbDeassign Also the cbValueChange callback is not supported for the following objects: - A memory or a memory word (index or element) - VarArray or VarSelect Support for the vpi_register_systf Routine VCS supports the vpi_register_systf VPI access routine. To use it you need to make an entry in the vpi_user.c file. You can copy this file from $VCS_HOME/etc/vpi.
You specify this file with the -use_vpiobj compile-time option. For example: vcs any.c any.v -use_vpiobj vpi_user.c +cli+3 +vpi PLI Table File for VPI Routines The PLI table file for VPI routines works the same way, and with the same syntax as a PLI table file for user-defined system tasks that execute C functions, which call PLI ACC routines.
Instead you enter the -load compile-time option to specify the registration routine. The syntax is as follows: -load shared_library:registration_routine You do not have to specify the pathname of the shared library if that path is part of your LD_LIBRARY_PATH environment variable. The following are some examples of using this option: • -load lib1:my_register The my_register() routine is in lib1.so. The location of lib1.so is in the LD_LIBRARY_PATH environment variable.
• -load /usr/lib/mylib.so:my_register The registration routine my_register() is in lib1.so, which is in /usr/ lib/mylib.so, and not in the LD_LIBRARY_PATH environment variable. Writing Your Own main() Routine You write your own main() routine if you wrote your PLI application in C++ code or if your standard C code application does some processing before starting the simv executable. When you write your own main() routine you must include the -e compile-time option on the vcs command line.
static void do_cleanup(int code) { /* do simv post-processing work */ } int main(int argc, char *argv[]) { /* Startup code (if any) goes here. */ vcs_atexit(do_cleanup); /* Register callback */ SimvMain(argc, argv); /* Run simv */ return 0; /* Never gets here */ } Note that SimvMain does not return, it calls exit() directly. If you need to do any post-processing, you can register at-exit functions using vcs_atexit(). The function you pass to vcs_atexit() is called with the exit status.
Using the PLI 17-36
18 DirectC Interface 3 DirectC is an extended interface between Verilog and C/C++. It is an alternative to the PLI that, unlike the PLI, enables you to do the following: • More efficiently pass values between Verilog module instances and C/C++ functions by calling the functions directly, along with actual parameters, in your Verilog code. • Pass more kinds of data between Verilog and C/C++. With the PLI you can only pass Verilog information to and from a C/C++ application.
Similarly you can use DirectC to develop applications to run with VCS to which you can pass pointers to the location of simulation values for your design. DirectC is an alternative to, but not a replacement for, the PLI. You can do things with the PLI that you cannot do with DirectC. For example there are PLI TF and ACC routines to implement a callback to start a C/C++ function when a Verilog signal changes value. You cannot do this with DirectC.
Using Direct C/C++ Function Calls To enable a direct call of a C/C++ function during simulation, do the following: 1. Declare the function in your Verilog code. 2. Call the function in your Verilog code. 3. Compile your Verilog and C/C++ code using compile-time options for DirectC. However there are complications to this otherwise straightforward procedure. DirectC allows the invocation of C++ functions that are declared in C++ using the extern "C" linkage directive.
There are two access modes for C/C++ function calls. These modes don’t make much difference in your Verilog code; they only pertain to the development of the C/C++ function. They are as follows: • The slightly more efficient direct access mode - This mode has rules for how values of different types and sizes are passed to and from Verilog and C/C++.
Using abstract access is “safer” because the library of accessory functions for abstract access has error messages to help you to debug the interface between the C/C++ and Verilog. With direct access, errors simply result in segmentation faults, memory corruption, etc. Abstract access can be generalized more easily for your C/C++ function. For example, with open arrays you can call the function with 8-bit arguments at one point in your Verilog design and call it again some place else with 32-bit arguments.
If a C/C++ function returns a value to a Verilog register (the C/C++ function is in an expression that is assigned to the register) the return value of the C/C++ function is restricted to the following: • The value of a scalar reg or bit Note: In two state simulation a reg has a new name, bit.
attribute ::= pure return_type ::= void | reg | bit | DirectC_primitive_type | small_bit_vector small_bit_vector ::= bit [ (constant_expression : constant_expression ) ] extern_func_args ::= extern_func_arg ( , extern_func_arg ) * extern_func_arg arg_direction ::= arg_direction ? arg_type arg_id ? ::= input | output | inout arg_type ::= bit_or_reg_type | array_type | DirectC_primitive_type bit_or_reg_type ::= ( bit | reg ) optional_vector_range ? optional_vector_range ::= [ ( constant_expressi
small_bit_vector Specifies a bit-width of a returned vector bit. A C/C++ function cannot return a four state vector reg but it can return a vector bit if its bit-width is 32 bits or less. function_id The name of the C/C++ function. direction One of the following keywords: input, output, inout. These keywords specify in a C/C++ function the same thing that they specify in a Verilog task; see Table 18-2. arg_type The valid argument types are real, reg, bit, int, pointer, string.
Note: Argument direction, i.e. input, output, inout applies to all arguments that follow it until the next direction occurs; the default direction is input. Table 18-1 C/C++ Function Return Types Return Type What it specifies int The C/C++ function returns a value for type int. bit The C/C++ function returns the value of a bit, which is a Verilog reg in two state simulation, if it is 32 bits or less. reg The C/C++ function returns the value of a Verilog scalar reg.
Table 18-3 C/C++ Function Argument Types keyword What it specifies real The C/C++ function reads or writes the address of a Verilog real data type. reg The C/C++ function reads or writes the value or address of a Verilog reg. bit The C/C++ function reads or writes the value or address of a Verilog reg in two state simulation. int The C/C++ function reads or writes the address of a C/C++ int data type. pointer The C/C++ function reads or writes the address that a pointer is pointing to.
The keyword input is omitted. This keyword can be omitted if the first argument specified is an input argument. Example 3 extern string return_string(); This example declares a C/C++ function named return_string. This function returns a character string and takes no arguments. Example 4 extern void receive_string( input string r5); This example declares a C/C++ function named receive_string. It is a void function.
This example declares a C/C++ function named memory_reorg. When we call this function the values in memory mem2 are passed to the function. After the function executes, new values are passed to memory mem1. Example 8 extern void incr (inout bit [] r7); This example declares a C/C++ function named incr. When we call this function the value in bit r7 is passed to the function. When it finishes executing it passes a new value to bit r7. We did not specify a bit width for vector bit r7.
You call a non-void (returns a value) C/C++ function in the same manner as you call a Verilog function call, that is, by entering its name and arguments, either in an expression on the RHS of a procedural assignment statement in an always or initial block, or in a Verilog task or function declaration. Examples r2=return_reg(r1); The value of scalar reg r1 is passed to C/C++ function return_reg. It returns a value to reg r2.
memory_reorg(mem1,mem2); In this example all the values in memory mem2 are passed to C/C++ function memory_reorg and when it finishes executing, it passed new values to memory mem1. incr(r7); In this example the value of bit r7 is passed to C/C++ function incr and when it finishes executing, it passes new a new value to bit r7. Storing Vector Values in Machine Memory Users of direct access need to know how vector values are stored in memory. This information is also helpful for users of abstract access.
For a four-state vector (denoted by the keyword reg) the Verilog data is stored in type vec32, which for abstract access is defined as follows: typedef unsigned int U; typedef struct { U c; U d;} vec32; So type vec32* has two members of type U; member c is for control bits and member d is for data bits. For a two state vector bit the Verilog data is stored in type U*. Vector values are stored in arrays of chunks of 32 bits.
For long vectors the chunk for the least significant bits come first, followed by the chunks for the more significant bits.
Converting Strings There are no *true* strings in Verilog and a string literal, like "some_text," is just a notation for vectors of bits, based on the same principle as binary, octal, decimal, hexadecimal numbers. So there is a need for a conversion between the two representations of "strings": the C-style representation (which actually is a pointer to the sequence of bytes terminated with null byte) and the Verilog vector encoding a string.
This call causes a core dump because the function expects a pointer and gets some random bits instead. It may happen that a string, or different strings, are assigned to a signal in Verilog code and their values are passed to C. For example: task DoStuff(...., result_code); ... output reg [100*8:1] result_code; begin . . . if (...) result_code = "Bus error"; . . . if (...) result_code = "Erroneous address"; . . . else result_code = "Completed"); end endtask reg [100*8:1] message; .... DoStuff(...
Solution 2: Perform the conversion on the Verilog side. This requires some additional effort, as the memory space for a C string has to be allocated as follows: extern "C" string malloc(int); extern "C" void vc_ConvertToString(reg [], int, string); // this function comes from DirectC library reg [31:0] sptr; . . .
Using Direct Access Direct access was implemented for C/C++ routines whose formal parameters are of the following types: int int* double* void* char* char** scalar scalar* U* vec32 UB* void** Some of these type identifiers are standard C/C++ types; the ones that aren’t were defined with the following typedef statements: typedef typedef typedef typedef unsigned int U; unsigned char UB; unsigned char scalar; struct {U c; U d;} vec32; The type identifier you use depends on the corresponding argum
• An open bit-width for a reg makes it possible for you to pass a vector reg, so the corresponding formal parameter for a reg argument, specified with an open bit-width, must be a pointer. Similarly an open bit-width for a bit makes it possible for you to pass a bit larger than 32 bits, so the corresponding formal parameter for a bit argument specified with an open bit width must be a pointer. • Direct access passes by value the following types of input arguments: int, string, and pointer.
Table 18-8 For Output and Inout Arguments argument type C/C++ formal parameter data type Passed by int int* reference real double* reference pointer void** reference string char** reference bit scalar* reference reg scalar* reference bit [] - any vector, including open vector U* reference reg[] - any vector, including open vector vec32* reference array[] - any array, 2 state or 4 state, including UB* open array reference In direct access the return value of the function is alw
If return_reg() is a C++ function, it must be protected from name mangling, as follows: extern "C" scalar return_reg(scalar reti); Note: The extern "C" directive has been omitted in subsequent examples, for brevity. A scalar reg is passed by value to the function so the parameter is not a pointer. The parameter’s type is scalar.
Example 3 Consider the following C/C++ function declared in the Verilog source code: extern void receive_pointer ( input pointer r6 ); Here the function named receive_pointer does not return a value. The argument passed to it is declared to be a pointer. The header of the C/C++ function is as follows: void receive_pointer(*pointer_receiver); A pointer is passed by value to the function so the parameter is a pointer of type void, a generic pointer.
Example 5 Consider the following C/C++ function declared in the Verilog source code: extern void incr (inout bit [] r7); Here the function named incr, that does not return a value, has an argument declared as inout. No bit-width is specified for it but the [] entry for the argument specifies that it is not a scalar bit. The header of the C/C++ function is as follows: void incr (U *p); Open bit-width parameters are always passed to by reference.
Here the parameters in and out are pointers to type U. Pointers because their corresponding arguments are larger than 32 bits and type U because the corresponding arguments are type bit. Example 7 Consider the following C/C++ function declared in the Verilog source code: extern void passbig2 (input reg [63:0] r10, output reg [63:0] r11); Here the function named passbig2, that does not return a value, has input and output arguments declared as non-scalar reg.
Here the parameters in and out are pointers to type double because their corresponding arguments are type real. Using the vc_hdrs.h File When you compile your design for DirectC (by including the +vc compile-time option), VCS writes a file in the current directory named vc_hdrs.h. In this file are extern declarations for all the C/C++ functions that you declared in your Verilog code.
You can copy from these extern declarations to the function headers in your C code. If you do you will always use the right type of parameter in your function header and you don’t have to learn the rules for direct access. Let VCS do this for you. Access Routines for Multi-Dimensional Arrays DirectC requires that Verilog multi-dimensional arrays be linearized (turned into arrays of the same size but with only one dimension).
UB *vc_array2ElemRef(UB*, U, U) UB *vc_array3ElemRef(UB*, U, U, U) U vc_getSize(UB*,U) This routine is similar to the vc_mdaSize() routine used in abstract access. It returns the following: • If the U type parameter has a value of 0, it returns the number of indices in an array. • If the U type parameter has a value greater than 0, it returns the number of values in the index specified by the parameter. There is an error condition if this parameter is out of the range of indices.
Using vc_handle In the function header, the vc_handle for a Verilog reg, bit, or memory is based on the order that you declare the vc_handle and the order that you entered its corresponding reg, bit, or memory in the function call in your Verilog code. For example, you could have declared the function and called it in your Verilog code as follows: extern "A" void my_function( input bit [31:0] r1, input bit [32:0] r2); module dev1; Declare the function reg [31:0] bit1; reg [32:0] bit2; initial begin . . .
The corresponding header for the C/C++ function is as follows: . . . my_function(vc_handle h1, vc_handle h2) { . . . h1 is the vc_handle for bit1 h2 is the vc_handle for bit2 up1=vc_2stVectorRef(h1); up2=vc_2stVectorRef(h2); . . } . A routine that accesses the data structures for bit1 and bit2 using their vc_handles After declaring the vc_handles you can use them to pass data to and from these descriptors.
The access routines were named to help you to remember their function. Routine names beginning with vc_get are for retrieving data from the descriptor for the Verilog parameter. Routine names beginning with vc_put are for passing new values to these descriptors. These routines can convert Verilog representation of simulation values and strings to string representation in C/C++.
Here we declare a routine named scalarfinder and input a scalar reg, a vector reg and two memories (one with scalar elements). The declaration contains the "A" specification for abstract access. You typically include it in the declaration when other functions will use direct access, that is, you have a mix of functions with direct and abstract access. #include #include "DirectC.
int i1 = vc_isVector(h1), i2 = vc_isVector(h2), i3 = vc_isVector(h3), i4 = vc_isVector(h4); printf("\ni1=%d i2=%d i3=%d i4=%d\n\n",i1,i2,i3,i4); } The function prints the following: i1=0 i2=1 i3=0 i4=0 int vc_isMemory(vc_handle) This routine returns a 1 value if the vc_handle is to a memory. It returns a 0 value for a bit or reg that is not a memory. For example, using the Verilog code from the previous example, and the following C/C++ function: #include #include "DirectC.
int vc_is4state(vc_handle) This routine returns a 1 value if the vc_handle is to a reg or memory that simulates with four states. It returns a 0 value for a bit or a memory that simulates with two states.
vc_is4state(h3),vc_is4state(h4)); printf("\nThe vc_handles to 2state are:"); printf("\nh5=%d h6=%d h7=%d h8=%d\n\n", vc_is4state(h5),vc_is4state(h6), vc_is4state(h7),vc_is4state(h8)); } The function prints the following: The vc_handles to 4state are: h1=1 h2=1 h3=1 h4=1 The vc_handles to 2state are: h5=0 h6=0 h7=0 h8=0 int vc_is2state(vc_handle) This routine does the opposite of the vc_is4state routine.
The function prints the following: The vc_handles to 4state are: h1=0 h2=0 h3=0 h4=0 The vc_handles to 2state are: h5=1 h6=1 h7=1 h8=1 int vc_is4stVector(vc_handle) This routine returns a 1 value if the vc_handle is to a vector reg. It returns a 0 value if the vc_handle is to a scalar reg, scalar or vector bit, or memory. For example, using the Verilog code from the previous example, and the following C/C++ function: #include #include "DirectC.
The function prints the following: The vc_handle to a 4state Vector is: h2=1 The vc_handles to 4state scalars or memories and 2state are: h1=0 h3=0 h4=0 h5=0 h6=0 h7=0 h8=0 int vc_is2stVector(vc_handle) This routine returns a 1 value if the vc_handle is to a vector bit. It returns a 0 value if the vc_handle is to a scalar bit, scalar or vector reg, or to a memory. For example, using the Verilog code from the previous example, and the following C/C++ function: #include #include "DirectC.
The function prints the following: The vc_handle to a 2state Vector is: h6=1 The vc_handles to 2state scalars or memories and 4state are: h1=0 h2=0 h3=0 h4=0 h5=0 h7=0 h8=0 int vc_width(vc_handle) Returns the width of a vc_handle.
int vc_arraySize(vc_handle) Returns the number of elements in a memory or multi-dimensional array. The previous example also shows a use of vc_arraySize(). scalar vc_getScalar(vc_handle) Returns the value of a scalar reg or bit.
int vc_toInteger(vc_handle) Returns an int value for a vc_handle to a scalar bit or a vector bit of 32 bits or less.
The following C/C++ function uses this routine: #include #include "DirectC.h" void rout1 (vc_handle onebit, vc_handle mobits) { printf("\n\nonebit is %d mobits is %d\n\n", vc_toInteger(onebit), vc_toInteger(mobits)); } This function prints the following: onebit is 0 mobits is 0 onebit is 1 mobits is 128 char *vc_toString(vc_handle) Returns a string that contains the 1, 0, x, and z characters.
{ vec32 b,*c; c=vc_4stVectorRef(h); b=*c; printf("\n b is %x[control] %x[data]\n\n",b.c,b.d); printf("\n b is %s \n\n",vc_toString(h)); } In this example a vector reg is assigned a value that contains x and z values as well as 1 and 0 values. In the abstract access C/C++ function there are two ways of displaying the value of the reg: • Recognize that type vec32 is defined as follows in the DirectC.
So if we modify the C/C++ function in the previous example, it is as follows: void vector_printer (vc_handle h) { vec32 b,*c; c=vc_4stVectorRef(h); b=*c; printf("\n b is %s \n\n",vc_toStringF(h,’b’)); printf("\n b is %s \n\n",vc_toStringF(h,’o’)); printf("\n b is %s \n\n",vc_toStringF(h,’d’)); printf("\n b is %s \n\n",vc_toStringF(h,’x’)); } This example now displays: b is zx01zx01 b is XZX b is X b is XX void vc_putReal(vc_handle, double) Passes by reference a real (double) value to a vc_handle.
double vc_getReal(vc_handle) Returns a real (double) value from a vc_handle. For example: void print_real(vc_handle h) { printf("[print_real] %f\n", vc_getReal(h)); } void vc_putValue(vc_handle, char *) This function passes, by reference through the vc_handle, a value represented as a string containing the 0, 1, x, and z characters.
} The vc_putValue routine passes the string "10xz" to the reg r1 through the vc_handle. The Verilog code displays: r1=10xz void vc_putValueF(vc_handle, char *, char ) This function passes by reference, through the vc_handle, a value for which you specify a radix with the third parameter. The valid radixes are ’b’, ’o’, ’d’, and ’x’.
vc_handle h4) { vc_putValueF(h1,"10",’b’); vc_putValueF(h2,"11",’o’); vc_putValueF(h3,"10",’d’); vc_putValueF(h4,"aff",’x’); } The Verilog code displays the following: r1=10 in binary r1=2 in decimal r2=11 in octal r2 =9 in decimal r3=10 in decimal r3=1010 in binary r4=aff in hex r4= 2815 in decimal void vc_putPointer(vc_handle, void*) void *vc_getPointer(vc_handle) These functions pass a generic type of pointer or string to a vc_handle by reference.
end endmodule This Verilog code passes the string "abc" to the C/C++ function passback by reference, and that function passes it by reference to reg r2. The Verilog code then passes it by reference to the C/C++ function printer from reg r2.
module Test; reg [`FILE_NAME_SIZE*8:1] file_name; // this file_name will be passed to the Verilog code that expects // a Verilog-like string . . . initial begin s2v(FullPath("myStimulusFile"), file_name); // C-string to Verilog-string // bits of 'file_name' represent now 'Verilog string' end . . . endmodule The C code is as follows: void s2v(vc_handle hs, vc_handle hv) { vc_StringToVector((char *)vc_getPointer(hs), hv); } void vc_VectorToString(vc_handle, char *) Converts a vector value to a string value.
{ int a,b,c,d; a=1; b=2; c=3; d=9999999; vc_putInteger(h1,a); vc_putInteger(h2,b); vc_putInteger(h3,c); vc_putInteger(h4,d); } vec32 *vc_4stVectorRef(vc_handle) Returns a vec32 pointer to a four state vector. Returns NULL if the specified vc_handle is not to a four state vector reg.
if (n != 1) { printf("Error: write failed.\n"); } /* write the vector into a file; vc_*stVectorRef is a pointer to the actual Verilog vector */ if (vc_is4stVector(a_vector)) { n = fwrite(vc_4stVectorRef(a_vector), sizeof(vec32), size, fp); } else { n = fwrite(vc_2stVectorRef(a_vector), sizeof(U), size, fp); } if (n != size) { printf("Error: write failed for vector.\n"); } } U *vc_2stVectorRef(vc_handle) Returns a U pointer to a bit vector that is larger than 32 bits.
Here the Verilog code declares a 32-bit bit vector, r1, and a 33-bit bit vector, r2. The values of both are passed to the C/C++ function big_2state. When we pass the short bit vector r1 to vc_2stVectorRef it returns a null value because it has fewer than 33 bits. This is not the case when we pass bit vector r2 because it has more than 32 bits. Notice that from right to left, the first 32 bits of r2 have a value of 2 and the MSB 33rd bit has a value of 1.
else{ u2=0; printf("\nShort 2 state vector passed to up2\n");} } In this example the short bit vector is passed to the vc_2stVectorRef routine, so it returns a null value to pointer up1. Then the long bit vector is passed to the vc_2stVectorRef routine, so it returns a pointer to the Verilog data for vector bit r2 to pointer up2. It checks for the null value in up1. If it doesn’t have null value, whatever it points to is passed to u1.
void vc_get4stVector(vc_handle, vec32 *) void vc_put4stVector(vc_handle, vec32 *) Passes a four state vector by reference to a vc_handle to and from an array in C/C++ function. vc_get4stVector receives the vector from Verilog and passes it to the array and vc_put4stVector passes the array to Verilog. These routines work only if there are enough elements in the array for all the bits in the vector.
} This function declares a vec32 array of three elements named holder. It uses three elements because its parameters are 68-bit regs so we need an element for every 32 bits and one more for the remaining four bits.
UB *vc_MemoryRef(vc_handle) Returns a pointer of type UB that points to a memory in Verilog.
for ( i = 0; i < 8; i++){ memcpy(p2,p1,8); p2 += 8; } } The purpose of the C/C++ function mem_doer is to copy the four elements in Verilog memory memory1 into the 32 elements of memory2. The vc_MemoryRef routines return pointers to the Verilog memories and the machine memory locations they point to are also pointed to by pointers p1 and p2. Pointer p1 points to the location of Verilog memory memory1, and p2 points to the location of Verilog memory memory2.
In an element in a Verilog memory, for each eight bits in the element there is a data byte and a control byte with an additional set of bytes for remainder bit, so if a memory had 9 bits it would need two data bytes and two control bytes. If it had 17 bits it would need three data bytes and three control bytes. All the data bytes precede the control bytes.
Here there is a Verilog memory with four addresses, each element has 25 bits. This means that the Verilog memory needs eight bytes of machine memory because there is a data byte and a control byte for every eight bits in an element, with an additional data and control byte for any remainder bits. Here in element 0 the 25 bits are assigned, from right to left, eight 1 bits, eight unknown x bits, eight 0 bits, and one high impedance z bit. #include #include "DirectC.
C/C++ function mem_elem_doer uses the vc_MemoryElemRef routine to return pointers to addresses 0 and 3 in Verilog memory1 and pass them to UB pointers p1 and p2. The standard memcpy routine then copies the eight bytes for address 0 to address 3. The remainder of the function is additional code to show you data and control bytes. The eight bytes pointed to by p2 are copied to array t and then the elements of the array are printed.
scalar vc_getMemoryScalar(vc_handle, U indx) Returns the value of a one-bit memory element. For example: extern void bitflipper (inout reg array [127:0] mem1); module test; reg mem1 [127:0]; initial begin mem1 [0] = 1; $display("mem1[0]=%0d",mem1[0]); bitflipper(mem1); $display("mem1[0]=%0d",mem1[0]); $finish; end endmodule Here in this Verilog code we declare a memory with 128 one-bit elements, assign a value to element 0, and display its value before and after we call a C/C++ function named bitflipper.
The Verilog code displays the following: mem[0]=1 mem[0]=0 void vc_putMemoryScalar(vc_handle, U indx, scalar) Passes a value of type scalar to a Verilog memory element. You specify the memory by vc_handle and the element by the indx parameter. This routine is used in the previous example. int vc_getMemoryInteger(vc_handle, U indx) Returns the integer equivalent of the data bits in a memory element whose bit-width is 32 bits or less.
Here when the C/C++ function is declared on our Verilog code it does not specify a bit-width or element range for the inout argument to the mem_elem_halver C/C++ function because in the Verilog code we call the C/C++ function twice, with a different memory each time and these memories have different bit widths and different element ranges. Notice that we assign a value that included X values to the 0 element in memory mem2. #include #include "DirectC.
Element mem2[0] has an X value because half of its binary value is x and the value is displayed with the %d format specification and here a partially unknown value is just an unknown value. After the second call of the function, the Verilog code displays: mem1[1]=499 mem2[0]=127 This is because before calling the function, mem1[0] had a value of 999, and after the call it has a value of 499 which is as close as it can get to half the value with integer values.
So type vec32 has two members, c and d, for control and data information. This routine always copies to the 0 element of the array.
This C/C++ function declares an array of type vec32. We must declare an array for this type but we, as shown here, specify that it have only one element. The vc_get4stMemoryVector routine copies the data from the Verilog memory element (here specified as the 0 element) to the 0 element of the vec32 array. It always copies to the 0 element. The vc_put4stMemoryVector routine copies the data from the vec32 array to the Verilog memory element (in this case element 32).
void vc_get2stMemoryVector(vc_handle, U indx, U *) Copies the data bytes, but not the control bytes, from a Verilog memory element to an array in your C/C++ function. For example, if you use the Verilog code from the previous example but simulate in two state and use the following C/C++ code: #include #include "DirectC.
void vc_putMemoryValue(vc_handle, U indx, char *) This routine works like the vc_putValue routine except that is for passing values to a memory element instead of to a reg or bit. You enter an argument to specify the element (index) to which you want the routine to pass the value. For example: #include #include "DirectC.
char *vc_MemoryString(vc_handle, U indx) This routine works like the vc_toString routine except that it is for passing values to from memory element instead of to a reg or bit. You enter an argument to specify the element (index) whose value you want the routine to pass.
} } The Verilog and C/C++ code display the following: Verilog code says "mem [0] Verilog code says "mem [1] Verilog code says "mem [2] Verilog code says "mem [3] Verilog code says "mem [4] Verilog code says "mem [5] Verilog code says "mem [6] Verilog code says "mem [7] C/C++ code says "mem [0] is C/C++ code says "mem [1] is C/C++ code says "mem [2] is C/C++ code says "mem [3] is C/C++ code says "mem [4] is C/C++ code says "mem [5] is C/C++ code says "mem [6] is C/C++ code says "mem [7] is = 111" = 111" =
memcheck_vec(mem); end endmodule The C/C++ function that calls vc_MemoryStringF is as follows: #include #include "DirectC.
void vc_FillWithScalar(vc_handle, scalar) This routine fills all the bits or a reg, bit, or memory with all 1, 0, x, or z values (you can choose only one of these four values). You specify the value with the scalar argument, which can be a variable of the scalar type. The scalar type is defined in the DirectC.
The following Verilog and C/C++ code shows how to use this routine to fill a reg and a memory these values: extern void filler (inout reg [7:0] r1, inout reg [7:0] array [1:0] r2, inout reg [7:0] array [1:0] r3); module top; reg [7:0] r1; reg [7:0] r2 [1:0]; reg [7:0] r3 [1:0]; initial begin $display("r1 is %0b",r1); $display("r2[0] is %0b",r2[0]); $display("r2[1] is %0b",r2[1]); $display("r3[0] is %0b",r3[0]); $display("r3[1] is %0b",r3[1]); filler(r1,r2,r3); $display("r1 is %0b",r1); $display("r2[0] is %0
The Verilog code displays the following: r1 is r2[0] r2[1] r3[0] r3[1] r1 is r2[0] r2[1] r3[0] r3[1] xxxxxxxx is xxxxxxxx is xxxxxxxx is xxxxxxxx is xxxxxxxx 11111111 is 0 is 0 is zzzzzzzz is zzzzzzzz char *vc_argInfo(vc_handle) Returns a string containing the information about the argument in the function call in your Verilog source code.
Verilog memories mem, mem2, and mem3 are all arguments to the function named show. If that function is defined as follows: #include #include "DirectC.h" void show(vc_handle h) { printf("%s\n", vc_argInfo(h)); /* notice \n after the string */ } This routine prints the following: input reg[0:31] array[0:7] input reg[0:31] array[0:15] input reg[0:63] array[0:31] int vc_Index(vc_handle, U, ...
int sum = 0; int i1, i2, i3, i4, indx; i1 = vc_getInteger(vh_indx1); i2 = vc_getInteger(vh_indx2); /* loop over all possible indices for that slice */ for (i3 = 0; i3 < vc_mdaSize(vh_array, 3); i3++) { for (i4 = 0; i4 < vc_mdaSize(vh_array, 4); i4++) { indx = vc_Index(vh_array, i1, i2, i3, i4); sum += vc_getMemoryInteger(vh_array, indx); } } return sum; } There are specialized, more efficient versions for two and three dimensional arrays. They are as follows.
• If the U type parameter has a value greater than 0, it returns the number of values in the index specified by the parameter. There is an error condition if this parameter is out of the range of indices. • If the vc_handle parameter is not an array, it returns 0.
Access Routine Description int vc_arraySize(vc_handle) Returns the number of elements in a memory. scalar vc_getScalar(vc_handle) Returns the value of a scalar reg or bit. void vc_putScalar(vc_handle, scalar) Passes the value of a scalar reg or bit to a vc_handle by reference. char vc_toChar(vc_handle) Returns the 0, 1, x, or z character. int vc_toInteger(vc_handle) Returns an int value for a vc_handle to a scalar bit or a vector bit of 32 bits or less.
Access Routine Description void vc_StringToVector(char *, vc_handle) Converts a C string (a pointer to a sequence of ASCII characters terminated with a null character) into a Verilog string (a vector with 8-bit groups representing characters). void vc_VectorToString(vc_hand le, char *) Converts a vector value to a string value. int vc_getInteger(vc_handle) Same as vc_toInteger.
Access Routine Description scalar vc_getMemoryScalar(vc_han dle, U indx) Returns the value of a one bit memory element. void vc_putMemoryScalar(vc_han dle, U indx, scalar) Passes a value, of type scalar, to a Verilog memory element. You specify the memory by vc_handle and the element by the indx parameter. int vc_getMemoryInteger(vc_ha ndle, U indx) Returns the integer equivalent of the data bits in a memory element whose bit-width is 32 bits or less.
Access Routine Description char *vc_MemoryStringF(vc_hand le, U indx, char) This routine works like the vc_MemoryString function except that you specify a radix with the third parameter. The valid radixes are ’b’, ’o’, ’d’, and ’x’. void vc_FillWithScalar(vc_hand le, scalar) This routine fills all the bits or a reg, bit, or memory with all 1, 0, x, or z values (you can choose only one of these four values).
There are suffixes that you can append to the +vc option to enable additional features. You can append all of them to the +vc option in any order. For example: +vc+abstract+allhdrs+list These suffixes specify the following: +abstract Specifies that you are using abstract access through vc_handles to the data structures for the Verilog arguments. When you include this suffix all functions use abstract access except those with "C" in their declaration; these exceptions use direct access.
function return_pointer function return_reg _____________________ [DirectC interface] _________ Mixing Direct And Abstract Access If you want some C/C++ functions to use direct access and others to use abstract access you can do so by using a combination of "A" or "C" entries for abstract or direct access in the declaration of the function and the use of the +abstract suffix.
• Include the -CC option as follows: -CC "-I$VCS_HOME/include" Useful Compile-Time Options VCS has other compile-time options that are not specially for DirectC but you might find them useful when enabling and calling C/C++ functions in your Verilog source code.
Environment Variables The following environment variables can be useful with DirectC. Bear in mind that command line options override environment variables. VCS_CC Specifies the C compiler for VCS, same as the -cc compile-time option. VCS_CPP Specifies the C++ compiler for the PLI and cmodule code compilation, same as the -cpp compile-time option. VCS_LD Specifies the linker.
extern_func_type ::= void | reg | bit | DirectC_primitive_type | bit_vector_type bit_vector_type ::= bit [ constant_expression : constant_expression ] list_of_extern_func_args ::= extern_func_arg ( , extern_func_arg ) * extern_func_arg ::= arg_direction ? arg_type optional_arg_name ? Note: Argument direction, i.e. input, output, inout applies to all arguments that follow it until the next direction occurs; default direction is input.
DirectC Interface 18-87
DirectC Interface 18-88
19 Using the VCS / SystemC Cosimulation Interface 1 The VCS / SystemC Cosimulation Interface enables VCS and the SystemC modeling environment to work together when simulating a system described in the Verilog and SystemC languages. VCS contains a built-in SystemC simulator that is compatible with OSCI SystemC 2.0.1 . By default, when you use the interface, VCS runs its own SystemC simulator. No setup is necessary. .
With the interface you can use the most appropriate modeling language for each part of the system, and verify the correctness of the design. For example, the VCS / SystemC Cosimulation Interface allows you to: • Use a SystemC module as a reference model for the Verilog RTL design under test in your testbench.
Notes: • There are examples of Verilog instantiated in SystemC and SystemC instantiated in Verilog in the $VCS_HOME/doc/ examples/osci_dki directory. • The interface supports the following compilers: - Linux: gnu 3.3.6 compiler - Solaris: SC 8.0, and gcc 3.3.6 (default) and 3.4.6 • The VCS / SystemC Cosimulation Interface supports 32-bit simulation 32-bit as well as 64-bit (VCs flag -full64) simulation. Do not use the -comp64 compile-time options with the interface.
• Using a Customized SystemC Installation Usage Scenario Overview The usage models for the VCS /SystemC Cosimulation Interface are: • Verilog designs containing SystemC modules • SystemC designs containing Verilog modules The major steps involved to create a simulation for each of these design scenarios are: 1. Analyze the SystemC and Verilog modules from the bottom of the design to the top. 2. For Verilog designs containing SystemC modules: - Use the syscan file.
Note: There are examples of Verilog instantiated in SystemC, and SystemC instantiated in Verilog, in the $VCS_HOME/doc/ examples/osci_dki directory. Supported Port Data Types SystemC types are restricted to the sc_clock, sc_bit, sc_bv, sc_logic, sc_lv, sc_int, sc_uint, sc_bigint, and sc_biguint data types. Native C/ C++ types are restricted to the uint, uchar, ushort, int, bool, short, char, long and ulong types. Verilog ports are restricted to bit, bit vector and signed bit vector types.
Verilog Design Containing SystemC Leaf Modules To cosimulate a Verilog design that contains SystemC and Verilog modules, you need to import one or more SystemC instances into the Verilog design. Using the VCS / SystemC Cosimulation Interface, you generate a wrapper and include it in the Verilog design for each SystemC instance. The ports of the created Verilog wrapper are connected to signals that are attached to the ports of the corresponding SystemC modules. Figure 19-1 illustrates VCS DKI communication.
Input Files Required To run a cosimulation with a Verilog design containing SystemC instances, you need to provide the following files: • SystemC source code - You can directly write the entity-under-test source code or generate it with other tools. - Any other C or C++ code for the design • Verilog source code (.v extensions) including: - A Verilog top-level simulation that instantiates the interface wrapper and other Verilog modules.
Generating the Wrapper for SystemC Modules You use the syscan utility to generate the wrapper and interface files for cosimulation. This utility creates the csrc directory in the current directory, just like VCS does when you include compile-time options for incremental compilation. The syscan utility writes the wrapper and interface files in subdirectories in the ./csrc directory. There is nothing you need to do to the files that syscan writes.
-cpp path_to_the_compiler Specifies the location of the C compiler. If you omit -cpp path_to_the_compiler, the environment finds the following compilers as defaults: -Linux : g++ -SunOS : CC (native Sun compiler) Note: -See the VCS Release Notes for more details on supported compiler versions. -You can override the default compilers in your environment by supplying a path to the g++ compiler. For example: -cpp /usr/bin/g++ -port port_mapping_file Specifies a port mapping file.
-o name The syscan utility uses the specified name instead of the module name as the name of the model. Do not enter this option when you have multiple modules on the command line. Doing so results in an error condition. -V Displays code generation and build details. Use this option if you are encountering errors or are interested in the flow that builds the design. -vcsi Prepares all SystemC interface models for simulation with VCSi.
Instantiating the Wrapper and Coding Style You instantiate the SystemC wrapper just like a Verilog module. For example, consider the following SystemC module in a file named stimulus.
initial begin counter = 0; end always @(output_data_ready) begin counter = counter + 1; $display("Display : %d", result); if (counter >= 24) begin $finish; end end endmodule You instantiate the SystemC model as follows in the Verilog part of the design: File: tb.v module testbench (); reg clock; wire reset; wire input_valid; wire [31:0] sample; wire output_data_ready; wire [31:0] result; // Stimulus is the SystemC model. stimulus stimulus1(.sample(sample), .input_valid(input_valid), .reset(reset), .
... end module Controlling Time Scale and Resolution in a SystemC Module Contained in a Verilog Design To control the time resolution of your SystemC module, create a static global object that initializes the timing requirements for the module. This can be a separate file that is included as one of the .cpp files for the design. Sample contents for this file are: include
Compiling a Verilog Design Containing SystemC Modules To compile your Verilog design, include the -sysc compile-time option. For example: vcs -sysc tb.v display.v When you compile with this option, VCS looks in the csrc directory for the subdirectories containing the interface and wrapper files needed to instantiate the SystemC design in the Verilog design. Using GNU Compilers on Sun Solaris On Solaris the default compiler is Sun Forte CC.
vcs -cc /usr/bin/gcc -cpp /usr/bin/g++ -sysc top.v dev.v Using GNU Compilers on Linux On Linux the default compiler is gcc. You can specify a different compiler with the -cpp and -cc compile-time options. The interface supports the gcc 3.3.6 compiler. SystemC Designs Containing Verilog Modules To cosimulate a SystemC design that contains Verilog modules, you import one or more Verilog instances into the SystemC design.
Figure 19-2 VCS DKI Communication of SystemC Design Containing Verilog Modules Managed by the tool DKI SystemC environment HDL simulator HDL source code entity-under-test Block 2 Block 3 rdy_read out HDL interface to the SystemC environment Block 1 clk reset in SystemC interface to the HDL simulator SystemC source code clk reset in Block 1 rdy_read Block 2 out Automatically generated by the tool Input Files Required To run cosimulation with a SystemC design containing Verilog modules, you need
• SystemC source code including: - A SystemC top-level simulation (sc_main) that instantiates the interface wrappers and other SystemC modules. - Any other SystemC source files for the design. • An optional port mapping file. If you do not provide this file, the interface uses the default port mapping definition. For details of the port mapping file, see “Using a Port Mapping File” on page 19-26. • An optional data type mapping file.
The syntax for the vlogan command line is as follows: vlogan -sc_model modulename file.v [-cpp path_to_the_compiler] [-sc_portmap port_mapping_file] [-Mdir=directory_path] [-V] Here: -sc_model modulename file.v Specifies the module name and its Verilog source file. -cpp path_to_the_compiler Specifies the location of the C compiler.
-Mdir=directory_path Works the same way that the -Mdir VCS compile-time option works. If you are using the -Mdir option with VCS, you should use the -Mdir option with vlogan to redirect the vlogan output to the same location that VCS uses. -V Displays code generation and build details. Use this option if you are encountering errors or are interested in the flow that builds the design. To generate the wrapper and interface files for a Verilog module named adder, in a Verilog source file named adder.
The module name is adder. You instantiate it in your SystemC code in main.cpp as follows: #include #include "adder.h" int sc_main(int argc, char *argv[]){ sc_clock clock ("CLK", 20, .5, 0.0); sc_signal > value1; sc_signal > value2; sc_signal > result; // Verilog adder module adder adder1("adder1"); adder1.value1(value1); adder1.value2(value2); adder1.result(result); sc_start(clock, -1); } One of the generated files is modulename.
In this example, dev.v might contain Verilog code utilized by the adder.v module above. When you compile with this option, VCS looks in the ./csrc directory for the subdirectories containing the interface and wrapper files needed to connect the Verilog and SystemC parts of the design. Elaborating the Design When SystemC is at the top of the design hierarchy and you instantiate Verilog code in the SystemC code, the elaboration of the simulation is done in the following two steps: 1.
extern "C" bool hdl_elaboration_only() Both will be set/yield true only during this extra execution of simv during step 1. For example, guard statements like this: module constructor: if (! hdl_elaboration_only()) { ... open log file for coverage data ... } module destructor: if (! hdl_elaboration_only()) { ... close log file for covergae data ...
Example Aassume that you want to instatiate the following SystemVerilog module inside a SystemC module: module vlog_top; export "DPI" task task1; import "DPI" context task task2(input int A); export "DPI" function function3; task task1(int n); ... endtask function int function3(int m); ... endfunction // int endmodule You must do the folloing steps before you can elaborate the simulation syscan -export_DPI task1 syscan -export_DPI function3 ... syscsim ...
fprintf(stderr,"Error: stub for my_export_DPI is used\n"); exit(1); } ... more stubs for other export DPI function ... gcc -c my_DPI_stubs.c ar r my_DPI_stubs.a my_DPI_stubs.o ... syscsim ... my_DPI_stubs.a ... It is important to use an archive (file extension .a ) and not an object file (file extension .o). Specifying Runtime Options to the SystemC Simulation You start a simulation with the simv command line.
Using GNU Compilers on SUN Solaris On Solaris the default compiler is Sun Forte CC. You can specify a different compiler with -cpp and -cc compile-time options. The interface supports the gcc 3.3.6 compiler. If you use the -cpp g++ option on the interface analysis command line, you must also use it on every command line that compiles C++ source: vlogan -cpp g++ display.v -sc_model display syscsim -cpp g++ -sysc main.cpp a.
Using a Port Mapping File You can provide an optional port mapping file for the syscan command with the -port option, and for vlogan by using -sc_portmap. If you specify a port mapping file, any module port that is not listed in the port mapping file is assigned the default type mapping. A SystemC port has a corresponding Verilog port in the wrapper for instantiation. The syscan utility uses the entry for the port in the port mapping file. A port mapping file is an ASCII text file.
The following example shows a port mapping file. Example 19-1 # Port Mapping File Port name in1 in2 clock out1 out2 Bits 8 8 1 8 8 Verilog type signed bit_vector bit bit_vector bit_vector SystemC type sc_int sc_lv sc_clock sc_uint sc_uint SystemC types are restricted to the sc_clock, sc_bit, sc_bv, sc_logic, sc_lv, sc_int, sc_uint, sc_bigint, and sc_biguint data types. Native C/C++ types are restricted to the bool, char, uchar, short, ushort, int, uint, long, and ulong data types.
The data type mapping file is named cosim_defaults.map. The interface looks for and reads the data mapping file in the following places and in the following order: 1. In $VCS_HOME/include/cosim 2. In your $HOME/.synopsys_ccss directory 3. In the current directory. An entry in a later file overrules an entry in an earlier file. Each entry for a SystemC type has the following: 1. It begins with the keyword Verilog. 2. It is followed by the bit width.
Verilog Verilog Verilog Verilog Verilog Verilog * * * * * * bit_vector bit_vector bit_vector bit_vector bit_vector bit_vector uchar short ushort uint long ulong Debugging the SystemC Portion of a Design To debug just the SystemC code in the mixed simulation, do the following: 1. Run syscan with the -cflags "-g" option to build the SystemC source code for debugging. 2. Start the C++ debugger on the simv executable file as follows: - If you are using the Sun Forte compiler: dbx .
vcs -sysc -R -o simv top.v If you instantiate Verilog code in SystemC: syscsim -R -o simv dev.v Debugging Both the Verilog and SystemC Portions of a Design To debug both the SystemC and Verilog portions of your design: 1. Run syscan with the -cflags "-g" option to build the SystemC source code for debugging. 2. Include the -debug_all compile-time options on the vcs or syscsim command line to compile the Verilog part of the design for post-processing debug tools and for Verilog source code debugging.
% ps -e | grep simv 12216 pts/1 0:00 simv 5. You then can launch your debugger as outlined above, but provide the process ID from the ps command as the third argument to the debugger: % gdb ./simv 12216 Transaction Level Interface The transaction level interface (TLI) between SystemVerilog and SystemC supports communication between these languages at the transaction level. At RTL, all communication goes through signals. At transaction level, communication goes through function or task calls.
the other part at the hardware level and have full control over the level of detail required for your simulation runs. This integration also helps you to leverage the powerful features of SystemVerilog for transaction-level verification and you can use the same testbenches for hardware verification. TLI enables you to do the following: • Call interface methods of SystemC interfaces from SystemVerilog • Call tasks or functions of SystemVerilog interfaces from SystemC.
Interface Definition File The interface definition file contains all the necessary information to generate the TLI adapters. It consists of a general section and a section specific to task/function. The order of lines within the general section is arbitrary, and the first occurrence of a task or function keyword marks the end of this section.
The direction field specifies the caller and callee language domains, and defaults to sv_calls_sc. The SystemC calling SystemVerilog direction is indicated by sc_calls_sv. The verilog_adapter and systemc_adapter fields are optional and define the names of the generated TLI adapters and the corresponding file names. File extension .sv is used for the verilog_adapter and file extensions .h and .cpp for the systemc_adapter.
The return keyword is only allowed once for each task. It becomes an output argument on the Verilog side to a return value on the SystemC side. This feature is required because blocking functions in SystemC may return values, while Verilog tasks do not have a return value. There is one special case here. If the methods of the SystemC interface class use reference parameters, for example my_method(int& par), then you need to mark this parameter as inout& parameter in the interface definition file.
Generation of the TLI Adapters The following command generates SystemVerilog and SystemC source code for the TLI adapters from the specified interface definition file: syscan -tli_gen interface_definition_file or syscan -tli_gen_class interface_definition_file The command generates SystemC and SystemVerilog files that define the TLI adapters for each language domain. All generated files can be compiled just like any other source file for the corresponding domain.
Transaction Debug Output Since the transaction information traveling back and forth between SystemVerilog and SystemC along with the transaction timing is often crucial information (for example, comparison of ref-model and design for debugging and so on), the SystemC part of the TLI adapters are generated with additional debugging output that can be enabled or disabled, See “Instantiation and Binding” on page 19-38.
Note: Do not manually modify the code generated by the TLI adapter. Instead, override the debug functions in a derived class. Instantiation and Binding TLI adapters must always be instantiated in pairs, where each pair forms a point-to-point connection from one language domain to the other. If multiple pairs of the same TLI adapter type are needed in the design, you must instantiate the adapter multiple times in each domain.
format of debug information that the adapter prints when an interface method is called. If the LSB of this argument is set, the TLI adapter prints messages to stdout. If the next bit (LSB+1) is set, this information is written to an sc_signal string that you can display in DVE. For SystemC calling SystemVerilog, the SystemC part of the TLI adapter is an sc_module that you can instantiate within the module where you want to call the Verilog tasks or functions.
The Verilog adapter is a group of task definitions and other statements that must be included in a program with an `include "if_name_sc_calls_sv.sv" statement. Calls initiated by the SystemC side are routed through the XMR path to some class object of the SV testbench. • combination -tli_gen_class, no hdl-path: This combination is not supported and displays an error message.
SystemVerilog inout input inout input inout input inout input inout input inout input inout | output | output | output | output | output | output | output longint real real shortreal shortreal chandle chandle string string bit bit logic logic SystemC long long* double double* float float* void* void** char* char** unsigned char unsigned char* unsigned char unsigned char* For the integral data types in the above table, the signed and unsigned qualifiers are allowed and map to the equivalent C unsigned da
Miscellaneous The TLI generator uses Perl5 which needs to be installed on the local host machine. Perl5 is picked up in the following order from your installation paths (1=highest priority): 1. use ${SYSCAN_PERL}, if (defined) 2. /usr/local/bin/perl5 3. perl5 from local path and print warning Using the Built-in SystemC Simulator VCS contains a built-in SystemC 2.0.1 which it uses by default.
Using a Customized SystemC Installation You can install the OSCI SystemC simulator and instruct VCS to use it for Verilog/SystemC cosimulation. To do so you need to: • Obtain OSCI SystemC version from www.systemc.org • Set the SYSTEMC environment variable to the OSCI SystemC installation path, as shown below: % setenv SYSTEMC /net/user/download/systemc-2.0.1 • Replace following SystemC files $SYSTEMC/src/systemc/kernel/sc_simcontext.cpp $SYSTEMC/src/systemc/kernel/sc_simcontext.
• Set the SYSTEMC_OVERRIDE environment variable to the user defined OSCI SystemC library installation path, as shown below: % setenv SYSTEMC_OVERRIDE /net/user/systemc-2.0.1 • Header files must exist in the $SYSTEMC_OVERRIDE/include directory and the library file libsystemc.a in $SYSTEMC_OVERRIDE/lib-linux/, and the $SYSTEMC_OVERRIDE/lib-gccsparcos5/ directories. Note: - VcsSystemC 2.0.1 is binary compatible with OSCI SystemC 2.0.1. - VcsSystemC 2.1 is binary compatible with OSCI SystemC 2.
If you use the option -sysc=, you must use it consistently during both analysis and compilation. Any mismatch in the version displays the error message: Error: Mixing different SystemC versions is not allowed. Either add or omit argument -sysc= to all calls of vlogan, vhdlan, syscan, and vcs where you use SystemC. Please note, this option is not a replacement for -sc_model. Compiling Source Files If you need to compile the source files, which include systemc.
Using the VCS / SystemC Cosimulation Interface 19-46
20 Using OpenVera Assertions 1 This chapter introduces the OpenVera Assertions (OVA) language and explains how to compile and run OVA within VCS.
• Using Verilog Parameters in OVA Bind Statements • OVA System Tasks and Functions For a detailed decsription of OpenVera Assertions, see the OpenVera Assertions Language Reference Manual. Introducing OVA OVA is a clear, easy way to describe sequences of events and facilities to test for their occurrence. With clear definitions and less code, testbench design is faster and easier, and you can be confident that you are testing the right sequences in the right way.
OVA performs the following tasks: • Tests Verilog, VHDL, and mixed-HDL designs using VCS and VCS MX. • Automatically tests and reports results on all defined sequences. You just write the definitions. • Produces results that can be viewed with DVE. • Can be monitored and controlled as part of a Vera testbench. VCS also has functional coverage that provides you with code coverage information about your OVA code.
How Sequences Are Tested Using the assert Directive Testing starts with a temporal assertion file, which contains the descriptions of the sequences and instructions for how they should be tested. OVA is designed to resemble Verilog with similar data types, operators, and lexical conventions. A typical temporal assertion file consists mostly of temporal expressions in OVA units. These temporal expressions are the descriptions of the event sequences. Events are values or changes in value of any OVA signal.
Example 20-1 Temporal Assertion File, cnt.ova /* Define a unit with expressions and assertions (or select one from the Checker Library).
Figure 20-1 Assertion Attempts for cnt.ova posedge m_clk outp 1 2 06 3 04 4 08 5 04 6 06 7 09 8 03 9 0d 10 0e 11 04 12 06 13 09 14 06 c_normal_s Important: Synopsys recommends always specifying a clock signal for an assertion. An assertion without a clock is called a simtime assertion. VCS checks simtime assertions with a default clock that is the equivalent to the smallest time precision in the design and this significantly impedes simulation performance.
You can also increment a second counter using the compile-time option ova_enable_dialog. In this case, the first counter is the same as the default counter, and the second counter reports the number of total matches of the event expression. OVA Flow OVA uses the following flow: 1. Create a temporal assertion or cover file. See the OpenVera Assertions Language Reference Manual ($VCS_HOME/doc/ UserGuide/ova_lrm.pdf). Start with simple temporal expressions and then combine them to form complex sequences.
Checking OVA Code With the Linter Option The linter option adds predefined rules. Rule violations other than syntax / semantic errors are not errors in the strict sense of the word, but are warnings of potential performance issues or differences in intended and real semantics of the OVA expressions.
If used without any Verilog design file, only the OVA files are analyzed (including bind statements), and potential problems are reported. The command is: vcs ova_files_list -ova_lint If used with Verilog and OVA files (or inlined OVA), the compilation proceeds normally while detailed linting analysis is also done. If no fatal error is found, the simulation can go ahead and any recommendations from the linter can be incorporated for later runs.
Whenever "a" is false, event "e1" will match because the "if - then" implication is satisfied. This means that "e2" will also trigger and try to match on "c" at the next clock tick. This may not be, however, what is intended.
Consider rephrasing the expression using for instance a disjunction, e.g., if m is 0 then (a*[1..n] #k b) || (#(k-1) b); GR8: WARNING "matched" used in the same clock domain (one clock tick delay) Example: clock posedge clk { event e1: ... ; event e2: if matched e1 then ... ; } The successful match on "e1" would only be detected in "e2" at the subsequent posedge of "clk". Consider changing "e2" as follows: event e2: if ended e1 then ...
posedge a ? 10'd1 : cnt > 10'd1000 ? cnt : cnt = cnt + 10'd1; event e1: if posedge a then ((cnt <= 11'd1000) && a) * [1..] #1 b; } Alternately, if overlaps are possible consider using time stamps stored in a queue (see for instance the OVA standard checker unit "ova_req_ack_unique"). GR14: RECOMMENDATION top-level conjunctions over events in "check" assertions. Example: clock posedge clk { event e1: ...; ... event eN: ...; event e: if a then e1 && e2 && e3 && ...
GR17: RECOMMENDATION for loop over events / assertions with large (>20) ranges with loop index appearing in delay or repetition operators. Consider using variables and / or compacting into a single event. For an example see the OVA standard checker "ova_req_ack_unique". It contains two versions of a checker, version 0 that is suitable for small ranges of parameters, and version 1 that uses a time stamp and a queue when the loop ranges become large (thus creating too many events / assertions).
GR27: WARNING assert check over a non-bool sequence that does not start with an "if". Example: event e: a #1 b; assert c: check(e); The assertion will fail any time "a" is false.
GR32: WARNING the unit instance name in a bind statement is missing. The problem is that an automatically generated name is inserted by the compiler which makes it more difficult for the user to locate the checker instance. GR34: WARNING multiplication *N (by a constant) is the last operator on an expression - consider changing to repetition *[N]. Example: event e: a #[1..] b*3; Often [] is omitted by accident from the repetition operation. Consider changing the expression to event e: a #[1..
The problem is that any evaluation attempt that matches on "a" will remain active till the end of simulation, waiting for (yet another) occurrence of "b". Most likely this is not intended. Consider rewriting "e1" to terminate on the first match of "b" as follows: event e1: a #1 (!b)*[0..] #1 b; Applying Magellan Rules for Formal Verification This section describes use of Magellan Rules (MR) for checking OVA code to be used with formal verification tools such as Magellan.
This type of an assertion cannot be used effectively as an assumption in Magellan because it requires constraining the signals driving the OVA variable "tmp" in the past clock tick. This is not possible when doing random simulation constrained by OVA assertions. The result is that no constraint is imposed.
Try to rewrite event "e2" without the use of "matched". In the case of our simple example, the solution is simple due to the one cycle delay introduced by "matched": clock posedge clk { // event e1: c #1 d; -- do not use event e2: if a then c #1 d; } assert c: check(e2); In general the transformation may not be as simple as in the above example. It may be preferable to approach the problem differently right from the start rather than trying to rewrite the case later.
Compiling Temporal Assertions Files Temporal assertions files are compiled concurrently with Verilog source files. You can use a set of OVA-specific compile-time options to control how VCS compiles the temporal assertions files. Note: When you use the OVA compile-time options, VCS creates a Verification Database directory in your current directory (by default named simv.vdb). VCS writes intermediate files and reports about OpenVera Assertions in subdirectories in this directory.
-ova_dir pathname Specifies an alternative name and location for the Verification Database directory. There is no need to specify the name and location of the new Verification Database directory at runtime. The simv executable contains this information. If you move or rename this directory after you create the simv executable, you include this option at runtime to tell VCS its new name or location. -ova_file filename Identifies filename as an assertion file. Not required if the file name ends with .ova.
For example it can be: top.\gen_2.aova2 .cover_temp_no_vacuous_f_eq_t, 4 total match, 4 first match -ova_inline Enables compiling of OVA code that is written inline with a Verilog design. Note: You can also use the VCS -f option to specify a file containing a list of all absolute pathnames for Verilog source files and compile-time option. You can pass all OVA compile-time options through this file, except -ova_debug.
-ova_report [filename] Generates a report file in addition to printing results on your screen. Specifying the full path name of the report file overrides the default report name and location, which is ./simv.vdb/report/ ova.report. -ova_verbose Adds more information to the end of the report including assertions that never triggered and attempts that did not finish, and a summary with the number of assertions present, attempted, and failed.
-ova_simend_max_fail N Terminates the simulation if the number of failures for any assertion reaches N. N must be supplied, otherwise no limit is set. -ova_success Enables reporting of successful assertion matches in addition to failures. The default is to report only failures. For a cover statement, triggers the match (success) message in the following format: Ova [i][j]: ".
Functional Code Coverage Options Functional coverage is code coverage for your OVA code. With functional coverage enabled, the cover statement is treated in the same manner as an assert statement. The runtime options are enabled by the -ova_cov compile-time option. These runtime options are as follows: -ova_cov Enables functional coverage reporting. -ova_cov_name filename Specifies the file name or the full path name of the functional coverage report file.
• Post-process a compiled design several times with different temporal assertions files each time. You can observe the effects of different assertion scenarios and collect several distinct sets of functional coverage data. • Develop assertions incrementally over a series of post-processing runs, improving and augmenting the assertions in the process. OVAPP Flow The following steps show a typical flow for post-processing a compiled VCS design with temporal assertions. 1.
Building and Running a Post-Processor The procedure to build and run a post-processor is as follows: 1. Include either of the following in your Verilog code: - The $vcdpluson system task to tell VCS to write a VPD file during simulation. Note: Use the -PP compile-time option to write the VPD files as described in the following step. - The $dumpvars system task to tell VCS to write a VCD file during simulation.
-ova_PP Tells VCS to record in the verification database directory design information that is used by the post-processor. By default VCS also creates the simv.vdb directory in the current directory when you include this option. We call this directory the verification database directory. VCS writes post-processing data in a subdirectory in the verification database directory -PP Optional compile-time option that enables VCS to write a VPD file.
During simulation VCS writes the VPD file. 4. The next step is to build the post-processor from the post-processing data and one or more temporal assertions files. You specify building the post-processor and the temporal assertions file with the -ova_RPP compile-time option. For example: vcs -ova_RPP filename.ova...[-o simv_name] [-ova_dir directory_path] [-ova_cov] In this example compilation command line: -ova_RPP Tells VCS to compile the post-processing engine.
-vdb_lib directory_path Specifies an alternative location for the VDB that VCS searches for data generated during a prior step. VCS first searches the directory specified by the -ova_dir option, then the directory specified by this option. If it does not find this information in either directory, the compilation fails. If you include this option without the -ova_dir option, VCS searches the directory specified by this option, then the simv.vdb directory in the current directory.
-vcd filename.vcd Specifies the VCD file. The post-processor will call the vcd2vpd utility to translate it to a VPD file name vcdplus.vpd. If the VCD file is named verilog.dump and it is in the current directory (if the current directory doesn’t contain a file named vcdplus.vpd). You can omit this option and the post-processor will use the verilog.dump file. -cli Specifies that post-processing starts with a command line prompt for entering CLI commands.
-o simv_name Specifies the executable name so the post-processor knows the name and location of the post-processing engine and the verification database directory. If you used the -o compile-time option when you built the post-processor, you need to enter it again on this command line so that the post-processor will know the name and location of the dynamic library.
Enables the tracing of the specified assertion in the specified instance, at the specified simulation time. ova_trace_on assertion_hierarchical_name Enables tracing of the specified assertion name the next time. Using Multiple Post-Processing Sessions You can repeatedly run the post-processor using different input (either different temporal assertion files or different waveforms). This section describes how to use the -ova_name option to generate a unique report for each session.
In this section, reference will be made to the following four-step post-process flow: 1. Capture waveforms from a simulation of the base design. 2. Compile the base design for post-processing (vcs -ova_PP). 3. Compile the OVA checkers against the base design (vcs -ova_RPP). 4. Replay the captured waveforms against the compiled checkers (ovapp). Note that step 1 could also be run after step 2 using the executable generated as part of the compilation of the base design.
Note: In this discussion, the vdb directory derived from the basename given with the -o option will be referred to as simv.vdb for simplicity. The other directory is a read-only directory that you can specify with the -vdb_lib option. This directory is used as the source for files generated by the previous step, but the files are not located in the simv.vdb directory (as specified by the -o option). If no -vdb_lib option is given, all intermediate files are expected to be found in the simv.
As you can see, in step1, we pass simv1 as the basename for the intermediate output files. In step 2, we pass the vdb directory created as a result of step1 as the argument of the -vdb_lib option and give VCS a second basename, simv2, for the new intermediate file directory. When VCS tries to locate a file in the simv2.vdb directory (during step 2) and cannot find the file, it next checks the directory specified by the -vdb_lib option.
This dump file must contain, as a minimum, any signal referenced by the OVA checkers to be post-processed. The signals used by the OVA checkers must be included in a $dumpvars or $vcdpluson dumped scope (an instance specified in one of these system tasks) in order to be visible by the post-process checkers. Automated dumping of OVA signals is not supported. The runtime option -vcd filename can be used to name the VCD file if there is a $dumpvars system task in the design.
Note that OVAPP internally requires a VPD file. Therefore, if you pass a VCD file to OVAPP, it calls the vcd2vpd converter prior to the post-processing run. This means that using VPD files to capture the waveforms to be replayed will result in better overall performance. Dumping Signals Automatically If you include the OVA checkers to the compilation step before the waveform replay dump is generated, these signals will be included in the dump automatically.
Incremental Compile The step 2 OVA engine compile (-ova_RPP) uses incremental compile in order to speed up the compilation process for multiple runs. Incremental compile generates intermediate files in a directory named csrc by default. If you enable the incremental compile feature in the step1 compile, it is possible for the csrc intermediate files to be corrupted.
Reporting By default, the assertion report generated by the OVA engine is written into ./simv.vdb/report/ova.report. In the case of multiple post-processing runs, there is a chance the file will be overwritten. For each run, it is suggested that the -ova_report name.report and -ova_name name options be used to ensure that any report files generated will be stored under unique names.
Things to watch out for • If you pass path/name (a full path) to -ova_cov_report, fcovReport does not automatically create the directories in path. If the path does not exist, the report is not created and no error message is generated. • The -ova_inline compile-time option should not be included with the -ova_PP compile-time option. If both options are present on the same command line, and inlined OVA references to checker library elements are included in the design, an error message will result.
Viewing Output Results The two main ways of viewing the results of a simulation involving OVA are: • Viewing Results in a Report File • Viewing Results with Functional Coverage Viewing Results in a Report File A report file is created when the -ova_report runtime option is used. The report file name is ova.report unless you specified a different name in the run command. This default ova.report file is stored in directory simv.vdb/report, where the .
Assertion attempts generate messages with the following format: File and line with the assertion Severity Full hierarchical name of the assertion Start time Status (succeeded at ..., failed at ..., not finished) Ova [0]: "cnt.ova", 10: cnt.dut.c_normal_s: started at 5ns failed at 9ns, "Wrong result sequence.
• Had successes • Had failures Coverage is broken down by module and instance, showing the number of attempts, failures, and successes for each assertion and expression. Because if-then constructs register a success anytime the if portion is false (and so the then portion is not checked), the report also shows the number of real successes in which the whole expression matched. This works with nested if statements too.
Assertion and Event Summary Report Since no changes are introduced to the data collection process when generating functional coverage reports, you can produce different reports from a simulation. One report could show all assertions and events; another report could show assertions filtered by category and severity. The assertion and event summary report generates four html files: • The report.index.
• The category.html file is generated when -ova_cov_category and/or -ova_cov_severity are used to filter results. Tables display functional coverage results for assertions showing the assertions having the category and severity specified along with number of attempts, successes, failures and incompletes. To generate the assertion and event summary report, run the fcovReport command after compilation and simulation: fcovReport [-ova_cov_severity value,...] [-ova_cov_category value,...
-ova_cov_cover Specifies reporting of cover directive information only. -ova_cov_db path Specifies the path of the template database. If this option is not included, fcovReport uses simv.vdb. -ova_cov_events Specifies reporting only about OVA events. -ova_cov_grade_instances target,metric [, time_limit] Generates an additional report, grade.html, that lists the minimum set of tests that add up to the target value for the metric (see previous page for metric codes). The grading is by instance.
-ova_cov_merge filename Specifies the path name of a functional coverage result file or directory to be included in the report. If filename is a directory, all coverage result files under that directory are merged. Repeat this option for any result file or directory to be merged into this report. If this option is not used, fcovReport merges all the result files in the directory of the template database (specified with -ova_cov_db or simv.vdb/fcov by default).
Using OVA with Third Party Simulators Synopsys has developed OVAsim, a PLI application that enables you to run non-Synopsys simulators using OVA (OVA). With OVAsim, you can create a powerful system of assertion-based checkers. Because the checkers are compiled independently of a specific simulator, they can be used with any major simulator, packaged with IP designs, and shipped to any customer.
Inlined OVA is enabled in VCS by the -ova_inline command line switch. Specifying Pragmas in Verilog Inlined OVA is specified in Verilog code using pragmas. Several different forms are accepted, including C and C++ style comments, and modified C++ multi-line comments. The general C++ style form is as follows: /* ova first_part_of_pragma ... last_part_of_pragma */ You can also use the following modified C++ approach: //ova_begin // pragma_statement //...
Methods for Inlining OVA There are four basic methods you can use to inline OVA within Verilog: • Unit Instantiation Using the Unit-based Checker Library (recommended for using Synopsys-developed OVA checkers) • Context-Independent Full Custom OVA (uses custom-developed OVA code that resides in a Verilog file) • Template Instantiation Using the Template-Based Checker Library • Context-Dependent Full Custom OVA These methods are described in detail throughout this section.
Figure 20-2 Methods for Inlining OVA within Verilog Method #1 — Unit-based Instantiation Verilog File (.v) module OVA Checker Library endmodule OVA code calls unit-based checkers from Checker Library Unit-based Checkers Template-based Checkers Method #2 — Context Independent Full Custom OVA Verilog File (.v) module endmodule Bind statement instantiates custom OVA code Method #3 — Template Instantiation Verilog File (.v) Method #4 — Context Dependent Full Custom OVA Verilog File (.
Unit Instantiation Using the Unit-Based Checker Library The easiest and most efficient method to inline OVA is to instantiate a unit-based checker from the OVA Checker Library (For more information on the Checker Library, see the OpenVera Assertions Checker Library Reference Manual). The context of the checker is automatically inferred based upon the location of the OVA pragma statement within a module of Verilog code.
Note: In all syntax styles, you can also split a pragma statement into separate lines as follows: //ova //ova //ova //ova bind unit_name [instance_name] [#(parameter1, ..., parameterN)] [(port1, ..., portN)]; The following example shows how to instantiate a checker, called ova_one_hot, from the OVA Checker Library: module test(); Uses a single-line, C style pragma to instantiate the reg [3:0] x; ova_mutex checker from the Checker Library, and wire clk; checks for mutual exclusive of a and b.
Instantiating Context-Independent Full Custom OVA You can inline OVA within Verilog by instantiating independent custom OVA code located in the Verilog file but outside a Verilog module definition. The unit definition associated with the code must be specified outside a Verilog module.
module test(); reg [3:0] x; Binding from inside a module wire clk; wire a,b; // ova bind my_mutex(clk,{a,b}); wire error; // verilog code endmodule // module test /* ova unit error_check (logic clk, logic error); clock posedge clk { event e1 : error == 1; Binding from outside a module } assert a1 : forbid(e1); endunit bind module test : error_check(clk,error) ; unit my_mutex (logic clk, logic [1:0] x); clock posedge clk { event e1 : x != 2'b11; } assert a1 : check(e1); endunit */ Two units are defined: err
Template Instantiation Using the Template-Based Checker Library You can instantiate any template-based checker from the Checker Library in your Verilog code. The context of the checker is automatically inferred based on the location of the call from within Verilog.
• You cannot mix a template instantiation and unit instantiation within the same OVA pragma using the multi-line C++ and modified C++ pragma specification formats. You can, however, specify a template instantiation and a unit instantiation using separate single-line C pragmas.
Inlining Context-Dependent Full Custom OVA You can directly inline any custom OVA code, except for the unit definition, within a Verilog module. In this case, the unit and binding definitions are implicit. The following example demonstrates this method: module test(); reg clk; wire a,b; // other verilog code // ova_begin // clock posedge clk { Uses modified C++ style pragma to // event e1 : a #1 b; specify custom OVA code that defines // } event e1 and assertion a1.
Case Checking You can perform two types of case checking when using inlined OVA: • Parallel — The actual case selection value must select exactly one of the specified cases in the statement. • Full — The actual case selection value must fall into the range specified by the case items. A case containing the default item is by definition full.
If the off argument is specified, full case checking is disabled unless overridden by another command or a pragma associated with a case statement. When the pragma is not specified, the default is off. The following rules govern parallel and full case commands: • The commands must precede any module instance and any case statement in the module. • If such a command is not provided, the default from the parent module is taken. (It can be by default off.
The parallel_case and full_case statements enable their own type of case check on the associated case statement and disable the other type unless both are present. The no_case statement disables any case checking on that case statement. The following rules govern assertion pragmas: • These assertions verify the correct operation of case statements. They are triggered any time the case statement is executed. That is, no sampling of signals by a clock takes effect.
General Inlined OVA Coding Guidelines Note the following guidelines when coding inlined OVA: • Since OVA pragmas are declarative in nature, they do not need to placed within procedural code, for example, within tasks, functions, and always/initial/forever blocks. • Cross-module References (XMRs) are not allowed to concurrently reside within a custom OVA description. • Template instantiation will be treated as an OVA description (the XMR restriction also applies).
Using Verilog Parameters in OVA Bind Statements This section describes the enhancement to VCS that allows Verilog parameters to be used in temporal context in OVA bind statements. This enhancement is under an optional switch. At this time, use of Verilog parameters is limited to inline bind statements, but simple workarounds exist to allow binding of non-inline OVA while still allowing full use of Verilog parameters.
The enhancement described in this document will cause the Verilog parameters to be expanded at the time the inlined OVA is processed by the OVA extractor, since the OVA binds and the design hierarchy are both available at that time. This implies that Verilog parameters can only be used in temporal context if the parameter was first expanded during the inlining phase.
For example, the following binds would not be legal if count and delay were used by the bound unit in temporal context: /* ova bind module ova bind module */ // ova_begin ova bind module ova bind module // ova_end foo : unitA u1 #( count ) ( ... ); bar : unitB u2 #( delay ) ( ... ); foo : unitA u1 #( count ) ( ... ); bar : unitB u2 #( delay ) ( ... ); The parameter names are resolved in the context of the module to which the unit is bound.
Recommended Methodology To make use of Verilog parameters in temporal context, the binds that use such parameters must follow the inlined OVA flow. For OVA binds which are already inlined into the RTL, no additional work is required. It is not necessary, however, that the bind statements be inserted directly into the RTL source. Rather, a separate file (such as dummy.v) could be created to hold all the binds in the design that come from separate (non-inlined) OVA files. Giving this file a ".
• The -ova_exp_param option is not enabled. • Any modules to which units using Verilog parameters are bound occur only once in the design • Multiple instances of any modules to which units using Verilog parameters are bound use the same value for each parameter across all instances.
The first step generates a skeleton Verilog file containing the hierarchy of the design and the nets converted to registers (for playback). It also preserves the Verilog parameters. This skeleton Verilog file must be compiled in the second step before the playback can occur. It is this compilation step that we will exploit to allow Verilog parameters to be used in the post-processing flow. The change to the flow involves the same dummy Verilog file that was discussed in the sections above.
Setting and Retrieving Category and Severity Attributes You can use the following system tasks to set the category and severity attributes of assertions: $ova_set_severity("assertion_full_hier_name", severity) Sets the severity level attributes of an assertion. The severity level is an unsigned integer from 0 to 255. $ova_set_category("assertion_full_hier_name", category) Sets the category level attributes of an assertion. The category level is an unsigned integer from 0 to 224 - 1.
Starting and Stopping the Monitoring of Assertions There are several methods you can use to start and stop the monitoring of assertions: • Global Monitoring — Starts or stops assertions based upon their hierarchical location level at or below specified modules, entities, or scopes (note that these tasks overwrite any other tasks that control monitoring). • Category-Based Monitoring — Starts or stops assertions based upon their category specifications.
Within OVA and Verilog code, arguments can be specified for one or more module names as quoted text strings (e.g.,"module_name") and/or instance scopes as Verilog scope names (unquoted), separated by commas. Scope resolution follows the Verilog Standard (IEEE Std 1364-2001) Section 12.5. That is, if a scope argument is specified, then the path name is first considered as relative to the module where the task was called. If it does not match any valid relative path, it is matched against paths one level up.
Arguments can be specified for one or more modules, entities, and instance scopes as in the case of $ova_start. The effect of a module or entity argument is to stop monitoring assertions for all instances of the module and their respective hierarchies under each instance as indicated by levels. The effect of a scope argument is to stop monitoring assertions for that instance scope and the hierarchy under it as indicated by levels.
$ova_start(1, "mod1") // Start assertions in all // instances of module mod1 at that level only. $ova_stop(0, i1.mod1) // Stop assertions in all of // the hierarchy at and below scope i1.mod1. $ova_stop(3, i1.mod1) // Stop assertions in the hierarchy // started at scope i1.
$ova_assertion_start("fullHierName") Starts the monitoring of the specified assetion (string). Controlling the Response To an Assertion Failure You can specify a response to an assertion failure, based upon its severity or category, using the $ova_severity_action or $ova_category_action system tasks.
- "continue" — Outputs the message associated with the assertion failure but otherwise has no effect on the simulation. Display Custom Message For an Assertion Failure You can display a custom message upon failure of an assert statement check or forbid.
The evaluation of the uses the sampled values of the variables as in the assertion. $ova_current_time Returns current simulation time as a 64-bit entity. (Same as type "time" in Verilog.) $ova_start_time Returns assertion start time as a 64-bit entity. (Same as type "time" in Verilog.) $ova_global_time_unit Returns global time unit as a string. (The definition of a string is the same as in Verilog.
Note that you can specify all OVA system tasks and functions described in this chapter ($ova_set_severity, $ova_set_category, etc.) at the CLI using the documented syntax. Debug Control Tasks When dumping of OVA assertion results for viewing using DVE is enabled using the -ova_debug or -ova_debug_vpd options, the debug information is dumped for all enabled OVA assertions (enabled using $ova_start or by default from time 0 if not stopped by $ova_stop).
Calls From Within Code The $ova_start, $ova_stop, and $ova_severity_action system tasks are provided to control the monitoring of assertions, such as delaying the start of assertion monitoring and terminating the monitoring based on some conditions. For example, you can start monitoring after some initial condition, such as reset, has been satisfied.
Scope resolution follows the Verilog Standard (IEEE Std 1364-2001) Section 12.5. That is, if a scope argument is specified, then the path name is first considered as relative to the module where the task was called. If it does not match any valid relative path, it is matched against paths one level up. If no match then one more level up, etc. For example, if scope a.b.c is an argument of a task called from module m, the scope name is first interpreted as a path starting at an instance a in m.
Arguments can be specified for one or more modules, entities, and instance scopes as in the case of $ova_start. The effect of a module or entity argument is to stop monitoring assertions for all instances of the module and their respective hierarchies under each instance as indicated by levels. The effect of a scope argument is to stop monitoring assertions for that instance scope and the hierarchy under it as indicated by levels.
$ova_stop(3, i1.mod1) // Stop assertions in the hierarchy // started at scope i1.mod1 to a depth 3. To specify the response to an assertion failure, use the $ova_severity_action system task: $ova_severity_action(level, action); Note the following syntax elements for $ova_severity_action: level Severity level to be associated with the action. action Can be specified as "continue", "stop" or "finish".
Developing a User Action Function Instead of specifying "continue", "stop" or "finish" as the action argument to the $ova_severity_action system task, you can specify a function that you develop to perform the action. To enable this feature the new struct types: Ova_AssertionSourceInfo This struct has the following fields: lineNo Represents the line number in the file where the assertion was written. fileName Represents the filename where the assertion was written in HDL or OVA source code.
category:24 This represents the category assigned to the assertion. It is a 24-bit integer constant. Ova_String userMessage This represents the custom user message assigned to the assertion. Ova_TimeL startTime This represents the start time for the assertion as an unsigned long long. Ova_TimeL endTime This represents the end time for the assertion as an unsigned long long. For non-temporal assertions, startTime and endTime will always be the same.
Using OpenVera Assertions 20-84
21 OpenVera Native Testbench 1 OpenVera Native Testbench is a high-performance, single-kernel technology in VCS that enables: • Native compilation of testbenches written in OpenVera and in SystemVerilog. • Simulation of these testbenches along with the designs. This technology provides a unified design and verification environment in VCS for significantly improving overall design and verification productivity.
Native Testbench is built around the preferred methodology of keeping the testbench and its development separate from the design. This approach facilitates development, debug, maintenance and reusability of the testbench, as well as ensuring a smooth synthesis flow for your design by keeping it clean of all testbench code. Further, you have the choice of either compiling your testbench along with your design or separate from it.
• Testbench Functional Coverage • Temporal Assertions • Using Reference Verification Methodology with OpenVera • Testbench Optimization Major Features Supported in Native Testbench OpenVera The features supported in Native Testbench have mainly two origins: those that are related to the OpenVera language and others that are related to the technology itself. These features are listed in the following sections.
• Concurrency, or spawning off of concurrent child threads from a parent thread, using fork-join with the return to the parent conditional on the completion of any, all, or none of the concurrent threads • Concurrency control constructs: - wait_child to wait on the completion of all child threads - wait_var to block the execution of a thread until the specified variable changes value - suspend_thread to suspend a thread until other threads complete or block - Mailboxes to pass data between concurrent thr
• Constraint solver for use in generating constrained random stimulus • Sequence generator for generating random stimulus streams • Dynamic checks with clear, concise constructs called expects that have automatic error-message generation capability for writing self-checking testbenches • Interfaces, containing interface signals, for providing the connectivity between signals in a testbench and ports or internal nodes of a design • Virtual ports and binds for sharing of interface signals between fun
Basics of an OpenVera Testbench This section outlines the fundamental program structure used in all OpenVera programs.
You must include the vera_defines.vrh file if you use predefined macros such as ON, OFF, HIGH, LOW. #include
• Testbench starts execution Any variable defined in a task or function has local scope. "Hello World!" The following simple program prints “Hello World!” to standard output. //hello.vr file program hello_world { string str; str = "Hello World!"; printf("%s \n", str); // printf() sends information // to stdout } //hello.vr file, is a comment line. A single-line comment starts with the two slashes, //. This comment provides the name of the testbench file containing the program.
Statements are indicated with a semi-colon, ; . The str variable is initialized on the next line (str = "Hello World!";). A variable can be declared and initialized on the same line, that is, you can modify the example as follows: string str = "Hello World!"; The printf() system task sends information to standard output during the simulation. printf("%s \n", str); %s is a string format specifier. \n indicates a line break. The str variable is passed to the task.
% ntb_template -t design_module_name [-c clock] filename.v \ [-vcs vcs_compile-time_options] Here: design_module_name The name of the module of your design. The following template-generator command line illustrates all possible options: % ntb_template -t arb -c clk arb.v [-vcs vcs_compile-time_options] -vcs vcs_option \ -t Specifies the top-level design module name. arb Name of the top-level design module. arb.v Name of the design file. -c Specifies the clock input of the design.
Multiple Program Support Multiple program support enables multiple testbenches to run in parallel. This is useful when testbenches model standalone components (for example, Verification IP (VIP) or work from a previous project). Because components are independent, direct communication between them except through signals is undesirable. For example, UART and CPU models would communicate only through their respective interfaces, and not via the testbench.
main1.vr main1_dep1.vr main1_dep2.vr ... main1_depN.vr [NTB_options ] program main2.vr main2_dep1.vr main2_dep2.vr ... main2_depN.vr [NTB_options ] program mainN.vr mainN_dep1.vr mainN_dep2.vr ... mainN_depN.vr [NTB_options ] In this example, main1.vr, main2.vr and mainN files each contain a program. The other files contain items such as definitions of functions, classes, tasks and so on needed by the program files. For example, the main1_dep1.vr, main1_dep2.vr .... main1_depN.
Specifying All OpenVera Programs in Configuration File You can specify all the OpenVera program files along with dependent OpenVera files in the configuration file using the configuration file syntax. The VCS command line for this method: $vcs -ntb_opts config=configuration_filename Specifying One OpenVera Program on Command Line Specify one OpenVera program file with its dependent files on the command line. Place all other OpenVera program files, and their dependent files in the configuration file.
The configuration file, could be: program main1.vr -ntb_define ONE program main2.vr -ntb_incdir /usr/vera/include One Program File is on the Command Line You can specify one program in the configuration file and the other program file at the command prompt. $vcs -ntb -ntb_opts config=configfile main2.vr -ntb_incdir /usr/vera/include \ The configuration file, in this example, is: program main1.vr In the above example, main1.vr is specified in the configuration file and main2.
program test1.vr program test2.vr You can specify, at most, one OpenVera program file, along with its dependent OpenVera files, at the command prompt. Specifying more than one OpenVera file that contains a program construct at the command prompt is an error. NTB Options and the Configuration File The configuration file supports different OpenVera programs with different NTB options such as include, define, or timescale. For example, if there are three OpenVera programs p1.vr, p2.vr and p3.vr, and p1.
• -ntb_define macro • -ntb_incdir directory • -ntb_opts no_file_by_file_pp • -ntb_opts tb_timescale=value • -ntb_opts dep_check • -ntb_opts print_deps • -ntb_opts use_sigprop • -ntb_opts vera_portname -ntb_define macro To run different OpenVera programs with different macro definitions, specify the macros name using the "-ntb_define" option. Multiple macro names are specified using the delimiter the "+".
ntb_options -ntb_incdir /usr/muddappa/include+/usr/vera/include -ntb_opts no_file_by_file_pp File by file preprocessing is done on each input file, feeding the concatenated results to the parser. To disable this behavior, use no_file_by_file_pp. -ntb_opts tb_timescale=value Specifies an overriding timescale for an OpenVera program. This option allows you to generate different timescale values for each OpenVera program.
• function string vera_get_name() • function string vera_get_ifc_name() • function string vera_get_clk_name() • function integer vera_get_dir() • function integer vera_get_width() • function integer vera_get_in_type() • function integer vera_get_in_skew() • function integer vera_get_in_depth() • function integer vera_get_out_type() • function integer vera_get_out_skew() These functions are documented in the “Retrieving Signal Properties” section of the OpenVera LRM: Native Testbench manu
Summary There are three major error scenarios, when specifying OpenVera files on the command line in addition to the configuration file: 1. An error is issued when the VCS command specifies multiple OpenVera files containing the program construct in addition to a configuration file. 2. An error is issued if the file on the command line which contains program, does not also have all of the files it is dependent on specified in the command line.
In this example configuration file, the prog1.vr, prog2.vr and prog3.vr files contain the OpenVera program construct. The OpenVera files task11.vr and task12.vr are two files needed by the program in the prog1.vr file. task21.vr and taks22.vr are OpenVera files needed by program in prog2.vr Multiple program example: top.
.d2 (d2), .rst_ .clk .q1 (q1), .q2 (q2) ); (rst_), (clk), initial begin SystemClock = 0; forever begin #(simulation_cycle/2) SystemClock = ~SystemClock; end end endmodule // duv.if1.vri #ifndef INC_DUV1_IF_VRH #define INC_DUV1_IF_VRH interface duv1 { input [7:0] q NSAMPLE ; inout [7:0] d PDRIVE #1 output rst_ PDRIVE ; input clk CLOCK ; } // end of interface duv PSAMPLE #-1 ; // hdl_node CLOCK "duv_test_top.clk"; #endif // test1.vr #include #include "duv.if1.
@1 duv1.d = 2 ; @1 duv1.d = 3 ; @20 duv1.q == 8'h3 ; printf("end of sim duv_test1\n") ; } // duv.if2.vri #ifndef INC_DUV2_IF_VRH #define INC_DUV2_IF_VRH interface duv2 { input [7:0] q PSAMPLE #-1; inout [7:0] d PDRIVE #1 PSAMPLE #-1 ; output rst_ PDRIVE #1 ; input clk CLOCK ; } // end of interface duv #endif // test2.vr #include #include "duv.if2.vri" program duv_test2 { printf("start of sim duv_test2\n") ; @1 duv2.rst_ = 0 ; @1 duv2.rst_ = 1 ; @1 duv2.rst_ = void ; @1 duv2.
output [7:0] q2 ; input rst_ ; input clk ; dff u1 (.q(q1), .d(d1), .rst_(rst_), .clk(clk)) ; dff u2 (.q(q2), .d(d2), .rst_(rst_), .clk(clk)) ; endmodule module dff (q, d, rst_, clk) ; input [7:0] d ; output [7:0] q ; input rst_ ; input clk ; reg [7:0] q ; always @(posedge clk) q <= (!rst_)? 8'h00 : d ; endmodule // vlog.f duv.v top.v // config.vrl program ./test1.vr program ./test2.vr // 1_comp_run_ntb #!/bin/csh -fx vcs -ntb -f vlog.f -ntb_opts config=config.
Compiling and Running the OpenVera Testbench This section describes how to compile your testbench with the design and how to compile the testbench independently from the design. It also describes compile-time and runtime options.
Compiling the Testbench Separate From the OpenVera Design This section describes how to compile your testbench separately from your design and then load it on simv (compiled design executable) at runtime. Separate compilation of testbench files allows you to: • Keep one or many testbenches compiled and ready and then choose which testbench to load when running a simulation. • Save time by recompiling only the testbench after making changes to it and then running simv with the recompiled testbench.
The following steps demonstrate a typical flow involving separate compilation of the testbench: 1. Compile the testbench in VCS to generate the shared object (libtb.so) file containing the compiled testbench and the Verilog testbench shell file. 2. Compile the Verilog design along with the top-level Verilog module and the testbench shell (.vshell) file to generate the executable simv. 3. Load the testbench on simv at runtime.
-ntb_spath Specifies the directory where the testbench shell and shared object files will be generated. The default is the compilation directory. -ntb_noshell Specifies not generating the shell file. Use this only when you are recompiling a testbench. -ntb_shell_only Generates only the .vshell file. Use this only when you are compiling a testbench separately from the design file.
vcs -ntb_vl dut.v name.test_top.v tb.vshell Here: -ntb_vl Specifies the compilation of all Verilog files, including the design, the testbench shell file and the top-level Verilog module. Example % vcs -ntb_vl sram.v sram.test_top.v sram.vshell Note: Remember, if, for example, you used -debug_all when compiling the .vr file, you must include -debug_all on the vcs command line as well. For example: % vcs -debug_all -ntb_vl dut.v name.test_top.v tb.
Example % simv +ntb_load=test1/libtb.so Limitations • The hdl_task inst_path specification should begin with a top-level module (that is, not the DUT module name). • When the hdl_task declaration has a var parameter, the corresponding task port in the DUT side must be “inout” (that is, it cannot be “output”). • The port direction and size in the hdl_task specification must match the corresponding task in the DUT.
-ntb_cmp Compiles and generates the testbench shell (file.vshell) and shared object files. Use this when compiling the .vr file separately from the design file. +error+n Sets the maximum number (n) of errors before compilation failure. -f filename Specifies the file containing a list of all the source files to be compiled. Synopsys recommends that you append the .list extension to the filename to indicate that it is an NTB source list file.
-ntb_filext extensions Specifies an OpenVera file extension. You can pass multiple file extensions at the same time using the + delimiter. Examples: -ntb_filext .vr -ntb_filext .vr+.vri+.vrl -ntb_incdir directory Specifies the include directory path for OpenVera files. You can specify multiple include directories using the + delimiter. Examples: -ntb_incdir ../src1 -ntb_incdir ../src1+../../src2 -ntb_noshell Specifies not generating the shell file. Use this only when recompiling a testbench.
-ntb_vl Specifies the compilation of all Verilog files, including the design, the testbench shell file and the top-level Verilog module. -ntb_opts Invokes a set of keyword arguments Syntax: -ntb_opts keyword_argument[+keyword_argument(s)] Examples: -ntb_opts check -ntb_opts no_file_by_file_pp+check A list of keyword arguments is as follows: check Reports error, at compile time or runtime, for out-of-bound or illegal array access. For example: // mda.
In cases where the out-of-bound index is directly specified as a constant expression as in the following example there is an error at compile time itself. program p { bit ia[4]; integer i; i = ia[4]; // Or i = ia[1'bx]; } The error message in this case is: Error-[IRIMW] Illegal range in memory word Illegal range in memory word shown below "mda_2.vr", 7: ia[4] Enables the built-in checker to identify any null-pointer access. For example, a list or class object being used without initialization.
print_deps The -print_deps option is supplied with dep_check telling the VCS compiler to output the dependencies for the source files to standard output or to a user specified file. -rvm Use -rvm when RVM is used in the testbench. tb_timescale Specifies an overriding timescale for the testbench. For example: vcs -ntb_opts tb_timescale=1ns/1ps file.vr This allows independent control of the testbench timescale as opposed to picking up the `timescale of the last .v file compiled.
Example: vcs -ntb -ntb_opts use_sigprop test_io.v \ test_io.test_top.v test_io.
Without this option, the default behavior is: 1. The Vera shell module name is based on the name of the OpenVera program. 2. Bind signals are named, for example, as: \ifc.signal[3:0] 3. The interface ports are named \ifc.signal covg_compat The covg_compat argument enables VCS to compile the source file in the old (pre-VCS 2006.06) semantics for coverage and disables all the new VCS 2006.
Runtime Options -cg_coverage_control The coverage_control() system task (see the OpenVera LRM: Native Testbench for description of this task), coupled with the -cg_coverage_control runtime argument, provides a single-point mechanism for enabling/disabling the coverage collection for all coverage groups or a particular coverage group. Syntax: -cg_coverage_control=value The values for -cg_coverage_control are 0 and 1.
+ntb_debug_on_error Stops the simulation when it encounters a simulation error. Simulation errors involve either an expect error or VCS calling the error() system task. +ntb_enable_solver_trace=value Enables a debug mode that displays diagnostics when VCS executes a randomize() method call. Allowed values are: Value Description 0 Disables tracing 1 Enables tracing 2 Enables more verbose message in trace If +ntb_enable_solver_trace is specified without an argument, the default value is 1.
For example: x == 0; x == 5; Allowed values are 0, 1, and 2. The default value is 2. Value Description 0 Disables tracing 1 Enables tracing 2 Enables more verbose message in trace If +ntb_enable_solver_trace_on_failure is specified without an argument, the default value is 1. The default is 2, if the option is not specified. +ntb_exit_on_error[=value] Causes VCS to exit when value is >0. The value can be: - 0: continue - 1: exit on first error (default value) - N: exit on nth error.
+ntb_solver_mode=value Allows you to choose between one of two constraint solver modes. When set to 1, the solver spends more pre-processing time in analyzing the constraints, during the first call to randomize() on each class. Subsequent calls to randomize() on that class are very fast. When set to 2, the solver does minimal pre-processing, and analyzes the constraint in each call to randomize(). Default is 2.
+vera_enable_solver_trace_on_failure Enables a mode that prints trace information only when the solver fails to compute a solution, usually due to inconsistent constraints. Legal values are 0, 1 and 2. When the value of the option is 2, the analysis narrows down to the smallest set of inconsistent constraints, thus aiding the debugging process. +vera_solver_mode Selects the Vera constraint solver to use.
If specifying a command line like the following leads to problems (error messages related to classes), adding -ntb_opts dep_check to the command line directs the compiler to activate analysis of Vera files and process them in topological order with regard to class derivation relationships. % vcs -ntb *.vr By default, files are processed in the order specified (or wildcard-expanded by the shell).
The first command line yields the order b.vr d.vr p.vr, while the second line yields, p.vr b.vr d.vr. Circular Dependencies With some programming styles, source files can appear to have circular inheritance dependencies in spite of correct inheritance trees being cycle-free. This can happen, for example, in the following scenario: a.vr: class class b.vr: class class Base_A {...} Derived_B extends Base_B {...} Base_B {...} Derived_A extends Base_A {...
.vrp, .vrhp, or as specified using option –ntb_vipext, and others. Only the latter unencrypted files are subject to dependency-based reordering, and encrypted files are prefixed to them. Note: The -ntb_opts dep_check compile-time option specifically resolves dependencies involving classes and enums. That is, we only consider definitions and declarations of classes and enums. Other constructs such as ports, interfaces, tasks and functions are not currently supported for dependency check.
files if the latter are marked as encrypted-mode by naming them with extensions .vrp, .vrhp, or additional extensions specified using option –ntb_vipext. This implies that the extensions are considered OpenVera extensions similar to using -ntb_filext for unencrypted files. This causes those files and everything they include to be preprocessed in encrypted mode.
Each time a user-specified activity occurs, a counter associated with the bin is incremented. By establishing a bin for each state, state transition, and variable change that you want to monitor, you can check the bin counter after the simulation to see how many activities occurred. It is, therefore, simple to check the degree of completeness of the testbench and simulation. VCS further expands this basic functionality to include two analysis mechanisms: open-loop analysis and closed-loop analysis.
• Optionally, a set of state and/or transition bins that define a named equivalence class for a set of values or transitions associated with each coverage point. • Optionally, cross products of subsets of the sampled coverage points (cross coverage). The coverage_group construct is similar to an OpenVera class in that the definition is written once and is instantiated one or more times.
Example 21-1 shows a standalone coverage_group definition and its instantiation. Example 21-1 Defining and Instantiating a Standalone Coverage Group interface ifc { input clk CLOCK; input sig1 PSAMPLE #-1; } coverage_group CovGroup { sample_event = @ (posedge CLOCK); sample var1, ifc.sig1; sample s_exp(var1 + var2); } program covTest { integer var1, var2; CovGroup cg = new(); } In this example, coverage_group CovGroup defines the coverage model for global variable var1, the signal ifc.
Measuring Coverage VCS computes a coverage number (or percentage) for the testbench run as a whole. Here, the coverage number is referred to as “coverage”. The coverage for the testbench is the weighted average of the coverages of every coverage_group in the testbench. When per-instance data is available, VCS also computes an instance coverage for the testbench. That number is the weighted average of the coverages of every coverage_group instance.
By default, VCS does not create automatic bins for ’X’ or ’Z’ values of a coverage point. For example, if a coverage point is a 4 bit bit-vector and the auto_bin_max attribute is set to 64 (default), then by default the total number of possible bins for the coverage point is 16 (24).
The following system function returns the cumulative coverage (an integer between 0 and 100) for the testbench: function integer get_coverage(); The following system function returns the instance-based coverage (an integer between -1 and 100) for the testbench: function integer get_inst_coverage(); Note: The get_inst_coverage() system function returns -1 when there is no instance-based coverage information (that is, the cumulative attribute of the coverage_group has not been set to 0).
The values for -cg_coverage_control are 0 or 1. A value of 0 disables coverage collection, and a value of 1 enables coverage collection. Example 21-2 #include
Another c1 = new; @(posedge CLOCK); coverage_control(0); x = 10; @(posedge CLOCK); x = 30; @(posedge CLOCK); coverage_control(1); x = 40; @(posedge CLOCK); x = 50; @(posedge CLOCK); coverage_control(0, "Cov"); x = 60; @(posedge CLOCK); coverage_control(1, "Cov"); coverage_control(0, "Another"); x = 70; @(posedge CLOCK); } Unified Coverage Reporting In VCS 2006.06, the db based coverage reporting has been replaced by the Unified Report Generator (URG) which can generate either HTML or text reports.
The format of the text report that the URG generates is different and better than the text report that used to be generated by the ntb -cov_report command line option. Any scripts that use these old command line options now need to be modified to use the URG options. The functional coverage database files and their location have been changed. The coverage database is written to a top-level coverage directory. By default this directory name is simv.vdb.
3. In order to view the results, invoke a browser (for example, invoke Mozilla): % mozilla urgReport/dashboard.html % more urgReport/dashboard.
Persistent Storage of Coverage Data and Post-Processing Tools Unified Coverage Directory and Database Control A coverage directory named simv.vdb contains all the testbench functional coverage data. This is different from previous versions of VCS, where the coverage database files were stored by default in the current working directory or the path specified by coverage_database_filename. For your reference, VCSassociates a logical test name with the coverage data that is generated by a simulation.
Table 21-1 Unique Name Generation Scheme Test Name Database pci_test Database for the first testbench run. pci_test_gen_1 Database for the second testbench run pci_test_gen_2 Database for the 3rd testbench run pci_test_gen_n Database for the nth testbench run You can disable this method of ensuring database backup and force VCS to always overwrite an existing coverage database.
Loading Coverage Data Both cumulative coverage data and instance-specific coverage data can be loaded. The loading of coverage data from a previous VCS run implies that the bin hits from the previous VCS run to this run are to be added. Loading Cumulative Coverage Data The cumulative coverage data can be loaded either for all coverage groups, or for a specific coverage group.
In the Example 20-4 below, there is a Vera class MyClass with an embedded coverage object covType. VCS finds the cumulative coverage data for the coverage group MyClass:covType in the database file Run1 and loads it into the covType embedded coverage group in MyClass. Example 21-1 MyClass{ integer m_e; coverage_group covType{ sample_event = wait_var(m_e); sample m_e; } } ... ...
The commands above direct VCS to find the coverage data for the specified instance name in the database, and load it into the coverage instance. In Example 20-5, there is a Vera class MyClass with an embedded coverage object covType. Two objects obj1 and obj2 are instantiated, each with the embedded coverage group covType. VCS will find the coverage information for the coverage instance obj1:covType from the database file Run1, and load this coverage data into the newly instantiated obj1 object.
-cm_name filename As a compile-time or runtime option, specifies an alternative test name instead of the default name. The default test name is "test". Solver Choice VCS incorporates two different solvers, each of which supports the entire OpenVera constraint language. You may select the solver you want using the runtime option vera_solver_mode, which takes the values 1 or 2. The default value is 2. Example 21-3 simv +vera_solver_mode=2 ... The two solvers have different performance characteristics.
Depending on the nature of constraints, and the number of calls to randomize() made per class, one or the other solver might be more suitable. Automatic Solver Orchestration As discussed before, VCS has two general purpose solvers. The user can indicate a preferred solver choice by setting the +vera_solver_mode option at runtime. In addition, there is a specialized solver that applies to simple constraint sets.
5. If the switched solver succeeds, then it remains the current solver choice. 6. Steps 3, 4, 5 are repeated for each call to randomize. Temporal Assertions OpenVera provides three pre-defined classes that enable the interaction of testbenches with OpenVera or SystemVerilog assertions.
Note: In this chapter the term “assertion” refers to an OVA (OpenVera Assertion) or SVA (SystemVerilog Assertion) in the DUT or testbench. The class, “Assertion,” is the corresponding assertion object in the OpenVera program. Figure 21-2 Interaction of Assertion Objects Actions Assertions Native Testbench testbench (*.
Note: This is not the event as defined in Assertions but rather as used in OpenVera. Here, an event is some occurrence that OpenVera can trigger on, such as a Failure or SUCCESS event. For more information about Assertion class, see the section titled “OpenVera Temporal Assertion Classes” in Chapter 7 (“Predefined Methods and Procedures”) of the OpenVera Language Reference Manual: Native Testbench.
4. Create an AssertEvent object for each event to be monitored. Including the Header Files To start, every file that instantiates an Assertion object must include the header file: #include Setting Up the AssertEngine Object The program block must instantiate one, and only one, AssertEngine object. For a summary of the class and its methods, see the description of AssertEngine Class in the OpenVera Language Reference Manual: Native Testbench book. program test { ...
Example 21-4 program { ... AssertEngine assert_engine = new(); assert_engine.Configure(ASSERT_QUIET, ASSERT_FALSE); assert_engine.Configure(ASSERT_INFO, ASSERT_TRUE); } Resetting Assertion At any time during the simulation, you can reset all attempts at matching assertions. You might want to reset when you switch to a new test and do not want to be confused by attempts started in the previous test. For example: assert_engine.
file: the order might change while compiling. The GetNextAssert() function fetches more Assertion handles until it delivers a null, indicating the end of the list. You can identify the handles with the Assertion object’s GetName() function. In Example 21-5, the testbench sets up Assertion objects for all assertions and expressions, however many there might be: Example 21-5 Assertion assert_check[]; string assert_name[]; int i = 0; assert_check[0] = assert_engine.
value, call the object’s GetCount() function. In Example 21-6, the code keeps track of how many times the assertion check1 fails and generates an error, and ends the simulation, if there are too many failures. Example 21-6 assert_check1.EnableCount(ASSERT_FAILURE); ... if (assert_check1.GetCount(ASSERT_FAILURE) > max_fail) error("Check1 exceeded failure limit."); EnableCount() starts a running count that cannot be disabled or reset.
Or, to watch for a global reset by the AssertEngine, use the following: AssertEvent assert_engine_reset = new(ASSERT_RESET); assert_engine.EnableTrigger(assert_engine_reset); Each AssertEvent object can be used with only one AssertEngine or Assertion object. For example, to watch for ASSERT_SUCCESS on three assertions, you must create three AssertEvent objects and attach each one to a different assertion object.
Terminating the AssertEngine When the testbench is completely finished with assertions, it should terminate all assertion activity with the AssertEngine’s DoAction() task. This task also recovers the memory space of all the assertion objects. Example 21-8 assert_engine.DoAction(ASSERT_TERMINATE); Example Testbench The following complete testbench is provided as an example: //Design under test `timescale 1ns/100ps module test; reg clk; reg dat; reg syn; test_ntb vsh( .
#10 dat = #10 dat = #10 dat = #10 dat = #10 dat = #10 dat = $finish; 0; 1; 1; 0; 0; 0; end initial begin #2 syn = 0; #10 syn = 1; #10 syn = 0; end initial $monitor( "vcs: clk=%b dat=%b syn=%b time=%0d", clk, dat, syn, $time); endmodule //OpenVera #include program test_ntb { AssertEngine Eng = new(); integer nCycGbl = 0; fork AssertListener( "test.t1.ck1"); AssertListener( "test.t1.ck2"); AssertListener( "test.t1.
printf( "\npgm: %s Assert.GetName() = %s " , tAsrt , Ast.GetName()); Ast.EnableTrigger(Event); printf("\npgm:Attached ASSERT_ALL event to %s " , tAsrt); while( 1) { Event.Wait(); EventType = Event.GetNextEvent(); while( EventType != ASSERT_NULL ) { printf( "pgm: Event.GetNextEvent(): asrt=%s ev=%s\n",tAsrt, AssertGetType(EventType)); EventType = Event.
event dk2 : if (syn == 1) then #2 dsyn ; event dk3 : if (syn == 1) then #3 dsyn ; } assert ck1: check(dk1); assert ck2: check(dk2); assert ck3: check(dk3); endunit //} bind instances test : test_u t1(clk,dat,syn); Running OpenVera Testbench with OVA Compilation: vcs ov_options_&_ov_files design_files_&_vcs_options ova_files_ova_options Assume that “design.v” is the DUT, “test.vr” is the OpenVera code containing assertion class, and the ova file is “checker.ova.” Example 21-9 % vcs -ntb test.vr design.
Simulation: % simv runtime_sva_options Running OpenVera Testbench with SVA and OVA Together Compilation: vcs ov_options_&_ov_files ova_&_ova_options \ sva_options_&_sva_files +sysvcs Simulation: simv simv_options OpenVera-SystemVerilog Testbench Interoperability The primary purpose of OpenVera-SystemVerilog interoperability in VCS Native Testbench is to enable you to reuse OpenVera classes in new SystemVerilog code without rewriting OpenVera code into SystemVerilog.
• The automatic mapping of data types between the two languages as well as the limitations of this mapping (some data types cannot be directly mapped). • Working with synchronization objects such as events, mailboxes and semaphores across the language boundary. • Mapping of SystemVerilog modports to OpenVera where they can be used as OpenVera virtual ports. • Effect of directly or indirectly calling blocking OpenVera functions from SystemVerilog.
Importing OpenVera types into SystemVerilog OpenVera has two user defined types: enums and classes. These types can be imported into SystemVerilog by using SystemVerilog package import syntax: import OpenVera::openvera_class_name; import OpenVera::openvera_enum_name; Allows one to use openvera_class_name in SystemVerilog code in the same way as an SystemVerilog class.
} class Derived extends Base { virtual task vfoo(arguments) { . . . } } // SystemVerilog import OpenVera::Derived; Derived d = new; // OK initial begin d.foo(); // OK (Base::foo automatically // imported) d.vfoo(); // OK end Base b = new; // not OK (don't know that Base is a //class name) The above example would be valid if we add the following line before the first usage of the name Base.
// SystemVerilog import OpenVera::Base; class SVDerived extends Base; virtual task vmt() begin . . . end endtask endclass Note: - If a derived class redefines a base class method, the arguments of the derived class method must exactly match the arguments of the base class method. - Explicit import of each data type from OpenVera can be avoided by a single import OpenVera::*. // OpenVera class Base { integer i; . . .
import OpenVera::Base; Data Type Mapping In this section, we describe how various data types in SystemVerilog are mapped to OpenVera and vice-versa. • Direct mapping: Many data types have a direct mapping in the other language and no conversion of data representation is required. In such cases, we say that the OpenVera type is equivalent to the SystemVerilog type. • Implicit conversion: In other cases, VCS performs implicit type conversion.
Mailboxes and Semaphores Mailboxes and semaphores are referenced using object handles in SystemVerilog whereas in OpenVera they are referenced using integral ids. VCS plans to support the mapping of mailboxes between the two languages as follows: Consider a mailbox created in SystemVerilog. To use it in OpenVera, we need to get the id for the mailbox somehow.
Once OpenVera gets an id for a mailbox/semaphore it can save it into any integer type variable. Note that however if get_id is invoked for a mailbox, the mailbox can no longer be garbage collected because VCS has no way of knowing when the mailbox ceases to be in use. Typed mailboxes (currently not supported), when they are supported in SystemVerilog can be passed to OpenVera code using the same method as untyped mailboxes above.
function semaphore $get_semaphore(int id); Events The OpenVera event data type is equivalent to the SystemVerilog event data type. Events from either language can be passed (as method arguments or return values) to the other language without any conversion. The operations performed on events in a given language are determined by the language syntax: An event variable can be used in OpenVera in sync and trigger. An event variable event1 can be used in SystemVerilog as follows: event1.
base type of the enum (an integral type) and then the bit-vector conversion rules (section 2.5) are applied to convert to an OpenVera type. This is illustrated in the following example. // SystemVerilog typedef reg [7:0] formal_t; // SV type equivalent to // 'reg [7:0]' in OV typedef enum reg [7:0] { red = 8'hff, blue = 8'hfe, green = 8'hfd } color; // Note: the base type of color is 'reg [7:0]' typedef enum bit [1:0] { high = 2'b11, med = 2'b01, low = 2'b00 } level; color c; level d = high; Foo foo; ...
Enumerated types with 2-value base types will be implicitly converted to the appropriate 4-state type (of the same bit length). See the discussion in 2.5 on the conversion of bit vector types.
Integers and Bit-Vectors The mapping between SystemVerilog and OpenVera integral types are shown in the table below.
Arrays Arrays can be passed as arguments to tasks and functions from SystemVerilog to OpenVera and vice-versa. The formal and actual array arguments must have equivalent element types, the same number of dimensions with corresponding dimensions of the same length. These rules follow the SystemVerilog LRM. • A SystemVerilog fixed array dimension of the form [m:n] is directly mapped to [abs(m-n)+1] in OpenVera. • An OpenVera fixed array dimension of the form [m] is directly mapped to [m] in SystemVerilog.
Some examples of compatibility: OpenVera SystemVerilog Compatible? integer a[10] integer b[11:2] Yes integer a[10] int b[11:2] No reg [11:0] a[5] logic [3:0][2:0] b[5] Yes Note: A 2-valued array type in SystemVerilog cannot be directly mapped to a 4-valued array in OpenVera. However, a cast may be performed as follows: // OpenVera class Foo { . . . task vera_method(integer array[5]) { . . . } . . . } // SystemVerilog int array[5]; typedef integer array_t[5]; import OpenVera::Foo; Foo f; . . . f.
OpenVera: they will be implicitly converted to bit vectors of the same width. packed struct {...} s in SystemVerilog is mapped to reg [m:0] r in OpenVera where m == $bits(s). Analogous mapping applies to unions. Connecting to the Design Mapping Modports to Virtual Ports This section relies on the following extensions to SystemVerilog supported in VCS. Virtual Modports VCS supports a reference to a modport in an interface to be declared using the following syntax. virtual interface_name.
Importing Clocking Block Members into a Modport VCS allows a reference to a clocking block member to be made by omitting the clocking block name. For example, in SystemVerilog a clocking block is used in a modport as follows: interface IFC(input clk); wire a, b; clocking cb @(posedge clk); input a; input b; endclocking modport mp (clocking cb); endinterface bit clk; . . . IFC i(clk); . . . virtual IFC.mp vmp; . . . vmp = i.mp; @(vmp.cb.
bit clk; . . . IFC i(clk); . . . virtual IFC.mp vmp; . . . vmp = i.mp; @(vmp.a); // cb can be omitted; 'cb.a' is // imported into the modport // Example-2 interface IFC(input clk); wire a, b; bit clk; clocking cb @(posedge clk); input a; input b; endclocking modport mp (import cb.*); // All members of cb // are imported. // Equivalent to the // modport in // Example-1. endinterface bit clk; . . . IFC i(clk); . . . virtual IFC.mp vmp; . . . vmp = i.mp; @(vmp.a); // cb can be omitted; //'cb.
• The modport and the virtual port have the same number of members. • Each member of the modport converted to a virtual port must either be (1) a clocking block or (2) imported from a clocking block using the import syntax above. • For different modports to be implicitly converted to the same virtual port, the corresponding members of the modports (in the order in which they appear in the modport declaration) be of bit lengths.
// SystemVerilog interface IFC(input clk); wire a; wire b; clocking cb @(posedge clk); output a; input b; endclocking modport mp (clocking cb, import cb.*); endinterface: IFC import OpenVera::Foo; . . . IFC ifc(clk); // use this to connect to DUT and TB . . . virtual IFC.mp vmp = ifc.mp; Foo f = new(vmp); // clocking event of ifc.cb mapped to // $clk in port P // ifc.cb.a mapped to $a in port P // ifc.cb.b mapped to $b in port P . . . f.foo(); . . . Note: It is not necessary to use a virtual modport above.
the current thread is suspended until that clock edge occurs and then the value is sampled. NTB-OV implements this behavior by default. On the other hand, in SystemVerilog, sampling never blocks and the value that was sampled at the most recent edge of the clock is used. Analogous differences exist for drives and expects.
• In SystemVerilog code, SystemVerilog syntax must be used to turn off/on constraint blocks or randomization of specific rand variables (even for OpenVera classes). • Random stability will be maintained across the language domain. //OV class OVclass{ rand integer ri; constraint cnst{...} } //SV OVclass obj=new(); SVclass Svobj=new(); SVobj.randomize(); obj.randomize() with {obj.ri==SVobj.
class A { B b; coverage_group cg { sample x(b.c); sample y(b.d); cross cc1(x, y); sample_event = @(posedge CLOCK); } task new() { b = new; } } // SystemVerilog import OpenVera::A; initial begin A obj = new; obj.cg.option.at_least = 2; obj.cg.option.comment = "this should work”; @(posedge CLOCK); $display("coverage=%f", obj.cg.get_coverage()); end Use Model Any `define from the OV code will be visible in SV once they are explicitly included.
VCS compile: vcs -sverilog -ntb_opts interop +Other_NTB_options -ntb_incdir incdir1+incdir2+... -ntb_define defines_for_OV_source_files OpenVera_.vrp_files OpenVera_source_files_.vr SystemVerilog_source_files_and_libraries A few more compile options are significant: 1. if RVM class libs are used in the OV code, this is required: -ntb_opts rvm 2.
and then receiving it back again, with the unsupported data items unchanged. Using Reference Verification Methodology with OpenVera VCS supports the use of Reference Verification Methodology (RVM) for implementing testbenches as part of a scalable verification architecture. The syntax for using RVM with VCS is: vcs -ntb_opts rvm [vcs_options] For details on the use of RVM, see the Reference Verification Methodology User Guide.
• RVM enhancements for assertion support in Vera 6.2.10 and later are not supported for NTB. • If there are multiple consumers and producers, no guarantee of fairness in reads from channels, etc. Testbench Optimization VCS/VCSi supports a set of features to analyze a testbench, identifying potential areas of improvement, and to partition the simulation run, reducing overall simulation time. NTB Performance Profiler The NTB Performance Profiler aids in writing more efficient OpenVera code.
Enabling the NTB Profiler The VCS profiler has been enhanced to support NTB. The +prof option enables the profiling of OpenVera NTB constructs and is used in the vcs command line in conjunction with -ntb and other NTB options when compiling the file. For example: % vcs -ntb +prof other_ntb_compile_time_options \ verilog_files testbench_files The NTB profile report is dumped in the vcs.prof log file. Performance Profiler Example The NTB performance profiler is illustrated here by means of a simple example.
result = a.pack(arr,index,left,right,0); } program MyTest { integer k = 0, j = 0; repeat (20) { @(posedge CLOCK); fork { for (j = 0; j < 200; j++) { k = k + 1; MyPack(k); } } { for(j = 1; j < 100000; j++) k ++; DPI_call(1, 2); } join all } @(posedge CLOCK); } Example 21-11 dpi.c #include
void DPI_call(int a, int b) { int i; for( i = 0; i < 1000; i++ ) { i +=b; i *=a; do_activity( i ); } } Compile: % vcs -R -ntb +prof dpi.vr dpi.c Run: % ./simv Example 21-12 // // // Log File (vcs.prof) Synopsys VCS X-2005.09-A[D] (ENG) Simulation profile: vcs.prof Simulation Time: 8.
MyTest (1) 1.40 1 test.vr:27. --------------------------------------------------------------------====================================================================== PROGRAM TO CONSTRUCT MAPPING ====================================================================== --------------------------------------------------------------------1.
--------------------------------------------------------------------Program %Totaltime --------------------------------------------------------------------MyTest 0.
• The predefined class method, pack(), invoked at test.vr:24 consumed 0.42% of the total time. • The task MyPack()defined at test.vr:12:24 consumed 0.14% of the total time. The time reported for construct is the exclusive time consumed by the construct itself. Time spent in dependants is not reported. VCS Memory Profiler The VCS memory profiler is an Limited Customer Availability (LCA) feature in VCS and requires a separate license. Please contact your Synopsys AC for a license key.
Use Model The $vcsmemprof() task can be called from the CLI or the UCLI interface. The syntax for $vcsmemprof() is as follows: $vcsmemprof("filename", "w|a+"); filename Name of the file where the memory profiler dumps the report. w | a+ w and a+ designate the mode in which the file is opened. Specify w for writing and a+ for appending to an existing file.
CLI Interface Compile-time The dynamic memory profiler is enabled only if you specify +dmprof on the VCS compile-time command line: vcs -ntb [-sverilog] +dmprof dut_filename.v testbench_filename.vr \ [-debug | -debug_all] Note: Use the -sverilog compile-time option when compiling SystemVerilog code. OpenVera code does not require this option. Runtime At runtime, invoke $vcsmemprof() from the CLI command line prompt as follows. You can make the call to $vcsmemprof() at any point during the simulation.
Only Active Memory Reported The memory profiler reports only memory actively held at the current simulation time instant by the dynamic data types. Consider the following OpenVera program: task t1() { integer arr1[*]; arr1 = new[500]; delay(5); } task t2() { integer arr2[*]; arr2 = new[500]; delay(10); } program main { fork { t1(); } { t2(); } join all } In this program, if $vcsmemprof() is called between 0 and 4 ns, then both arr1 and arr2 are active.
Reports the total dynamic memory consumed in all the programs (SV/OV) and that consumed in all the modules (SV) in the system. 2. Module View Reports the dynamic memory consumed in each SV module in the system. 3. Program View Reports the dynamic memory consumed in each SV/OV program in the system. 4. Program To Construct View a. Task-Function-Thread section Reports the total dynamic memory in each active task, function and thread in the module/program. b.
integer b; } class SecondClass { integer c; integer d[10]; } task FirstTask() { FirstClass a ; a = new; delay(100); } task SecondTask() { FirstClass a ; SecondClass b ; a = new; b = new; delay(100); } program test { integer i; integer sqProgram[$]; integer sqFork[$]; nonBlockTest(); fork { FirstTask(); } { delay(10); FirstTask(); } { delay(10); SecondTask(); } { delay(20); sqFork.push_front(1); delay(120); } join all sqProgram.
Compile: vcs -ntb +dmprof test.vr -debug_all Note: The -sverilog compile-time option is not used, since the program involves OpenVera code. Run: simv -ucli // Invokes ucli prompt ucli> next ucli> next ucli>call {$vcsmemprof("memprof.txt", "w")} //"w" the mode the file is // opened in.
VCS Memory Profiler Output ========================================================== $vcsmemprof called at simulation time = 20 ========================================================== ========================================================== TOP LEVEL VIEW ========================================================== TYPE MEMORY %TOTALMEMORY -------------------------------------------------------------------MODULES 0 0.00 PROGRAMS 512 100.
_____________________________________________________________________ Dynamic Data --------------------------------------------------------------------Type Memory %TotalMemory #Alive Instances --------------------------------------------------------------------Events 336 12.32 6 Queues 128 25.
OpenVera Native Testbench 21-114
22 SystemVerilog Design Constructs 1 This chapter begins with examples of the constructs in SystemVerilog that VCS has implemented. It then describes enabling the use of SystemVerilog code.
• Interfaces • Enabling SystemVerilog • Disabling unique And priority Warning Messages SystemVerilog Data Types SystemVerilog has several new data types which are described in the following sections.
You can also use the signed keyword to make the bit and logic data types store signed values. Note: In SystemVerilog the Verilog-2001 integer data type defaults to a signed value. The two state data types begin simulation with the 0 value. Assignments of the Z or X values to these data types result in an assignment of the 0 value. There is also the void data type that represents non-existent data. This data type can be used to specify that a function has no return value.
typedef chandle DataBase; // Data Base implemented in C/C++ import "DPI" function DataBase openDataBase(string name); import "DPI" function void saveDataBase(DataBase db); import "DPI" function void addToDataBase(DataBase db, Transaction tr); DataBase myDataBase; initial begin myDataBase = openDataBase("TestResults_1"); // ... while (1) begin // process transactions Transaction tr; // ... // record the just processed transaction in a data base addToDataBase(myDataBase, tr); // ... end end // ...
User-Defined Data Types You can define your own data types from other data types using the typedef construct like in C. For example: typedef logic [63:0] mylog; mylog m1, m2, m3, m4; Following the typedef keyword are the SystemVerilog data type for the user-defined type, the optional bit-width, and the name of the user-defined type. You can use a user-defined type, that is, declare a signal that has a user-defined type, before the definition of the user-defined type. For example: typedef mine; mine p; . .
In this example we have declared shortint variables northsouth and eastwest, that can hold a set of unassigned constants named green, yellow, and red. The default data type for an enumerated data type is int. If you omit the data type in the enumeration, the variables declared have the int data type. You can make assignments to the constants in the enumeration. For example: enum{now=0,next=1,old=2}cs,ns,tmp; You can declare a user-defined data type and then use it as the base type for an enumeration.
.last Displays the value of the last constant of the enumeration. .next Displays the value of the next constant of the enumeration. .prev Displays the value of the previous constant in the enumeration. .num Displays the total number of constants in the enumeration. .name Displays the name of the constant in the enumeration. The following is an example of the use of these methods: module top; typedef enum {red, green, blue, yellow} Colors; Here is an enumeration named Colors.
endmodule Results from the VCS simulation are as follows: Type Colors: name value total previous next last first red 0 4 3 1 3 0 green 1 4 0 2 3 0 blue 2 4 1 3 3 0 yellow 3 4 2 0 3 0 The $typeof System Function The $typeof SystemVerilog system function returns the data type of its argument, and its argument can be either of the following: • A primary expression.
module test; logic [31:0] log1,log2; bit [7:0] bit1; parameter type bus_t = $typeof(log1); In this type parameter, bus_t gets the data type of log1, which is logic[31:0]. initial begin if ($typeof(log1) == $typeof(log2)) $display("log1 same data type as log2"); if ($typeof(log1) != $typeof(bit1)); $display("log1 not the same data type as bit1"); if ($typeof(log2) == $typeof(logic [31:0])) $display("log2 is logic [31:0]"); VCS executes all three of these $display system tasks.
Expression: expression "filename", line_number Structures and Unions You can declare C-like structures and unions. The following are some examples of structures: struct { logic [31:0] lg1; bit [7:0] bt1; } st1; struct { bit [2:0] bt2; struct{ shortint st1; longint lg1; } st2; } st3; In these three structures: • The first structure is named st1 and it contains a 32 bit logic variable named lg1 and an 8 bit bit variable named bt1. • The second structure named st3 contains a structure named st2.
logic1 = st1.lg1; longint1 = st3.st2.lg1; st1.bt1 = bit1; end You can make assignments to an entire structure if you also make the structure a user-defined type. For example: typedef struct { logic [7:0] lg2; bit [2:0] bit2;} st4; st4 st4_1; initial st4_1={128,3}; The keyword typedef makes the structure a user-defined type. Then we can declare a variable of that type. Then we can assign values to the members of the structure. Here lg2 is assigned 128 and bit2 is assigned 3.
mbit1=lr[23:8]; mbit2=lr[7:0]; $display("mbit1=%0b mbit2=%0b",mbit1,mbit2); end In SystemVerilog you can enter an unsized literal single bit preceded by an apostrophe ’ as shown in the assignments to members left and right. All bits the variable are assigned the unsized literals single bit. In this case left is filled with ones and right is filled with zeroes. Here the $display system task displays the following: mbit1=1111111111111111 mbit2=0 VCS has not implemented an unpacked union.
myreg1=u1.r2[2]; end Structure Expressions You can use braces and commas to specify an expression to assign values to the members of a structure. For example: typedef struct{ bit bt0; bit bt11; } struct0; struct0 s0 = {0,1}; In this example, in the declaration of struct0 structure s0, bt0 is initialized to 0 and bt11 is initialized to 1, because they are listed that way in the declaration of structure struct0.
initial s2 = {default:0}; SystemVerilog Arrays SystemVerilog has packed and unpacked arrays. In a packed array all the dimensions are specified to the left of the variable name. In an unpacked array the dimensions are to the right of the variable name. For example: bit [1:0] b1; bit signed [10:0] b2; logic l1 [31:0]; // packed array // packed array // unpacked array Packed arrays can only have the following variable data types: bit, logic, and reg. You can make a packed array of any net data type.
When assigning to a packed array you can assign any vector expression, for example: bit [1:0] b1; bit signed [10:0] b2; logic [7:0] l2; . . . b1={r1,r2}; b2=’1; l2=b2[7:0]; // packed array // packed array // packed array Multiple Dimensions You can have multi-dimensional arrays where all the dimensions are packed or some dimensions are packed and others unpacked. Here is an example of all dimensions packed: logic [7:0][3:0][9:0] log1; Here, is a single entry of forty bytes.
log2[15][1][4]=1; Here is an example in which some dimensions are packed, but another is not: logic [11:0][1:0] log3 [6:0]; Here are seven entries of three bytes. In an assignment to this array, you reference the unpacked dimensions, followed by the packed ones. To assign to the left-most bit in the left most dimensions, do the following: log3[6][11][1]=1; In these assignments the last packed dimension can be a part select, or a slice.
Figure 22-1 Packed and Unpacked Multi-dimensional Array 6 5 7 6 5 4 3 2 1 0 11 10 9 8 7 6 5 4 3 2 1 0 11 10 9 8 7 6 5 4 3 2 1 0 11 10 9 8 7 6 5 4 3 2 1 0 11 10 9 8 7 6 5 4 3 2 1 0 11 10 9 8 7 6 5 4 3 2 1 0 11 10 9 8 7 6 5 4 3 2 1 0 1 0 1 3 1 2 1 0 8 0 4 1 11 10 9 1 0 0 0 1 0 1 0 The first of the previous two assignment statements: log3[6][11][1:0]=2’b11; This is an assignment to a part select.
Figure 22-2 A SystemVerilog Part Select 11 10 9 6 8 7 6 5 4 3 2 1 0 1 1 0 1 The second of the two previous assignment statements: log3[6][11:10]=2’b00; This is an assignment to a slice. A slice is a joint part select in contiguous elements of a multidimensional array. This slice assignment is shown in Figure 22-3.
The testbench constructs that you can enter outside programs with this option are as follows: classes associative arrays dynamic arrays SystemVerilog named events For descriptions and examples of these constructs see Chapter 24, "SystemVerilog Testbench Constructs". Writing To Variables SystemVerilog changes one of the basic concepts of Verilog: that variables are only written to by procedural statements.
As you can see, in SystemVerilog, you can write to a variable using a continuous assignment, connecting it to an output terminal of a primitive, or an output port of a module instance. Doing so is called using a structural driver. There are some limitations on structural drivers on variables: • A variable cannot have a behavioral driver (assigned a value by a procedural assignment statement) and a structural driver. • A variable, unlike a net, cannot have multiple structural drivers.
endmodule Automatic Variables You cannot force a value on to an automatic variable. For example: task automatic my_aut_task; . . . begin . . . #1 force mat=1; // causes this warning: . . . end endtask Doing so makes the task static and VCS displays the following warning message: Warning-[MNA] Making Task or Function Non-Automatic Disable/Force/Release/Assign/Deassign inside Automatic Task is not supported. "filename.
VCS displays the following warning message: Warning-[MNA] Making Task or Function Non-Automatic Making Task non-automatic due to Xmr access into it. "filename.v", line_number: task automatic task_name; Multiple Drivers If different elements of an unpacked array have structural and procedural drivers, then you cannot enter a force statement for any of the elements in the unpacked array. A procedural driver is a procedural assignment statement.
Error-[IFRLHS] Illegal force/release left hand side Force/Release of an unpacked array which is driven by a mixture of structural and procedural assignments is not valid The offending expression is signal_name "mult_driver.v", 10: force signal_name[1] = 1; This restriction does not hold for unpacked structures, see "Structures" on page 22-27.
begin assign l2=1; l3=1; #10 force l1=0; force l2=0; force l3=0; #10 release l1; release l2; release l3; end endmodule Signal l1 is continuously assigned a value of 1 at simulation time 10. Assuming a rising edge on the clock signal at simulation time 100, a procedural continuous assignment assigns the value of 1 to signal l2 and a procedural assignment assigns the value of 1 to signal l3. At simulation time110, all three signals are forced to a 0 value.
The following are examples of these data type declarations and valid force statements to the most significant bits in them: shortint si1; int int1; longint li1; byte byte1; bit [31:0] bit1; logic [31:0] log1; reg [31:0] reg1; integer intg1; initial begin force si1[15]=1; force int1[31]=1; force li1[63]=1; force byte1[7]=1; force bit1[31]=1; force log1[31]=1; force reg1[31]=1; force intg1[31]=1; end Notice that a bit-width was not specified for the shortint, int, longint, byte, or integer data types in thei
Unpacked Arrays You can make force statements to an element of an unpacked array or a slice of elements.
Like with force statements, you can enter a release statement for an entire array, a slice of elements in the array, or a single element. You can use a variable to specify the element of an unpacked array. For example: int int1; logic l1 [2:0]; initial begin int1=2; force l1[int1]=3; end If however, you have and unpacked array of packed bits, the packed bits must be specified with a value or a parameter, not a variable.
typedef struct{ int int1; bit [31:0] packedbit; integer intg1; } unpackedstruct; typedef struct packed{ logic [2:0] log1; bit [2:0] bit1; }packedstruct; module test; unpackedstruct ups1; unpackedstruct ups2; packedstruct ps1; packedstruct ps2; assign ups1.int1=30; initial begin #0 ups1.packedbit[0]=0; #20 force ups1.int1=1; #20 force ups2=ups1; #20 release ups2.int1; #20 release ups2; #20 force ps1.log1=1; #20 force ps1.
• VPI force and release should behave exactly in the same manner as procedural statement force and release. • If the vpi_put_value call contains a time delay information, VCS ignores it. • If the vpi_put_value call contains a value with vpiReleaseFlag, VCS ignores the value argument of vpi_put_value. • You cannot apply vpi_put_value to an entire struct. You can only apply it to individual members. In the following example, SystemVerilog code makes a PLI call $forceX.
s_vpi_value value_s = {vpiIntVal}; value_s.value.integer = 7; . . . vpi_put_value(var, &value_s, NULL, flag); . . . } void releaseX() { vpiHandle var; int flag = vpiReleaseFlag; s_vpi_value value_s = {vpiIntVal}; value_s.value.integer = 70; . . . vpi_put_value(var, &value_s, NULL, flag); . . . } At time 40 ns, another PLI call $releaseX is called, which will release the previously forced object.
=+ -= *= /= %= &= |= ^= <<= >>= <<<= >>>= The following table shows a few uses of these assignment operators and their equivalent in Verilog-2001. operator example b += 2; b -= 2; b *= 2; Verilog-2001 equivalent b = b + 2; b = b - 2; b = b * 2; SystemVerilog includes the ++ increment and -- decrement operators. The following table shows how they work.
Statements The keyword unique preceding an if or nested else if statement specifies that one, and only one, conditional expression must be true. So in the following code: unique if (l2!=0) $display("l2!=0"); else if (l2==3) $display("l2=3"); There are two conditional expressions: (l2!=0) and (l2==3).
VCS evaluates these conditional expressions in sequence to see if they are true. VCS executes the first statement controlled by the first conditional expression that is true. In this example, therefore, VCS would display: l4!=0 The priority keyword allows more than one conditional expression to be true. In this example the conditional expression (l4==3)could also be true but this would not be a warning condition.
RT Warning: More than one conditions match in 'unique case' statement. "filename.v", line line_number, at time sim_time If none of the case item expressions have the value of the case expression, it is also a warning condition and VCS displays the following warning message: RT Warning: No condition matches in 'unique case' statement. "filename.
Here VCS repeatedly does these two things: increments signal i1 and then check to see if signal r1 is at 0. If when it checks r1 is no longer at 0, it stops incrementing i1. With a while statement, VCS would check on r1 before incrementing i1. SystemVerilog Processes SystemVerilog identifies the Verilog always block and its three variations, as static processes (There are dynamic processes that are not yet implemented).
if (!mode) var1 = sig1 + sig2; else var1 = sig1 - sig2; var2 = sig1 + sig2; end SystemVerilog uses the term sensitivity list and in an always_comb block, the signals in the right-hand side of the assignment statements are inferred to be in the sensitivity list, meaning that any transition in these signals causes the execution of the always_comb block. In this example any transition in signals sig1 and sig2 cause the always block to execute.
var1 = sig1 + sig2; else var1 = sig1 - sig2; var2 = sig1 + sig2; end This always block executes at time zero only because there were transitions on the signals in its implicit sensitivity list at time zero, in this example on signals sig1 and sig2. If there were to such time zero transitions, this always block would not execute at time zero. The always_comb block always executes at time zero so the always_comb block more accurately models proper wired logic behavior.
The always_latch Block The always_latch block models latched behavior, combinational logic with storage. The following is an example of an always_latch block: always_latch if (clk) sigq <= sigd; The always_latch block is similar to the always_comb block in the following ways: • It has an inferred sensitivity list. It executes when there is a transition in the signals in the right-hand side of assignment statements.
q <= d; An always_ff block can only have one event control. The final Block The final block is a counterpart to the initial block. The final block executes during the last simulation time step in the simulation. A final block cannot contain delay specifications, non-blocking assignments, event controls, wait statements or contain user-defined task enabling statements for tasks that contain these constructs.
• Returning values from a task or function before executing all the statements in a task or function Tasks The following is an example of a valid SystemVerilog task. Note the differences from what would be a Verilog-2001 task. task task1 (input [3:2][1:0]in1, in2, output bit [3:2][1:0]out); logic tlog1,tlog2; tlog1=in1[3][1]; . . . #10 out[3][1]=tlog1; . . .
instead of input [3:2][1:0] in1 • in2 takes both defaults. The default direction is an input port and the default data type is logic. • out deviates from both defaults and so it must be specified as an output port with the bit data type. It is also a multi-dimensional packed array. logic tlog1,tlog2; Local scalar variables tlog1 and tlog2 are declared, with the logic data type. Ports have a default data type, local variables do not. tlog1=in1[3][1]; . . . #10 out[3][1]=tlog1; . . .
function reg [1:0] outgo(reg [3:2][1:0] in1,in2, output int out); int funcint; funcint = in1[3] >> 1; . . . if (in2==0) return 0; out = funcint; . . . outgo = funcint; endfunction initial begin . . . #1 reg2=outgo(reg1,log1,int2); . . . end Lets take a look at a number of lines in the function: function reg [1:0] outgo(reg [3:2][1:0] in1,in2, output int out); The function header specifies that the function name is outgo.
• in2 is a scalar port that takes both defaults, input direction and the logic data type. • out is an output port so the direction must be specified. It is of the int data type so that too is specified. In SystemVerilog a function can have an output or an inout port. int funcint; Local scalar variable funcint is declared, with the int data type. Ports have a default data type, local variables do not. funcint = in1[3] >> 1; . . . out = funcint; . . .
4. If the value of in2 is not zero, the value of the local variable funcint is returned by the function. #1 reg2=outgo(reg1,log1,int2); In this statement that calls the function (SystemVerilog function calls are expressions unless they are void functions), signal reg2 is assigned the return value of the function. Signals reg1 and log1 input values to the function and the value of the output port is a structural driver of signal int2. SystemVerilog also allows void functions that do not have a return value.
You can specify default values for: • Input ports • Inout and ref ports (one-value arguments only; constant arguments not supported) • Automatic tasks/functions • Task/functions contained in classes or methods of classes • Dynamic/Associative arrays (available with +svtb switch only) • export and import tasks and functions in interfaces In the following example the function func1 has two integer parameters whose default values are 100 and 300 respectively. This function returns an integer value.
In the first location, the argument overrides the default and the second default value is applied as if the function call were written as: func1(2, 300); SystemVerilog Packages A package is a scope that contains declarations of things that you want to share with more than one module, macromodule, interface or program. Note: - A SystemVerilog package is a concept borrowed from VHDL. - Classes in packages are an LCA feature requiring a special license.
You define a SystemVerilog package between the package and endpackage keywords. You must specify an identifier for the package. This package declares int variable int1. A module, macromodule, interface, or program references something declared in a package with an import statement with the :: scope resolution operator.
#6 int1=7; endmodule Modules top1 and top2 share int1 in package pack1. They both declare the use of the variable with import statements that reference both the package and the variable. The $monitor system task displays the following: int1=0 at 0 int1=7 at 6 int1=11 at 10 Both modules top1 and top2 assign values to int1. Note: A data type declaration in a package is different from a data type declaration in $root.
initial begin #1 top_bool_value1 = top_bool_value2; #5 top_bool_value2 = FALSE; end initial $monitor("%0t top_bool_value1=%0d top_bool_value2=%0d", $time, top_bool_value1, top_bool_value2); endmodule The $monitor system task displays the following 0 top_bool_value1=0 top_bool_value2=1 1 top_bool_value1=1 top_bool_value2=1 6 top_bool_value1=1 top_bool_value2=0 The following package contains a structure and a user-defined function: package pack1; typedef struct {real real1, real2;} struct1; function struct1
module mod1; import pack1::*; struct1 mod1struct1; struct1 mod1struct2; struct1 mod1struct3; struct1 mod1struct4; initial begin mod1struct1.real1=5; mod1struct1.real2=11; mod1struct2.real1=3; mod1struct2.real2=7; #10 mod1struct3 = halvfunc1 (mod1struct1); #10 mod1struct4 = halvfunc1 (mod1struct2); #10 $display("mod1struct3.real1=%0f",mod1struct3.real1); #10 $display("mod1struct3.real2=%0f",mod1struct3.real2); #10 $display("mod1struct4.real1=%0f",mod1struct4.real1); #10 $display("mod1struct4.
Exporting time-consuming user-defined tasks is an LCA feature requiring a special license. Time-consuming user-defined tasks are also called blocking tasks, they suspend, for some simulation time, the C or C++ function that calls it.
• The context keyword enables, in this case, the C or C++ language function to call the user-defined task in the SystemVerilog code. (This keyword also has other uses in the DPI.) • The task keyword also enables the C or C++ language function to call the user-defined task in the SystemVerilog code. We are calling it a task even thought there are no tasks in C or C++. You must include both keywords. The SystemVerilog IEEE Std 1800-2005, Section 26.1.
Notice that there is a delay in this user-defined task. This is a blocking task for the C or C++ function that calls it. The argument for this user-defined task has the inout direction. Next comes the declaration that the user-defined task can be called by a C or C++ function: export "DPI" task task_in_SV; The module ends with procedural code that calls the C or C++ function: initial func_in_C(4); The C or C++ source code is as follows: #include
The extern declaration declares the user-defined function. The address of the int variable i is passed to the user-defined task because the argument of the task has the inout direction. The printf statements display the following: before export, i=4 after export, i=2 Hierarchy SystemVerilog contains enhancements for representing the design hierarchy: • The $root top-level global declaration space • New data types for ports • Instantiation using implicit .
parameter msb=7; typedef int myint; wire w1,w2,w3,w4; logic clk; and and1 (w2,w3,w4); tran tr1 (w1,w4); primitive prim1 (out,in); input in; output out; table // in : out 0 : x; 1 : 0; x : 1; endtable endprimitive event recieved_data; task task1 (input [3:2][1:0]in1, in2, output bit [3:2][1:0]out); logic tlog1,tlog2; tlog1=in1[3][1]; . . . #10 out[3][1]=tlog1; . . .
wire [7:0] send, receive; endinterface module top1(w1); output w1; endmodule module top2(w1); input w1; endmodule All constructs that are declared or defined in $root are, for the most part, accessible to the entire design. Any module, regardless of its place in the hierarchy, can use the parameter, use the type, read or write to these variables, use the named event, call the task and function, or instantiate the interface.
module mod1(input int in1, byte in2, inout wire io1, io2, output mystruct out); . . . endmodule In the module header for module mod1: 1. The first port is named in1. It is specified as an input port with the int data type. - If we omitted both the direction and data type, SystemVerilog expects the port to be declared following the header. - If only the direction is omitted, it defaults to inout.
Instantiation Using Implicit .name Connections In SystemVerilog if the name and size of a port matches the name and size of the signal that connects to that port, you can make connections in any order without matching the order of the ports or using a name based connection list where you have to enter each port and the signal that connects to it. For example: module top; logic [7:0] log1; byte byt1 [1:0]; dev dev1(.log1,.byt1); endmodule module dev(input byte byt1 [1:0], input logic [7:0] log1); . . .
as asterisk to connect the signals to the ports, similar to an implicit event control expression list for an always block. For example: module top; logic [7:0] log1; byte byt1 [1:0]; dev dev1(.*); endmodule module dev(input byte byt1 [1:0], input logic [7:0] log1); . . . endmodule New Port Connection Rules for Variables SystemVerilog allows you to declare an input port to be a variable. This is another way to use a structural driver, see "Writing To Variables" on page 22-19.
Ref Ports on Modules Like arguments to tasks that you declare with the ref keyword, you can declare module ports with the ref keyword instead of the input, output, or inout keywords. A ref port is a reference to the signal that connects to it in a module instantiation statement in a higher level module instance. This connected higher-level signal is called a highconn signal.
endmodule In module refportmod the port named refin1 is declared with the ref keyword. All operations done in module refportmod to ref port refin1 also happen to the value of the highconn signal, int1, in module test. The $monitor system task in module test displays the following: int1 int1 int1 int1 int1 int1 int1 = = = = = = = x at 0 100 at 10 50 at 11 66 at 20 33 at 21 24 at 30 12 at 31 The value of integer int1 is halved because it is connected to a ref port in a module that halves this port.
Interfaces Interfaces were developed because most bugs occur between blocks in a design and interfaces help eliminate these wiring errors. Interfaces are a way of encapsulating the communication and interconnect between these blocks, but they are more than just that. They help you to develop a divide and conquer methodology and are reusable in other places in a design and in other designs.
At its simplest level, an interface encapsulated communication like a struct encapsulates data: typedef struct{ int int1; logic [7:0] log1; } s_type; interface intf; int int1; wire [7:0] w1; endinterface Think of a wire as a built-in interface. An interface is like a module that straddles other modules. module module interface Interfaces help you to maintain your code.
Example 22-5 Basic Interface interface intf; wire [7:0] send,receive; endinterface Interface defined in $root module test; logic [7:0] data_in1, data_in2, data_out1, data_out2; intf intf1(); Interface instantiated in module definition sendmod sm1 (intf1, data_in1, data_out1); receivemod rm1 (intf1, data_in2, data_out2); endmodule Connect module instance to interface instance module sendmod (intf intfa1, input logic [7:0] in, output logic [7:0] out); assign out = intfa1.receive; assign intfa1.
and interface definitions can be in module definitions or nested in other interface definitions. • To use an interface to connect a module instance to another, you must instantiate the interface in the module that instantiates the two module instances. • You also must declare the interface in the port connection list of the module headers of the two modules you are connecting with the interface.
Using Modports A modport specifies direction for a signal from a “point of view.” With these two signals in the interface we can specify two modports or “points of view” and the two modules connected by the interface will use different modports, and have different points of view. Let’s modify the interface definition by adding two modports.
Now let’s modify the module definition for module sendmod: modport follows the interface name module sendmod (intf.sendmode intfa1, input logic [7:0] in, output logic [7:0] out); always @(intfa1.receive) out = intfa1.receive; always @(intfa1.receive) intfa1.send = in; endmodule In the module header, in the connection list in the header where using the interface is declared, the modport is also declared, using the following syntax: interface_name.
Functions In Interfaces If we define a user-defined task or function in the interface, we can use the import keyword in the modport to make it accessible to the module instances connected by the interface and that use the modport.
This module uses the method called parity, using the syntax: interface_instance_name.method_name Enabling SystemVerilog You tell VCS to compile and simulate SystemVerilog code with the -sverilog compile-time option. No runtime option is necessary. IMPORTANT: Radiant Technology (+rad) does not work with SystemVerilog design construct code, for example structures and unions, new types of always blocks, interfaces, or things defined in $root.
RT Warning: No condition matches in 'priority if' statement. "filename.v", line line_number, at time sim_time RT Warning: More than one conditions match in 'unique case' statement. "filename.v", line line_number, at time sim_time RT Warning: No condition matches in 'unique case' statement. "filename.v", line line_number, at time sim_time RT Warning: No condition matches in 'priority case' statement. "filename.
23 SystemVerilog Assertion Constructs 1 SystemVerilog assertions (SVA), just like OpenVera assertions (OVA), are a shorthand way to specify how you expect a design to behave and have VCS display messages when the design does not behave as specified. You can use both to accomplish the same thing. SystemVerilog assertions are in the SystemVerilog 3.1a standard promulgated by Accellera, the electronics industry wide organization for the advancement of hardware description languages.
Concurrent assertions specify how the design behaves during a span of simulation time. Immediate Assertions An immediate assertion resembles a conditional statement in that it has a boolean expression that is a condition. When VCS executes the immediate assertion it tests this condition and if it is true, VCS executes some statements in what is called a pass action block. If the condition is not true VCS executes statements in what is called a fail action block.
In this example the immediate assertion is labeled a1, and its expression (lg1 && lg2 && lg3) is the condition. If the condition is true, VCS executes the begin-end block labeled pass. This is the pass action block (it is not required to name this action block). If the condition is not true, VCS executes the begin-end block labeled fail (it is also not required to name this action block), it follows the keyword else.
Sequence s1 specifies that signal sig1 is true and then one clock tick later signal s2 is true. In this case the clock signal and the edge that specifies the clock tick, are in a property definition that instantiates this sequence. The ## operator specifies a delay of a number of clock ticks (the value you specify must be a non-negative integer). You can specify any number of signals in the sequential expression and the logical negation operator.
• At $root (in SystemVerilog $root means outside of any other definition, a sequence defined in $root is globally accessible). Note: The SystemVerilog LRM says that you can declare a sequence in a module definition but never in an always or initial block. Using Formal Arguments In A Sequence You can specify formal arguments in a sequence and then make substitutions when you use it in another sequence.
The operands in the sequences need to be boolean expressions, they do not have to be just signal names. For example: sequence s1; sig1 == 1 ##1 sig3 || sig4; endsequence Unconditionally Extending a Sequence You can unconditionally extend a sequence by using the literal true value 1 or a text macro defined as 1.
sig1 ##1 sig2 ##1 sig2 ##1 sig2; endsequence Can be shortened to the following: sequence s1; sig1 ##1 sig2 [*3]; endsequence Note: The value you specify with the [* operator must be a positive integer. You can use repetition in a range of clock ticks. For example: sequence s1; (sig1 ##2 sig2) [*1:3]; endsequence This sequence specifies that the sequence is run at the length of itself, or the length of itself doubled, or tripled.
You can specify an infinite number of repetitions with the $ token. For example: sequence s1; (sig1 ##2 sig2) [*1:$]; endsequence Note: ##1 is automatically added between repetitions.
The above expression would pass the following sequence, assuming that 3 is within the min:max range. a c c c c b c c b c b d d d c Specifying a Clock You can specify a clock in a sequence. For example: sequence s1; @(posedge clk) sig1 ##1 sig2; endsequecle This sequence specifies that the clock tick is on the rising edge of signal clk. Value Change Functions You can also include the following system functions in a sequential expression.
$fell(expression) If the expression is just a signal, this returns 1 if the least significant bit of the signal changed to 0 between clock ticks. If the expression is more than one signal and an operator, for example sig1 + sig2, this returns 1 if the value of the least significant bit in the evaluation of the expression changes from 1, X, or Z to 0. $stable(expression) Returns 1 if the value of the expression does not change between clock ticks. A change in a four state signal from X to Z returns false.
Intersecting Sequences (And With Length Restriction) You use intersect operator to specify the match of the operand sequential expressions at the same clock tick. For example: sequence s1; l1 ##1 l3; endsequence sequence s2; l2 ##1 l4; endsequence sequence s3; s1 intersect s2; endsequence In this example, sequence s3 can match because sequences s1 and s2 both have the same number of clock ticks, sequence s3 does match when sequences s1 and s2 match.
Sequence s3 succeeds when either sequences s1 and s2 succeed but only when sequences s1 and s2 start at the same time. Only Looking For the First Match Of a Sequence The first_match operator specifies that a sequential expression matches only once. After its first success, VCS no longer looks for subsequent matches.
Specifying That Sequence Match Within Another Sequence You use the within operator to require that one sequence begin and match when or after another starts but before or when the other one matches. For example: sequence s1; l1 ##3 l4; endsequence sequence s2; l2 ##1 l3; endsequence sequence s3; s2 within s1; endsequence Sequence s1 requires three clock ticks, sequence s2 only requires one clock tick.
Note: If you are referencing a sequence in another sequence, and you are using the ended method in the second sequence, the referenced sequence must specify its clock tick. The first sequence above does so by beginning with @(posedge clk). You cannot use the ended method on a sequence with formal arguments. Use (or instantiate) such a sequence in another sequence, and then you can use the method on the other sequence.
For example: if (sequence1.triggered) Level sensitive sequence controls are documented in section 8.11, starting on page 93, of the SystemVerilog 3.1a Language Reference Manual. The following annotated code example shows using a sequence for these purposes: module test; logic l1,l2,clk; sequence s1; @ (posedge clk) l1 ##1 l2; endsequence Sequence s1 specifies that when there is a rising edge on variable clk, variable l1 is true, and with the next rising edge on clk, variable l2 is true.
always @(s1) $display("sequence s1 event control at %0t\n",$time); Sequence s1 is an event control expression. initial begin wait (s1.triggered) $display("wait condition s1.triggered\n"); The triggered method with sequence s1 is the conditional expression for the wait statement. if (s1.triggered) $display("if condition s1.triggered\n"); case (s1.triggered) 1'b1 : $display("case condition s1.triggered happened\n"); 1'b0 : $display("s1.
case condition s1.triggered happened do while condition s1.triggered Properties A property says something about the design, so a property evaluates to true or false. Concurrent assertions use properties and properties contain sequences, either instantiated or containing sequential expressions like a sequence.
The last property is invalid because it instantiates a sequence with a different clock tick than the clock tick for the property. In the valid properties you see the following: • How to specify the clock tick in the property for the sequence it instantiates. • How to specify a clock tick both in the property and in the sequence instantiated in the property, if they specify the same clock tick. • That instead of instantiating a sequence you can include a sequential expression like sig1 ##1 sig2.
a1: assert property (p3(sig3,sig4)); Here the property uses signals sig1 and sig2 in its sequential expression, but signals sig3 and sig4 replace them in the assertion declaration. Implications Property implications, contain a boolean or sequential expression, called an antecedent, which must be true or match before VCS starts to monitor the events in another sequence or sequential expression, called the consequent, to see if that sequence matches.
Property p1 contains an overlapping implication. It specifies checking that (sig3 && sig4) is true and if so, during the same clock tick, checking to see if sig1 is true, and then, a clock tick later, checking to see if sig2 is true. property p2; @(posedge clk) (sig1 ##1 sig2) |-> (sig3 ##1 sig4); endproperty Property p2 also contains an overlapping implication. In p2 the antecedent is a sequential expression.
Inverting a Property The keyword not can also be used before the declared sequence or sequential expression, or if it contains an implication, before the antecedent, to make the property true, if it otherwise would be false, or make the property false if it otherwise would be true. For example: sequence s1; sig1 ##1 sig2; endsequence property p1; @(posedge clk) not s1; endproperty Property p1 is true if sig1 is never true, or if it is, one clock tick later sig2 is never true.
Past Value Function SystemVerilog has a $past system function that returns the value of a signal from a previous clock tick. The following is an example of its use: property p1; @(posedge clk) (cnt == 0) ##3 ($past(cnt,3)==0); endproperty This rather elementary use of the $past system function returns the value of signal cnt from three clock ticks ago. The first argument, an expression, is required.
sig1 ##1 sig2; endsequence property p1; @(posedge clk) disable iff (rst) s1; endproperty a1: assert property (p1); If during simulation sig2 turns false, the property no longer succeeds. If, some time later, rst turns true, the property starts to succeed again. If rst turns false again, the property once again no longer succeeds. assert Statements VCS never checks a property or a sequence unless it is instantiated in a concurrent assertion.
property Keyword for instantiating both a property or a sequence. p1 Property instantiated in the concurrent assertion. You could also have specified a sequence instead of a property.
Like an asserted property, VCS checks an assumed property and reports if the assumed property fails to hold. assume statements are syntactically similar to assert statements, as stated in the Accellera document. The biasing feature is only useful when properties are considered as assumptions to drive random simulation. When a property with biasing is used in an assertion or coverage, the list operator is equivalent to inside operator, and the weight specification is ignored.
In this cover statement: c1: Instance name of the cover statement. cover statements have hierarchical name beginning with the hierarchical name of the module instance in which they are declared, and ending with this instance name. Instance names are optional. cover Keyword for declaring a cover statement. property Keyword for instantiating both a property or a sequence. p1 Property instantiated in the cover statement. You could have specified a sequence instead of a property.
VCS, for example, displays the following after simulation as a result of these cover statements: "exp3.v", 31: test.c1, 9 attempts, 16 total match, 7 first match, 1 vacuous match "exp3.v", 32: test.c2, 9 attempts, 21 total match, 8 first match, 0 vacuous match This display is explained as follows: • In the first line: - The cover statement is in source file exp3.v. - The instance of the cover statement is test.c1. It is declared in module test. - There were nine attempts to cover the property p1.
- In those nine attempts there were 21 times that the sequence occurred. - There were no vacuous matches because the cover statement does not instantiate a property with an implication. You can declare a cover statement, in the following places in your code: • In a module definition • In an Interface definition • In $root Note: In the VCS implementation, you can declare a cover statement in a module definition including inside an always block but not in an initial block.
end else begin $display("p1 does not succeed"); failCount ++; end c1: cover property (p1) begin $display("p1 covered"); coverCount ++; end Binding An SVA Module To A Design Module You can define a module that contains just SVA sequence and property declarations, and assert and cover statements. The module ports are signals in these declarations and statements. These ports are also signals in a design module (a module that contains behavioral or RTL code or other types of design constructs).
a1: assert property(p1) else $display("p1 Failed"); endmodule bind dev dev_checker dc1 (clk,a,b); In this bind directive: bind Keyword that starts the bind directive dev Module identifier (name) of the module to which you want to bind the SVA module dev_checker Module identifier of the SVA module dc1 Instance name of the SVA module. (clk,a,b) Port connection list to the SVA module You can also bind an SVA module to a design module instances. For example: module top; logic clk,a,b; . . .
property p1; @(posedge clk) a ##1 b; endproperty a1: assert property(p1) else $display("p1 Failed"); endmodule bind top.d1 dev_checker dc1 (clk,a,b); In this bind directive top.d1 is an instance of module dev. IMPORTANT: Binding to an instance that is generated using a generate statement is not supported.
bind dev dev_check #(10) dc1 (clk,sig1,sig2); Notice that module dev_check, that contains the SVA code, also has a parameter for specifying the number of clock ticks in the property. In the parameter declaration it has a value of 5, but its value is changed to 10 in the bind directive, like in any other module instantiation. The VPI For SVA This VPI is to enable you to write applications that react to SVA events and to enable you to write SVA waveform, coverage, and debugging tools.
• In subsection 28.5.1 “Assertion system control,” vpiAssertionSysStart and vpiAssertionSysStop are not supported. • In subsection 28.5.2 “Assertion control,” vpiAssertionDisableStep and vpiAssertionEnableStep are not supported.
cbAssertionLocalVarDestroyed VCS calls this callback type when it destroys an SVA local variable. This happens when an assertion succeeds or fails. All these callback types return a handle to the local variable that caused the event. Use the handle provided in the callback to get the name and value of the local variable. Your application is responsible for keeping track of the destroyed local variable handles. Using a destroyed variable handle results in unpredictable behavior.
Note that if VCS duplicates the SVA local variable, the returned vpi_attempt_info structure contains the handle to the new local variable. Your application needs to keep track of all copies of local variable for a particular attempt. These callback types have the following limitations: • The name or fullname of the SVA local variable does not contain the name of sequence or property it is declared in. • The local variable handle supports only vpiType, vpiName, vpiFullName and getValue.
Compile-Time And Runtime Options VCS has the following compile-time option for controllong SystemVerilog assertions: -assert keyword_argument The keyword arguments are as follows: enable_diag Enables further control of results reporting with runtime options. filter_past For assertions that are defined with the $past system task, ignore these assertions when the past history buffer is empty. For instance, at the very beginning of the simulation the past history buffer is empty.
dumpoff Disables the dumping of SVA information in the VPD file during simulation. VCS has the following runtime option for controllong SystemVerilog assertions: -assert keyword_argument The keyword arguments are as follows: dumpoff Disables the dumping of SVA information in the VPD file during simulation. dve Tells VCS to record SystemVerilog assertion information in the VPD file. filter Blocks reporting of trivial implication successes.
maxcover=N When you include the -cm assert compile-time and runtime option, VCS include information about cover statements in the assertion coverage reports. This argument disables the collection of coverage information for cover statements after the cover statements are covered N number of times. N must be a positive integer, it can’t be 0. maxfail=N Limits the number of failures for each assertion to N. When the limit is reached, the assertion is disabled. N must be supplied, otherwise no limit is set.
quiet Disables the display of messages when assertions fail. quiet1 Disables the display of messages when assertions fail but enables the display of summary information at the end of simulation. For example: Summary: 2 assertions, 2 with attempts, 2 with failures report[=path/filename] Generates a report file in addition to printing results on your screen. By default this file’s name and location is ./assert.report, but you can change it to where you want by entering the filename path name argument.
success Enables reporting of successful matches, and successes on cover statements, in addition to failures. The default is to report only failures. verbose Adds more information to the end of the report specified by the report keyword argument and a summary with the number of assertions present, attempted, and failed. You can enter more than one keyword, using the plus + separator.
-ova_simend_max_fail -ova_success -ova_cov_name -ova_cov_db -ova_cov See "Compiling Temporal Assertions Files" on page 20-19, "OVA Runtime Options" on page 20-21, and "Functional Code Coverage Options" on page 20-24.
Disabling SystemVerilog Assertions at Compile-Time You can specify a list of SystemVerilog assertions in your code that you want to disable at compile-time. You do so with the -assert compile-time option and disable_file=filename argument, for example: vcs -sverilog -assert disable_file=disable_assertions.txt Enter one absolute hierarchical name of a SystemVerilog assertion on each line, for example: test.dev1.a1 Only one hierachical assertion name to a line.
@(posedge clk) sig1 && sig2 => s2; endproperty a1: a2: c1: c2: */ assert property (p1); assert property (@(posedge clk)s1); cover property (p1); cover property (@(posedge clk)s1); The sv_pragma keyword must immediately follow the characters that begin the comment: // for single line comments and /* for multi-line comments. Note: This feature is intended allow SVA code as pragmas.
Options for SystemVerilog Assertion Coverage SystemVerilog assertion coverage monitors the design for when assertions are met and not met. Coverage results are on assertions, not the properties or sequences that might be instantiated in these assertions. See "Reporting On Assertions Coverage" on page 23-45 To enable and control assertion coverage, VCS has the following compile-time options: -cm assert Compiles for SystemVerilog assertions coverage.
-cm_assert_report path/filename Specifies the file name or the full path name of the assertion coverage report file. This option overrides the default report name and location, which is ./simv.vdb/fcov/results.db If only a file name is given, the default location is used resulting in: ./simv.vdb/fcov/ filename.db. VCS also has the following runtime option and keyword options for assertion coverage: -assert nocovdb Tells VCS not to write the results.db database file for assertion coverage.
Assertion coverage can also grade the effectiveness of tests, producing a list of the minimum set of tests that meet the coverage target.
The Tcl commands provided by VCS, that you can input to fcovReport for OVA coverage reports (see "Tcl Commands For SVA And OVA Functional Coverage Reports" on page 23-49), you can also input to assertCovReport for SystemVerilog assertion (SVA) coverage. -cm_assert_cov_cover Specifies reporting only about cover statements. -cm_assert_cov Specifies reporting only about cover and assert statements (no OVA coverage). -cm_assert_category category_val [,category_val...
-cm_assert_map filename Maps the module instances of one design onto another while merging the results. For example, use this to merge the assertion coverage results of unit tests with the results of system tests. Give the path name of a file that lists the hierarchical names of from/to pairs of instances with one pair per line: from_name to_name The results from the first instance are merged with the results of the second instance in the report.
-cm_assert_severity int_val [,int_val...] Reports only on OpenVera assertions specified by severity value. You can specify any number of severity values, separating them with commas. Only OpenVera assertions can have a severity, SystemVerilog assertions cannot. Tcl Commands For SVA And OVA Functional Coverage Reports You can produce a custom report with Tcl commands that you enter in assertCovReport. These Tcl commands also work in fcovReport when you want a custom report about OVA coverage.
Command fcov_get_children -instance handle fcov_get_coverage -bin handle fcov_get_flag -bin handle fcov_get_handle -instance name fcov_get_handle -module name fcov_get_handle -instance | -module name1 -assertion name2 fcov_get_handle -instance | -module name1 -assertion name2 -bin name3 fcov_get_instances fcov_get_instances -module handle SystemVerilog Assertion Constructs 23-50 Return Description Value array of Returns an array of handles for the handles child instances that contain at least one a
Command fcov_get_modules fcov_get_name -object handle fcov_get_no_bins -assertion handle fcov_get_no_of_assertions fcov_get_no_of_assertions -instance handle fcov_get_no_of_assertions -module handle fcov_get_no_of_assertions_attempted fcov_get_no_of_assertions_attempted -instance handle fcov_get_no_of_assertions_attempted -module handle fcov_get_no_of_assertions_failed fcov_get_no_of_assertions_failed -instance handle fcov_get_no_of_assertions_failed -module handle fcov_get_no_of_assertions_succeeded fcov
Command Return Description Value fcov_get_no_of_children -bin handle int Returns total number of child bins whose parent is the bin handle handle. fcov_get_no_of_children -instance int Returns total number of child handle instances containing at least one assertion under their hierarchy. The parent instance is with the specified handle. fcov_get_no_of_instances int Returns total number of instances that contain at least one assertion under their hierarchy.
Command Return Description Value fcov_grade_instances -target value1 string Returns a list of the minimum set of -metric code [-timeLimit value2] tests that add up to the target value for the metric code. Each test is accompanied by the accumulated coverage value including that test. The grading is by instance. fcov_grade_modules -target value1 string Returns a list of the minimum set of -metric code [-timeLimit value2] tests that add up to the target value for the metric code.
Command fcov_set -bin handle -flag name fcov_write_coverage -file name Return Description Value empty Sets the flag with name for the bin string ““ with the specified handle. The flag can be: “illegal”, “ignored”, or “none”. empty Writes current coverage to a file with string ““ the specified name. The name can be a file name or full path name. (The search rules are described in the table for options.
6vacuoussuccess Holds the count of vacuous successes. 8incompletes Holds the count of unterminated attempts For SVA sequence coverage 1attempts Holds the count of attempts. 3allsuccess Holds the count of succesful attempts. 7firstmatches Holds the count of generated .matched events. 8incompletes Holds the count of unterminated attempts. For OVA assertions 1attempts Holds the count of attempts. 2failures Holds the count of failed attempts. 3allsuccess Holds the count of succesful attempts.
2failures Holds the count of failed attempts. 3allsuccess Holds the count of succesful attempts. 4realsuccess Holds the count of attempts with nonvacuous success. 5events Holds the count of generated event matches. 8incompletes Holds the count of unterminated attempts. The assertCovReport Report Files When you compile for SystemVerilog or OpenVera assertion coverage, by including the -cm assert compile-time option and keyword argument, VCS creates the simv.vdb directory in the current directory.
2. Creates the report.fcov directory in the reports directory and writes in the report.fcov directory the following files: category.html, hier.html, and tests.html. Note: If you include the -cm_assert_report name option on the assertCovReport command line, you see the following differences: - The report.fcov directory is named name.fcov - The report.index.html file is named name.index.html The report.index.html File This file begins with tables of numerical data about the assertions in your design.
Assertions with at least 1 Real Success SystemVerilog and OpenVera assertions can fail at certain times during simulation and succeed at other times. This is the total number and percentage of SystemVerilog and OpenVera assertions that had at least one success during simulation. Assertions with at least 1 Failure The total number an percentage of SystemVerilog and OpenVera assertions that had a least one failure during simulation.
Cover Directive for Property Not Covered The total number and percentage of SystemVerilog assertion cover statements with the name of a property is their argument, where the design’s behavior never matches the property specified in the cover statement.
Total number of Cover Directives for Sequences A SystemVerilog cover statement can have a sequence name for an argument instead of a property. For example: sequence s8; @(posedge clk1) sig17 ##[1:5] sig18; endsequence c7: cover property (s8); or sequence s8; sig17 ##[1:5] sig18; endsequence c7: cover property (@(posedge clk1) s8); This information is the total number of such cover statements.
This information is the total number and percentage of SystemVerilog cover statements with sequences with all matches. Cover Directive for Sequence with First Matches Total number and percentage of SystemVerilog cover statements where the argument is a sequence, and there was a cycle delay range expression, and the first possible match for the sequence occurred. Total number of Events In OpenVera assertions, you can define a sequential expression as an event.
These links are followed by general information about generating this report. The tests.html File You can use the -cm_assert_map and -cm_assert_merge command line options to merge the results from one design to another. This file indicates the path names of the results.db files from which assertCovReport merges the results. The category.html File You can use the $ova_set_category and $ova_set_severity system tasks to set the category and severity of a SystemVerilog assertion and an OpenVera assertion.
Next is the same information for the category numbers you used for the SystemVerilog cover statements where the argument is a property, and the OpenVera cover directives. Next is the same information for the severity numbers you used for the SystemVerilog cover statements where the argument is a property, and the OpenVera cover directives. Next is the category numbers you used for the SystemVerilog cover statements where a sequence is the argument.
Each number is a hypertext link that takes you to a list of each type of statement, directive, or event. For assert statements or directives, the list shows you the number of attempts, successes, failures, and incompletes. For cover statements or directives and events, the list shows you the number of attempts, all matches, first matches, and incompletes.
Here: 0 Specifies reporting on the assertion if it is active (VCS is checking for its properties) and for the rest of the simulation reporting on the assertion or assertions, whenever they start. 1 Specifies reporting on the assertion or assertions only once, the next time they start. If you specify neither 0 or 1, the default is 0. assertion_identifier... A comma separated list of assertions.
In this example simulation, signal clk initializes to 0 and toggles every 1 ns, so the clock ticks at 1 ns, 3 ns, 5 ns and so on. A typical display of this system task is as follows: Assertion test.a1 [’design.v’27]: 5ns: tracing "test.a1" started at 5ns: attempt startingfound: req1looking for: req2 or any 5ns: tracing "test.a1" started at 3ns: trace: req1 ##1 anylooking for: req2 or any failed: req1 ##1 req2 5ns: tracing "test.
At simulation time 5 ns VCS is tracing test.a1. An attempt at the assertion started at 5 ns. At this time VCS found req1 to be true and is looking to see if req2 is true one to five clock ticks after 5 ns. Signal req2 doesn’t have to be true on the next clock tick, so req2 not being true is okay on the next clock tick; that’s what looking for “or any” means, anything else than req2 being true. 5ns: tracing "test.
Assertion System Functions The assertion system functions are $onehot, $onehot0, and $isunknown. Their purposes are as follows: $onehot Returns true if only one bit in the expression is true. $onehot0 Returns true if at the most one bit of the expression is true (also returns true if none of the bits are true). $isunknown Returns true if one of the bits in the expression has an X value. In the VCS implementation, this function also returns true if one of the bits in the expression has a Z value.
• Using attributes After you categorize assertions you can use these categories to stop and restart assertions. Using OpenVera Assertion System Tasks VCS has a number of system tasks and functions for OpenVera assertions that also work on SystemVerilog assertions.
$ova_get_category("assertion_full_hier_name") or $ova_get_category(assertion_full_hier_name) System function that returns an unsigned integer for the category. Using Attributes You can prefix an attribute in front of an assert statement to specify the category of the assertion.
Note: In a generate statement the category value cannot be an expression, the attribute in the following example is invalid: genvar g; generate for (g=0; g<1; g=g+1) begin:loop (* category=g+1 *) a3: assert property (s2); end endgenerate If you use a parameter for a category value, the parameter value can be overwritten in a module instantiation statement. You can use these attributes to assign categories to both named and unnamed assertions.
$ova_category_stop(category) System task that stops all assertions associated with the specified category. Using Mask Values To Stop And Restart Assertions There are system tasks for both OpenVera and SystemVerilog assertions that allow you to use a mask to determine if a category of assertions should be stopped or restarted. These system tasks are $ova_category_stop and $ova_category_start. They have matching syntax.
globalDirective Can be either of the following values: 0 Enables an $ova_category_start system task, that does not have a globalDirective argument, to restart the assertions stopped with this system task. 1 Prevents an $ova_category_start system task that does not have a globalDirective argument from restarting the assertions stopped with this system task.
globalDirective Can be either of the following values: 0 Enables an $ova_category_stop system task, that does not have a globalDirective argument, to stop the assertions started with this system task. 1 Prevents an $ova_category_stop system task that does not have a globalDirective argument from stopping the assertions started with this system task. Examples This first example stops the odd numbered categories: $ova_set_category(top.d1.a1,1); $ova_set_category(top.d1.a2,2); $ova_set_category(top.d1.
category 3 maskValue result 011 1 1 1 match category 4 maskValue result 100 1 0 1 no match 1. VCS looks at the least significant bit of each category and logically ands that LSB to the maskValue argument, which is 1. 2. The results of these anding operations, 1 or true for categories 1 and 3, and 0 or false for categories 2 and 4, is compared to the categoryValue, which is 1, there is a match for categories 1 and 3. 3. VCS stops the odd numbered categories. Here is another example.
In this example: 1. The two $ova_category_stop system tasks stop first the odd numbered assertions and then the even numbered ones. The first $ova_category_stop system task has a globalDirective argument that’s 0, the second has a globalDirective argument that’s 1. 2. The first $ova_category_start system task can restart the odd numbered assertions but the second $ova_category_start system task can’t start the even numbered assertions.
24 SystemVerilog Testbench Constructs 1 The new version of VCS has implemented some of the SystemVerilog testbench constructs. As testbench constructs they must be in a program block (see “Program Blocks” on page 24-15). Enabling Use of SystemVerilog Testbench Constructs You enable the use of SystemVerilog testbench constructs with the -sverilog compile-time option. VCS Flow for SVTB The VCS use model now includes the use model for SystemVerilog NTB.
vcs -sverilog -ntb_opts options As the use of vcs indicates, SystemVerilog files are treated like Verilog files in the VCS flow. You can also specify other NTB options: For example: vcs -sverilog tb.sv or vcs -sverilog -f tb.
Runtime Options There are runtime options that were developed for OpenVera testbenches that also work with SystemVerilog testbenches. +ntb_random_seed=integer Sets the seed value used by the top level random number generator at the start of simulation. This option does not work for the Verilog $random(seed) system function.
2 Enables tracing with more verbose messages. The randomize() method is described in “Randomize Methods” on page 24-100. +ntb_enable_solver_trace_on_failure[=0|1|2] Enables a mode that displays trace information only when the constraint solver fails to compute a solution, usually due to inconsistent constraints. 0 Disables tracing. 1 Enables tracing. This is the default. This argument is the default argument when you enter this option without an argument.
The string Data Type The string data type is an LCA feature. VCS has implemented the string SystemVerilog data type. The following is the syntax for declaring this data type: string variable_name [=initial_value]; String Manipulation Methods SystemVerilog has the following methods for manipulating strings: len() Returns the number of characters in a string. string string_name = "xyz"; int int1 = string_name.len; getc() Returns the numerically specified character in the string. bit1=string_name.
string string1 = "abc"; string string2 = "xyz"; initial begin $display ("string1 is \"%s\"",string1); string1.putc(0,42); $display ("string1 is \"%s\"",string1); string1.putc(1,string2); $display ("string1 is \"%s\"",string1); end endmodule The $display system tasks display the following: string1 is "abc" string1 is "*bc" string1 is "*xc" toupper() Returns a string with the lower case characters converted to upper case. string string1 = "abc"; string string2 = string1.
tolower() Similar to the toupper method, this method returns a string with the upper case characters converted to lower case. compare() and icompare() Compares strings and returns 0 if they match, and a value less than 0 or more than zero, depending on the order of the strings, if they don’t match. The icompare method doesn’t see a difference between upper case and lower case. string string string string string1 string2 string3 string4 = = = = "abc"; "abc"; "xyz"; "ABC"; initial begin if (string1.
substr() Returns a substring of the specified string. The arguments specify the numbers of the characters in the specified string that begin and end the substring. string string1 = "abcdefgh"; string string2; initial begin string2 = string1.
end The $monitor system task display the following: r1 r1 r1 r1 r1 = = = = = x at 0 10 at 10 16 at 20 8 at 30 2 at 40 atoreal() Returns a real number that is the decimal value of a string. module m; real r1; string string1 = "1235/x0090"; initial begin r1 = string1.atoreal; $display("r1 = 0%f",r1); end endmodule The $display system task displays: r1 = 1235.000000 itoa() Stores the ASCII decimal representation of an integer in a string. reg [63:0] r1 = 456; string string1; initial begin string1.
if (string1 == "123") $display("string1 %s",string1); string1.itoa(r1); if (string1 == "456") $display("string1 %s",string1); end The $display system tasks display: string1 123 hextoa() hextoa(arg) returns the ASCII hexadecimal representation of the arg. octtoa() octtoa(arg) returns the ASCII octal representation of the arg. bintoa() bintoa(arg) returns the ASCII binary representation of the arg. realtoa() realtoa(arg) returns the ASCII real representation of the arg.
$display("-----Start of Program ----------------"); s.hextoa(h); $display("Ascii of hex value 'hfa1 is %s",s); s.octtoa(o); $display("Ascii of octal value 'o172 is %s",s); s.bintoa(b); $display("Ascii of binary value 'b101010 is %s",s); s = "12.3456"; r = s.atoreal; $display("Real value of ascii string \"12.3456\" is %f", r); s = ""; s.realtoa(r); $display("Ascii of real value 12.
Predefined String Methods SystemVerilog provides several class methods to match patterns within strings. search() The search() method searches for a pattern in the string and returns the index number to the beginning of the pattern. If the pattern is not found, then the function returns -1. The syntax is: integer string_variable.search(string pattern); Here, the argument must be a string. The following example illustrates the usage of the search( ) class method.
integer i; string str; str = "SystemVerilog supports match( ) method"; i = str.match("mat"); This example assigns the value 1 to integer i because the pattern “mat” exists within the string str. prematch() The prematch() method returns the string that is located just before the string found by the last match() function call. The syntax is: string string_variable.prematch(); The following example illustrates the usage of the prematch() class method.
string str, str1; str = "SystemVerilog supports postmatch( ) method"; i = str.match("postmatch( )"); str1 = str.postmatch(); This example assigns the value “method” to string str1. thismatch() The thismatch() method returns the matched string, based on the result of the last match() function call. The syntax is: string string_variable.thismatch(); The following example illustrates the usage of the thismatch() class method.
The following example illustrates the usage of the backref() function call. integer i; string str, patt, str1, str2; str = "1234 is a number." patt = "([0-9]+) ([a-zA-Z .]+)"; i = str.match(patt); str1 = str.backref(0); str2 = str.backref(1); This example checks the Perl expressions given by string patt with string str. It assigns the value “1234” to string str1 because of the match to the expression “[0-9]+”. It assigns the value “is a number.
Program blocks begin with the keyword program, followed by a name for the program, followed by an optional port connection list, followed by a semi colon (;). Program blocks end with the keyword endprogram, for example: program prog (input clk,output logic [31:0] data, output logic ctrl); logic dynamic_array []; logic assoc_array[*]; int intqueue [$] = {1,2,3}; class classA; function void vfunc(input in1, output out1); . . . endfunction . . .
. prog prog1 (clk,data,ctrl); // instance of the program . . . endmodule In many ways a program definition resembles a module definition and a program instance is similar to a leaf module instance but with special execution semantics. A program block can contain the following: • data type declarations including initial values. Dynamic arrays, associative arrays, and queues are implemented for program blocks.
Final Blocks The final block is Limited Customer availability (LCA) feature in NTB (SV) and requires a separate license. Please contact your Synopsys AC for a license key. A final block executes in the last simulation time step.
time there are other important differences in a final block.
Arrays Dynamic Arrays Dynamic arrays are unpacked arrays with a size that can be set or changed during simulation. The syntax for a dynamic array is as follows: data_type name []; The empty brackets specify a dynamic array.
The optional (source_array) argument specifies another array (dynamic or fixed-size) whose values VCS assigns to the dynamic array. If you don’t specify the (source_array) argument, VCS initializes the elements of the newly allocated array to their default value. The optional (source_array) argument must have the same data type as the array on the left-hand side, but it need not have the same size.
The size() Method The size method returns the current size of a dynamic array. You can use this method with the new[] built-in function, for example: bitDA3 = new[bitDA1.size] (bitDA1); The delete() Method The delete method sets a dynamic array’s size to 0 (zero). It clears out the dynamic array. bitDA1 = new[3]; $display("bitDA1 after sizing, now size = %0d",bitDA1.size); bitDA1.delete; $display("bitDA1 after sizing, now size = %0d",bitDA1.
lFA1[1]=1; lFA1[0]=0; lDA1=lFA1; $display("lDA1[1] = %0d", lDA1[1]); $display("lDA1[0] = %0d", lDA1[0]); $display("lDA1 size = %0d",lDA1.size); end endprogram VCS displays: lDA1 size = 0lDA1[1] = 1 lDA1[0] = 0 lDA1 size = 2 When you assign a fixed-size array to a dynamic array, the dynamic array’s size changes to the size of the fixed-size array.
lDA2[0] = 0 lDA2 size = 2 You can assign a dynamic array to a fixed-size array, provided that they are of equivalent data type and that the current size of the dynamic array matches the size of the fixed-size array. Associative Arrays An associative array has a lookup table for the elements of its declared data type. Its index is a data type which serves as the lookup key for the table. This index data type also establishes an order for the elements.
Wildcard Indexes You can enter the wildcard character as the index. data_type array_id [*]; Using the wildcard character permits entering any integral data type as the index. Integral data types represent an integer (shortint, int, longint, byte, bit, logic, reg, integer, and also packed structs, packed unions, and enum. Note: The wildcard index has a 64 bit limitation.
initial begin a["sa"] = 8; a["bb"] = 15; a["ec"] = 29; a["d"] = 32; a["e"] = 45; a[string_variable] = 1; end endprogram Associative Array Assignments and Arguments You can only assign an associative array to another associative array with a equivalent data type. Similarly, you can only pass an associative array as an argument to another associative array with a equivalent data type. Associative Array Methods There are methods for analyzing and manipulating associative arrays.
first Assigns the value of the smallest or alphabetically first entry in the array. Returns 0 if the array is empty and returns 1 if the array contains a value. last Assigns the value of the largest or alphabetically last entry in the array. Returns 0 if the array is empty and returns 1 if the array contains a value. next Finds the entry whose index is greater than the given index. If there is a next entry, the index variable is assigned the index of the next entry, and the function returns 1.
$display("the first entry is \"%s\"",s_index); do $display("%s : %0d",s_index,a[s_index]); while (a.next(s_index)); end if(a.last(s_index)) begin $display("the last entry is \"%s\"",s_index); do $display("%s : %0d",s_index,a[s_index]); while (a.prev(s_index)); end a.delete; $display("number of entries = %0d",a.
Queues A queue is an ordered collection of variables with the same data type. The length of the queue changes during simulation. You can read any variable in the queue, and insert a value anywhere in the queue. The variables in the queue are its elements. Each element in the queue has a number: 0 is the number of the first, you can specify the last element with the $ (dollar sign) symbol.
end The $display system task displays: s1=first s2=second s3=third s4=fourth You also assign values to the elements using the element number, for example: int intque [$] = {1,2,3}; initial begin intque[0]=4; intque[1]=5; intque[2]=6; $display("intque[0]=%0d intque[1]=%0d intque[2]=%0d", intque[0],intque[1],intque[2]); . . .
Queue Methods There are the following built-in methods for queues: size Returns the size of a queue. program prog; int intque [$] = {1,2,3}; initial begin for (int i = 0; i < intque.size; i++) $display(intque[i]); end endprogram insert Inserts new elements into the queue. This method takes two arguments: the first is the number of the element, the second is the new value. program prog; string strque [$] = {"first","second","third","forth"}; initial begin for (int i = 0; i < strque.
The $display system tasks display the following: first second third forth first next somewhere second third forth delete Removes an element from the queue, specified by element number. If you don’t specify an element number, this method deletes all elements in the queue. string strque [$] = {"first","second","third"}; initial begin for (int i =0; i
for (int i =0; i
$display("s1 after pop contains %s ",s1); $write("the elements of strque are "); for (int i =0; i
module test; bit [11:10][9:8][7:0] bit_array1; initial begin foreach (bit_array1[dim1,dim2]) bit_array1 [dim1][dim2]=dim1*dim2; foreach (bit_array1[dim1, dim2]) $display("bit_array1[%1d][%1d]=%0d", dim1,dim2,bit_array1[dim1][dim2]); end endmodule The bit data type array named bit_array1 has three dimensions. The first foreach loop iterates through the first two dimensions 11:10 and 9:8, to assign 8-bit values to these elements. The second foreach loop displays the deposited values.
endmodule The $display system task displays the following: string element number 0 contains "simulation" string element number 1 contains "verification" The foreach loop also works with queues and dynamic and associative arrays.
assoc_array1[7]=3'b111; foreach (assoc_array1[dim1]) $display("assoc_array1 [%1d]=%0d", dim1,assoc_array1[dim1]); end endprogram The $display system task displays the following: assoc_array1 [0]=0 assoc_array1 [1]=1 assoc_array1 [7]=7 Array Aggregates (Reduction/Manipulation) Methods in Constraints SystemVerilog includes a set of array reduction methods which allow declarations of complex constraints for arrays and queues in a compact and flexible format.
List of Aggregate Methods Table 24-1 Method Description sum() Performs addition and returns sum of array elements product() Performs multiplication, and returns product of array elements and() Performs bitwise AND operation, and returns bit-wise AND of array elements. or() Performs bitwise OR operation, and returns bit-wise OR of array elements xor() Performs logical XOR operation, and returns logical XOR of all array elements.
if(i) $display("Randomization Success"); else $display("Randomization Fails"); end endprogram Notes 1. Empty array - If the array over which the aggregate operation is defined has size 0, then the behavior is as follows: - array.sum(): The expression is substituted by 0. - array.product(): The expression is substituted by 1. For all other aggregate methods there is a runtime error if reference to the aggregate operation is in an ON constraint block. 2.
Classes The user-defined data type, class, is composed of data members of valid SystemVerilog data types (known as properties) and tasks or functions (known as methods) for manipulating the data members. The properties and methods, taken together, define the contents and capabilities of a class instance (also referred to as an object). Use the class and endclass keywords to declare a class.
logic [7:0] log1; } struct1; struct1 mystruct; typedef struct packed { int intt1; logic [31:0] logg1; } pstruct1; typedef union packed { pstruct1 u_pstruct1; } p_union1; endclass Creating an Instance (object) of a Class A class declaration is the template from which objects are created. When a class is constructed the object is built using all the properties and methods from the class declaration. To create an object (that is, an instance) of a declared class, there are two steps.
send = a * 2; endfunction task show(); $display("q = %0d", q); endtask endclass initial begin B b1; //declare handle, b1 b1 = new; //create an object by calling new end endprogram The above two steps can be merged into one for instantiating a class at the time of declaration: class_name handle_name = new(); For example: B b1 = new; The new() method of the class is a method which is part of every class.
handle_name = new([arguments]); Arguments are optional. Below is an example of a user-defined constructor: program P; class B; //declare class integer command; function new(integer inCommand = 1); command = inCommand; $display("command = %d", command); endfunction endclass endprogram When called, new() will print the value passed to it as the value of command. When a class property has been initialized in its declaration, the user-defined new() constructor can be used to override the initialized value.
The output of this program is: The value of q is 4. If a property is not initialized by the constructor, it is implicitly initialized, just like any other variable, with the default value of its data type. Assignment, Re-naming and Copying Consider the following: class Packet; ... endclass Packet p1; Packet p1; creates a variable, p1, that can hold the handle of an object of class Packet. The initial default value of p1 is null.
Now consider the following, assuming p1 and p2 have been declared and p1 has been instantiated: p2 = new p1; The handle p2 now points to a shallow copy of the object referenced by p1. Shallow copying creates a new object consisting of all properties from the source object. Objects are not copied, only their handles. That is, a shallow copy is a duplication of members, including handles, of an object´s first level constituents in the hierarchy.
initial begin Parcel pk1 = new; Parcel pk2 = new; Parcel pk3 = new; $display("%d Parcel", $display("%d Parcel", $display("%d Parcel", pk3.count); pk2.count); pk1.count); end endprogram Output 5 Parcel 5 Parcel 5 Parcel In the above example, every time an object of type Parcel is created, the new() function is invoked and the static variable count is incremented. The final value of count is “5.
class Xvdata_Class; const int pi = 31412;//const variable endclass Xvdata_Class data; initial begin data = new(); data.pi = 42; //illegal and will generate //compile time error end endprogram The line, data.pi=42, is not valid and yields the following compile time error message: Error-[IUCV] Invalid use of 'const' variable Variable 'pi' declared as 'const' cannot be used in this context "global_const.sv", 17: data.
rand A a1; rand E e1; extern function f1(); constraint c; endclass //out of class body method declared with the help of :: //operator function C::f1(); int i; $display("Accessing enum label in constraint block through :: operator"); repeat (5) begin i = this.randomize(); if(i) $display("e1 = %s", this.e1.name); else $display("Randomization Failed"); end // accessing enum label through :: operator in out // of class body method $display("Accessing enum label in function block through :: operator"); i = this.
end endprogram The Output of this program is Accessing enum label in constraint block through :: operator e1 = S1 e1 = S2 e1 = S3 e1 = S1 e1 = S1 Accessing enum label in function block through :: operator e1 = S3 Class Extensions Subclasses and Inheritance SystemVerilog’s OOP implementation provides the capability of inheriting all the properties and methods from a base class, and extending its capabilities within a subclass. This concept is called inheritance.
endclass Now, all of the methods and properties of Packet are part of LinkedPacket - as if they were defined in LinkedPacket - and LinkedPacket has additional properties and methods. We can also override the parent’s methods, changing their definitions. Abstract classes A group of classes can be created that are all “derived” from a common abstract base class.
endfunction endclass class EtherPacket extends BasePacket; function integer send(bit[31:0] data) // body of the function ... endfunction endclass EtherPacket is now a class that can be instantiated. If a subclass which is extended from an abstract class is to be instantiated, then all virtual methods defined in the abstract class must have bodies either derived from the abstract class, or provided in the subclass.
Methods of non-abstract classes can also be declared virtual. In this case, the method must have a body, since the class, and its subclasses, must be able to be instantiated. It should be noted that once a method is declared as “virtual,” it is forever virtual. Therefore, the keyword does not need to be used in the redefinition of a virtual method in a subclass. Polymorphism The ability to call a variety of functions using the exact same interface is called polymorphism.
class MyPacket extends Packet; task display(); $display("This is the display within MyPacket"); endtask endclass class YourPacket extends Packet; task display(); $display("This is the display within YourPacket"); endtask endclass This example illustrates how the two classes derived from Packet implement their own specific version of the display() method. All derived classes can be referenced by a base class object.
This is the display within MyPacket This is the display within YourPacket This is a typical, albeit small, example of polymorphism at work.
super keyword The super keyword is used from within a derived class to refer to properties of the parent class. It is necessary to use super when the property of the derived class has been overridden, and cannot be accessed directly. program sample; class Base; integer p; virtual task display(); $display("\nBase: p=%0d", p); endtask endclass class Extended extends Base; integer q; task display(); super.
Base: p=2 Extended: q=3 In the above example, the method, display() defined in Extended calls display(), which is defined in the super class, Base. This is achieved by using the super keyword. The property may be a member declared a level up or a member inherited by the class one level up. Only one level of super is supported. When using the super keyword within the constructor, new, it must be the first statement executed in the constructor.
integer q; virtual task display(); super.display(); $write("Extended: q=%0d\n", q); endtask endclass Base b1 = new(), b2; Extended e1 = new(), e2; initial begin b1.p = 1; $write("Shows the original base property p\n"); b1.display(); // Just shows base property e1.p = 2; e1.q = 3; $write("Shows the new value of the base property, p, and value of the extended property, q\n"); e1.
Shows new value of the base property, p, and value of the extended property, q Base: p=2 Extended: q=3 The base handle b2 is pointing to the Extended object Base: p=2 Extended: q=3 Using $cast to assign b2 to e2 Base: p=2 Extended: q=3 The $cast() can be used to cast non-enum types into an enum-type destination.
class ClassA; ... endclass class Class_a extends ClassA; ... endclass class class_ab extends Class_a; ... endclass class Class_b extends ClassA; ... endclass Both Class_a and Class_b are extended from ClassA using the extends keyword, making ClassA the base class for these two subclasses. Class_ab extends from Class_a, making Class_a the base class for the subclass, Class_ab. Both ClassA and Class_a are super classes since they each have subclasses extended from them.
Figure 24-1 Base and Sub Classes ClassA Class_a Class_ab Base Class Subclass Class_b When a subclass is instantiated, the constructor of the extended super class is implicitly called. If that class, in turn, has a super class, it will implicitly call the constructor of that class. This will continue up the hierarchy until no further super classes exist.
Figure 24-2 Chaining Constructors ClassA Class_a Class_ab Base Class Subclass Class_b when Class_ab is instantiated, the “new” constructor for Class_a is called. In turn, the “new” constructor for ClassA is called. Since ClassA is the last super class in the chain, an object of Class_ab is then created. When Class_b is instantiated, the “new” constructor for ClassA is called and an object of Class_b is created. This process is called “chaining constructors.
This will pass 5 to the new() routine associated with “Packet”. A more general approach is to use the super keyword to call the superclass constructor. function new(); super.new(5); endfunction If included, the call to super() must be the first executable statement (that is, not a declaration) in the constructor. Accessing Class Members Properties A property declaration may be preceded by one of these keywords: • local • protected The default protection level for class members is “public.
Accessing Properties A property of an object can be accessed using the dot operator (.). The handle name for the object precedes the dot, followed by the qualifying property name (for example, address, command). instance_name.property_name Methods Tasks or functions, known as “methods,” can be designated as local, public, or protected. They are public by default. Accessing Object Methods An object´s methods can be accessed using the dot operator (.).
Output of program q = 3 value returned by b1.send() = 8 “this” keyword The this keyword is used to unambiguously refer to properties or methods of the current instance. For example, the following declaration is a common way to write an initialization task: program P; class Demo; integer x; task new (integer x); this.x = x; endtask endclass endprogram The x is now both a property of the class and an argument to the task new().
The following is another, complete, example. program P; class Demo; integer x=4; function integer send(integer x); this.x = x*3; endfunction task show(); $display("The value of x in the object of type Demo is = %d", send(this.x)); endtask endclass intial begin integer x=5; Demo D =new; D.
Class Packet Example class Packet; bit [3:0] command; //property declarations bit [40:0] address; bit [4:0] master_id; integer time_requested; integer time_issued; integer status; function new(); // initialization command = 0; address = 41’b0; master_id = 5’bx; endfunction task clean(); //method declaration command = 0; address = 0; master_id = 5’bx; endtask task issue_request(int delay); //method // declaration send request to bus endtask function integer current_status(); //method // declaration current_s
class myclass; . . . typedef struct { int int1; logic [7:0] log1; } struct1; struct1 mystruct1; . . .
Random Constraints SystemVerilog has constructs for the random testing of a design and a means of constraining the random testing to find hard to reach corner cases. Note: To enable the new constraint features, use the -ntb_opts new_constraints compile-time option. Random Variables You need variables to which VCS assigns random values.
Variable randc1 has two bits so its possible values range from 3 to 0. VCS derives a random order, or permutation, of all the possible values, and assigns the values in the permutation in a sequence. If VCS assigns a value of 3, it won’t assign 3 again until it first assigns 2, 1, and 0 (in no particular order), and after it assigns the permutation, it derives the next permutation, beginning with any of the possible values.
class myclass; rand logic [1:0] log1,log2,log3; randc logic [1:0] log4; constraint c1 {log1 > 0;} constraint c2 {log2 < 3;} endclass myclass mc = new; initial repeat (10) if(mc.randomize()==1) $display("log1 = %0d log2=%0d log3=%0d log4=%0d",mc.log1, mc.log2, mc.log3, mc.log4); endprogram In this program block class myclass contains the following: • Declarations for standard random variables, with the logic data type and two bits, named log1, log2, and log3.
log1 log1 log1 log1 log1 log1 log1 log1 log1 = = = = = = = = = 1 2 1 3 3 3 1 2 1 log2=2 log2=0 log2=1 log2=2 log2=2 log2=1 log2=1 log2=0 log2=0 log3=0 log3=1 log3=1 log3=1 log3=3 log3=0 log3=1 log3=2 log3=2 log4=0 log4=1 log4=3 log4=0 log4=3 log4=2 log4=1 log4=3 log4=0 The possible values of all the random variables range from 3 to 0, but the values of log1 are never 0, and the values of log2 are never greater than 3.
External Declaration You can declare a constraint block outside of a class declaration. program prog1; class cl1; rand integer rint1, rint2, rint3; constraint constr1; endclass constraint cl1::constr1 { rint1 < rint2; rint2 < rint3; } endprogram Inheritance Constraints follow the same rules of inheritance as class variables, tasks, and functions.
Set Membership You can use the inside operator to specify a set of possible values that VCS randomly applies to the random variable. program prog; class myclass; rand int int1; constraint c1 {int1 inside {1, [5:7], [105:107]};} endclass myclass mc = new; initial repeat (10) if(mc.randomize()==1) $display("int1=%0d",mc.
All these values are equally probable. In the following example, the inside operator is used to specify possible values in an integer array: program test; class pkt; integer bills[0:8] = { 1, 2, 5, 10, 20, 50, 100, 500, 1000 }; rand integer v; constraint c4 { v inside bills; } endclass int result; pkt Pkt=new(); initial begin repeat (10) begin result = Pkt.randomize(); $display("v is %d\n",Pkt.
Weighted Distribution You can use the dist operator to specify a set of values or ranges of values, where you give each value or range of values a weight, and the higher the weight, the more likely VCS is to assign that value to the random variable.
• A range of 1 to 2, each value in this range has a weight of 1. The := operator, when applied to a range, specifies applying the weight to each value in the range. • A range of 6 to 7 with a weight of 5. The :/ operator specifies applying the weight to the range as a whole. • 9 with a weight of 10, which is twice as much as the weight for 6. The repeat loop repeats 1700 times so that we have a large enough sample.
constraint c1 { (norandvar == 1) -> (randcvar == 0);} endclass Bus bus = new; initial begin bus.norandvar = 0; #5 bus.norandvar = 1; #5 bus.norandvar = 0; #5 $finish; end initial repeat (15) #1 if (bus.randomize() ==1) $display("randcvar = %0b norandvar = %0b at %0t", bus.randcvar, bus.norandvar,$time); endprogram In constraint c1, when variable norandvar has a 1 value (the implication expression), VCS constrains random variable randcvar to 0. The -> token is the implication operator.
randcvar = 0 norandvar = 0 at 13 randcvar = 1 norandvar = 0 at 14 When variable norandvar is 0, random-cyclic variable randcvar is either 0 or 1. When variable norandvar is 1, random-cyclic variable randcvar is always 0. if else Constraints An alternative to an implication constraint is the if else constraint. The if else constraint allows a constraint or constraint set on the else condition.
$display("randcvar = %0d norandvar = %0b at %0t", bus.randcvar, bus.norandvar,$time); endprogram constraint c1 { if (norandvar == 1) randcvar == 0; else randcvar inside {[1:3]};} Constraint c1 specifies that when variable norandvar has the 1 value, VCS constrains random-cyclic variable randcvar to 0, and when norandvar doesn’t have the 1 value, in other words when it has the 0 value, VCS constrains random-cyclic variable randcvar to 1, 2, or 3.
program prog; class myclass; rand bit [7:0] randvar; endclass class myextclass extends myclass; rand myclass left = new; rand myclass right = new; constraint c1 {left.randvar <= randvar; right.randvar <= randvar;} endclass endprogram In this example, class myextclass extends class myclass. In class myextclass are two randomized objects (or instances) of class myclass. They are named left and right and are randomized because they are declared with the rand keyword.
A default constraint for a particular variable is deemed applicable if no other non-default constraints apply to that variable. The solver satisfy all applicable default constraints for all variables. If the applicable default constraints cannot be satisfied, the solver generates a solver failure. The following example illustrates the specification of default constraints.
• A default constraint block can be defined externally (that is, in a different file from the one in which the constraint block is declared). • You can use ordering constraints in default blocks, but these constraints will be treated as non-default constraints. Overriding default constraints. Default constraints are applied when they are not overridden by any non-default constraints and contain at least one default variable.
A default constraint does not override other default constraints under any condition. Thus, if you declare all constraint blocks as default, then none of them will be overridden. program P; class C; rand reg[3:0] x; default constraint c1 {x == 0;} endclass class D extends C; constraint d1 {x > 5;} endclass initial begin D d = new(); d.randomize(); d.d1.constraint_mode(0); d.randomize(); end endprogram In the example, the default constraint in block c1 is overriden by the non-default constraint in block d1.
initial begin D d = new(); d.y = 1; d.randomize(); d.y = 0; d.randomize(); end endprogram In the example, the default constraint in block c1 is overriden by the non-default constraint in block d1. The first call to randomize will pick a value between 6 and 15 for x, since the non-default constraint is applicable, given that the guard evaluates to TRUE. The default constraint is ignored.
Output x = 10 y = 0 In the example, x = 10 since only the second constraint in the default constraint block is overridden. program test; class A; rand reg[3:0] x; rand reg[3:0] y; rand reg g; default constraint T{x + y == 10;} constraint E {g -> y == 1;} function void post_randomize(); $display("x = %0d y = %0d g = %0d\n", x, y, g); endfunction endclass initial begin integer ret; A a = new; $display("First call to randomize, the guard g evaluates to FALSE\n"); ret = a.randomize() with {a.
Output: First call to randomize,the guard g evaluates to FALSE x = 9 y = 1 g = 0 Second call to randomize,the guard g evaluates to TRUE x = 3 y = 1 g = 1 Third call to randomize, constraint mode of constraint block E is OFF x = 1 y = 9 g = 1 In the first call to randomize, the guard is evaluated to FALSE. Therefore, the constraint does not override the default constraint and consequently x + y == 10. In the second call to randomize, the guard is evaluates to TRUE.
Output First call to randomize, rand mode of x and y are ON x = 3 y = 7 Second call to randomize, rand mode of x and y are OFF x = 0 y = 0 Return status of randomize is 1 In the first call to randomize, the default is not overridden and consequently, x + y == 10; In the second call to randomize, the rand mode of x and y are turned OFF and both are set to 0. In this call the default variables are rand mode OFF and the default constraint is there fore ignored. If not the randomize() would fail and return 0.
Unidirectional Constraints The current extension to the constraint language allows the specification of partition points in the constraint set using the unary function $void()or using the hard keyword in conjunction with solve-before, improving the performance and capacity of the solver system. • $void() • solve-before hard $void(). The constraint language allows the use of built-in unary identity function, $void(). Any valid constraint expression can be a parameter to the $void() function.
The $void() function imposes an ordering among the variables. All parameters to $void() function calls in a constraint are solved for before the constraint is solved. The support set of a constraint (that is, the set of variables that participate in that constraint) is split into two sets, namely, those that are $void() parameters, and those that are not $void() parameters. 1.
} Table 24-2 Constraint Function Parameter y inside {2,3}; x%void(y)==0; y y x!=(y+r); z==void(x*y); Non-Function Parameter x x,y.r x,y r == 5; z r Figure 24-1 Figure 24-1 illustrates the dependencies between the variables. The variable y must be solved before x (see x% $void(y) ==0;). y and x must be solved before z (see z==$void(x*y);). Therefore, the solving order is y, x and then z. When can r be solved for? • Can r be solved at the same time as y? Consider the constraint x !=(y+r).
• Can r be solved at the same time as x? Consider x !=(y+r) again. Figure 24-1 illustrates that the relationship between r and x is bidirectional which means there is no unidirectional constraint imposed between these two variables as well as there is no ordering dependency between x and r therefore, the constraints can be solved at the same time. The solving order: 1. y 2. x and r 3. z The constraints used for solving x,y, z and r are: 1. y is solved using the constraint y inside {2,3}. 2.
• A void() function being applied to a sub-expression of the parameter of another void() function (for example, constraint b1{x==$void(y + $void(z));} - the runtime will ignore the nested $void() specifications (that is, same as x==$void(y+z). Whenever the compile is not able to detect such conditions, no warning is issued at runtime. solve-before hard. The solve-before construct allows for an optional hard modifier.
2. The constraint is solved when the lowest priority variables incident on it are solved. 3. When the constraint is solved, all lowest priority variables incident on it get solved. 4. hard solve-before constraints in OFF constraint blocks are ignored, and do not affect partitioning in any way.
2. x is solved using the constraints: x%y == 0; x!=y; 3. z is solved using the constraint: z ==x*y; The sequence in which the constraints are solved is exactly as listed in the previous section. solve-hard before and $void(). $void() and solve-before hard have the same behavior regarding partitioning the solver-space (that is, every randomized variable inside the $void() or solve-before hard is solved first and set to static values prior to randomizing any other variables in the constraint).
Semantics of solve-before construct without the hard modifier The solve-before constraints that are not modified by the “hard” directive will be used together in a partition. Thus, the non-hard solve-before constraints will not affect the partitioning, but will affect the order of variable assignment within a partition, very much like they affect the order of variable assigning on the complete problem prior to this release.
class B; rand integer x[$]; rand bit[1:0] k; constraint b1 { x.size() == k; k != 2; foreach(x, i) { $void(k-1) == i -> x[i] == 0; } } endclass The constraints x.size() = k; k != 2; are solved for, since the use of the $void() function call renders k unconstrained in the constraint inside the foreach loop. The use of $void() in this example specifies that k is solved for before any of the members of the x array.
3. The loop is expanded and all the members of the x array are solved for. The semantics of array constraints in the presence of $void calls are as follows: 1. Implicit ordering relations are introduced between array sizes and members of the array, *only* those with variable expressions in the index. • Array sizes are solved before the constraints inside loops are solved or constraints involving array aggregate methods calls are solved.
1. y is solved using the constraint y inside {0,1}. 2. z, x are solved using the default constraint x<=y and the non-default constraints z==y; z=>x ==0;. the default constraint applies if and only if z is 0 (that is, if and only if y was chosen as 0 in the previous partition.).
However, when unidirectional constraints are used in the presence of randc variables, it is possible that rand variables could be solved before randc variables. Example 24-8 randc bit[3:0]x; rand bit[3:0] y,z; constraint b1{ y inside {0,1}; x<12; if($void(y)){ x<5; } else{ x<10; } z>x; } The sequence in which the constraints are solved is: 1. y is solved using the constraint y inside {0,1}. 2. x is solved using the constraints if(y) x<5 else x<10; x<12. 3. z is solved using the constraint z>x.
Randomize Methods randomize() Variables in an object are randomized using the randomize() class method. Every class has a built-in randomize() method. randomize() Generates random values for active random variables, subject to active constraints, in a specified instance of a class. This method returns a 1 if VCS generates these random values, otherwise it returns 0. Examples of the use of this method appear frequently in previous code examples.
constraint con_size { s > 0; s < 50; } endclass class Pkt; integer header[7]; rand bit [7:0] payload[]; size sz; function void pre_randomize(); /* Randomize the sz.s variable and instantiate the dynamic array. */ integer res; sz = new(); res = sz.randomize(); /* calling randomize() on object sz of class size. Randomizes rand variable s (constrained to >0 and <50 */ if(res==0) $display("Randomization Failed"); else begin if((sz.s>0) && (sz.s<50))/* check for size between 0 and 50*/ payload = new[sz.
integer success,i; initial begin pkt = new(); //instantiate pkt for (int j = 0; j < 5; j++) begin success = pkt.randomize(); /*calling randomize on object of class packet*/ if(success==0) $display("Randomization Failed"); else $display("Randomization Succeeded"); end // end of for loop end // end of initial block endprogram The output of the program is: payload.size = 12 Randomization Succeeded payload.size = 17 Randomization Succeeded payload.size = 8 Randomization Succeeded payload.
Syntax: task object[.constraint_identifier]::constraint_mode (bit ON | OFF); or function int object.constraint_identifier::constraint_mode(); In the following example, there are two constraint blocks defined in a class, bus. The constraint_mode() method, when used as a task, turns on and off the word_align and addr_range constraints. constraint_mode() is also being used as a function to report the ON/ OFF value of the two constraints.
else $display("Error with constraint_mode"); generateRandomAddresses(`N); // turn OFF "word_align" constraint in "bb" bb.word_align.constraint_mode(0); $display("=========one constraint ON ======="); generateRandomAddresses(`N); // turn OFF all constraints in "bb" bb.constraint_mode(0); $display("=========both constraints OFF ======="); generateRandomAddresses(`N); // turn ON "addr_range" constraint in "bb" bb.addr_range.
bb.addr = 36593 bb.addr = 19491 bb.addr = 6853 bb.addr = 48017 =========one constraint ON ======= bb.addr = 11 bb.addr = 8 bb.addr = 15 bb.addr = 7 bb.addr = 4 =========both constraints ON ======= bb.addr = 2 bb.addr = 10 bb.addr = 12 bb.addr = 10 bb.addr = 8 Disabling Random Variables SystemVerilog provides the predefined rand_mode() method to control whether a random variable is active or inactive. Initially, all random variables are active.
function int object.randvar_identifier::rand_mode(); rand_mode() returns -1 if the specified variable does not exist within the class hierarchy or it exists but is not declared as rand or randc. In the following example, there are two random variables defined in a class, bus. The rand_mode() method, when used as a task, turns on and off the random variables, addr and data. rand_mode() is also being used as a function to report on the value (ON or OFF) of the two random variables.
generateRandomAddresses(`N); // turn OFF "data" random variable in "bb" bb.data.rand_mode(0); $display("======one random variable ON ======"); generateRandomAddresses(`N); // turn OFF all random variables in "bb" bb.rand_mode(0); $display("======both random variables OFF======"); generateRandomAddresses(`N); // turn ON "data" constraint in "bb" bb.data.rand_mode(1); $display("======one random variable ON========"); generateRandomAddresses(`N); // turn ON all random variable in "bb" bb.
bb.addr = 121,, bb.data = 219 bb.addr = 121,, bb.data = 219 bb.addr = 121,, bb.data = 219 bb.addr = 121,, bb.data = 219 ========one random variable ON======== bb.addr = 121,, bb.data = 456 bb.addr = 121,, bb.data = 511 bb.addr = 121,, bb.data = 67 bb.addr = 121,, bb.data = 316 bb.addr = 121,, bb.data = 405 ======both random variables ON ======= bb.addr = 18,, bb.data = 491 bb.addr = 231,, bb.data = 113 bb.addr = 118,, bb.data = 230 bb.addr = 46,, bb.data = 96 bb.addr = 155,, bb.
repeat (10) begin int1 = bus.randomize() with {bitrand1[1:0] == 2'b00;}; if (int1 ==1) $display("bitrand1 = %0b", bus.bitrand1); end endtask initial inline(bus); endprogram The $display system task displays the following bitrand1 bitrand1 bitrand1 bitrand1 bitrand1 bitrand1 bitrand1 bitrand1 bitrand1 bitrand1 = = = = = = = = = = 100 100 100 0 100 100 0 100 100 0 In-line Constraint Checker The randomize() method can act as a checker when a special “null” argument is specified.
The following example illustrates the usage of in-line constraint checker. program test; class myclass; rand int a, b; // random variable a,b constraint cc { a + b == 4;} function new(); // constructor initiliazing values of a // and b a = 2; b = 2; endfunction endclass myclass mc = new; int i; initial begin $display("Calling Randomize method with null args :-"); i = mc.randomize(null); // values of a and b should be // preserved $display("a = %0d, b = %0d, return from method = %0d", mc.a, mc.
Random Number Generation SystemVerilog includes a number of system functions to work with random numbers. Some of these are: $urandom() The system function $urandom() generates pseudorandom numbers. It returns an unsigned 32-bit number every time this function is called. The syntax is: $urandom( seed ) The seed is an optional argument that determines the sequence of the random number that are generated. It could also be an expression. The same sequence is always generated for the same seed.
$display("Generation of random number with seed 3 :"); a = $urandom(3); b = $urandom(); c = $urandom(); d = $urandom(); $display("a = %0d,b= %0d, c = %0d, d = %0d",a,b,c,d); end endprogram The output of this program is: Generation a = 229,b= Generation a = 228,b= Generation a = 229,b= of random number with seed 3 : 175, c = 7, d = 99 of random number with seed 4 : 15, c = 254, d = 230 of random number with seed 3 : 175, c = 7, d = 99 $urandom_range() The system function $urandom_range() generates random
a = 10; a1 = 3; $display("Generating random numbers with urandom_range with expressions in range"); //generating value of b between 7 and 3 b = $urandom_range((a-a1), a1); //expressions as args to urandom_range $display("value of b generated with range %0d and %0d is %0d",a-a1,a1,b); //generating value of b between 3 and 7 b = $urandom_range(a1,(a-a1)); $display("value of b generated with range %0d and %0d is %0d",a1,a-a1,b); $srandom(2); // changing the seed for thread //generating value of b between 0 a
Providing the same seed ensures that the same set of random values are generated by the random number generator. The following program demonstrates that the same random numbers are generated for the same seed.
The output of this program is: Setting the seed as 2 through srandom a = 8, b = 3 a = 14, b = 3 Changing the seed as 1 through srandom a = 12, b = 13 a = 15, b = 9 Setting the seed once again to 2 through srandom a = 8, b = 3 a = 14, b = 3 Seeding for Randomization The srandom() method initializes the current Random Number Generator (RNG) of objects or threads using the value of the seed. The following example involves using srandom() to initialize the RNG for an object using a real variable as the seed.
d3 = a.x; a.srandom(r); d1 = a.randomize(); if(d1 == 1) d4 = a.x; if((d2 == d4) && (d2 != d3)) $display("test passed"); else $display("test failed"); end endprogram Output of the above program is: test passed randcase Statements The randcase construct specifies a block of statements with corresponding weights attached to them. Weights can be any expression. When a randcase statement occurs, one of the statement with weights is executed at random.
randcase a+3 10 : count_2++; // simple add expression as weight : count_c++; // constant used as weight endcase endfunction initial begin repeat (15) f1(); $display("Number of times a+3 called is %0d", count_2); $display("Number of times constant called is %0d", count_c); end endprogram The output of this program is: Number of times a+3 called is 5 Number of times constant called is 10 This example defines a randcase block of two statements with different weights (one as an expression and another as an
SystemVerilog’s sequence generation allows you to specify the syntax of valid sequences using BNF-like notation. Random sequences are ideal for generating streams of instructions for which it is easier to specify the syntax of valid streams than the constraints on specific values. This section includes the following: • RSG Overview • Production Declaration • Production Controls RSG Overview The syntax for programming languages is often expressed in Backus Naur Form (BNF) or some derivative thereof.
Note:Nesting of randsequence blocks is not supported When the randsequence block is executed, random production definitions are selected and streamed together to generate a random stream. How these definitions are generated is determined by the base elements included in the block. Any RSG code block is comprised of production definitions. Native Testbench also provides weights, production controls, and production system functions to enhance production usage.
The syntax for rs_production_list is: rs_prod{rs_prod} | rand join [(expression)] production_item production_item {production_item} weight_specification The syntax for weight_specification is: integral_number | ps_identifier | (expression) (see also “Weights for Randomization” on page 24-122) rs_code_block The syntax for rs_code_block is: {{data_declaration}{statement_or_null}} The following table provides the syntax for the non-terminals within rs_production_list, weight_specification, and rs_code_block
A randsequence block is made up of one or more productions, yielding a “production list.” Productions are made up of terminals and non-terminals, as seen in the above syntax description. A terminal is an indivisible code element. It needs no further definition beyond the code block associated with it. A non-terminal is an intermediate variable defined in terms of other terminals and non-terminals.
F : {$write ("F");}; G : {$write ("G");}; endsequence end endprogram Production Controls SystemVerilog provides several mechanisms that can be used to control productions: weights for randomization, if-else statements, case statements, and repeat loops.
weight_specification The syntax for weight_specification is: integral_number | ps_identifier | (expression) The expression can be any valid SystemVerilog expression that returns a non-negative integer. Function calls can be made within the expression, but the expression must return a numeric value, or else a simulation error is generated. Assigning weights to a production item affects the probability that it is selected when the randsequence block is called.
If the conditional evaluates to true, the first production item is selected. If it evaluates to false, the second production item is selected. The else statement can be omitted. If it is omitted, a false evaluation ignores the entire if statement. The following is an example of a production definition with an if-else statement. assembly_block : if (nestingLevel > 10) seq_block else any_block; This example defines the production assembly_block.
case Statements A general selection mechanism is provided by the case statement. The syntax to declare a case statement within a production definition is: case(expression) rs_case_item {rs_case_item} endcase expression Is evaluated. The value of the expression is successively checked, in the order listed, against each rs_case_item.
repeat Loops The repeat loop is used to loop over a production a specified number of times. The syntax to declare a repeat loop within a production definition is: repeat(express) production_item expression Can be any valid SystemVerilog expression that evaluates to a non-negative integer, including functions that return a numeric value. The expression is evaluated when the production definition is executed. The value specifies how many times the corresponding production item is executed.
Syntax break; A break statement can be executed from within an rs_code_block within a production definition. When a break statement is executed, the randsequence block terminates immediately and control is passed to the first line of code after the randsequence block. The following is an example of a production definition using a break statement. return Statement The return statement is used to interrupt the execution of the current production.
Aspect Oriented Extensions The Aspect oriented extensions is a Limited Customer availability (LCA) feature in NTB(SV) and requires a separate license. Please contact your Synopsys AC for a license key. Aspect-Oriented Programming (AOP) methodology complements the OOP methodology using a construct called aspect or an aspect-oriented extension (AOE) that can affect the behavior of a class or multiple classes. In AOP methodology, the terms “aspect” and “aspect-oriented extension” are used interchangeably.
methodology. AOP is a way of modularizing such cross-cutting concerns. AOP extends the functionality of existing OOP derived classes and uses the notion of aspect as a natural unit of modularity. Behavior that affects multiple classes can be encapsulated in aspects to form reusable modules.
For information on the creation and refinement of verification testbenches, see the Reference Verification Methodology User Guide. Aspect-Oriented Extensions in SV In SV, AOP is supported by a set of directives and constructs that need to be processed before compilation.
An extends directive for a class defines a scope in SV language. Within this scope exist the items that modify the class definition. These items within an extends directive for a class can be divided into the following three categories. • Introduction Declaration of a new property, or the definition of a new method, a new constraint, or a new coverage group within the extends directive scope adds (or introduces) the new symbol into the original class definition as a new member.
Processing of AOE as a Precompilation Expansion As a precompilation expansion, AOE code is processed by VCS to modify the class definitions that it extends as per the directives in AOE. A symbol is a valid identifier in a program. Classes and class methods are symbols that can be affected by AOE. AOE code is processed which involves adding of introductions and weaving of advices in and around the affected symbols.
Syntax: extends_directive ::= extends extends_identifier (class_identifier)[dominate_list]; extends_item_list endextends dominate_list ::= dominates(extends_identifier {,extends_identifier}); extends_item_list ::= extends_item {extends_item} extends_item ::= class_item | advice | hide_list class_item ::= class_property | class_method | class_constraint | class_coverage | enum_defn advice ::= placement procedure placement ::= before | after | around procedure ::= | optional_method_specifiers task task_ident
stmt ::= statement | proceed ; hide_list ::= hide([hide_item {,hide_item}]); hide_item ::= // Empty | virtuals | rules The symbols in boldface are keywords and their syntax are as follows: extends_identifier Name of the aspect extension. class_identifier Name of the class that is being extended by the extends directive. dominate_list Specifies extensions that are dominated by the current directive. Domination defines the precedence between code woven by multiple extensions into the same scope.
aspects are added to the class definition. It also determines the order in which advices defined in the aspects are woven into the class method definitions thus affecting the behavior of a class method. Rules for determination of precedence among aspects are explained later in “Precedence” on page 24-143. class_property Refers to an item that can be parsed as a property of a class. class_method Refers to an item that can be parsed as a class method.
opt_method_specifiers Refers to a combination of protection level specifier (local, or protected), virtual method specifier (virtual), and the static method specifier (static) for the method. task_identifier Name of the task. function_identifier Name of the function. function_type Data type of the return value of the function. list_of_task_proto_formals List of formal arguments to the task. list_of_function_proto_formals List of formal arguments to the function.
element could be any of the keywords, before, after, or around, and the advices with these placement elements are referred to as before advice, after advice and around advice, respectively. proceed statement The proceed keyword specifies an SV statement that can be used within advice code. A proceed statement is valid only within an around block and only a single proceed statement can be used inside the advice code block of an around advice.
The following table shows the rest of the steps involved in weaving of the advice for each type of placement element (before, after, and around). Table 24-4 Placement Elements Element Description before Inserts a new method-call statement that calls an advice method. The statement is inserted as the first statement to be executed before any other statements. after Creates a new method A with the target method prototype, with its first statement being a call to the target method.
Advice: before task myTask (); $display("Before in aoe1\n"); endtask Weaving of the advice in the target method yields the following. task myTask(); mytask_before(); $display("Executing original code\n"); endtask task mytask_before (); $display("Before in aoe1\n"); endtask Note that the SV language does not impose any restrictions on the names of newly created methods during pre-compilation expansion, such as mytask_before .
Weaving of the advice in the target method yields the following. task myTask_newTarget(); myTask(); myTask_after(); endtask task myTask(); $display("Executing original code\n"); endtask task myTask_after (); $display("After in aoe1\n"); endtask As a result of weaving, all the method calls to myTask() in the input program code are replaced by method calls to myTask_newTarget(). Also, myTask_newTarget replaces myTask as the target method for myTask().
Weaving of the advice in the target method yields the following. task myTask_around(); $display("Around in aoe1\n"); endtask task myTask(); $display("Executing original code\n"); endtask As a result of weaving, all the method calls to myTask() in the input program code are replaced by method calls to myTask_around(). Also, myTask_around() replaces myTask() as the target method for myTask().
Weaving of the advice in the target method yields: task myTask_around(); myTask(); $display("Around in aoe1\n"); endtask task myTask(); $display("Executing original code\n"); endtask As a result of weaving, all the method calls to myTask() in the input program code are replaced by method calls to myTask_around(). The proceed statement in the around code is replaced with a call to the target method myTask(). Also, myTask_around replaces myTask as the target method for myTask().
5. Weaving of all advices in the input program are weaved into their respective class methods as per the precedence order. These steps are described in more detail in the following sections. Precedence Precedence is specified through the dominate_list (see “dominate_list” on page 24-134) There is no default precedence across files; if precedence is not specified, the tool is free to weave code in any order.
class packet; ... // Other member fields/methods ...
since aspect_3 is coded later in Input.vr than aspect_2, aspect_3 has higher precedence than aspect_2. Therefore, the precedence of these aspect extensions in the decreasing order of precedence is: {aspect_1, aspect_3, aspect_2} This implies that the advice(s) within aspect_2 have lower precedence than advice(s) within aspect_3, and advice(s) within aspect_3 have lower precedence than advice(s) within aspect_1. Therefore, advice 2 has lower precedence than advice 3 and advice 4.
Weaving of advices An input program may contain several aspect extensions for any or each of the different class definitions in the program. Weaving of advices needs to be carried out for each class method for which an advice is specified. Weaving of advices in the input program consists of weaving of advices into each such class method.
other in the sense that their relative precedence to each other does not affect their relative order of execution when a method call to the target method is executed. The before advice’s code block executes before the target method code block, and the after advice code block executes after the target method code block. When an around advice is used with a before or after advice in the same aspect, code weaving depends upon their precedence with respect to each other.
$display("Aspect_2: send advice after\n"); endtask endclass extends aspect_1(packet) dominates (aspect_2, aspect_3); after task send(); // Advice 1 $display("Aspect_1: send advice after\n"); endtask endextends extends aspect_3(packet); around task send(); // Advice 3 $display("Aspect_3: Begin send advice around\n"); proceed; $display("Aspect_3: End send advice around\n"); endtask before task send(); // Advice 4 $display("Aspect_3: send advice before\n"); endtask endextends // End of file Input.
...
call to send_Created_a. At the end of this step, send_around_Created_c becomes the new target method for weaving of further advices to packet::send. Example 24-14 // Beginnning of file Input.vr program top; packet p; p = new(); p.send_around_Created_c(); endprogram class packet; ... // Other member fields/methods ...
endtask endextends // End of file Input.sv This Example 24-14 shows what the input program looks like after weaving advice 4 into the class method. A new method send_before_Created_d is created in this step and a call to it is added as the first statement in the target method packet::send_around_Created_c.
$display("Aspect_2: send advice after\n"); endtask task send_around_Created_c(); send_before_Created_d(); $display("Aspect_3: Begin send advice around\n"); send_after_Created_a(); $display("Aspect_3: End send advice around\n"); endtask task send_before_Created_d(); $display("Aspect_3: send advice before\n"); endtask task send_after_Created_e(); $display("Aspect_1: send advice after\n"); endtask task send_Created_f(); send_around_Created_c(); send_after_Created_e() endtask endclass // End of file Input.
// Begin file input.vr program top; foo f; f = new(); f.myTask(); endprogram class foo; int i; task myTask(); $display("Executing original code\n"); endtask endclass extends aoe1 (foo) dominates(aoe2); around task myTask(); proceed; $display("around in aoe1\n"); endtask endextends extends aoe2 (foo); around task myTask(); proceed; $display("around in aoe2\n"); endtask endextends // End file input.
f = new(); f.myTask(); endprogram class foo; int i; task myTask(); printf("Executing original code\n"); endtask endclass extends aoe1 (foo); around task myTask(); proceed; printf("around in aoe1\n"); endtask endextends extends aoe2 (foo) dominates (aoe1); around task myTask(); proceed; printf("around in aoe2\n"); endtask endextends // End file input.
Because advices are woven after introductions have been added to the class definitions, advices can be specified for introduced member methods and can reference introduced symbols. An advice to a class method can access and modify the member fields and methods of the class object to which the class method belongs. An advice to a class function can access and modify the variable that stores the return value of the function.
before task foo(integer x); x = 99; //force every call to foo to use x=99 endtask endextends // End file example.sv The extends directive in Example 24-17 sets the x parameter inside the foo() task to 99 before the original code inside of foo() executes. Actual argument to foo() is not affected, and is not set unless passed-by-reference using ref. Example 24-18 // Begin file example.sv program top ; packet p; p = new(); $display(“Output is: %d\n”, p.
When executed, the output of the program code is: Point 1: Value = 5 Point 2: Value = 5 Point 3: Value = 6 Output is: 6 hide_list details The hide_list item of an extends_directive specifies the permission(s) for introductions to hide symbols, and/or advice to modify local and protected methods.
Example 24-19 class pbase; virtual task print(); $display("I’m pbase\n"); endtask endclass class packet extends pbase; task foo(); $display(); //Call the print task endtask endclass extends myaspect(packet); hide(virtuals); // Allows permissions to // hide pbase::print task virtual task print(); $display("I’m packet\n”); endtask endextends As explained earlier, there are two types of hide permissions: a.
b. Permission to suspend access rules and to specify advice that changes protected and local virtual methods (option "rules") is referred to as rules-permission. If within an aspect, at an aspect item, such permission is granted, then the rules-permission is said to be on or the status of rules-permission is said to be on at that aspect item and at all the aspect items following that, until a hide list that forfeits the permission is encountered.
class packet extends pbase; task foo(); $display(); endtask local virtual task rules-test(); $display("Rules-permission example\n"); endtask endclass extends myaspect(packet); // At this point within the myaspect scope, // virtuals-permission and rules-permission are both off. hide(virtuals); // Grants virtuals-permission // virtuals-permission is on at this point within aspect, // and therefore can define print1 method introduction.
Example 24-21 is shows how AOE can be used to introduce new members into a class definition. myaspect adds a new property, constraint, coverage group, and method to the packet class. Example 24-21 class packet; rand bit[31:0]... ...
constraint con1 { myfield == 4; } endextends Examples of advice code In Example 24-23, the extends directive adds advices to the packet::send method. Example 24-23 : // Begin file example.sv program test; packet p; p = new(); p.send(); endprogram class packet; task send(); $display("Sending data\n”); endtask endclass extends myaspect(packet); before task send(); $display("Before sending packet\n"); endtask after task send(); $display("After sending packet\n"); endtask endextends // End file example.
In Example 24-24, extends directive myaspect adds advice to turn off constraint c1 before each call to the foo::pre_randomize method. Example 24-24 : class foo; rand integer myfield; constraint c1 { myfield == 4; } endclass extends myaspect(foo); before task pre_randomize(); constraint_mode(OFF, "c1") endtask endextends In Example 24-23, extends directive myaspect adds advice to set a property named valid to 0 after each call to the foo::post_randomize method.
Example 24-26 // Begin file example.sv program test; packet p; p = new(); p.setLen(5000); p.send(); p.setLen(10000); p.send(); endprogram class packet; integer len; task setLen( integer i); len = i; } task send(); $display("Sending data\n”); endtask endclass extends myaspect(packet); around task send(); if (len < 8000){ proceed; } else{ $display("Dropping packet\n"); } endtask endextends // End file example.
Array manipulation methods VCS-NTB provides the following types of built-in methods for analyzing and manipulating arrays. - Array ordering methods - Array locator methods - Array reduction methods Note: For the integral types the with construct is not required but for non integral type like class objects, mailbox or semaphores using the with construct enhances the array manipulation methods ability to deliver.
sort() The sort() method sorts the element in an ascending order using the expression in the with construct. The with expression is optional here. Syntax task array_name.sort() [with (expression)]; Example 24-28 queue1.sort(); queue2.sort() with (item.i ); In the first example the queue1 is sorted in ascending order of the value of the elements provided they are of a integral type.
In the first example the elements in the queue1 are sorted in descending order of their values provided they are of a integral type. In the second example queue2 is a queue of class objects and the class contains an element i and r, now the objects are sorted in descending order depending on the product value of the member variable i and r.
Example 24-30 queue2 = queue1.find() with (queue1.leg() > 5); In the example, queue1 contains a set of strings, all the elements whose string length is greater than 5 are returned and they are assigned in the same order to the queue queue2. find_index() The find_index() method returns the indexes of all the elements satisfying the expression using the with construct. If the match fails or if the array is empty an empty queue is returned. The with expression is required and is not optional.
function array_type[$] array_name.first() with (expression); Example 24-32 value = queue1.first() with (item > 5); object = queue1.first() with (item.x > 5); In the first example, the first element which is greater than 5 is returned. In the second example, the first element with the member variable greater than 5 is returned. find_first_index() The find_first_index() method returns the first index satisfying the expression using with construct.
find_last() The find_last() method returns a queue with the last element satisfying the expression. If the array is empty, a warning message is issued and an empty queue is returned. The with expression is required and is not optional. Syntax function array_type[$] array_name.last() with (expression); Example 24-34 value = array1.last() with (item == 5); object = array1.last() with (item.x == 5); In the first example, the last element which is equal to 5 is returned.
In the first example, the index of the last element which is greater than 5 is returned. In the second example, the index of the last element has its member variable x equal to 5 is returned. min() The min() method returns a queue with the minimum value element for the integral types. For non-integral types the method returns a queue with the element whose with expression evaluates to a minimum. If the array is empty, a warning message is issued and a type dependent default value is returned.
Syntax function array_type[$] array_name.max() [with (expression)]; Example 24-37 value = array1.max(); object = array1.max() with (item.x >5); object = array1.max() with (item.x * item.y); The first example, returns a maximum value element of the array. The second example returns the element that has the maximum value of the member variable x. The third example returns the element that has the maximum value of the product of the member values of x and y.
unique_index() The unique_index()method returns the indexes of all elements with unique values or whose expression is unique. If the array is empty or if no match is found with the expression then an empty queue is returned. The with expression is optional here. Syntax function int_or_index_type[$] unique_index() [with (expression)]; Example 24-39 array2 = array1.unique_index(); In the example indices of only the unique elements are returned.
Example 24-40 value = Qint.sum(); // Calculates sum of all elements value = QPacket.sum() with (item.pkt_size); // Computes sum of // member pkt_size for all elements of queue SQPacket. In the first example the sum of all the elements of the queue Qint is calculated. The second example computes sum of member variable pkt_size for all elements of queue QPacket is calculated. product() The product() method computes the product of all the array elements for integral types.
and() The and() method computes the bitwise AND (&) of all the array elements for integral types. The with expression is optional for integral types. When the with expression is specified for non-integral types they returns the bitwise AND (&) of the member variables specified using the with expression. Syntax function expression_or_array_type array_name.and() [with (expression)]; Example 24-42 value = Qint.and(); // Calculates bitwise AND of all elements value = QPacket.and() with (item.
Example 24-43 value = Qint.or(); // Calculates sum of all elements value = QPacket.or()with (item.pkt_size ); // Computes bitwise // OR of member pkt_size for all elements of queue QPacket. In the first example the bitwise OR of all the elements of the queue Qint is calculated. The second example computes bitwise OR of member variable pkt_size for all elements of queue QPacket is calculated. xor() The xor() method computes the logical xor (^) of all the array elements for integral types.
Interprocess Synchronization and Communication Semaphores SystemVerilog semaphores are not signal devices. They are buckets that contain keys, where competing resources, such as different initial blocks in a program, require keys from the bucket to continue processing. program prog; semaphore sem1 = new(2); initial begin:initial1 #1 sem1.get(1); $display("initial1 takes 1 key at %0t", $time); #6 sem1.put(1); $display("initial1 returns 1 key at %0t",$time); #1 sem1.
The program has a semaphore named sem1 that starts with two keys, as specified with the semaphore keyword and new() method. If it were not for initial2, initial1 would do the following: 1. Take a key at simulation time 1 (using the get method). 2. Return a key at time 7 (using the put method). 3. Take a key again at time 8 (using the get method). If it were not for initial1, initial2 would do the following: 1. Take two keys at simulation time 5 (using the get method). 2.
#5 sem1.put(1); $display("inital2 returns 1 key at %0t",$time); end endprogram In the revised initial2, at simulation time 5, the try_get method checks to see if there are two keys in sem1. There aren’t, because initial1 took one. At time 10 the put method “returns” a key to sem1. Actually the get and put methods only decrement and increment a counter for the keys, there are no keys themselves, so initial2 can increment the key count without having previously decrementing this count.
get(number_of_keys) Decrements the number of keys in the semaphore. If there aren’t the specified number of keys in the semaphore, VCS halts simulation of the process (initial block, task, etc.) until there the put method in another process increments the number of keys to the sufficient number. try_get (number_of_keys) Decrements the number of keys in the semaphore. If there aren’t the specified number of keys in the semaphore, this method returns a 0.
end i = mbx.num(); repeat (3) begin #5 $display("No. of msgs in mbx = %0d j = %0d at %0t",i,j,$time); mbx.get(j); i = mbx.num(); end end endprogram This program declares a mailbox named mbx with the mailbox keyword and the new() method. The initial block does the following: 1. Executes a repeat loop three times which does the following: a. Puts the value of k in the mailbox. b. Assigns the number of messages in the mailbox to i. c. Increments the value of k. 2.
Mailbox Methods Mailboxes use the following methods: new() Along with the mailbox keyword, declares a new mailbox. You cannot yet specify the maximum number of messages with this method. num() Returns the number of messages in the mailbox. put(expression) Puts another message in the mailbox. get(variable) Assigns the value of the first message to the variable. VCS removes the first message so that the next message becomes the first method.
try_peek(variable) Assigns the value of the first message to the variable without removing the message. If the mailbox is empty, this method returns the 0 value. If the message is available, this method returns a non-zero value. After returning the value, VCS executes the next statement. Note VCS does an assignment compatibility check instead of equivalent types check for the mailbox methods. Events SystemVerilog has a number of extensions to named events.
task t1; event evt1; #5 -> evt1; endtask initial t1; initial @(t1.evt1) $display("t1.evt1 happened at %0t",$time); endprogram The $display system task displays the following: t1.evt1 happened at 5 Persistent Trigger The triggered property persists on a named event throughout the time step when it is triggered, preventing a race condition, for example, when a named event is triggered and is evaluated in an event control during the same time step.
fork -> evt2; begin wait (evt2.triggered); $display("evt2 occurred"); end join endprogram The $display system tasks display the following: evt1 triggered evt2 occurred Merging Events You can assign a SystemVerilog named event to another named event. When you do, they alias each other and when VCS executes a line calling for the triggering of one of these events, VCS triggers both named events.
initial #1 @ (evt3) $display("evt3 triggerred"); endprogram The $display system tasks display the following: evt1 triggerred evt2 triggerred evt3 triggerred IMPORTANT: When you merge events, the merger takes effect only in subsequent event controls or wait statements. In this example, the merging occurred at time 0, the event controls at time 1, and the triggering of the events at time 2.
#1 @(evt1) $display("evt1 triggered"); initial begin #5 wait (evt1.triggered); $display("evt1 occurred"); end endprogram The $display system tasks do not display anything.
evt1 === evt2 evt1 != evt3 evt3 != null In comparing named events, the case equality operator === works the same as the equality operator ==, and the case inequality operator !== works the same as the inequality operator !=. Clocking Blocks A clocking block encapsulates a group of signals that are sampled or synchronized by a common clock. It defines the timing behavior of those signals with respect to the associated clock.
clocking_identifier Name of the clocking block being declared. clocking_event Event that acts as the clock for the clocking block (for example: posedge, negedge of a clocking signal): @(posedge clk) or @(clk) Note: Program signals cannot be used inside a clocking event expression. clocking_dir Direction of the signal: input, output or inout. If you specify more than one clocking_dir, they must be in the order input...
clocking_skew Determines how long before the synchronized edge the signal is sampled, or how long after the synchronized edge the signal is driven. A clocking_skew can consist of an edge identifier and a delay control, just an edge identifier, or just the delay control. The edge identifiers are posedge and negedge. The edge can be specified only if the clocking event is a singular clock (that is, a simple edge of a single signal like @(posedge clk), @(clk), @(negedge top.clk), etc.).
input #1 i1; where i1 is the signal_identifier. Note: A clocking block signal can only be connected to a scalar, vector, packed array, integer or real variable. Program signals are not allowed in clocking block signal declarations. hierarchical_identifier Hierarchical path to the signal being assigned to the signal_identifier. For example: input negedge #2 i = top.i2; where i2 is defined in a module top. Note: see page 182 of the System Verilog LRM 3.
reg out3; reg out1; reg clk = 0; p1 p(out3,clk,out1); assign out1 = out3; initial forever begin clk = 0; #10; clk = 1; #10; end endmodule program p1(output reg out3,input logic clk,input reg in ); clocking cb @(posedge clk); output #3 out2 = out3; //CB output signal input #0 out1 = in; endclocking initial #200 $finish; initial begin $display($time,,,cb.out1); cb.out2 <= 0; //driving output at "0" time @(cb.out1); //sampling input for change $display($time,,,cb.out1); #100; $display($time,,,cb.out1); cb.
end endprogram The output of this program is: 0 x 30 0 130 0 150 1 Input and Output Skews The skew for input and inout signals determines how long before clocking_event the signal is sampled. The skew for output and inout signals determines how long after the clock_event the signal is driven. Figure 24-3 Driving and sampling on the negative edge of the clock input signal sampled here output signal driven here Clock input skew output skew For more details see section 15.3 of the SystemVerilog LRM 3.
Hierarchical Expressions Every signal in a clocking block is associated with a program port or a cross module reference. As described when defining hierarchical_identifier, the hierarchical path is assigned to the defined in the clocking block. clocking cb2 @ (negedge clk); input #0 b = top.
endclocking Clocking blocks that use the same clock can share the same synchronization event. For example: program test( input bit clk_1, input reg [15:0] address, input reg [15:0] data ); default clocking data @(posedge clk_1); input data; endclocking clocking address @(posedge clk_1); input address; endclocking Clocking Block Scope and Lifetime Signals associated with a clocking block can be accessed by using a dot (.) operator.
Clocking Block Events The clocking_identifier can be used to refer to the clocking_event of a clocking block. For example: clocking cb1 @(posedge clk); input #0 i1; input negedge #2 address; endclocking The clocking event of the cb1 clocking block can be used to wait for that particular event: @(cb1); Therefore, @(cb1) is equivalent to @(posedge clk).
Note: You can specify only one default clocking block in a program, module, or interface. VCS issues a compilation error if you specify more than one default clocking block. For example: program test( input bit clk, input reg [15:0] data ); default clocking bus @(posedge clk); input data; endclocking initial begin ## 5; if ( bus.data == 10 ) ## 1; else ##2; end endprogram Cycle Delays Cycle delays can be used to postpone or delay the execution by a specified number of clock cycles or clocking events.
Any SystemVerilog expression that evaluates to a positive integer value. For example: ## 2; ## (x+1); Note: VCS issues a compilation error if you use a cycle delay without specifying a default clocking block for the current module, interface, or program. Input Sampling All inputs and inouts of a clocking block are sampled at the clocking_event for that block.
Synchronous Events The event control operator, @, is used for explicit synchronization. This operator causes a process to wait for a particular event (that is, signal value change, or a clocking event) to occur. Syntax @ (expression); expression denotes clocking block input or inout, or a slice, which may include dynamic indices. The dynamic indices are evaluated when @(expression) executes. For examples, see pages 189-190 of the SystemVerilog LRM3.
initial begin @ (cb1); //synchronising with clocking event cb1.a <= 0; //drive at first posedge cb1.b <= 0; //drive after skew on first posedge ##2 cb1.a <= 1; ##1 cb1.b <= 1; //drive after 3 clock cycles end The expression cb1.a (and cb1.b) is referred to as the clockvar_expression in the SystemVerilog LRM 3.1a (see page 190). Note:Synchronous drives with a blocking cycle delay is supported. However, a synchronous drive with an intra cycle delay is not yet supported.
sequence seq ; @(ck1) a ##1 b ; endsequence A: assert property (@(ck1) a ##1 b) ; N: assert property (seq) ; In this example the clocking block named ck1 is specified a the clock signal in the sequence and the two assertions. The clocking event in the clocking block, posedge clk, becomes the clock signal. Sequences and Properties in Clocking Blocks You can enter sequences and properties in a clocking block and then use them in an assertion.
SystemVerilog Assertions Expect Statements SystemVerilog assertions expect statements differ from assert, assume, and cover statements in the following ways: • expect statements must appear in a SystemVerilog programs, whereas assert, assume, and cover statements can appear in modules, interfaces, and programs. • You can declare sequences and properties and use them as building blocks for assert, assume, and cover statements, but this is not true for expect statements.
The following is an example of an expect statement: e1: expect (@(posedge clk) ##1 in1 && in2) begin . // statements VCS executes . // if in1 && in2 is true . end else begin . // Statements VCS executes . // if in1 && in2 is false . end Where: e1: Is an instance name for the expect statement. You can use any unique name you want, followed by a colon (:). expect The expect keyword. (@(posedge clk) ##1 in1 && in2) Is the property of the expect statement. Such properties are enclosed in parentheses.
called the success block. if false VCS executes the second action blockafter the keyword else, called the failure block. Here is another example of an expect statement. This one calls for evaluating the expression after a range of clocking events. e2: expect (@(posedge clk) ##[1:9] in1 && in2) begin . // statements VCS executes . // if in1 && in2 is true . end else begin . // Statements VCS executes . // if in1 && in2 is false .
[*] is the consecutive repeat operator. This expect statement calls for waiting a clock delay and then seeing if the expression is true, and doing both of these things five times in a row. Note: You can use the [*] consecutive repeat operator when you specify a range of clocking events such as ##[1:9].
else begin bit1=0; $display("failure at %0t in %m\n",$time); end e2: expect (@(posedge clk) ##[1:9] in1 && in2) begin bit1=1; $display("success at %0t in %m\n",$time); end else begin bit1=0; $display("failure at %0t in %m\n",$time); end e3: expect (@(posedge clk) ##1 in1 && in2 [*5]) begin bit1=1; $display("success at %0t in %m\n",$time); end else begin bit1=0; $display("failure at %0t in %m\n",$time); end end endprogram The program block includes an elementary clocking block, specifying a clocking event o
success at 125 in test.tbpb1.e3 Virtual Interfaces A Virtual Interface (VI) allows a variable to be a dynamic reference to an actual instance of an interface. VCS classifies such a variable with the Virtual Interface data type. Here is an example: interface SBus; logic req, grant; endinterface module m; SBus sbus1(); SBus sbus2(); . . . endmodule program P; virtual SBus bus; initial begin bus = m.sbus1; // setting the reference to a real // instance of Sbus $display(bus.grant); // displaying m.sbus1.
Scope of Support VCS supports virtual interface declarations in the following locations: • program blocks and classes (including any named sub-scope) • tasks or functions inside program blocks or classes (including any named sub-scope). Variables with the virtual interface data type can be either of the following: • SystemVerilog class members. • Program, task, or function arguments. You cannot declare a virtual interface in a module or interface definition.
writing assignments are subject to modport direction enforcement so that, for example, “sb.req = 1" would become illegal now (violates input direction of the modport REQ). Driving a Net Using a Virtual Interface There are two ways of driving interface nets from a testbench.
interface intf(input clk); int d; clocking cb @(posedge clk); default input #2 output #2; inout d; endclocking modport CB(clocking cb); //synchronous testbench modport modport master(inout d); //asynchronous testbench modport endinterface module top; bit clk; always #5 clk = ~clk; intf INTF(clk); tb TB(INTF); endmodule program tb(intf.CB ckb); //CB type modport is used to pass //clocking information with interface signals virtual intf.CB x = ckb; initial #200 $finish; initial begin x.cb.d <= 1; @(x.cb.
In the above example, if the modport passed to the testbench is of asynchronous type “intf.master” then the program will be: program tb(intf.master ckb); virtual intf.master x = ckb; initial begin x.d <= 1; x.d <= 2; end endprogram @(x.d); $display($time,,x.d); @(x.d); $display($time,,x.d); The output of this example is: 0 0 1 2 Since clocking information is not passed through modport, the values are driven irrespective of clock.
program p; virtual intf VI[3:0]; initial begin VI = top.INTF; //aggregate assignment $display(VI[0].k); t1(VI);//passing whole VI array to task end task t1(virtual intf vif[3:0]); $display(vif[0].k); endtask endprogram module top; intf INTF [3:0](); endmodule The output of this program is: 30 30 Driving/sampling of interface signals through Virtual Interface array elements is possible.For example: VI[0].k <= 10; @ (VI[0].
endinterface .... program P; virtual SyncBus vi; ... initial vi.cb.w <= 1; ... endprogram In this case the assignment executes in accordance with the clocking block semantics. Event Expression/Structure Consider SyncBus as defined in the section “Clocking Block” . task wait_on_expr(virtual SyncBus vi1, virtual SyncBus vi2); @(posedge (vi1.a & vi2.a)) $display(vi1.b, vi2.
begin virtual I vi; vi.data <= 1; end • NULL assignment virtual I vi = NULL; Not Yet Implemented • Named type that involves virtual interface - typedef struct {reg rl; virtual I ii} T; - typedef virtual I T; • Comparison of vi variables By definition, vi1 == vi2 iff they refer to the same instance of an interface (or both NULL). • VI variables defined in the design. • Class member variable access through VI when is declared in parent interface.
VCS collects all the coverage data during simulation and generates a database. VCS provides a tool to read the database and generate text or HTML reports. The covergroup Construct The covergroup construct specifies the set of cover points of interest, crosses of these cover points and the clocking event that tells VCS when to sample these cover points during simulation. A covergroup can be declared inside a module or the program block.
endprogram This program contains the following: • The enumerated data type colors, with members named red, blue, and yellow (whose default values are 0, 1, and 2). • A variable of type colors called my_color • A covergroup named cg1 that specifies the following: - the clocking event that is the rising edge on signal clk. - the coverage point that is to monitor the values of the variable my_color. The identifier of the coverage point, for hierarchical name purposes, is cp1.
Defining a Coverage Point In a coverage point definition you can specify the following: • bins for value ranges • bins for value transitions • bins for illegal coverage point values Bins for Value Ranges You use the curly braces { } and the bins keyword to specify the bins for a coverage point, for example: covergroup cg1 @ (posedge clk); coverpoint data { bins some_name [] = {[1:20]}; } endgroup In coverage point data: • The keyword bins specifies one or more bins for coverage data.
Coverage point data will have 20 bins, the first named some_name_1 and the last named some_name_20. Bin Value/ Range Resolution The values corresponding to the range specified by a bin for a coverpoint are resolved according to the precision and sign-ness of the corresponding coverpoint expression. To evaluate a bin hit and update the hit count the coverpoint and bin expressions are compared and evaluated. A warning is generated in the following cases.
Example : bit [1:0] cp_exp1; // type evaluates to the value range of 0 to 3 bit signed [2:0] cp_exp2; // type evaluates to the value range of -4 to 3 covergroup g1 @(posedge clk); coverpoint cp_exp1 { bins b_exp1 = {1, [2:5] }; bins b_exp2 = { -1, [1:4]}; } coverpoint cp_exp2 { bins b_exp3 = {1, [2:5], [6:10] }; } endgroup Warnings Issued and their resolutions A warning is issued for the bin b_exp1 since the range [2:5] exceeds the upper bound for the coverpoint cp_exp1.
You can specify different bins for different value ranges, for example: coverpoint data { bins first_ten = {[1:10]}; bins second_ten = {[11:20]}; } Here the coverage information about when the coverage point data has the values 1 to 10 is in the bin named first_ten, and the information about when data has the values from 11 to 20 is in the bin named second_ten.
Here the information about when data is 0, 1, 2, 3, 5, 7, 9, and 10 is in bin1, the information about when data is 4, 6, and 8 is in bin2, and the information about when data has any other value is in bin3.
You can use range lists to specify more than one starting value and more than one ending value, for example: bins from1and5to6and7 = (1,5=>6,7); Is the equivalent of: bins from1and5to6and7 = (1=>6, 1=>7, 5=>6, 5=>7); You can use the repetition [*] operator, for example: bin fivetimes3 = (3 [*5]); Is the equivalent of: bin fivetimes3 = (3=>3=>3=>3=>3); You can specify a range of repetitions, for example: bin fivetimes4 = (4 [*3:5]); Is the equivalent of: bin threetofivetimes4 = (4=>4=>4,4=>4=>4=>4,4=>4=
} VCS displays an error message when the coverage point reaches these values or makes these transitions. Defining Cross Coverage Cross coverage is when there are two coverage points that you want VCS to compare to see if all the possible combinations of the possible values of the two coverage points occurred during simulation.
In covergroup cg1 there are two coverpoints labeled bit1 and bit2. In addition, there is the following: 1. the bit1Xbit2 identifier for the cross. 2. The cross keyword, specifying the coverpoints to be crossed. Both coverpoints are two-bit signals. The four possible values of each are 0 through 3. There are 16 possible combinations of values. The prog.
The binsof construct supplies the coverage bins for the expression argument, which can be either a coverpoint or a coverpoint bin. covergroup cg1 @(posedge clk); cp1 : coverpoint bit1 { bins lowcp1vals = {[0:7]}; bins hicp1vals = {[8:15]}; } cp2 : coverpoint bit2 { bins lowcp2vals = {[0:7]}; bins hicp2vals = {[8:15]}; } cp1Xcp2 : cross cp1, cp2 { bins bin1 = binsof(cp1) intersect {[0:7]}; bins bin2 = binsof(cp1.hicp1vals) || binsof(cp2.
Similarly, cross bin, bin2 receives data whenever either bin hicp1vals, of coverpoint cp1, receives data, or bin hicp2vals, of cover point cp2, receives data. Cross bin, bin3 receives data if any bin of cover point cp1, whose value range overlaps with the range [0:1], receives data, and, for the same sample event occurrence, any bin of cover point cp2, whose value range overlaps with the range [0:3], also receives data.
Note: In cumulative mode, only cumulative information can be queried for. Furthermore, the coverage reports only report on cumulative data for the covergroup definitions, and not instances. Instance-based Coverage Instance-based coverage statistics involve computing coverage statistics for every instance of a covergroup as well as the covergroup definition as a whole. VCS computes per-instance coverage statistics when you set the cumulative attribute of the option.per_instance to 1.
type_option.weight = integer; Specifies the weight of the covergroup when calculating the overall coverage. Specify an unsigned integer. The default weight value is 1. type_option.goal = integer; Specifies the target goal of the covergroup. Specify an integer between 0 and 100. The default goal is 90. Note: “Coverage number” is a percentage. If all bins of a covergroup are covered, then the coverage number for that covergroup is 100%. type_option.
cg1 cg1_1 = new; initial begin cg1_1.option.weight = 10; cg1_1.option.goal = 75; . . . end Instance specific options are procedural statements in an initial block. There are additional options that are just for instances: instance_name.option.at_least=integer Specifies the minimum number of hits in a bin for VCS to consider the bin covered. instance_name.option.detect_overlap=boolean The boolean argument is 1 or 0.
Predefined Coverage Methods SystemVerilog provides a set of predefined covergroup methods described in this section. These predefined methods can be invoked on an instance of a covergroup. They follow the same syntax as invoking class functions and tasks on an object.
bins bins bins bins bins bins s0 s1 s2 s3 s4 s5 = = = = = = {[ 0 : 2]} ; { 3 }; { 4 }; { 5 }; { 6 }; { 7 }; } endgroup function new; covType = new(); //instantiate the embedded covergroup endfunction endclass A A_inst; initial begin repeat (10) begin #5 clk = ~clk; var = var + 1; /* get_coverage() calculates the number of the embedded covergroup covType as a whole */ $display("var=%b coverage=%f\n", var, A_inst.covType.
var=111 coverage=83.333336 var=000 coverage=100.000000 var=001 coverage=100.000000 var=010 coverage=100.000000 var=011 coverage=100.000000 See the get_coverage(), stop(), start() example on page 235 for another example of using the get_coverage() function. get_inst_coverage() Calculates the coverage number for coverage information related to the covergroup instance. Return type: real.
end end initial cov1 = new(2); endprogram The output of the program is: va1r=010 coverage=0.000000 va1r=011 coverage=25.000000 va1r=100 coverage=50.000000 va1r=101 coverage=75.000000 va1r=110 coverage=100.000000 set_inst_name(string) The instance name is set to string. Return type: void. In the example below, cov1 is the name of an instance that is of type covType, declared as such (covType cov1; cov1 = new(2);). The name is changed to new_cov1 after calling set_inst_name("new_cov1").
initial begin cov1 = new(2); $display("Original instance name is %s\n", cov1.option.name); cov1.set_inst_name("new_cov1");//change instance name $display("Instance name after calling set_inst_name() is %s\n", cov1.option.name); end endprogram Output of the program is: Original instance name is cov1 Instance name after calling set_inst_name() is new_cov1 sample() sample() triggers sampling of the covergroup instance. Return void.
covType cov1; initial cov1 = new(); initial begin repeat (10) begin #10 clk = ~clk; var = var + 1; end end initial begin repeat (40) begin #3 cov1.sample(); end end endprogram stop() When called, collecting of coverage information is stopped for that instance. Return type: void. See the get_coverage(), stop(), start() example on page 235. start() When called, collecting of coverage information resumes for that instance. Return type: void. See the get_coverage(), stop(), start() example on page 235.
bins bins bins bins s2 s3 s4 s5 = = = = { { { { 4 5 6 7 }; }; }; }; } endgroup covType cov1; initial begin repeat (10) begin #5 clk = ~clk; var = var + 1; $display("var=%b covergae=%f\n", var, cov1.get_coverage()); end end initial begin cov1 = new(2); cov1.stop(); cov1.option.weight = 5; #30 cov1.start(); end endprogram OUTPUT: var=010 covergae=0.000000 var=011 covergae=0.000000 var=100 covergae=0.000000 var=101 covergae=0.000000 var=110 covergae=0.
var=111 covergae=0.000000 var=000 covergae=16.666666 var=001 covergae=33.333332 var=010 covergae=33.333332 var=011 covergae=33.333332 Unified Coverage Reporting The db based coverage reporting has been replaced by the Unified Report Generator (URG). The URG generates combined reports for all types of coverage information. The reports may be viewed through through an overall summary "dashboard" for the entire design/ testbench.
The Coverage Report During simulation VCS creates a default database directory simv.vdb. For the code example above, VCS writes the simv.vdb directory in the current directory. This directory contains the coverage database and all the information VCS needs to write a coverage report. There are two types of coverage reports: • an ASCII text file • an HTML file The ASCII Text File The command to instruct VCS to generate a coverage report in ASCII format is: urg -dir simv.
Total 3 3 100.00 cp1 3 3 100.00 100 1 ---------------------------------------------------------Summary for variable cp1 Expected Covered Percent User Defined Bins 3 3 100.00 User Defined Bins for cp1 Bins name auto_yellow auto_blue auto_red count at least 2 1 2 1 4 1 The report begins with a summary of the coverage for the covershapes created. There is 100% coverage, meaning that VCS saw all possible values for the coverage point(s) in the covergroup.
The HTML File The command to instruct VCS to generate a coverage report in HTML format is: urg -dir simv.vdb This command instructs VCS to generate, coverage reports (dashboard.html, grp0.html, tests.html and groups.html) in the directory urgReports. The HTML coverage report grp0.html for the previous code example is as follows: The report has links to other .html reports. Click on them to see the appropriate information.
Persistent Storage of Coverage Data and Post-Processing Tools Unified Coverage Directory and Database Control A coverage directory named simv.vdb contains all the testbench functional coverage data. This is different from previous versions of VCS, where the coverage database files were stored by default in the current working directory or the path specified by coverage_database_filename. For your reference, VCS associates a logical test name with the coverage data that is generated by a simulation.
Table 24-5 Unique Name Generation Scheme Test Name Database pci_test Database for the first testbench run. pci_test_gen_1 Database for the second testbench run pci_test_gen_2 Database for the 3rd testbench run pci_test_gen_n Database for the nth testbench run You can disable this method of ensuring database backup and force VCS to always overwrite an existing coverage database.
Loading Coverage Data Both cumulative coverage data and instance-specific coverage data can be loaded. The loading of coverage data from a previous VCS run implies that the bin hits from the previous VCS run to this run are to be added. Loading Cumulative Coverage Data The cumulative coverage data can be loaded either for all coverage groups, or for a specific coverage group.
In the Example 1-1, below, there is a SystemVerilog class MyClass with an embedded covergroup covType. VCS finds the cumulative coverage data for the covergroup MyClass:covType in the database file Run1 and loads it into the covType embedded coverage group in MyClass. Example 24-45 class MyClass; integer m_e; covergroup covType @m_e; cp1 : coverpoint m_e; endgroup endclass ...
The commands above direct VCS to find the coverage data for the specified instance name in the database, and load it into the coverage instance. In the Example 1-2, there is a SystemVerilog class MyClass with an embedded covergroup covType. Two objects obj1 and obj2 are instantiated, each with the embedded covergroup covType. VCS will find the coverage information for the coverage instance obj1:covType from the database file Run1, and load this coverage data into the newly instantiated obj1 object.
-cm_name filename As a compile-time or runtime option, specifies an alternative test name instead of the default name. The default test name is "test". VCS NTB (SV) Memory Profiler The VCS NTB(SV) memory profiler is a Limited Customer availability (LCA) feature in NTB(SV) and requires a separate license. Please contact your Synopsys AC for a license key.
filename Name of the file where the memory profiler dumps the report. w | a+ w and a+ designate the mode in which the file is opened. Specify w for writing and a+ for appending to an existing file. UCLI Interface Compile-time The dynamic memory profiler is enabled only if you specify +dmprof on the VCS compile-time command line: vcs -ntb -sverilog +dmprof dut_filename.v testbench_filename.sv \ [-debug | -debug_all] Note: Use the -sverilog compile-time option when compiling SystemVerilog code.
vcs -ntb -sverilog +dmprof dut_filename.v testbench_filename.sv \ [-debug | -debug_all] Note: Use the -sverilog compile-time option when compiling SystemVerilog code. Runtime At runtime, invoke $vcsmemprof() from the CLI command line prompt as follows. You can make the call to $vcsmemprof() at any point during the simulation: simv -s //Invokes the cli prompt cli_0>$vcsmemprof("memprof.
integer arr1[*]; arr1 = new[500]; delay(5); } task t2() { integer arr2[*]; arr2 = new[500]; delay(10); } program main { fork { t1(); } { t2(); } join all } In this program, if $vcsmemprof() is called between 0 and 4 ns, then both arr1 and arr2 are active. If the call is made between 5 and 10 ns, then only arr2 is active and after 10 ns, neither is active. VCS NTB (SV) Dynamic Memory Profile Report The profile report includes the following sections. 1.
3. Program View Reports the dynamic memory consumed in each SV program in the system. 4. Program To Construct View a. Task-Function-Thread section Reports the total dynamic memory in each active task, function and thread in the module/program. b. Class Section Reports the total dynamic memory consumed in each class in the module/program. c.
The Direct Programming Interface (DPI) The Direct Programming Interface (DPI) is a Limited Customer availability (LCA) feature in NTB (SV) and requires a separate license. Please contact your Synopsys AC for a license key. The DPI is an interface between SystemVerilog and another language such as C. Using DPI you can directly call a function in the other language. Note: Currently DPI is implemented only for the C/C++ languages.
Example: import "DPI" context task c_task(input int addr); program top; initial c_task(1000); initial c_task(2000); endprogram #include void c_task(int addr) { ... } vcs -sverilog top.sv c_task.c Export Functions- C/C++ Calling SystemVerilog The export tasks/functions are SystemVerilog tasks/functions that can be called from C/C++ languages. You must declare them before you can use them.
Example: import "DPI" task c_test(int addr); initial c_task(1000); export "DPI" task sv_add; function int sv_add(input int a, input int b); sv_add = a+b; endtask #include extern void sv_add(int, int); void c_task(int addr) { ... sv_add(addr, 10); ... } vcs -sverilog top.sv c_task.c Note: You can export all SystemVerilog functions except class member functions.
• The main include file, $VCS_HOME/lib/svdpi.h, is defined in the SystemVerilog 3.1 standard and defines the canonical representation, all basic types, and all interface functions.The file also provides function headers and defines a number of helper macros and constants. See section D.9.1 of the SystemVerilog 3.1 LRM. The following functions are not implemented: • svGetNameFromScope svAckDisabledState svGetCallerInfo svIsDisabledState The second include file, $VCS_HOME/lib/svdpi_src.
Time Consuming Blocking Tasks When SystemVerilog calls a C import task, this task can then call blocking (context) SystemVerilog tasks. This is particularly useful if the C code must call a read/write task in a SystemVerilog BFM model. Note that the C task must be initially called from SystemVerilog using an import task call. For example, the following C code contains a test that calls the SystemVerilog apb_write task as needed to issue writes on an APB bus. #include
SystemVerilog File This SV code calls C_test(), which then calls the blocking APB_Write task in SystemVerilog. The APB_Write task has a simple semaphore to ensure unique access. import "DPI" context task c_test(input int base_addr); program top; semaphore bus_sem = new(1); export "DPI" task apb_write; task apb_write(input int addr, data); bus_sem.get(1); #10 $display("VLOG : APB Write : Addr = %x, Data = %x ", addr, data); #10 ifc.addr <= addr; #10 ifc.data <= data; bus_sem.
25 Source Protection 1 Source protection changes the source description of a Verilog model so that others cannot read or understand it but they can still simulate it. Source protection enables you to protect proprietary information about your designs but enables users in companies that purchase your designs to simulate them.
• Creating a VMC model from source description: A VMC model is an executable binary that you compile from your Verilog model. To simulate the VMC model you link it to VCS. VMC is a separate Synopsys product. These source protection methods vary in the levels of security they provide, their impact on performance, platform and vendor independence, and PLI and CLI access as described in Table 25-1, Source Protection Methods.
Encrypting Source Files Encrypt Using Compiler Directives You use compiler directives and command line options to encrypt source and SDF files. VCS creates copies of your files with encrypted contents. The following sections describe how you encrypt Verilog source and SDF files: • The section “Encrypting Specified Regions” on page 25-4 describes how you can specify what part of your source description you want VCS to encrypt.
Encrypting Specified Regions You can control what part of your source VCS encrypts in the new files and which part remains readable. To do so you do the following: 1. Enclose the part of your source that you want VCS to encrypt between the ‘protect and the ‘endprotect compiler directives. 2. Include the +protect option on the vcs command line. When you run VCS with the +protect option: - VCS creates new files for the Verilog source files you specify on the vcs command line.
always begin:counter `protect //begin protected region reg [7:0] int; count = 0; int = inp; while (int) begin if (int [0]) count = count + 1; int = int >> 1; end `endprotect //end protected region end endmodule The following is the contents of the new file after you run source protection with the +protect option: module top( inp, outp); input [7:0] inp; output [7:0] outp; reg [7:0] count; assign outp = count; always begin:counter `protected %%AqDtf%,%,%,%,%,%,-%,%,UB@%,|%5%B%
To do so include the +autoprotect, +auto2protect or +auto3protect option on the vcs command line. The difference between these options is where VCS begins to encrypt the Verilog source description in modules and UDPs. This difference is as follows: +autoprotect The +autoprotect option encrypts the module port list (or UDP terminal list) in addition to the body of the module (or UDP.) +auto2protect The +auto2protect option does not encrypt the module port list (UDP terminal list).
• VCS inserts the ‘protected compiler directive after the module header and the ‘endprotected compiler directive before the endmodule keyword. VCS encrypts the Verilog source between the ‘protected and ‘endprotected compiler directives that it inserts.
CB75+Q/]R_IAP/>HS+b(?(&ZL:4Z:.F[<5J)gQ+CaA]^7\.N^/0@RRZQe-]A,Z+L>?FQG ([A0S=LXHPgN[S#aSR58?]Qgg6\#OOf<^.
Encrypting SDF Files To create a new SDF file with encrypted content include, on the vcs command line, the +sdfprotect option with the SDF filename. For example, the following is the contents of an SDF file named delays.sdf, that you want to encrypt. (DELAYFILE (DESIGN"test") (VENDOR"Synopsys") (DIVIDER.) (VOLTAGE:1:) (PROCESS"typical") (TEMPERATURE:1:) (TIMESCALE10ps) (CELL (CELLTYPE"leaf") (INSTANCEleaf1) (DELAY (ABSOLUTE (IOPATH in1 out1 (IOPATH in2 out2 (IOPATH in3 out3 (IOPATH in4 out4 ) ) (50.
Specifying Encrypted Filename Extensions You can specify a different extension for the new filenames by adding the new extension as a suffix to the +protect, +auto2protect, +autoprotect, or +sdfprotect options. For example, if you include the +protect.protected option on the vcs command line, for the source file named my_design.v, the encrypted new filename is my_design.v.protected.
• If the encrypted file already exists, VCS outputs an error message and does not overwrite the existing file. This error message is: Error: file 'filename.vp' already exists. • If an error condition exists in the source file, VCS continues to create the encrypted file. This file might be corrupt. To circumvent these problems you can use the +deleteprotected source protection option.
Simulating Encrypted Models When you simulate an encrypted model, information about hierarchical names and design objects is protected. This means that some CLI commands, such as those that display hierarchical names and design objects at a specified level of the hierarchy, do not work at protected levels of the design hierarchy. Protected levels are the encrypted levels.
Some CLI commands whose arguments are design objects continue to work but only if you know the hierarchical name of the object. These CLI commands are: always print break release force set once tbreak You must know the hierarchical path names to use these commands.
if (acc_object_of_type(obj, accProtected)) { printf("object %s is from a protected module\n", acc_fetch_name(obj)); } If the object passed to acc_object_of_type() is a design object in a module, a port or register for example, the status of the parent module will be returned.
You can substitute -Xman for -Xmangle. The argument number can be 1 or 4: -Xman=1 Randomly changes names and identifiers to provide a more secure code. -Xman=4 Preserves variable names but removes comments. -Xman=12 Does the same as -Xman=4 but also adds comments about the system tasks in the source and the source file and line numbers of the module headers. -Xman=28 Does the same as -Xman=12 but adds a statistical analysis of the design.
inData35=iPb[cpuTmpCnt]; $display("\tiPb[%0h]=%b, %h", cpuTmpCnt, iPb[cpuTmpCnt],iPb[cpuTmpCnt] >> 3); cpuDatareg=merge_word(cpuData,inData35[0:31],cpuTmpCn t); end end endmodule The following is the mangled code in tokens.
initial begin Wfmoe = 256’b0; for (Ifmoe = 0; (Ifmoe < 8); Ifmoe = (Ifmoe + 1)) begin : Bimoe reg [0:34] Timoe; Timoe = Sfmoe[Ifmoe]; $display("iPb[%0h]=%b, %h", Ifmoe, Sfmoe[Ifmoe], (Sfmoe[Ifmoe] >> 3)); Wfmoe = Hgmoe(Afmoe, Timoe[0:31], Ifmoe); end end endmodule Notice that comments are not included in the mangled file. The following is the mangled code in tokens.
reg [0:255] reg [0:31] reg [0:2] begin end endfunction source_line; source_word; word_index; initial begin cpuDatareg = 256’b0; for (cpuTmpCnt = 0; (cpuTmpCnt < 8); cpuTmpCnt = (cpuTmpCnt + 1)) begin : assemble_incoming reg[0:34] inData35; inData35 = iPb[cpuTmpCnt]; $display("iPb[%0h]=%b, %h", cpuTmpCnt, iPb[cpuTmpCnt], (iPb[cpuTmpCnt] >> 3)); cpuDatareg = merge_word(cpuData, inData35[0:31], cpuTmpCnt); end end endmodule The comment is removed and default compiler directives and a comment about timescale
input[7:0] modulus1; output[255:0] cpuData; integer reg [255:0] cpuTmpCnt; cpuDatareg; reg [0:34] iPb[0:10]; assign cpuData = cpuDatareg; function [0:255] merge_word; input[0:255] source_line; input[0:31] source_word; input[0:2] word_index; reg [0:255] reg [0:31] reg [0:2] begin end endfunction source_line; source_word; word_index; initial begin cpuDatareg = 256’b0; for (cpuTmpCnt = 0; (cpuTmpCnt < 8); cpuTmpCnt = (cpuTmpCnt + 1)) begin : assemble_incoming reg[0:34] inData35; inData35 = iPb[cpuTmpCnt]
Here there are additional comments about the system tasks used and the source file and line number of the module header. The following is the mangled code in tokens.v produced by the -Xmangle=28 option: /* System Tasks: $display */ ‘portcoerce ‘inline /* Source file "mangle2.
cpuDatareg = 256’b0; for (cpuTmpCnt = 0; (cpuTmpCnt < 8); cpuTmpCnt = (cpuTmpCnt + 1)) begin : assemble_incoming reg[0:34] inData35; inData35 = iPb[cpuTmpCnt]; $display("iPb[%0h]=%b, %h", cpuTmpCnt, iPb[cpuTmpCnt], (iPb[cpuTmpCnt] >> 3)); cpuDatareg = merge_word(cpuData, inData35[0:31], cpuTmpCnt); end end endmodule // // // // // // // // // // // // // // // // // // // // // // // // // // =================== DESIGN STATISTICS =================== No. No. No. No. No. No. No. No. No. No. No. No. No. No.
// No. of user function calls: 0 0 // No. of hierarchical references: 0 0 // No. of concatenations: 0 0 // No. of force/release statements: 0 0 // No. of bit selects: 0 0 // No. of part selects: 1 1 // No. of non-blocking assignments: 0 0 // No. of specify blocks<#>: 0 0 // No. of timing checks: 0 0 // // No. of top level modules: 1 // modules: 1 // No. of udps: 0 // seq. udps: 0 // comb. udps: 0 // No. of module+udp ports: 2 // No. of system tasks: 1 // No. of user tasks: 0 // No.
Creating A Test Case Here is a quick way to create a small test case: 1. Remove -o option if you are using it. 2. Add the-Xman=4 option to your vcs command line (in addition to whatever other options you are using) and run VCS. VCS will not actually compile your design, instead it generates a file called tokens.v. 3. Rename the tokens.v file to tokens.orig 4. Run the following command line: vcs tokens.orig 5. Cut out the problem module from tokens.orig and paste it into a new file, say test.v. 6.
b. At the Name prompt, enter anonymous. At the Password prompt, enter your e-mail address. c. At the ftp> prompt enter: cd incoming d. Enter the following FTP command: binary e. Enter the following FTP command: put tokens.v.gz 10. Now send e-mail to VCS_support@synopsys.com informing us that you have uploaded the test case. Preventing Mangling of Top-Level Modules You can prevent the mangling of top-level modules in your source description with the -Xnomangle option.
The -Xnomangle option should only be used on top level modules, i.e., ones that are not called by any other module in the design being mangled. The code which performs the mangling knows how to identify module and port declarations, but not module references. Thus, if you exempt a module which is referenced by some other module, the reference will try to use the mangled name instead of the original (and fail).
Source Protection 25-26
A VCS Environment Variables A There are a number of variables you use to set up the simulation environment in VCS.
Simulation Environment Variables ERROR_WHEN_UNBOUNDTo run VCS, you need to set the following basic environment variables: $VCS_HOME When you or someone at your site installed VCS, the installation created a directory that we call the vcs_install_dir directory. Set the $VCS_HOME environment variable to the path of the vcs_install_dir directory. For example: setenv VCS_HOME /u/net/eda_tools/vcs2005.06 PATH On UNIX, set this environment variable to $VCS_HOME/bin.
Optional Environment Variables VCS also includes the following environment variables that you can set in certain circumstances. DISPLAY_VCS_HOME Enables the display, at compile time, of the path to the directory specified in the VCS_HOME environment variable. Specify a value other than 0 to enable the display. For example: setenv DISPLAY_VCS_HOME 1 SYSTEMC Specifies the location of the SystemC simulator used with the VCS / SystemC cosimulation interface.
VCS_LIC_EXPIRE_WARNING By default VCS displays a warning 30 days before a license expires. You can specify that this warning begin fewer days before the license expires with this environment variable, for example: VCS_LIC_EXPIRE_WARNING 5 To diable the warning, enter the 0 value: VCS_LIC_EXPIRE_WARNING 0 VCS_LOG Specifies the runtime log file name and location. VCS_NO_RT_STACK_TRACE Tells VCS not to return a stack trace when there is a fatal error and instead dump a core file for debugging purposes.
B Compile-Time Options B The vcs command performs compilation of your designs and creates a simulation executable. Compiled event code is generated and used by default. The generated simulation executable, called simv, can then be used to run multiple simulations. This section describes the vcs command and related options. Syntax: vcs source_files [source_or_object_files] options Here: source_files The Verilog or OVA source files for your design separated by spaces.
source_or_object_files Optional C files (.c), object files (.o), or archived libraries (.a). These are DirectC or PLI applications that you want VCS to link into the binary executable file along with the object files from your Verilog source files. When including object files include the -cc and -ld options to specify the compiler and linker that generated them. options Compile-time options that control how VCS compiles your Verilog source files.
• Options for 64-bit Compilation • Options for Debugging • Options for Finding Race Conditions • Options for Starting Simulation Right After Compilation • Options for Compiling OpenVera Assertions (OVA) • Options for Compiling For Simulation With Vera • Options for Compiling For Coverage Metrics • Options for Discovery Visual Environment and UCLI • Options for Converting VCD and VPD Files • Options for Specifying Delays • Options for Compiling an SDF File • Options for Profiling Your
• Options for Controlling Messages • Options for Cell Definition • Options for Licensing • Options for Controlling the Assembler • Options for Controlling the Linker • Options for Controlling the C Compiler • Options for Source Protection • Options for Mixed Analog/Digital Simulation • Options for Changing Parameter Values • “Checking for X and Z Values in Conditional Expressions” on page B-57 • Options to Specify the Time Scale • General Options Options for Accessing Verilog Librari
VCS looks in this directory for a file with the same name as the module or UDP identifier in the instance (not the instance name). If it finds this file, VCS looks in the file for the module or UDP definition to resolve the instance. Include the +libext compile-time option to specify the file name extension of the files you want VCS to look for in these directories. +incdir+directory+ Specifies the directory or directories that VCS searches for include files used in the `include compiler directive.
in a source file in a Verilog library directory that resolves a module instantiation statement that VCS read in your source files, a library file, or in another file in a library directory. The message is as follows: Resolving module "module_identifier" By default, VCS does not display this message when it finds a module definition in a Verilog library file that resolves a module instantiation statement.
argument specifies the default condition, which is incremental compilation and updating the makefile. -Mdefine=name=value Adds a definition to the makefile. -Mdelete Use this option for the rare occurrence when the chmod -x simv command in the makefile can’t change the permissions on an old simv executable. This option replaces this command with the rm -f simv command in the makefile. -Mdirectory=directory Specifies the incremental compile directory.
vcs design.v -Mlib=/design/dir1 -Mlib=/design/dir2 Or you can specify more than one directory with this option, using a colon (:) as a delimiter between them, for example: vcs design.v -Mlib=/design/dir1:/design/dir2 -Mloadlist=value Directly invokes the linker to link programs if value is Yes. -Mmakefile=filename Names the generated makefile (default is makefile).
-Mlib option, the -Mrelative_path option does not expand the relative path to an absolute path on the linker line in the make file. -Msrclist=filename Specifies the name of source list file that lists all object files created by VCS. The default is filelist. -noIncrComp Disable incremental compilation. Options for Help and Documentation -h or -help Lists descriptions of the most commonly used VCS compile and runtime options.
-ignore keyword_argument Suppresses warning messages depending on which keyword argument is specified. The keyword arguments are as follows: unique_checks Suppresses warning messages about unique if and unique case statements. priority_checks Suppresses warning messages about priority if and priority case statements. all Suppresses warning messages about unique if, unique case, priority if and priority case statements.
dumpoff Disables the dumping of SVA information in the VPD file during simulation. vpiSeqBeginTime Enables you to see the simulation time that a SystemVerilog assertion sequence starts when using Debussy. vpiSeqFail Enables you to see the simulation time that a SystemVerilog assertion sequence doesn’t match when using Debussy. -sv_pragma Tells VCS to compile the SystemVerilog Assertions code that follows the sv_pragma keyword in a single line or multi-line comment.
-ntb_filext .ext Specifies an OpenVera file name extension. You can specify multiple file name extensions using the plus (+) character. -ntb_incdir directory_path Specifies the include directory path for OpenVera files. You can specify multiple include directories using the plus (+) character. -ntb_noshell Tells VCS not to generate the shell file. Use this option when you recompile a testbench.
print_deps Tells VCS to display the dependencies for the source files on the screen or in the specified file. Enter this argument with the dep_check argument. tb_timescale=value Specifies an overriding timescale for the testbench. The timescale is in the Verilog format (for example, 10ns/10ns). tokens Preprocesses the OpenVera files to generate two files, tokens.vr and tokens.vrp. The tokens.vr contains the preprocessed result of the non-encrypted OpenVera files, while the tokens.
... ); Without vera_portname, the Vera shell module name is based on the name of the OpenVera program by default. Bind signals are named, for example, as: \ifc.signal[3:0]. The interface ports are named \ifc.signal. In this example, assume that “adder” is the name of the OpenVera program: adder_test vshell( .SystemClock (SystemClock), .\adder.inp1 (inp1), .\adder.inp2 (inp2), ... ); You can enter more than one keyword argument, using the plus (+) character.
files for processing in OpenVera encrypted IP mode. Unlike the -ntb_filext option, the default encrypted-mode extensions .vrp, .vrhp are not overridden, and will always be in effect. You can pass multiple file extensions at the same time using the plus (+) character. -ntb_vl Specifies the compilation of all Verilog files, including the design, the testbench shell file, and the top-level Verilog module.
Options for Initializing Memories and Regs +vcs+initmem+0|1|x|z Initializes all bits of all memories in the design. See “Initializing Memories and Regs” on page 3-8. +vcs+initreg+0|1|x|z Initializes all bits of all regs in the design. See “Initializing Memories and Regs” on page 3-8. Options for Using Radiant Technology +rad Performs Radiant Technology optimizations on your design.
Options for Debugging -line Enables source-level debugging tasks such as stepping through the code, displaying the order in which VCS executed lines in your code, and the last statement executed before simulation stopped. Typically you enter this option with a +cli option. For example: vcs +cli+1 -line +cli+[module_identifier=]level_number Enables command line interface (CLI) interactive debugging commands. Using this option creates the Direct Access Interface Directory, by default named simv.
+cli+4 Same as above, plus enables force and release of registers. Using these options also creates the Direct Access Interface Directory, by default named simv.daidir, in the directory where VCS creates the executable file. You can include a module identifier (name) in this option to enable a level of CLI commands for all instances of the module. If you want to enable CLI commands in other modules, enter another +cli option, for example: vcs source.
5. Enter the FTP command bin. 6. Enter the FTP command get readline-2.0.tar.gz. This downloads the file to your current directory. 7. Enter the FTP command quit to exit FTP. 8. Unzip the tar file by entering: gunzip readline-2.0.tar.gz. 9. Extract the tar file by entering, for example: tar xvf readline-2.0.tar 10. This creates the readline-2.0 directory. In that directory is the make_gnurl script. 11. Execute the make_gnurl script. This script builds the gnurl.
+acc or +acc+1 Enables all capabilities except breakpoints and delay annotation. +acc+2 Above, plus breakpoints +acc+3 Above, plus module path delay annotation +acc+4 Above, plus gate delay annotation +applylearn+filename Recompiles your design to enable only the ACC capabilities that you needed for the debugging operations you did, such as applying breakpoints to signals or stepping through the code in certain parts of your design, during a previous simulation of the design.
+race=all Analyzes the source code during compilation to look for coding styles that cause race conditions. See “The Static Race Detection Tool” on page 11-13. +racecd Specifies that during simulation VCS generate a report of the race conditions in the design between the ‘race and ‘endrace compiler directives and write this report in the race.out file. See “The Dynamic Race Detection Tool” on page 11-2.
Options for Compiling OpenVera Assertions (OVA) -ovac Starts the OVA compiler for checking the syntax of OVA files that you specify on the vcs command line. This option is for when you first start writing OVA files and need to make sure that they can compile correctly. -ova_cov Enables viewing results with functional coverage. -ova_cov_events Enables coverage reporting of expressions. -ova_cov_hier filename Limits functional coverage to the module instances specified in filename.
-ova_inline Enables compiling of OVA code that is written inline with a Verilog design. -ova_lint Enables general rules for the OVA linter. -ova_lint_magellan Enables Magellan rules for the OVA linter. Options for Compiling For Simulation With Vera -vera Specifies the standard VERA PLI table file and object library. -vera_dbind Specifies the VERA PLI table file and object library for dynamic binding.
fsm Compile for FSM coverage. tgl Compile for toggle coverage. path Compile for path coverage. branch Compile for branch coverage assert Compile for SystemVerilog assertion coverage. If you want VCS to compile for more than one type of coverage, use the plus (+) character as a delimiter between arguments, for example: -cm line+cond+fsm+tgl The -cm option is also a runtime option and an option on the cmView command line.
full Logical and non-logical, multiple conditions, no sensitized conditions. allops Logical and non-logical conditions. event Signals in event controls in the sensitivity list position are conditions. anywidth Enables conditions that need more than 32 bits. sop Specifies condition SOP coverage. for Enables conditions in for loops. tf Enables conditions in user-defined tasks and functions.
- In FSM coverage, reports not just whether an FSM reached a state, and had such a transition, but also the number of times it did. - In condition coverage, reports not just whether a condition was met or not, but also the number of times the condition was met. - In line coverage, reports not just whether a line was executed, but how many times. -cm_constfile filename Specifies a file listing signals and 0 or 1 values.
optimist Specifies identifying illegal transitions when VCS extracts FSMs in FSM coverage. cmView then reports illegal transitions in report files. report2StateFsms By default, VCS does not extract two state FSMs. This keyword tells VCS to extract them. reportvalues Specifies reporting the value transitions of the reg that holds the current state of a One Hot or Hot Bit FSM where there are parameters for the bit numbers of the signals that hold the current and next state.
to either exclude from coverage or exclusively compile for coverage. -cm_ignorepragmas Tells VCS to ignore pragmas for coverage metrics. -cm_libs yv|celldefine Specifies compiling for coverage source files in Verilog libraries when you include the yv argument. Specifies compiling for coverage module definitions that are under the ‘celldefine compiler directive when you include the celldefine argument. You can specify both arguments together using the plus (+) character.
gui Tells VCS to start the cmView graphical user interface to display coverage data. batch Tells VCS to start cmView to write reports in batch mode. This is the default operation. You enter cmView command line options to the right of this option and its argument. -cm_resetfilter filename Filters out FSM coverage transitions in assignment statements controlled by if statements where the conditional expression (following the keyword if) is a signal you specify in the file.
-cm_tgl mda Enables toggle coverage for Verilog-2001 multidimensional arrays (MDAs) and SystemVerilog unpacked MDAs. Not required for SystemVerilog packed MDAs. Options for Discovery Visual Environment and UCLI -debug Enables DVE and UCLI debugging. This option does not enable line stepping. -debug_all Enables DVE and UCLI debugging including line stepping. -ucli Forces runtime to go into UCLI mode by default. -gui When used at compile time, starts DVE at runtime.
-assert dve Enables SystemVerilog assertions tracing in the VPD file. This tracing enables you to see assertion attempts. Note: The –debug_pp option writes a smaller VPD file than –debug -PP making for less overhead. +vpdfile+filename Specifies the name of the generated VPD file. You can also use this option for post-processing, where it specifies the name of the VPD file. +vcdfile+filename Specifies the VCD file you want to use for post-processing.
Options for Specifying Delays +allmtm Specifies enabling the simv executable for the +mindelays, +typdelays, or +maxdelays options at runtime, instead of at compile-time, to specify which of the minimum, typical, or maximum delay values to use during simulation from min:typ:max delay value triplets in module path delays and timing delays. This option is also used for compiling SDF files. This option does not work for min:typ:max delay value triplets in other delay specification in your source code.
‘timescale compiler directives in the source code. The default time unit and time precision argument of the ‘timescale compiler directive is 1s. +delay_mode_distributed Ignores the module path delays in specify blocks and uses only the delay specifications on all gates, switches, and continuous assignments. +maxdelays Specifies using the maximum timing delays in min:typ:max delay triplets in delay specifications and also in delay entries in SDF files. See “Min:Typ:Max Delays” on page 13-37.
These delays impede the simulation performance of the design so after debugging you can remove these delays with this option. Note: The +nbaopt option removes all intra-assignment delays in all the nonblocking assignment statements in the design, not just the #1 delays. +old_iopath By default VCS replaces negative module path delays in SDF files with a 0 delay. If you include this option, VCS replaces these negative delays with the delay specified in a module’s specify block.
Options for Compiling an SDF File +allmtm Specifies compiling separate files for minimum, typical, and maximum delays when there are min:typ:max delay triplets in SDF files. If you use this option, you can use the +mindelays, +typdelays, or +maxdelays options at runtime to specify which compiled SDF file VCS uses. Do not use this option with the +maxdelays, +mindelays, or +typdelays compile-time options. See “Specifying Min:Typ:Max Delays at Runtime” on page 13-38.
triplets when compiling the SDF file. See “Min:Typ:Max Delays” on page 13-37. The mtm_spec argument to the $sdf_annotate system task overrides this option. See “The $sdf_annotate System Task” on page 13-3. -negdelay Enables the use of negative values in IOPATH and INTERCONNECT entries in SDF files. +oldsdf Disables compiling the SDF file. Use this option if you cannot meet the conditions for compiling SDF files. See “Limitations on Compiling the SDF File” on page 13-5.
As an alternative to using this option, you can use the ‘vcs_mipdexpand compiler directive or you can enter the mipb ACC capability in your PLI table file. For example: $sdf_annotate call=sdf_annotate_call acc+=rw,mipb:top_level_mod+ When you compile the SDF file (recommended) the backannotation of the delay values for individual bits of a port does not require this option. Options for Profiling Your Design +prof Specifies that VCS writes the vcs.prof file during simulation.
Options for File Containing Source File Names and Options -f filename Specifies a file name that contains a list of absolute path names for Verilog source files and compile-time options. You can enter in this file all the compile-time options that begin with a plus (+) character with three exceptions: do not enter the +comp64, +full64, or +memopt compile-time options.
-file filename This option is for problems you might encounter with entries in files specified with the -f or -F options. This file can contain more compile-time options and different kinds of files. It can contain options for controlling compilation, PLI options and object files. You can also use escape characters and meta-characters like $, ‘, and ! in this file and they will expand. For example: -CFLAGS '-I$VCS_HOME/include' /my/pli/code/$PROJECT_VERSION/treewalker.
Options for Pulse Filtering +pulse_e/number Displays an error message and propagates an X value for any path pulse whose width is less than or equal to the percentage of the module path delay specified by the number argument but is still greater than the percentage of the module path delay specified by the number argument to the +pulse_r/number option. +pulse_r/number Rejects any pulse whose width is less than number percent of the module path delay. The number argument is in the range of 0 to 100.
until the short pulse propagates through the module or until another simulation event drives a value on the output port. See “Specifying the Delay Mode” on page 12-20. Options for PLI Applications +applylearn+filename Recompiles your design to enable only the ACC capabilities that you needed for the debugging operations you did during a previous simulation of the design. -e new_name_for_main Specifies the name of your main() routine.
Options to Enable and Disable Specify Blocks and Timing Checks +pathpulse Enables the search for the PATHPULSE$ specparam in specify blocks. +nospecify Suppresses module path delays and timing checks in specify blocks. This option can significantly improve simulation performance. +notimingcheck Tells VCS to ignore timing check system tasks when it compiles your design. This option can moderately improve simulation performance.
display of warning messages when VCS finds a timing violation that you specified in a timing check. +no_tchk_msg Disables display of timing violations but does not disable the toggling of notifier registers in timing checks. This is also a runtime option. Options to Enable the VCS DirectC Interface +vc+[abstract+allhdrs+list] The +vc option enables extern declarations of C/C++ functions and calling these functions in your source code. See The VCS DirectC Interface User Guide.
the signals in the $setuphold and $recrem timing checks. See “Other Timing Checks Using the Delayed Signals” on page 14-14. +NTC2 In $setuphold and $recrem timing checks, specifies checking the timestamp and timecheck conditions when the original data and reference signals change value instead of when their delayed versions change value. See “Checking Conditions” on page 14-18.
+vcs+flush+fopen Increases the frequency of flushing all the buffers for the files opened by the $fopen system function. +vcs+flush+all Shortcut option for entering all three of the +vcs+flush+log, +vcs+flush+dump, and +vcs+flush+fopen options. These options do not increase the frequency of dumping other text files, including the VCDE files specified by the $dumpports system task or the simulation history file for LSI certification specified by the $lsi_dumpports system task.
instantiation statement that VCS read in your source files, a library file, or in another file in a library directory. The message is: Resolving module "module_identifier" VCS does not display this message when it finds a module definition in a Verilog library file that resolves a module instantiation statement. +lint=[no]ID|none|all Enables messages that tell you when your Verilog code contains something that is bad style but is often used in designs. See “Using Lint” on page 3-10.
-Vt Verbose mode; provides CPU time information. Like -V, but also prints the amount of time used by each command. Use of the -Vt option can cause the simulation to slow down. +warn=[no]ID|none|all Uses warning message IDs to enable or disable display of warning messages. In the following warning message: Warning-[TFIPC] Too few instance port connections The text string TFIPC is the message ID. The syntax of this option is as follows: +warn=[no]ID|none|all,...
Options for Cell Definition +nolibcell Does not define as a cell modules defined in libraries unless they are under the `celldefine compiler directive. +nocelldefinepli+0 Enables recording in VPD files, the transition times and values of nets and registers in all modules defined under the ‘celldefine compiler directive or defined in a library that you specify with the -v or -y compile-time options. This option also enables full PLI access to these modules.
As an alternative to using the +nocelldefinepli+1 option, you can add an entry in the virsims.tab AND virsims_pp.tab files (located in $VCS_HOME/virsims_support) to turn off VPD dumping for modules defined under the `celldefine compiler directive. Enter the keyword nocelldefinepli with appropriate spaces in the $virsim line.
host ID of your work station (used in licensing), the version of the VCS compiler (same as VCS) and the VCS build date. Options for Controlling the Assembler -gen_asm Enables assembly code generation mode. Use this option if you encounter problems in native code generation. Not supported on IBM RS/6000 AIX. -as assembler Selects an alternate assembler. Not supported on IBM RS/6000 AIX. -ASFLAGS options Passes options to assembler. Not supported on IBM RS/6000 AIX.
-c Tells VCS to compile the source files, generate the intermediate C, assembly, or object files, and compile or assemble the C or assembly code, but not to link them. Use this option if you want to link by hand. -lname Links the name library to the resulting executable. Usage is the letter l followed by a name (no space between l and name). For example: -lm (instructs VCS to include the math library). -syslib libs Specifies system libraries.
arguments: %vcs top.v test.c -CFLAGS "-I$VCS_HOME/include" or %setenv CWD ‘pwd‘ %vcs top.v test.c -CFLAGS "-I$CWD/include" or %vcs top.v test.c -CFLAGS "-I../include" Note: The reason to enter "../include" is because VCS creates a default csrc directory where it runs gcc commands. The csrc directory is under your current working directory. Therefore, you need to specify the relative path of the include directory to the csrc directory for gcc C compiler.
platforms), generating intermediate assembly files (-gen_asm) and then their parallel assembly, or generating intermediate C files (-gen_c) and their parallel compilation. -C Stops after generating the C code intermediate files if you also enter the -gen_c option, does not compile the C code files (-gen_c is the default on IBM RS/6000 AIX). Use this option if you want to compile by hand. This option can also be used with the -gen_asm option for disabling assembly.
Options for Source Protection +autoprotect[file_suffix] Creates a protected source file; all modules are encrypted. +auto2protect[file_suffix] Creates a protected source file that does not encrypt the port connection list in the module header; all modules are encrypted. +auto3protect[file_suffix] Creates a protected source file that does not encrypt the port connection list in the module header or any parameter declarations that precede the first port declaration; all modules are encrypted.
single file. Output is saved in tokens.v file. You can substitute -Xman for -Xmangle. The argument number can be 1, 4, 12, or 28: -Xman=1 Randomly changes names and identifiers, and removes comments, to provide more secure code. -Xman=4 Preserves variable names but removes comments. -Xman=12 Does the same thing as -Xman=4 but also enters, in comments, the original source file name and the line number of each module header.
Options for Mixed Analog/Digital Simulation +ad=partition_filename Specifies the partition file that you use in mixed Analog/Digital simulation to specify the part of the design simulated by the analog simulator, the analog simulator you want to use, and the resistance mapping information that maps analog drive resistance ranges to Verilog strengths. -ams_discipline discipline_name Specifies the default discrete discipline in VerilogAMS.
-parameters filename Changes parameters specified in the file to values specified in the file. The syntax for a line in the file is as follows: assign value path_to_parameter The path to the parameter is similar to a hierarchical name except that you use the forward slash character (/) instead of a period as the delimiter. See “Changing Parameter Values From the Command Line” on page 3-12.
source files that do. Do not include spaces when specifying the arguments to this option. -override_timescale=time_unit/time_precision Overrides the time unit and precision unit for all the ‘timescale compiler directives in the source code and, like the -timescale option, provides a timescale for all module definitions that precede the first ‘timescale compiler directive. Do not include spaces when specifying the arguments to this option.
TetraMAX +tetramax Enables simulation of TetraMAX’s testbench in zero delay mode. Make Accessing an Undeclared Bit an Error Condition +vcs+boundscheck Changes reading from or writing to an undeclared bit to an error condition instead of a warning condition. Treat Output Ports As Inout Ports +spl_read Tells VCS to treat output ports as “inout” in order to facilitate more accurate multi-driver contention analysis across module boundaries. This option can have an adverse impact on runtime performance.
Memories and Multi-Dimensional Arrays (MDAs) +memcbk Enables callbacks for memories and multi-dimensional arrays (MDAs). Use this option if your design has memories or MDAs and you are doing any of the following: - Writing a VCD or VPD file during simulation. For VCD files, at runtime, you must also enter the +vcs+dumparrays runtime option. For VPD files you must enter the $vcdplusmemon system task. VCD and VPD files are used for post-processing with DVE.
Hardware Modeling -lmc-hm Compiles a design that instantiates a hardware model. Including this option is an alternative to specifying the lmvc.tab PLI table file and the lmvc.o lm_sfi.a object file and library that you need for hardware modeling. Changing Source File Identifiers to Upper Case -u Changes all the characters in identifiers to uppercase. It does not change identifiers in quoted strings such as the first argument to the $monitor system task.
Specifying the Name of the Executable File -o name Specifies the name of the executable file. In UNIX the default is simv. Returning The Platform Directory Name -platform Returns the name of the platform directory in your VCS installation directory. For example, when you install VCS on a Solaris version 5.4 workstation, VCS creates a directory named sun_sparc_solaris_5.4 in the directory where you install VCS.
Compile-Time Options C-63
Compile-Time Options C-64
C Simulation Options C This appendix describes the options and syntax associated with the simv executable. These runtime options are typically entered on the simv command line but some of them can be compiled into the simv executable at compile-time. See “Compiling Runtime Options Into the simv Executable” on page 3-21. For complete usage information on the simv executable, see Chapter 4, "Simulating Your Design".
• Options for Specifying VERA Object Files • Options for Coverage Metrics • Options for Enabling and Disabling Specify Blocks • Options for Specifying When Simulation Stops • Options for Recording Output • Options for Controlling Messages • Options for Discovery Visual Environment and UCLI • Options for VPD Files • Options for Controlling $gr_waves System Task Operations • Options for VCD Files • Options for Specifying Min:Typ:Max Delays • Options for Flushing Certain Output Text File
+ntb_enable_solver_trace=value Enables a debug mode that displays diagnostics when VCS executes a randomize() method call. Allowed values are: 0 - Do not display (default). 1 - Displays the constraints VCS is solving. 2 - Displays the entire constraint set. +ntb_enable_solver_trace_on_failure[=value] Enables a mode that displays trace information only when the VCS constraint solver fails to compute a solution, usually due to inconsistent constraints.
+ntb_solver_mode=value Allows you to choose between one of two constraint solver modes. When set to 1, the solver spends more preprocessing time in analyzing the constraints during the first call to randomize() on each class. Therefore, subsequent calls to randomize() on that class are very fast. When set to 2, the solver does minimal preprocessing, and analyzes the constraint in each call to randomize(). The default is 2.
./simv.vdb/scov/results.db and ./simv.vdb/reports/ova.report files. Use this option if you want data and reports from a series of simulation runs. It is a way of preventing VCS from overwriting these files from a previous simulation. If you just specify a name, VCS creates the alternatively named files in the default directories. You can also specify a different location and name for these files by specifying the path using the slash character /.
-ova_simend_max_fail N Terminates the simulation if the number of failures for any assertion reaches N. You must supply N, otherwise no limit is set. -ova_success Enables reporting of successful matches in addition to failures. The default is to report only failures. The following runtime options enable functional coverage. You can use them only if you compiled with the -ova_cov compile-time option. -ova_cov Enables functional coverage reporting.
filter Blocks reporting of trivial implication successes. These happen when an implication construct registers a success only because the precondition (antecedent) portion is false (and so the consequent portion is not checked). With this option, reporting only shows successes in which the whole expression matches. finish_maxfail=N Terminates the simulation if the number of failures for any assertion reaches N. You must supply N, otherwise no limit is set.
nopostproc Disables the display of the SVA coverage summary at the end of simulation. This summary looks like this for each cover statement: "source_filename.v", line_number: cover_statement_hierarchical_name number attempts, number total match, number first match, number vacuous match quiet Disables the display of messages when assertions fail. quiet1 Disables the display of messages when assertions fail but enables the display of summary information at the end of simulation.
- A file name containing () results in a Badly placed ()’s message. - A file name containing ! results in an Event not found message. success Enables reporting of successful matches, and successes on cover statements, in addition to failures. The default is to report only failures. verbose Adds more information to the end of the report specified by the report keyword argument, and a summary with the number of assertions present, attempted, and failed.
takes commands from the standard input. This option is normally used along with the -s runtime option and a +cli+number compile-time option. A typical file for this option is the vcs.key file. -k filename | off Specifies an alternative name or location for the vcs.key file into which VCS writes the CLI and DVE interactive commands that you enter during simulation. The off argument tells VCS not to write this file.
fsm Monitors for FSM coverage. tgl Monitors for toggle coverage. path Monitors for path coverage. branch Monitors for branch coverage assert Monitors for SystemVerilog assertion coverage If you want VCS to monitor for more than one type of coverage, use the plus (+) character as a delimiter between arguments. For example: simv -cm line+cond+fsm+tgl+path The -cm option is also a compile-time option and an option on the cmView command line.
-cm_name filename As a compile-time or runtime option, specifies the name of the intermediate data files. On the cmView command line, specifies the name of the report files. -cm_tglfile filename Specifies displaying a total toggle count at runtime for one or more subhierarchies specified by the top-level module instance entered in the file. This option is also a compile-time option.
If you need the delayed versions of the signals in negative timing checks but want faster performance, include this option at runtime. The delayed versions are not available if you use this option at compile-time. See “Enabling Negative Timing Checks” on page 14-13. VCS recognizes +notimingchecks to be the same as +notimingcheck when you enter it on the vcs or simv command line. Options for Specifying When Simulation Stops +vcs+stop+time Stop simulation at the time value specified.
Options for Controlling Messages -q Quiet mode; suppresses display of VCS header and summary information. Suppresses the proprietary message at the beginning of simulation and suppresses the VCS Simulation Report at the end (time, CPU time, data structure size, and date). -V Verbose mode; displays VCS version and extended summary information. Displays VCS compile and runtime version numbers, and copyright information, at start of simulation.
+vcs+nostdout Disables all text output from VCS including messages and text from $monitor and $display and other system tasks. VCS still writes this output to the log file if you include the -l option. Options for Discovery Visual Environment and UCLI -ucli Starts the UCLI debugger command line -l log_filename Specifies a log file that contains the commands you entered and the responses from VCS and DVE. -i input_filename Specifies a file containing UCLI commands.
Note: VCS automatically increases the buffer size as needed to comply with this limit. +vpdfile+filename Specifies the name of the output VPD file (default is vcdplus.vpd). You must include the full file name with the .vpd extension. +vpdfilesize +number_of_megabytes Creates a VPD file that has a moving window in time while never exceeding the file size specified by number_of_megabytes. When the VPD file size limit is reached, VPD continues saving simulation history by overwriting older history.
+vpdignore Tells VCS to ignore any $vcdplusxx system tasks and license checking. By default, VCS checks out a VPD PLI license if there is a $vcdplusxx system task in the Verilog source. In some cases, this statement is never executed and VPD PLI license checkout should be suppressed. The +vpdignore option performs the license suppression. +vpddrivers Reports value changes for all drivers when there is more than one driver.
Operations -grw filename Sets the name of the $gr_waves output file to the specified filename. The default file name is grw.dump. +vcs+grwavesoff Suppress $gr_waves system tasks. Options for VCD Files -vcd filename Sets name of $dumpvars output file to filename. The default file name is verilog.dump. A $dumpfile system task in the Verilog source code overrides this option. +vcs+dumpoff+t+ht Turns off value change dumping ($dumpvars) at time t. ht is the high 32 bits of a time value greater than 32 bits.
Options for Specifying Min:Typ:Max Delays +maxdelays Specifies using the maximum delays in min:typ:max delay triplets in module path delays and timing checks, if you compiled your design with the +allmtm compile-time option. Also specifies using the maximum timing delays in min:typ:max delay triplets in an uncompiled SDF file. If you compiled the SDF file with the +allmtm compile-time option, the +maxdelays option specifies using the compiled SDF file with the maximum delays.
+typdelays Specifies using the typical delays in min:typ:max delay triplets in module path delays and timing checks, if you compiled your design with the +allmtm compile-time option. Also specifies using the typical timing delays in min:typ:max delay triplets in an uncompiled SDF file. If you compiled the SDF file with the +allmtm compile-time option, the +typdelays option specifies using the compiled SDF file with the typical delays. This is a default option.
+vcs+flush+log Increases the frequency of dumping both the compilation and simulation log files. +vcs+flush+dump Increases the frequency of dumping all VCD files. +vcs+flush+fopen Increases the frequency of dumping all files opened by the $fopen system function. +vcs+flush+all Increases the frequency of dumping all log files, VCD files, and all files opened by the $fopen system function.
General Options Viewing the Compile-Time Options Used to Create the Executable -E program Starts the program that displays the compile-time options that were on the vcs command line when you created the simv (or simv.exe) executable file. For example: simv -E echo simv -E echo > simvE.log You cannot use any other runtime options with the -E option. Stopping Simulation When the Executable Starts -s Stops simulation just as it begins, and enters interactive mode. Use with the +cli+number option.
Suppressing the $stop System Task +vcs+ignorestop Tells VCS to ignore the $stop system tasks in your source code. Enabling User-Defined Plusarg Options +plus-options User-defined runtime options to perform some operation when the option is on the simv command line. The $test$plusargs system task can check for such options. For an example of checking for a user-defined plusarg runtime option “Enabling Debugging Features At Runtime” on page 2-10.
If during a simulation run, acc_handle_simulated_net is called before MIPD annotation happens, VCS issues a warning message. When this happens you can use this option to disable such aliasing for all ports whenever mip, mipb capabilities have been specified. This option works for reading an ASCII SDF file during simulation and not for compiled SDF files.
D Compiler Directives and System Tasks D This appendix describes: • Compiler Directives • System Tasks and Functions Compiler Directives and System Tasks D-1
Compiler Directives Compiler directives are commands in the source code that specify how VCS compiles the source code that follows them, both in the source files that contain these compiler directives and in the remaining source files that VCS subsequently compiles. Compiler directives are not effective down the design hierarchy.
Compiler Directives for Setting Defaults `default_nettype Sets default net type for implicit nets. See IEEE Std 1364-2001 page 350. Syntax: ‘default_nettype wire | tri | tri0 | wand | triand | tri1 | wor | trior | trireg |none `resetall Resets all compiler directives. See IEEE 1364-2001 page 357. Syntax: ‘resetall Compiler Directives for Macros `define Defines a text macro. See IEEE Std 1364-2001 page 351. Syntax: ‘define text_macro_name macro_text `else Used with `ifdef.
`endif Used with `ifdef.. Specifies the end of a group of lines specified by the ‘ifdef or ‘else compiler directives. See IEEE Std 13642001 page 353. Syntax: ‘endif `ifdef Specifies compiling the source lines that follow if the specified text macro is defined by either the ‘define compiler directive or the +define compile-time option. See IEEE Std 1364-2001 page 353. Syntax: ‘ifdef text_macro_name group_of_lines The exception is the character string "VCS", whichis a predefined text macro in VCS .
‘ifndef Specifies compiling the source code that follows if the specified text macro is not defined. See IEEE Std 1364-2001 page 353. Syntax: ‘ifndef text_macro_name group_of_lines `undef Undefines a macro definition. See IEEE Std 1364-2001 page 351. Syntax: ‘undef text_macro_name Compiler Directives for Detecting Race Conditions ‘race Specifies the beginning of a region in your source code where you want VCS to look for race conditions when you include the Xrace=0x1 compile time option.
`delay_mode_distributed Ignores the module path delays specified in specify blocks in modules under this compiler directive and uses only the delay specifications on all gates, switches, and continuous assignments. Syntax: ‘delay_mode_distributed `delay_mode_unit Ignores the module path delays. Changes all the delay specifications on all gates, switches, and continuous assignments to the shortest time precision argument of all the ‘timescale compiler directives in the source code.
Compiler Directives for Backannotating SDF Delay Values ‘vcs_mipdexpand If the +oldsdf compile-time option has been used to turn off SDF compilation at compile-time, this compiler directive enables the runtime backannotation of individual bits of a port declared in an ASCII text SDF file. This is done by entering the compiler directive over the port declarations for these ports.
`endprotected Defines the end of protected code. Syntax: ‘endprotected `protect Defines the start of code to be protected. Syntax: ‘protect `protected Defines the start of protected code. Syntax: ‘protected Compiler Directives for Controlling Port Coercion `noportcoerce Does not coerce ports to inout. Syntax: ‘noportcoerce `portcoerce Coerces ports as appropriate (default). Syntax: ‘portcoerce General Compiler Directives Compiler Directive for Including a Source File `include Includes source file.
Compiler Directive for Setting the Time Scale `timescale Sets the timescale. See IEEE Std 1364-2001 page 357. Syntax: ‘timescale time_unit / time_precision In VCS the default time unit is 1 s (a full second) and the default time precision is also 1 s. Compiler Directive for Specifying a Library `uselib Searches specified library for unresolved modules. You can specify either a library file or a library directory. Syntax: ‘uselib file = filename or ‘uselib dir = directory_name libext+.ext | libext=.
To specify more than one search library enter additional dir or file keywords, for example: ‘uselib dir = /net/designlibs/library1.lib dir=/ net/designlibs/library2.lib libext+.v Here the libext+.ext keyword applies to both libraries. Compiler Directive for Maintaining The File Name and Line Numbers ‘line line_number "filename" level Maintains the file name and line number. See IEEE Std 1364-2001 page 358.
System Tasks for SystemVerilog Assertions Severity $fatal Generates a runtime fatal assertion error. See the Accellera SystemVerilog 3.1 LRM, page 227. $error Generates a runtime assertion error. See the Accellera SystemVerilog 3.1 LRM, page 227. $warning Generates a runtime warning message. See the Accellera SystemVerilog 3.1 LRM, page 227. $info Generates an information message. See the Accellera SystemVerilog 3.1 LRM, page 227.
System Tasks for SystemVerilog Assertions $onehot Returns true if only one bit in the expression is true. See the Accellera SystemVerilog 3.1 LRM, page 228. $onehot0 Returns true if at the most one bit of the expression is true (also returns true if none of the bits are true). See the Accellera SystemVerilog 3.1 LRM, page 228. $isunknown Returns true if one of the bits in the expression has an X value. See the Accellera SystemVerilog 3.1 LRM, page 228.
$dumpon Starts recording value change information in the VCD file. See IEEE std 1364-2001 page 326. $dumpfile Specifies the name of the VCD file you want VCS to record. Syntax: $dumpfile("filename"); $dumpflush Empties the VCD file buffer and writes all this data to the VCD file. See IEEE std 1364-2001 page 328. $dumplimit Limits the size of a VCD file. See IEEE std 1364-2001 page 327. $dumpvars Specifies the nets and registers whose transition times and values you want VCS to record in the VCD file.
$fflush VCS stores VCD data in the operating system’s dump file buffer and as simulation progresses, reads from this buffer to write to the VCD file on disk. If you need the latest information written to the VCD file at a specific time, use the $fflush system task. Syntax: $fflush("filename"); Code example: $fflush("vcdfile1.vcd"); $fflushall If you are writing more than one VCD file and need VCS to write the latest information to all these files at a particular time, use the $fflushall system task.
System Tasks for LSI Certification VCD and EVCD Files $lsi_dumpports For LSI certification of your design, this system task specifies recording a simulation history file that contains the transition times and values of the ports in a module instance. This simulation history file for LSI certification contains more information than the VCD file specified by the $dumpvars system task.
tasks both generated simulation history files for LSI certification and had identical syntax except for the name of the system task. Syntax of the $dumpports system task is now: $dumpports(module_instance,[module_instance,] "filename"); You can specify more than one module instance. Code example: $dumpports(top.middle1,top.middle2, "dumports.
$dumpportsall By default VCS writes to files only when a signal changes value. The $dumpportsall system task records the values of the ports in the module instances, which are specified by the $lsi_dumpports or $dumpports system task, whether there is a value change on these ports or not.
$dumpportslimit Specifies the maximum file size of the file specified by the $lsi_dumpports or $dumpports system task. You specify the file size in bytes. When the file reaches this limit VCS no longer writes to the file. You can specify the file whose size you want to limit or specify no particular file, in which case your specified size limit applies to all files opened by the $lsi_dumpports or $dumpports system task. See IEEE Std 1364-2001 page 341342.
Note: To use the system tasks for VPD files you must compile your source code with the -I or -PP compile-time options. $vcdplusautoflushoff Turns off the automatic “flushing” of simulation results to the VPD file whenever there is an interrupt, such as when VCS executes the $stop system task.
$vcdplusdeltacycleon Enables delta cycle recording in the VPD file for post-processing. Syntax: $vcdplusevent(net_or_reg,"event_name", ""); Displays, in DVE, a symbol on the signal’s waveform and in the Logic Browser. The event_name argument appears in the status bar when you click on the symbol. E|W|I specifies severity. E for error, displays a red symbol, W for warning, displays a yellow symbol, I for information, displays a green symbol. S|T|D specifies the symbol shape.
$vcdplusdumpportson Records transition times and values of ports in a module instance. A level value of 0 tells VCS to dump all levels below the specified instance. If you do not specify a level, the default level is 1. If you use the system task without arguments, VCS dumps all ports of all instances of the while design in the VPD file.
$vcdplusflush Tells VCS to “flush” or write all the simulation results in memory to the VPD file at the time VCS executes this system task. Use $vcdplusautoflushon to enable automatic flushing of simulation results to the file when simulation stops. Syntax: $vcdplusflush; $vcdplusmemon Records value changes and times for memories and multidimensional arrays. Syntax: system_task( Mda [, dim1Lsb [, dim1Rsb [, dim2Lsb [, dim2Rsb [, ...
dim2Lsb This is an optional argument with the same functionality as dim1Lsb, but refers to the second dimension. dim2Rsb This is an optional argument with the same functionality as dim1Rsb, but refers to the second dimension. dimNLsb This is an optional argument that specifies the left bound of the Nth dimension. dimNRsb This is an optional argument that specifies the right bound of the Nth dimension.
$vcdplusmemorydump Records (dumps) a snapshot of the values in a memory or multi-dimensional array into the VPD file. Syntax is the same as the $vcdplusmenon system task. $vcdplusoff Stops recording, in the VPD file, the transition times and values for the nets and registers in the specified module instance or individual nets or registers.
level_number Specifies the number of hierarchy scope levels for which to record signal value changes (a zero value records all scope instances to the end of the hierarchy; default is all). module_instance Specifies the name of the scope for which to record signal value changes (default is all). net_or_variable Specifies the name of the signal for which to record signal value changes (default is all).
$assert_monitor([0|1,]assertion_identifier...); Where: 0 Specifies reporting on the assertion if it is active (VCS checks for its properties) and if not, reporting on the assertion or assertions, whenever they start. 1 Specifies reporting on the assertion or assertions only once, the next time they start. If you specify neither 0 or 1, the default is 0. assertion_identifier... A comma separated list of assertions.
Commands $system Executes operating system commands. Syntax: $system("command"); Code example: $system("mv -f savefile savefile.1"); $systemf Executes operating system commands and accepts multiple formatted string arguments. Syntax: $systemf("command %s ...","string",...); Code example: int = $systemf("cp %s %s", "file1", "file2"); The operating system copies the file named file1 to a file named file2.
$nolog Disables writing to the vcs.log file or the log file specified by either the -l runtime option or the $log system task. Syntax: $nolog; System Tasks for Data Type Conversions $bitstoreal[b] Converts a bit pattern to a real number. See IEEE std 1364-2001 page 310. $itor[i] Converts integers to real numbers. See IEEE std 1364-2001 page 310. $realtobits Passes bit patterns across module ports, converting a real number to a 64 bit representation. See IEEE std 1364-2001 page 310.
$monitoroff Disables the $monitor system task. See IEEE std 1364-2001 page 286. $monitoron Re-enables the $monitor system task after it was disabled with the $monitoroff system task. See IEEE std 1364-2001 page 286. $strobe[b|h|0]; Displays simulation data at a selected time. See IEEE 1364-2001 page 285. $write[b|h|0] Displays text. See IEEE std 1364-2001 pages 278-285. System Tasks for File I/O $fclose Closes a file. See IEEE std 1364-2001 pages 286-288. $fdisplay[b|h|0] Writes to a file.
$fgets Reads a string from a file. See IEEE Std 1364-2001 page 290. $fmonitor[b|h|0] Writes to a file when an argument changes value. See IEEE std 1364-2001 pages 287-288. $fopen Opens files. See IEEE std 1364-2001 pages 286-288. $fread Reads binary data from a file. See IEEE Std 1364-2001 page 293. $fscanf Reads characters in a file. See IEEE Std 1364-2001 pages 290293. $fseek Sets the position of the next read or write operation in a file. See IEEE Std 1364-2001 page 294.
$sformat Assigns a string value to a specified signal. See IEEE Std 1364-2001 pages 289-290. $sscanf Reads characters from an input stream. See IEEE Std 1364-2001 pages 290-293. $swrite Assigns a string value to a specified signal, similar to the $sformat system function. See IEEE Std 1364-2001 pages 289-290. $ungetc Returns a character to the input stream. See IEEE Std 1364-2001 page 290. System Tasks for Loading Memories $readmemb Loads binary values in a file into memories.
$writememb Writes binary data in a memory to a file. Syntax: $writememb ("filename",memory [,start_address] [,end_address]); Code example: $writememb ("testfile.txt",mem,0,255); $writememh Writes hexadecimal data in a memory to a file.
$finish Ends simulation. See IEEE std 1364-2001 page 301. System Tasks for Timing Checks $disable_warnings Disables the display of timing violations but does not disable the toggling of notifier registers. Syntax: $disable_warnings[(module_instance,...)]; An alternative syntax is: $disable_warnings("timing"[,module_instance,...]); If you specify a module instance, this system task disables timing violations for the specified instance and all instances hierarchically under this instance.
$enable_warnings("timing"[,module_instance,...]); If you specify a module instance, this system task enables timing violations for the specified instance and all instances hierarchically under this instance. If you omit module instances, this system task enables timing violations throughout the design. $hold Reports a timing violation when a data event happens too soon after a reference event. See IEEE Std 1364-2001 pages 241-242.
$recrem Reports a timing violation if a data event occurs less than a specified time limit before or after a reference event. This timing check is identical to the $setuphold timing check except that typically the reference event is on a control signal and the data event is on a clock signal. You can specify negative values for the recovery and removal limits.
$setuphold Combines the $setup and $hold system tasks. See IEEE Std 1364-1995 page 189 for the official description. There is also an extended syntax that is in IEEE Std 1364-2001 pages 242-244. This extended syntax is as follows: $setuphold(reference_event, data_event, setup_limit, hold_limit, notifier, timestamp_cond, timecheck_cond, delay_reference, delay_data); See “The $setuphold Timing Check Extended Syntax” on page 14-7 for more information.
$q_exam Provides statistical information about activity at the queue. See IEEE Std 1364-2001 page 307. $q_full Returns 0 if the queue is not full, returns a 1 if the queue is full. See IEEE Std 1364-2001 page 307. $q_initialize Creates a new queue. See IEEE Std 1364-2001 page 306-307. $q_remove Receives an entry from a queue. See IEEE Std 1364-2001 page 307. System Tasks for Simulation Time $realtime Returns a real number time. See IEEE Std 1364-2001 pages 309-310.
System Tasks for Probabilistic Distribution $dist_exponential Returns random numbers where the distribution function is exponential. See IEEE std 1364-2001 page 312. $dist_normal Returns random numbers with a specified mean and standard deviation. See IEEE Std 1364-2001 page 312. $dist_poisson Returns random numbers with a specified mean. See IEEE Std 1364-2001 page 312. $dist_uniform Returns random numbers uniformly distributed between parameters. See IEEE Std 1364-2001 page 312.
$reset_count Keeps track of the number of times VCS executes the $reset system task in a simulation session. See IEEE std 1364-2001 pages 741-742. $reset_value System function that you can use to pass a value from before to after VCS executes the $reset system task, that is, you can enter a reset_value integer argument to the $reset system task, and after VCS resets the simulation the $reset_value system function returns this integer argument. See IEEE std 13642001 pages 741-742.
Counting the Drivers on a Net $countdrivers Counts the number of drivers on a net. See IEEE std 1364-2001 page 738-739. Depositing Values $deposit Deposits a value on a net or variable. This deposited value overrides the value from any other driver of the net or variable. The value propagates to all loads of the net or variable. A subsequent simulation event can override the deposited value. You cannot use this system task to deposit values to bit-selects or part-selects.
Saving and Restarting The Simulation State $save Saves the current simulation state in a file. See IEEE std 1364-2001 pages 742-743, also see “Save and Restart” on page -4-4. $restart Restores the simulation to the state that you saved in the check file with the $save system task. Enter this system task at the CLI prompt instead of in the source code. You can also do this by entering the name of the check file at the system prompt.
$xzcheckoff Suppress the warning message every time VCS evaluates a conditional expression to have an X or Z value. Syntax: $xzcheckoff(hierarchical_name,level_number) hierarchical_name Hierarchical name of the module instance, that is, the top-level instance of the subhierarchy for which you want to enable checking. level_number Number of levels down in the subhierarchy from the specified module instance. Checking is also enabled for the instances on these levels.
E PLI Access Routines E VCS comes with a number of access routines.
• Access Routine for Signal in a Generate Block • VCS API Routines Access Routines for Reading and Writing to Memories VCS comes with the a number of access routines for reading and writing to a memory. These access routines are as follows: acc_setmem_int Writes an integer value to specific bits in a Verilog memory word. See "acc_setmem_int" on page E-4 for details. acc_getmem_int Reads an integer value from specific bits in a Verilog memory word. See "acc_getmem_int" on page E-5 for details.
acc_setmem_bitstr Writes a string of binary bits (including x and z) to a Verilog memory word. See "acc_setmem_bitstr" on page E-16 for details. acc_getmem_bitstr Reads a bit string from specific bits in a Verilog memory word. See "acc_getmem_bitstr" on page E-17 for details. acc_handle_mem_by_fullname Returns the handle used by acc_readmem. See "acc_handle_mem_by_fullname" on page E-18 for details. acc_readmem Reads a data file and writes the contents to a memory.
acc_setmem_int You use the acc_setmem_int access routine to write an integer value to specific bits in a Verilog memory word. acc_setmem_int Synopsis: Writes an integer value to specific bits in a memory word. Syntax: acc_setmem_int (memhand, value, row, start, length) Type Returns: Arguments: Related routines: void Type Name Description handle memhand Handle to memory int value The integer value written in binary format to the bits in the word. int row The memory array index.
acc_getmem_int You use the acc_getmem_int access routine to return an integer value for certain bits in a Verilog memory word. acc_getmem_int Synopsis: Returns an integer value for specific bits in a memory word. Syntax: acc_getmem_int (memhand, row, start, length) Returns: Arguments: Related routines: Type Description int Integer value of the bits in the memory word.
acc_clearmem_int You use the acc_clearmem_int access routine to write zeros to all bits in a memory. acc_clearmem_int Synopsis: Clears a memory word.
• Example D-3 shows the Verilog source code containing these system tasks. Example D-1 C Source Code for Functions Calling acc_getmem_int, acc_setmem_int, and acc_clearmem_int #include #include "acc_user.h" #include "vcs_acc_user.
memhand = acc_handle_tfarg(1); if(!memhand) error_handle("NULL MEM HANDLE\n"); row = acc_fetch_tfarg_int(2); start_bit = acc_fetch_tfarg_int(3); len = acc_fetch_tfarg_int(4); value = acc_getmem_int(memhand, row, start_bit, len); printf("getmem: value of word %d is : %d\n",row,value); fflush(stdout); } void clear_mem() { handle memhand = NULL; memhand = acc_handle_tfarg(1); if(!memhand) error_handle("NULL MEM HANDLE\n"); acc_clearmem_int(memhand); } The function with the set_mem identifier calls the IEEE st
The function with the clear_mem identifier likewise calls the acc_fetch_tfarg_int routine to get a handle and then calls acc_clear_mem_int with that handle. Example D-2 PLI Table File $set_mem call=set_mem acc+=rw:* $get_mem call=get_mem acc+=r:* $clear_mem call=clear_mem acc+=rw:* Here the $set_mem user-defined system task is associated with the set_mem function in the C code, as are the $get_mem and $clear_mem with their corresponding get_mem and clear_mem function identifiers.
// print values through acc_getmem_int #1 len = bfinish - bstart + 1; $display(); $display("Begin Memory Values"); for (i=start;i<=finish;i=i+1) begin $get_mem(mymem,i,bstart,len); end $display("End Memory Values"); $display(); // display values #1 $display(); $display("Begin Memory Display"); for (i=start;i<=finish;i=i+1) begin $display("mymem word %d is %b",i,mymem[i]); end $display("End Memory Display"); $display(); end endmodule In this Verilog code, in the initial block, the following events occur: 1.
acc_setmem_hexstr You use the acc_setmem_hexstr access routine for writing the corresponding binary representation of a hexadecimal string to a Verilog memory. acc_setmem_hexstr Synopsis: Writes a hexadecimal string to a word in a Verilog memory.
Examples The following code examples illustrates the use of acc_setmem_hexstr: • Example D-4 shows the C source code for an application that calls acc_setmem_hexstr. • Example D-5 shows the contents of a data file read by the application. • Example D-6 shows the PLI table file that associates the user-defined system task in the Verilog code with the application. • Example D-7 shows the Verilog source that calls the application.
Example D-4 shows the source code for a PLI application that: 1. Reads a data file named initfile to find the memory identifiers of the memories it writes to, the hexadecimal string to be converted to its bit representation when written to the memory, the index of the memory where it writes this value, and the starting bit for writing the binary value. 2. Displays where in the memory it is writing these values 3. Calls the access routine to write the values in the initfile.
testbench.U1.slave_addr[0], testbench.U1.slave_addr[1], testbench.U1.slave_addr[2], testbench.U1.load, testbench.U2.cmd_array[0], testbench.U2.cmd_array[1], testbench.U2.
acc_getmem_hexstr You use the acc_getmem_hexstr access routine to get a hexadecimal string from a Verilog memory. acc_getmem_hexstr Synopsis: Returns a hexadecimal string from a Verilog memory.
acc_setmem_bitstr You use the acc_setmem_bitstr access routine for writing a string of binary bits (including x and z) to a Verilog memory. acc_setmem_bitstr Synopsis: Writes a string of binary bits to a word in a Verilog memory.
acc_getmem_bitstr You use the acc_getmem_bitstr access routine to get a bit string, including x and z values, from a Verilog memory. acc_getmem_bitstr Synopsis: Returns a hexadecimal string from a Verilog memory.
acc_handle_mem_by_fullname Returns a handle to a memory that can only be used as a parameter to acc_readmem.
acc_readmem You use the acc_readmem access routine to read a data file into a memory. It is similar to the $readmemb or $readmemh system tasks. The memhandle argument must be the handle returned by acc_handle_mem_by_fullname.
Examples The following code examples illustrate the use of acc_readmem and acc_handle_mem_by_fullname. Example D-8 C Source Code Calling Tacc_readmem and acc_handle_mem_by_fullname #include "acc_user.h" #include "vcs_acc_user.h" #include "vcsuser.
acc_getmem_range You use the acc_getmem_range access routine to access the upper and lower limits of a memory.
acc_getmem_size You use the acc_getmem_size access routine to access the number of elements in a memory.
acc_getmem_word_int You use the acc_getmem_word_int access routine to access the integer value of an element (or word, address, or row).
acc_getmem_word_range You use the acc_getmem_word_range access routine to access the least significant bit of an element (or word, address, or row) and the length of the element.
Access Routines for Multidimensional Arrays The type for multidimensional arrays is defined in the vcs_acc_user.h file. Its name is accMda. We also have the following tf and access routines for accessing data in a multidimensional array: tf_mdanodeinfo and tf_imdanodeinfo Returns access parameter node information from a multidimensional array. See "tf_mdanodeinfo and tf_imdanodeinfo" on page E-26 for details. acc_get_mda_range Returns all the ranges of the multidimensional array.
tf_mdanodeinfo and tf_imdanodeinfo You use these routines to access parameter node information from a multidimensional array. tf_mdanodeinfo(), tf_imdanodeinfo() Synopsis: Returns access parameter node information from a multidimensional array.
int node_vec_size; int node_sign; int node_ms_index; int node_ls_index; int node_mem_size; int *node_lhs_element; int *node_rhs_element; int node_dimension; int *node_handle; int node_vec_type; } s_tfmdanodeinfo, *p_tfmdanodeinfo; PLI Access Routines E-27
acc_get_mda_range The acc_get_mda_range routine returns the ranges of a multidimensional array. acc_get_mda_range() Synopsis: Gets all the ranges of the multidimensional array.
And you call a routine, such as the following: handle hN = acc_handle_by_name(my_mem); acc_get_mda_range(hN, &size, &msb, &lsb, &dim, &plndx, &prndx); It yields the following result: size = 8; msb = 7, lsb = 0; dim = 4; plndx[] = {255, 255, 31} prndx[] = {0, 0, 0} acc_get_mda_word_range() The acc_get_mda_word_range routine returns the range of an element in a multidimensional array. acc_get_mda_word_range() Synopsis: Gets the range of an element in a multidimensional array.
If you have a multidimensional array such as the following: reg [7:0] my_mem[255:0][255:0][31:0]; And you call a routine, such as the following: handle hN = acc_handle_by_name(my_mem); acc_get_mda_word_range(hN, &left, &right); It yields the following result: left = 7; right = 0; PLI Access Routines E-30
acc_getmda_bitstr() You use the acc_getmda_bitstr access routine to read a bit string, including x and z values, from a multidimensional array. acc_getmda_bitstr() Synopsis: Gets a bit string from a multidimensional array.
It yields the following string from my_mem[5][5][10][3:5]. acc_setmda_bitstr() You use the acc_setmda_bitstr access routine to write a bit string, including x and z values, into a multidimensional array. acc_setmda_bitstr() Synopsis: Sets a bit string in a multidimensional array.
handle hN = acc_handle_by_name(my_mem); acc_setmda_bitstr(hN, &bitStr, dim, 3, 3); It writes 111 in my_mem[5][5][10][3:5]. Access Routines for Probabilistic Distribution VCS comes with the following API routines that duplicate the behavior of the Verilog system functions for probabilistic distribution: vcs_random Returns a random number and takes no argument. See "vcs_random" on page E-34 for details. vcs_random_const_seed Returns a random number and takes an integer argument.
vcs_dist_poisson Returns random numbers with a specified mean. See "vcs_random" on page E-34 for details. These routines are declared in the vcs_acc_user.h file in $VCS_HOME/lib. vcs_random You use this routine to obtain a random number. vcs_random() Synopsis: Returns a random number.
vcs_random_const_seed You use this routine to return a random number and you supply an integer constant argument as the seed for the random number. vcs_randon_const_seed Synopsis: Returns a random number. Syntax: vcs_random_const_seed(integer) Type Description int Random number Type Name Description Arguments: int integer An integer constant.
vcs_dist_uniform You use this routine to return a random number uniformly distributed between parameters. vcs_dist_uniform Synopsis: Returns random numbers uniformly distributed between parameters. Syntax: vcs_dist_uniform(seed, start, end) Returns: Arguments: Related routines: Type Description int Random number Type Name Description int * seed Pointer to a seed integer value. int start Starting parameter for distribution range. int end Ending parameter for distribution range.
vcs_dist_normal You use this routine to return a random number with a specified mean and standard deviation. vcs_dist_normal Synopsis: Returns random numbers with a specified mean and standard deviation. Syntax: vcs_dist_normal(seed, mean, standard_deviation) Returns: Arguments: Related routines: Type Description int Random number Type Name Description int * seed Pointer to a seed integer value. int mean An integer that is the average value of the possible returned random numbers.
vcs_dist_exponential You use this routine to return a random number where the distribution function is exponential. vcs_dist_exponential Synopsis: Returns random numbers where the distribution function is exponential. Syntax: vcs_dist_exponential(seed, mean) Returns: Arguments: Related routines: Type Description int Random number Type Name Description int * seed Pointer to a seed integer value. int mean An integer that is the average value of the possible returned random numbers.
vcs_dist_poisson You use this routine to return a random number with a specified mean. vcs_dist_poisson Synopsis: Returns random numbers with a specified mean. Syntax: vcs_dist_poisson(seed, mean) Returns: Arguments: Related routines: Type Description int Random number Type Name Description int * seed Pointer to a seed integer value. int mean An integer that is the average value of the possible returned random numbers.
For your convenience VCS provides the acc_fetch_paramval_str routine to directly return a string pointer. acc_fetch_paramval_str Returns the value of a string parameter directly as char*. acc_fetch_paramval_str Synopsis: Returns the value of a string parameter directly as char*. Syntax: acc_fetch_paramval_str(param_handle) Type Description char* string pointer Type Name Description Arguments: handle param_handle Handle to a module parameter or specparam.
acc_lsi_dumpports_close Closes specified VCDE files. See "acc_lsi_dumpports_close" on page E-45 for details. acc_lsi_dumpports_flush Flushes cached data to the VCDE file on disk. See "acc_lsi_dumpports_flush" on page E-46 for details. acc_lsi_dumpports_limit Sets the maximum VCDE file size. See "acc_lsi_dumpports_limit" on page E-47 for details. acc_lsi_dumpports_misc Processes miscellaneous events. See "acc_lsi_dumpports_misc" on page E-48 for details. acc_lsi_dumpports_off Suspends VCDE file dumping.
acc_lsi_dumpports_all Syntax int acc_lsi_dumpports_all(char *filename) Synopsis Adds a checkpoint to the file. This is a PLI interface to the $dumpportsall system task. If the filename argument is NULL, this routine adds a checkpoint to all open VCDE files. Returns The number of VCDE files that matched. Example D-11 Example of acc_lsi_dumpports_all #include "acc_user.h" #include "vcs_acc_user.h" handle instance = acc_handle_by_name("test_bench.device", 0); char *outfile = "device.
acc_lsi_dumpports_all(outfile); acc_lsi_dumpports_flush(outfile); } ... if (resume_dumping_now) acc_lsi_dumpports_on(outfile); ... Caution This routine may affect files opened by the $dumpports and $lsi_dumpports system tasks. acc_lsi_dumpports_call Syntax int acc_lsi_dumpports_call(handle instance, char *filename) Synopsis Monitors instance ports. This is a PLI interface to the $lsi_dumpports task.
Example D-12 Example of acc_lsi_dumpports_all #include "acc_user.h" #include "vcs_acc_user.h" handle instance = acc_handle_by_name("test_bench.device", 0); char *outfile = "device.evcd"; acc_lsi_dumpports_setformat(USE_DUMPPORTS_FORMAT_IEEE); if (acc_lsi_dumpports_call(instance, outfile)) { /* error */ } Caution Multiple calls to this routine are allowed, but the output file name must be unique for each call.
acc_lsi_dumpports_close Syntax int acc_lsi_dumpports_call(handle instance, char *filename) Synopsis Closes specified VCDE files. This routine reads the list of files opened by a call to the system tasks $dumpports and $lsi_dumpports or the routine acc_lsi_dumpports_call() and closes all that match either the specified instance handle or the filename argument. One or both arguments can be used. If the instance handle is non-null, this routine closes all files opened for that instance.
Caution A call to this function can also close files opened by the $lsi_dumpports or $dumpports system tasks. acc_lsi_dumpports_flush Syntax int acc_lsi_dumpports_flush(char *filename) Synopsis Flushes cached data to the VCDE file on disk. This is a PLI interface to the $dumpportsflush system task. If the filename is NULL all open files are flushed. Returns The number of files matched. Example D-14 Example of acc_lsi_dumpports_flush #include "acc_user.h" #include "vcs_acc_user.
/* add checkpoint (no need to enable dumping) */ acc_lsi_dumpports_all(outfile); acc_lsi_dumpports_flush(outfile); } ... if (resume_dumping_now) acc_lsi_dumpports_on(outfile); ... acc_lsi_dumpports_limit Syntax int acc_lsi_dumpports_limit(unsigned long filesize, char *filename) Synopsis Sets the maximum VCDE file size. This is a PLI interface to the $dumpportslimit task. If the filename is NULL the file size is applied to all files. Returns The number of files matched.
if (time == yada_yada) acc_lsi_dumpports_off(outfile); ... if (time == yada_yada_yada) { /* add checkpoint (no need to enable dumping) */ acc_lsi_dumpports_all(outfile); acc_lsi_dumpports_flush(outfile); } ... if (resume_dumping_now) acc_lsi_dumpports_on(outfile); ... Caution This routine may affect files opened by the $dumpports and $lsi_dumpports system tasks. acc_lsi_dumpports_misc Syntax void acc_lsi_dumpports_misc(int data, int reason) Synopsis Processes miscellaneous events.
Example D-16 Example or acc_lsi_dumpports_misc #include "acc_user.h" #include "vcs_acc_user.h" void my_task_misc(int data, int reason) { acc_lsi_dumpports_misc(data, reason); ... } acc_lsi_dumpports_off Syntax int acc_lsi_dumpports_off(char *filename) Synopsis Suspends VCDE file dumping. This is a PLI interface to the $dumpportsoff system task. If the filename is NULL dumping is suspended on all open files. Returns The number of files that matched.
if (time == yada_yada) acc_lsi_dumpports_off(outfile); ... if (time == yada_yada_yada) { /* add checkpoint (no need to enable dumping) */ acc_lsi_dumpports_all(outfile); acc_lsi_dumpports_flush(outfile); } ... if (resume_dumping_now) acc_lsi_dumpports_on(outfile); ... Caution This routine may suspend dumping on files opened by the $dumpports and $lsi_dumpports system tasks. acc_lsi_dumpports_on Syntax int acc_lsi_dumpports_on(char *filename) Synopsis Resumes VCDE file dumping.
char *outfile = "device.evcd"; /* use IEEE format for this file */ acc_lsi_dumpports_setformat(USE_DUMPPORTS_FORMAT_IEEE); if (acc_lsi_dumpports_call(instance, outfile)) { /* rut-roh */ } acc_lsi_dumpports_limit(100000, outfile); ... if (time == yada_yada) acc_lsi_dumpports_off(outfile); ... if (time == yada_yada_yada) { /* add checkpoint (no need to enable dumping) */ acc_lsi_dumpports_all(outfile); acc_lsi_dumpports_flush(outfile); } ... if (resume_dumping_now) acc_lsi_dumpports_on(outfile); ...
acc_lsi_dumpports_setformat Syntax int acc_lsi_dumpports_setformat(lsi_dumpports_format_type format) Where the valid lsi_dumports_format_types are as follows: USE_DUMPPORTS_FORMAT_IEEE USE_DUMPPORTS_FORMAT_LSI Synopsis Specifies the format of the VCDE file. Use this routine to specify which output format (IEEE or the original LSI) should be used. This routine must be called before acc_lsi_dumpports_call(). Returns Zero if success, non-zero if error. Errors are reported through tf_error().
acc_lsi_dumpports_setformat(USE_DUMPPORTS_FORMAT_LSI); if (acc_lsi_dumpports_call(instance, outfile2)) { /* error */ } ... Caution The runtime plusargs +dumpports+ieee and +dumpports+lsi have priority over this routine. The format of files created by calls to the $dumpports and $lsi_dumpports tasks are not affected by this routine.
char *outfile1 = "device.evcd1"; char *outfile2 = "device.evcd2"; /* Include VHDL drivers in this report */ acc_lsi_dumpports_vhdl_enable(1); acc_lsi_dumpports_call(instance, outfile1); /* Exclude VHDL drivers from this report */ acc_lsi_dumpports_vhdl_enable(0); acc_lsi_dumpports_call(instance, outfile1); ... Caution This routine has precedence over the +dumpports+vhdl+enable and +dumpports+vhdl+disable runtime options.
acc_mod_lcb_fetch Returns an array of breakable lines. See "acc_mod_lcb_fetch" on page E-59 for details. acc_mod_lcb_fetch2 Returns an array of breakable lines. See "acc_mod_lcb_fetch2" on page E-60 for details. acc_mod_sfi_fetch Returns the source file composition for a module. See "acc_mod_sfi_fetch" on page E-62 for details.
Returns No return value. Example D-21 Example of acc_mod_lcb_add #include #include "acc_user.h" #include "vcs_acc_user.
acc_mod_lcb_del Syntax void acc_mod_lcb_del(handle handleModule, void (*consumer)(), char *user_data) Synopsis Unregisters a line callback routine previously registered with the acc_mod_lcb_add() routine. Returns No return value. Example D-22 Example of acc_mod_lcb_del #include #include "acc_user.h" #include "vcs_acc_user.h" /* VCS 4.
acc_fetch_fullname (parent_mod)); acc_mod_lcb_del (parent_mod, line_call_back, parent_mod); } while ((child = acc_next_child (parent_mod, child))) { register_lcb (child); } Caution The module handle, consumer routine and user data arguments must match those supplied to the acc_mod_lcb_add() routine for a successful delete. For example, using the result of a call such as acc_fetch_name() as the user data will fail, because that routine returns a different pointer each time it’s called.
Example D-23 Example of acc_mod_lcb_enabled if (! acc_mod_lcb_enable) { tf_warning("Line callbacks not enabled. Please recompile with -line."); } else { acc_mod_lcb_add ( ... ); ... } acc_mod_lcb_fetch Syntax p_location acc_mod_lcb_fetch(handle handleModule) Synopsis Returns an array of breakable lines. This routine returns all the lines in a module that you can set breakpoints on. Returns The return value is an array of line number, file name pairs.
Example D-24 Example of acc_mod_lcb_fetch #include #include "acc_user.h" #include "vcs_acc_user.h" void ShowLines(handleModule) handle handleModule; { p_location plocation; if ((plocation = acc_mod_lcb_fetch(handleModule)) != NULL) { int i; io_printf("%s:\n", acc_fetch_fullname(handleModule)); } } for (i = 0; plocation[i].filename; i++) { io_printf(" [%s:%d]\n", plocation[i].filename, plocation[i].
The tag field is a unique identifier used to distinguish ‘include files. For example, in the following Verilog module, the breakable lines in the first ‘include of the file sequential.code have a different tag than the breakable lines in the second ‘include. (The tag numbers will match the vcs_srcfile_info_t->SourceFileTag field. See the acc_mod_sfi_fetch() routine for details.) module x; initial begin ‘include sequential.code ‘include sequential.
if ((plocation = acc_mod_lcb_fetch2(handleModule)) != NULL) { int i; io_printf("%s:\n", acc_fetch_fullname(handleModule)); } } for (i = 0; plocation[i].filename; i++) { io_printf(" file %s, line %d, tag %d\n", plocation[i].filename, plocation[i].line_no, plocation[i].tag); } acc_free(plocation); acc_mod_sfi_fetch Syntax vcs_srcfile_info_p acc_mod_sfi_fetch(handle handleModule) Synopsis Returns the source file composition for a module.
Returns NULL if the module is source protected. Example D-26 Example of acc_mod_sfi_fetch #include #include "acc_user.h" #include "vcs_acc_user.h" void print_info (mod) handle mod; { vcs_srcfile_info_p infoa; io_printf("Source Info for Module %s:\n", acc_fetch_fullname(mod)); } if ((infoa = acc_mod_sfi_fetch(mod)) != NULL) { int i; for (i = 0; infoa[i].SourceFileName != NULL; i++) { io_printf(" Tag %2d, StartLine %2d, ", infoa[i].SourceFileTag, infoa[i].
Access Routines for Source Protection The enclib.o file provides a set of access routines that you can use to create applications which directly produce encrypted Verilog source code. Encrypted code can only be decoded by the VCS compiler. There is no user-accessible decode routine. Note that both Verilog and SDF code can be protected. VCS knows how to automatically decrypt both.
vcsSpEncoding This routine gets the current state of encoding. See "vcsSpEncoding" on page E-71 for details. vcsSpGetFilePtr This routine just returns the value previously passed to the vcsSpSetFilePtr() routine. See "vcsSpGetFilePtr" on page E-72 for details. vcsSpInitialize Allocates a source protect object. See "vcsSpInitialize" on page E-73 for details. vcsSpOvaDecodeLine Decrypts one line. See "vcsSpOvaDecodeLine" on page E-74 for details. vcsSpOvaDisable Switches to regular encryption.
vcsSpSetPliProtectionFlag Sets the PLI protection flag. See "vcsSpSetPliProtectionFlag" on page E-80 for details. vcsSpWriteChar Writes one character to the protected file. See "vcsSpWriteChar" on page E-81 for details. vcsSpWriteString Writes a character string to the protected file. See "vcsSpWriteString" on page E-83 for details. Example D-27 outlines the basic use of the source protection routines. Example D-27 Using the Source Protection Routines #include #include "enclib.
write_error += vcsSpWriteString(esp, "This text will *not* be encrypted.\n"); write_error += vcsSpEncodeOn(esp); write_error += vcsSpWriteString(esp, "This text *will* be encrypted."); write_error += vcsSpWriteChar(esp, ’\n’); write_error += vcsSpEncodeOff(esp); write_error += vcsSpWriteString(esp, "This text will *not* be encrypted.
vcsSpClose Syntax void vcsSpClose(vcsSpStateID esp) Synopsis This routine frees the memory allocated by vcsSpInitialize(). Call it when source encryption is finished on the specified stream. Returns No return value. Example D-28 Example of vcsSpClose vcsSpStateID esp = vcsSpInitialize(); ... vcsSpClose(esp); vcsSpEncodeOff Syntax int vcsSpEncodeOff(vcsSpStateID esp) Synopsis This function performs two operations: 1.
Returns Non-zero if there was an error writing to the output file, 0 if successful. Example D-29 Example of vcsSpEncodeOff vcsSpStateID esp = vcsSpInitialize(); FILE *fp = fopen("protected.file", "w"); int write_error = 0; * if (fp == NULL) exit(1); vcsSpSetFilePtr(esp, fp); if (vcsSpWriteString(esp, "This text will *not* be encrypted. ++write_error; if (vcsSpEncodeOn(esp)) ++write_error; if (vcsSpWriteString(esp, "This text *will* be encrypted.
Synopsis This function performs two operations: 1. It inserts a header section which contains the ‘protected compiler directive into the output file. It also inserts some initial header information used by the decryption algorithm. 2. It toggles the encryption flag to true so that subsequent calls to vcsSpWriteString() and vcsSpWriteChar() will have their data encrypted. Returns Non-zero if there was an error writing to the output file, 0 if successful.
Caution You must call vcsSpInitialize() and vcsSpSetFilePtr() before calling this routine. vcsSpEncoding Syntax int vcsSpEncoding(vcsSpStateID esp) Synopsis Calling vcsSpEncodeOn() and vcsSpEncodeOff() turns encoding on and off. Use this function to get the current state of encoding. Returns 1 for on, 0 for off. Example D-31 Example of vcsSpEncoding vcsSpStateID esp = vcsSpInitialize(); FILE *fp = fopen("protected.file", "w"); if (fp == NULL) { printf("ERROR: file ...
vcsSpGetFilePtr Syntax FILE *vcsSpGetFilePtr(vcsSpStateID esp) Synopsis This routine just returns the value previously passed to the vcsSpSetFilePtr() routine. Returns File pointer or NULL if not set. Example D-32 Example of vcsSpGetFilePtr vcsSpStateID esp = vcsSpInitialize(); FILE *fp = fopen("protected.file", "w"); if (fp != NULL) vcsSpSetFilePtr(esp, fp); else /* doh! */ ... if ((gfp = vcsSpGetFilePtr(esp)) != NULL) { /* Add comment before starting encryption */ fprintf(gfp, "\n// TechStuff Version 2.
vcsSpInitialize Syntax vcsSpStateID vcsSpInitialize(void) Synopsis This routine allocates a source protect object. Returns a handle to a malloc’d object which must be passed to all the other source protection routines. This object stores the state of the encryption in progress. When the encryption is complete, this object should be passed to vcsSpClose() to free the allocated memory.
Caution This routine must be called before any other source protection routine. A NULL return value means the call to malloc() failed. Your program should test for this. vcsSpOvaDecodeLine Syntax vcsSpStateID vcsSpOvaDecodeLine(vcsSpStateID esp, char *line) Synopsis This routine decrypts one line. Use this routine to decrypt one line of protected IP code such as OVA code. Pass in a null vcsSpStateID handle with the first line of code and a non-null handle with subsequent lines.
... } if (!esp) break; /* done */ } /* next line should be ‘endprotected_ip */ fgets(linebuf, sizeof(linebuf), infile); if (strcmp(linebuf, "‘endprotected_ip\n")!=0) { printf("warning - expected ‘endprotected_ip\n"); } } vcsSpOvaDisable Syntax void vcsSpOvaDisable(vcsSpStateID esp) Synopsis This routine switches to regular encryption. It tells VCS’s encrypter to use the standard algorithm. This is the default mode. Returns No return value. Example D-35 Example of vcsSpOvaDisable #include "enclib.
if (vcsSpWriteString(esp, "This text will NOT be encrypted.\n")) ++write_error; if (vcsSpEncodeOn(esp)) ++write_error; if (vcsSpWriteString(esp, "This text WILL be encrypted.\n")) ++write_error; if (vcsSpEncodeOff(esp)) ++write_error; if (vcsSpWriteString(esp, "This text will NOT be encrypted.\n")) ++write_error; /* Switch back to regular encryption */ vcsSpOvaDisable(esp); if (vcsSpEncodeOn(esp)) ++write_error; if (vcsSpWriteString(esp, "This text WILL be encrypted.
Example D-36 Example of vcsSpOvaEnable #include "enclib.h" #include "encint.h" int write_error = 0; vcsSpStateID esp; if ((esp = vcsSpInitialize()) printf("Out Of Memory"); vcsSpSetFilePtr(esp, fp); /* previously opened FILE* pointer */ /* Configure for OVA IP encryption */ vcsSpOvaEnable(esp, "synopsys"); if (vcsSpWriteString(esp, "This text will NOT be encrypted.\n")) ++write_error; if (vcsSpEncodeOn(esp)) ++write_error; if (vcsSpWriteString(esp, "This text WILL be encrypted.
vcsSpSetDisplayMsgFlag Syntax void vcsSpSetDisplayMsgFlag(vcsSpStateID esp, int enable) Synopsis This routine sets the DisplayMsg flag. By default the VCS compiler does not display decrypted source code in its error or warning messages. Use this routine to enable this display. Returns No return value.
Example D-38 Example of vcsSpSetFilePtr vcsSpStateID esp = vcsSpInitialize(); FILE *fp = fopen("protected.file", "w"); if (fp != NULL) vcsSpSetFilePtr(esp, fp); else /* abort */ vcsSpSetLibLicenseCode Syntax void vcsSpSetLibLicenseCode(vcsSpStateID esp, unsigned int code) Synopsis This routine sets the OEM library license code that will be added to each protected region started by vcsSpEncodeOn(). This code can be used to protect library models from unauthorized use.
vcsSpEncodeOn(esp); /* start protected region */ vcsSpWriteString(esp, "this text will be encrypted and licensed"); vcsSpEncodeOff(esp); /* end protected region */ /* The following text will be encrypted but unlicensed */ vcsSpSetLibLicenseCode(esp, 0); /* clear license code */ vcsSpEncodeOn(esp); /* start protected region */ vcsSpWriteString(esp, "this text encrypted but not licensed"); vcsSpEncodeOff(esp); /* end protected region */ Caution The rules for mixing licensed and unlicensed code is determined
This routine only affects encrypted Verilog files. Encrypted SDF files, for example, are not affected. Returns No return value. Example D-40 Example of vcsSpSetPliProtectionFlag vcsSpStateID esp = vcsSpInitialize(); vcsSpSetPliProtectionFlag(esp, 0); /* disable PLI protection */ Caution Turning off PLI protection will allow users of your modules to access object names, values, etc. In essence, the source code for your module could be substantially reconstructed using the CLI commands and ACC routines.
Returns Non-zero if the file pointer has not been set (see "vcsSpSetFilePtr" on page E-78) or if there was an error writing to the output file (out-of-disk-space, etc.) Returns 0 if the write was successful. Example D-41 Example of vcsSpWriteChar vcsSpStateID esp = vcsSpInitialize(); FILE *fp = fopen("protected.file", "w"); int write_error = 0; if (fp == NULL) exit(1); vcsSpSetFilePtr(esp, fp); if (vcsSpWriteChar(esp, ’a’)) /* This char will *not* be encrypted.
vcsSpWriteString Syntax int vcsSpWriteString(vcsSpStateID esp, char *s) Synopsis This routine writes a character string to the protected file. If encoding is enabled (see "vcsSpEncodeOn" on page E-69) the specified string is encrypted as it is written to the output file. If encoding is disabled (see "vcsSpEncodeOff" on page E-68) the specified string will be written as-is to the output file (no encryption.
encrypted.\n")) ++write_error; if (vcsSpEncodeOff(esp)) ++write_error; if (vcsSpWriteString(esp, "This text will *not* be encrypted.\n")) ++write_error; fclose(fp); vcsSpClose(esp); Caution vcsSpInitialize() and vcsSpSetFilePtr() must be called prior to calling this routine. Access Routine for Signal in a Generate Block There is only one access routine for signals in generate blocks.
VCS API Routines Typically VCS controls the PLI application. If you write your application so that it controls VCS you need these API routines. Vcsinit() When VCS is run in slave mode, you can call this function to elaborate the design and to initialize various data structures, scheduling queues, etc. that VCS uses. After this routine executes, all the initial time 0 events, such as the execution of initial blocks, are scheduled.
If t is less than the current simulation time, VCS returns control to the calling routine.
Index Symbols -a filename 4-13, C-13 -ams_discipline B-56 -ams_iereport B-56 -as assembler B-50 -ASFLAGS B-50 -assert 20-21, 20-23, 23-36, B-31 -B B-62 -C B-50, B-53 -c B-51 -CC B-51 -cc B-51 -CFLAGS B-51 -cm 23-44 -cm_assert_cov 23-47 -cm_assert_cov_cover 23-47 -cm_assert_grade_instances 23-47 -cm_assert_grade_module 23-47 -cm_assert_hier 23-44 -cm_assert_map 23-48 -cm_assert_merge 23-48 -cm_assert_name 23-44, 23-45, 23-47 -cm_assert_report 23-48 -cm_fsmopt allowTemp B-26 -cm_fsmopt optimist B-27 -cm_fsmop
-k 9-13, C-10, C-15 -l C-15 -l filename 1-15, 1-19, 4-13, B-60, C-13 -ld linker B-50 -LDFLAGS B-50 -line 1-15, B-17 -lmc-hm B-61 -lmc-swift 16-16, B-45 -lmc-swift-template 16-4, B-45 -lname B-51 -load 17-33, B-41 -Mdelete B-7 -Mdirectory B-7 -Mfilename B-7 -Minclude B-7 -Mldcmd B-7 -Mloadlist B-8 -Mmakefile B-8 -Mmakeprogram B-8 -Mrelative_path B-8 -Msrclist B-9 -Mupdate B-6 -negdelay B-34, B-36 -noIncComp B-9 -ntb B-11 -ntb_opts B-12 -ntb_sfname B-14 -ntb_vipext B-14 -ntb_vl B-15 -o name B-62 -O number B-5
-Xnoman B-55 -Xnomangle B-55 -y 1-17, B-4 "A" specifier of abstract access 18-7 "C" specifier of direct access 18-7 $ token 23-5 $assert_monitor 23-64, D-25 $assert_monitor_off 23-64, D-26 $assert_monitor_on 23-64, D-26 $assertkill D-11 $assertoff D-11 $asserton D-11 $async$and$array D-36 $bitstoreal D-28 $countdrivers D-40 $countones 23-68 $deposit D-40 $disable_warnings D-33 $display D-28 $display statement 20-75 $dist_exponential D-38 $dist_normal D-38 $dist_poisson D-38 $dist_uniform D-38 $dumpall D-12
$period D-34 $printtimescale D-32 $q_add D-36 $q_exam D-37 $q_full D-37 $q_initialize D-37 $q_remove D-37 $random 2-33, D-38 $readmemb D-31 $readmemh D-31 $realtime D-37 $realtobits D-28 $recovery D-34 $recrem D-35 $removal D-35 $reset D-38 $reset_count D-39 $reset_value D-39 $restart D-41 $root 22-54 $rose 23-9 $rtoi D-28 $save D-41 $sdf_annotate D-39 $setup D-35 $setuphold D-36 $skew D-36 $sreadmemb D-31 $sreadmemh D-31 $stable 23-10 $stime D-37 $stop D-32 $strobe D-29 $sync$nor$plane D-36 $system D-27 $s
+csdf+precompile 13-7, B-35 +define+macro=value 1-15, B-61 +delay_mode_distributed 12-21, B-33 +delay_mode_path 12-21, B-32 +delay_mode_unit 12-22, B-32 +delay_mode_zero 12-22, B-32 +deleteprotected 25-11, B-54 +enable_solver_trace 21-40 +enable_solver_trace_on_failure 21-41 +error+n 21-30 +incdir 1-15, B-5 +libext B-5 +liborder B-5 +librescan B-5 +libverbose B-5, B-45 +lint B-46 +list 18-82 +maxdelays 13-38, 13-39, 16-16, B-33, B-35, C-19 +memcbk B-60 +memopt B-58 +mindelays 13-38, 13-39, 16-16, B-33, B-35
+sdfverbose C-14 +spl_read B-59 +systemverilogext B-15 +timopt 13-40 +transport_int_delays 12-7, 12-10, 12-12, B-34 +transport_path_delays 12-7, 12-9, 12-12, B-34 +typdelays 13-38, 13-39, 16-16, B-33, B-36, C-20 +v2k 1-17, B-58 +vc 18-81, B-43 +vcdfile B-31 +vcs+boundscheck 3-20, B-59 +vcs+dumpoff+t+ht C-18 +vcs+dumpon+t+ht C-18 +vcs+finish 4-8, C-13 +vcs+flush+all C-21 +vcs+flush+dump C-21 +vcs+flush+fopen C-21 +vcs+flush+log C-21 +vcs+grwavesoff C-18 +vcs+ignorestop 4-12, C-23 +vcs+initmem B-16 +vcs+initr
‘noportcoerce 2-15, D-8 ‘nounconnected_drive D-10 ‘portcoerce D-8 ‘protect D-8 ‘protected D-8 ‘race D-5 ‘resetall D-3 ‘timescale D-9 ‘unconnected_drive D-10 ‘undef D-5 ‘uselib D-9 ‘vcs_mipdexpand D-7 ‘vcs_mipdnoexpand D-7 A -a filename 4-13, C-13 "A" specifier of abstract access 18-7 +abstract 18-82 abstract access for C/C++ functions access routines for 18-31–18-77 enabling with a compile-time option 18-82 using 18-29–18-77 +acc+level_number 17-22, B-19 ACC capabilities 17-27 cbk 17-13, 17-19 cbka 17-14 f
$assert_monitor 23-64, D-25 $assert_monitor_off 23-64, D-26 $assert_monitor_on 23-64, D-26 assertion classes 21-63 Assertion failure, displaying message 20-75 assertion files 20-4 assertion pragmas 20-60 assertions 20-4 assertions, monitoring 20-70 $assertkill D-11 $assertoff D-11 $asserton D-11 $async$and$array D-36 +auto2protect 25-6, B-54 +auto3protect 25-6, B-54 +autoprotect 25-6, B-54 B -B B-62 behavioral drivers 22-20 benefits of OpenVera Assertions 20-2 bit C/C++ function argument type 18-10 C/C++ f
char** direct access for C/C++ functions formal parameter type 18-20 +charge_decay B-32 check 21-32 check argument to -ntb_opts B-12 check PLI specification 17-9 class methods of 24-63 accessing 24-63 properties of 24-62 accessing 24-63 CLI 9-13 summary 9-14 +cli+level_number B-17 CLI commands, OVAPP 20-31 CLI task invocation 20-76 cli_0, OVAPP CLI command 20-31 +cliecho C-10 +cliedit B-18 clock signals 13-40–13-44 clocking block with virtual interfaces 24-211, 24-212 -cm 23-44, B-23, C-9, C-10 -cm_assert_c
triggering 3-4 verbose messages B-46 compiling, design, design, testbench and Verilog module 21-27 compiling, design, shell, and Verilog module 21-27 concurrent assertions 23-1 consecutive repetition 23-6 context-dependent pragmas 20-60 continue syntax 24-127 control constructs 21-4 control tasks, OVA debug 20-77 $countdrivers D-40 cover OVA directive 20-3 cover statements 23-25–23-28 coverag_group embedded syntax for defining 21-47 syntax for defining 21-47 Coverage 20-42 coverage closed-loop analysis 21-4
$deposit D-40 design, compiling 21-27 DEVICE SDF construct 13-28 direct access for C/C++ functions examples 18-22–18-27 formal parameters types 18-20 rules for parameter types 18-20–18-22 using 18-20–18-81 Direct Access Interface directory 3-7 direction of a C/C++ function argument 18-9 directive, assert 20-3 directive, cover 20-3 directory .
extends directive advice 24-131 introduction 24-131 extern declaration 18-7 extern declarations 18-27 F -f syntax 21-30 -F filename B-38 -f filename 1-15, B-38 facilities, test 20-2 $fatal D-11 $fclose D-29 $fdisplay D-29 $ferror D-29 $fflush D-14, D-29 $fflushall D-14 $fgetc D-29 $fgets D-30 -file B-39 file, report 20-41 Files tokens.v B-55 vcs.
Ignoring Calls and License Checking 6-27, C-17 implications 23-19 implicit .* connections 22-58 implicit .
linking by hand B-51 passing options to the linker B-50 specifying another linker B-50 +lint B-46 Lint, using 3-10–3-12 linter rules, OVA code checking 20-9 linter rules, OVA MR code checking 20-16 +list 18-82 list, CLI command 9-3 -lmc-hm B-61 -lmc-swift 16-16, B-45 -lmc-swift-template 16-4, B-45 -lname B-51 -load 17-33, B-41 loading the testbench 21-28 loads 9-5 local 24-62, 24-63 $log D-27 log file, environment variable specifying the A-4 log files specifying compilation log file 1-15, B-60 specifying wi
+multisource_int_delays 12-6, 13-13, B-33, B-34 -Mupdate B-6 N native code generating specifying B-62 Native Testbench in VCS 9-13 +nbaopt B-33 -nbt_v1 21-32 **NC 11-8 +neg_tchk 14-13, 14-20, B-43 -negdelay B-34, B-36 new() 24-62 user-defined, syntax 24-43 next, CLI command 9-3 no_case 20-60 no_file_by_file_pp 21-10, 21-33 no_file_by_file_pp argument to -ntb_opts B-12 +no_identifier C-12 +no_notifier 14-13, B-42 +no_pulse_msg C-14 +no_tchk_msg 14-13, B-43, C-12 +nocelldefinepli+1 B-48 nocelldefinepli PLI s
object data members 9-9 +old_ntc B-43 +oldsdf 13-5, B-36 OpenVera Assertions benefits 20-2 flow 20-7 introduction 20-2 overview 20-4 operating system commands, executing D-27 OpernVera assertion classes 21-63 +optconfigfile 3-35, 3-37, B-16 or operator 23-11 oring sequences 23-11 output C/C++ function argument direction 18-9 output ports valid data types 22-56 OVA cover directive 20-3 OVA debug control tasks 20-77 OVA linter 20-8 OVA post-processing 20-24 OVA post-processor building 20-26 running 20-26 OVA
-override_timescale B-58 P -P pli.
prx ACC capability 17-14 public 24-63 +pulse_e/number 12-8, 12-9, 12-12, 12-17, 12-18, B-40 +pulse_int_e 12-7, 12-8, 12-10, 12-12, B-40 +pulse_int_r 12-7, 12-8, 12-10, 12-12, B-40 +pulse_on_detect 12-18, B-40 +pulse_on_event 12-17, B-40 +pulse_r/number 12-8, 12-9, 12-12, 12-17, 12-18, B-40 pulses filtering out narrow pulses B-40 and flag as error B-40 +putprotect+target_dir 25-10, B-54 -pvalue 3-13, B-56 Q -q B-46, C-14 $q_add D-36 $q_exam D-37 $q_full D-37 $q_initialize D-37 $q_remove D-37 R -R 1-16, B-2
passing a value from before to after a reset D-39 resetting VCS to simulation time 0 D-38 $restart D-41 results 20-41, 20-42 return range of a C/C++ function 18-8 return type of a C/C++ function 18-7, 18-9 reverse() example 24-165, 24-166, 24-168, 24-169, 24-170, 24-171, 24-172, 24-173, 24-174, 24-175, 24-176 syntax 24-165, 24-166, 24-167, 24-168, 24-169, 24-170, 24-171, 24-172, 24-173, 24-174, 24-175, 24-176 $rtoi D-28 rules, OVA linter option 20-9, 20-16 running OVA post-processor 20-26 runtime libraries,
simv executable file 1-13 size PLI specification 17-9 $skew D-36 slicing arrays 22-16 SmartQ reverse() 24-165, 24-166 solve-before hard 24-92 Source Pane Toolbar icon 5-5, 5-6 sparse memory models 2-25 specify blocks disabling for an instance 13-39 suppressing 1-15, B-42 in specific module instances 13-40 specifying libraries on the link line B-51 $sreadmemb D-31 $sreadmemh D-31 stack, CLI command 9-9 starting DVE 5-7 static 24-45 step, CLI command 9-3 $stimen D-37 $stop D-32 stream generation production de
setting 5-9 $timeformat D-32 -timescale B-57 ‘timescale D-9 timing check system tasks disabling in specific module instances 13-40 timing check system tasks, disabling 1-16, B-42 timing checks disabling for an instance 13-39 Timopt the timing optimizer 13-40–13-44 +timopt 13-40 TMPDIR A-3 tokens.
vc_FillWithScalar() 18-72 vc_get2stMemoryVector() 18-67 vc_get2stVector() 18-55 vc_get4stMemoryVector() 18-64 vc_get4stVector() 18-54 vc_getInteger() 18-49 vc_getMemoryInteger() 18-62 vc_getMemoryScalar() 18-61 vc_getPointer() 18-47 vc_getReal() 18-45 vc_getScalar() 18-40 vc_handle definition 18-29 using 18-30–18-31 vc_hdrs.
vcdpost utility 7-2 syntax 7-4 VCS predefined text macro D-4 using Native Testbench 9-13 -vcs 21-10 vcs command line 1-13 +vcs+boundscheck 3-20, B-59 +vcs+dumpoff+t+ht C-18 +vcs+dumpon+t+ht C-18 +vcs+finish 4-8, C-13 +vcs+flush+all C-21 +vcs+flush+dump C-21 +vcs+flush+fopen C-21 +vcs+flush+log C-21 +vcs+grwavesoff C-18 +vcs+ignorestop 4-12, C-23 +vcs+initmem B-16 +vcs+initreg B-16 +vcs+learn+pli 1-20, 17-25–17-29, C-22 +vcs+lic+vcsi C-21 +vcs+lic+wait B-49, C-21 +vcs+mipd+noalias C-23 +vcs+mipdexpand B-36 +
syntax 24-88 void* direct access for C/C++ functions formal parameter type 18-20 void** direct access for C/C++ functions formal parameter type 18-20 VPD Command line options Ignore $vcdplus calls in code C-17 VPD files D-18 -vpd2vcd B-31 +vpdfile B-31 +vpdfileswitchsize B-31 +vpi B-41 VSG if-else usage 24-123 overview 24-118 production definitions 24-119 production weights 24-122 randseq 24-118 usage of case 24-125 usage of repeat 24-126 use of break 24-126 -Vt B-47 wait_var 21-4 +warn 2-34, B-47 $warning