OVI Verilog HDL LRM Version 1.0 Contents Introduction 1 Cover Pages/Copyrights ............................................................................................................ 1 1.0 Overview ............................................................................................................................. 2 1.1 Criteria for Selecting Material for This Manual .................................................................. 3 1.2 The Contents of the Reference Manual................................................................................ 4 Lexical Conventions 6 2.0 Lexical Conventions Overview............................................................................................ 6 2.1 Operators ............................................................................................................................. 6 2.2 White Space and Comments ................................................................................................ 6 2.3 Numbers............................................................................................................................... 7 2.4 Strings.................................................................................................................................. 9 2.4.1 String Variable Declaration ................................................................................ 9 2.4.2 String Manipulation............................................................................................ 9 2.4.3 Special Characters in Strings............................................................................ 10 2.5 Identifiers, Keywords, and System Names ........................................................................ 10 2.5.1 Escaped Identifiers ........................................................................................... 11 2.5.2 Keywords.......................................................................................................... 12 2.5.3 The $keyword Construct .................................................................................. 12 2.5.4 The `keyword Construct ................................................................................... 12 2.6 Text Substitutions .............................................................................................................. 13 Data Types 15 3.0 Data Types Overview ........................................................................................................ 15 3.1 Value Set............................................................................................................................ 15 3.2 Registers and Nets ............................................................................................................. 15 3.2.1 Nets................................................................................................................... 15 3.2.2 Registers ........................................................................................................... 16 3.2.3 Declaration Syntax ........................................................................................... 16 3.2.4 Declaration Examples....................................................................................... 18 3.3 Vectors............................................................................................................................... 18 3.3.1 Specifying Vectors ........................................................................................... 18 3.3.2 Vector Net Accessibility................................................................................... 19 3.4 Strengths ............................................................................................................................ 19 3.4.1 Charge Strength ................................................................................................ 19 3.4.2 Drive Strength .................................................................................................. 20 3.5 Implicit Declarations.......................................................................................................... 20 3.6 Net Initialization ................................................................................................................ 20 3.7 Net Types........................................................................................................................... 20 3.7.1 wire and tri Nets ............................................................................................... 20 3.7.2 Wired Nets........................................................................................................ 21 3.7.3 trireg Net........................................................................................................... 22 3.7.4 tri0 and tri1 Nets............................................................................................... 25 Verilog HDL LRM Contents • i 3.7.5 supply Nets ....................................................................................................... 25 3.8 Memories ........................................................................................................................... 25 3.9 Integers and Times............................................................................................................. 26 3.10 Real Numbers .................................................................................................................. 27 3.10.1 Declaration Syntax for Real Numbers ............................................................ 28 3.10.2 Specifying Real Numbers............................................................................... 28 3.10.3 Operators and Real Numbers.......................................................................... 28 3.10.4 Conversion...................................................................................................... 29 3.11 Parameters........................................................................................................................ 29 Expressions 31 4.0 Expressions Overview ....................................................................................................... 31 4.1 Operators ........................................................................................................................... 31 4.1.1 Binary Operator Precedence............................................................................. 33 4.1.2 Numeric Conventions in Expressions............................................................... 34 4.1.3 Arithmetic Operators ........................................................................................ 34 4.1.4 Arithmetic Expressions with Registers and Integers ........................................ 35 4.1.5 Relational Operators......................................................................................... 36 4.1.6 Equality Operators............................................................................................ 36 4.1.7 Logical Operators ............................................................................................. 37 4.1.8 Bit-Wise Operators........................................................................................... 38 4.1.9 Reduction Operators......................................................................................... 39 4.1.10 Syntax Restrictions......................................................................................... 40 4.1.11 Shift Operators................................................................................................ 41 4.1.12 Conditional Operator ...................................................................................... 41 4.1.13 Concatenations ............................................................................................... 42 4.2 Operands............................................................................................................................ 43 4.2.1 Net and Register Bit Addressing ...................................................................... 43 4.2.2 Memory Addressing ......................................................................................... 44 4.2.3 Strings............................................................................................................... 45 4.2.4 String Operations.............................................................................................. 46 4.2.5 String Value Padding and Potential Problems .................................................. 46 4.2.6 Null String Handling ........................................................................................ 47 4.3 Minimum, Typical, Maximum Delay Expressions ............................................................ 47 4.4 Expression Bit Lengths...................................................................................................... 48 4.4.1 An Example of an Expression Bit Length Problem.......................................... 48 4.4.2 Verilog Rules for Expression Bit Lengths........................................................ 49 Assignments 51 5.0 Assignments Overview ...................................................................................................... 51 5.1 Continuous Assignments ................................................................................................... 51 5.1.1 The Net Declaration Assignment...................................................................... 52 5.1.2 The Continuous Assignment Statement............................................................ 53 5.1.3 Delays............................................................................................................... 54 5.1.4 Strength ............................................................................................................ 55 5.2 Procedural Assignments .................................................................................................... 56 Gate and Switch Level Modeling 57 6.0 Gate and Switch Level Modeling Overview...................................................................... 57 6.1 Gate and Switch Declaration Syntax ................................................................................. 57 6.2 and, nand, nor, or, xor, and xnor Gates.............................................................................. 60 6.3 buf and not Gates ............................................................................................................... 61 6.4 bufif1, bufif0, notif1, and notif0 Gates .............................................................................. 62 6.5 MOS Switches ................................................................................................................... 63 Verilog HDL LRM Contents • ii 6.6 Bidirectional Pass Switches ............................................................................................... 65 6.7 cmos Gates......................................................................................................................... 66 6.8 pullup and pulldown Sources............................................................................................. 66 6.9 Implicit Net Declarations................................................................................................... 67 6.10 Logic Strength Modeling ................................................................................................. 67 6.11 Strengths and Values of Combined Signals ..................................................................... 69 6.11.1 Combined Signals of Unambiguous Strength................................................. 69 6.11.2 Ambiguous Strengths: Sources and Combinations......................................... 70 6.11.3 Ambiguous Strength Signals and Unambiguous Signals................................ 75 6.11.4 Wired Logic Net Types .................................................................................. 78 6.12 Strength Reduction by Non-Resistive Devices ................................................................ 80 6.13 Strength Reduction by Resistive Devices ........................................................................ 80 6.14 Strengths of Net Types .................................................................................................... 80 6.14.1 tri1 Net Strengths............................................................................................ 80 6.14.2 trireg Strength................................................................................................. 80 6.14.3 supply0 and supply1 Net Strengths ................................................................ 81 6.15 Gate and Net Delays ........................................................................................................ 81 6.15.1 min/typ/max Delays........................................................................................ 83 6.15.2 trireg Net Charge Decay ................................................................................. 83 User-Defined Primitives (UDPs) 86 7.0 UDP Overview................................................................................................................... 86 7.1 Syntax ................................................................................................................................ 86 7.2 UDP Definition.................................................................................................................. 88 7.2.1 UDP Terminals................................................................................................. 88 7.2.2 UDP Declarations............................................................................................. 89 7.2.3 Sequential UDP initial Statement ..................................................................... 89 7.2.4 UDP State Table ............................................................................................... 89 7.3 Combinational UDPs ......................................................................................................... 90 7.4 Level-Sensitive Sequential UDPs ...................................................................................... 91 7.5 Edge-Sensitive UDPs......................................................................................................... 92 7.6 Sequential UDP Initialization ............................................................................................ 93 7.7 UDP Instances ................................................................................................................... 95 7.8 Symbols to Enhance Readability ....................................................................................... 96 7.9 Mixing Level and Edge-Sensitive Descriptions................................................................. 97 7.10 Reducing Pessimism ........................................................................................................ 98 7.11 Level-Sensitive Dominance ............................................................................................. 99 7.12 Summary of Symbols..................................................................................................... 100 7.13 Examples ....................................................................................................................... 101 Behavioral Modeling 103 8.1 Behavioral Model Overview............................................................................................ 103 8.2 Procedural Assignments .................................................................................................. 104 8.2.1 Blocking Procedural Assignments.................................................................. 105 8.2.2 The Non-Blocking Procedural Assignment.................................................... 106 8.2.3 How the Simulator Processes Blocking and Non-Blocking Procedural Assignments ............................................................................................................ 110 8.3 Conditional Statement...................................................................................................... 110 8.3.1 if-else-if Construct.......................................................................................... 112 8.3.2 Example.......................................................................................................... 113 8.4 Case Statement................................................................................................................. 114 8.4.1 Case Statement with Don’t-Cares................................................................... 116 8.5 Looping Statements ......................................................................................................... 117 8.5.1 forever Loop ................................................................................................... 118 Verilog HDL LRM Contents • iii 8.5.2 repeat Loop Example...................................................................................... 119 8.5.3 while Loop Example....................................................................................... 119 8.5.4 for Loop Examples ......................................................................................... 120 8.6 Procedural Timing Controls............................................................................................. 121 8.6.1 Delay Control ................................................................................................. 122 8.6.2 Event Control ................................................................................................. 122 8.6.3 Named Events................................................................................................. 123 8.6.4 Event OR Construct........................................................................................ 124 8.6.5 Level-Sensitive Event Control........................................................................ 124 8.6.6 Intra-Assignment Timing Controls................................................................. 125 8.7 Block Statements ............................................................................................................. 128 8.7.1 Sequential Blocks ........................................................................................... 128 8.7.2 Parallel Blocks................................................................................................ 130 8.7.3 Block Names .................................................................................................. 131 8.7.4 Start and Finish Times.................................................................................... 131 8.8 Structured Procedures ...................................................................................................... 133 8.8.1 initial Statement.............................................................................................. 133 8.8.2 always Statement ............................................................................................ 134 8.8.3 Examples ........................................................................................................ 135 Tasks and Functions 138 9.0 Tasks and Functions Overview........................................................................................ 138 9.1 Distinctions between Tasks and Functions ...................................................................... 138 9.2 Tasks and Task Enabling ................................................................................................. 138 9.2.1 Defining a Task .............................................................................................. 139 9.2.2 Task Enabling and Argument Passing............................................................ 140 9.2.3 Task Example ................................................................................................. 141 9.2.4 Effect of Enabling an Already Active Task.................................................... 142 9.3 Functions and Function Calling ....................................................................................... 142 9.3.1 Defining a Function........................................................................................ 143 9.3.2 Returning a Value from a Function ................................................................ 144 9.3.3 Calling a Function .......................................................................................... 144 9.3.4 Function Rules................................................................................................ 144 9.3.5 Function Example........................................................................................... 145 Disabling of Named Blocks and Tasks 146 10.0 Disabling Blocks and Tasks Overview .......................................................................... 146 Procedural Continuous Assignments 151 11.0 Procedural Continuous Assignment Overview .............................................................. 151 11.1 The assign and deassign Procedural Statements ............................................................ 151 11.2 The force and release Procedural Statements................................................................. 152 Hierarchical Structures 154 12.0 Hierarchical Structures Overview.................................................................................. 154 12.1 Modules ......................................................................................................................... 154 12.1.1 Top-Level Modules ...................................................................................... 155 12.1.2 Module Instantiation..................................................................................... 155 12.1.3 Module Definition and Instance Example .................................................... 156 12.2 Overriding Module Parameter Values ........................................................................... 158 12.2.1 defparam Statement ...................................................................................... 158 12.2.2 Module Instance Parameter Value Assignment............................................ 159 12.2.3 Parameter Dependence ................................................................................. 160 Verilog HDL LRM Contents • iv 12.3 Macro Modules.............................................................................................................. 160 12.3.1 Specifying Macro Modules .......................................................................... 161 12.3.2 Instances of Macro Modules......................................................................... 161 12.4 Ports ............................................................................................................................... 161 12.4.1 Port Definition .............................................................................................. 161 12.4.2 Port Declarations .......................................................................................... 162 12.4.3 Connecting Module Ports by Ordered List ................................................... 162 12.4.4 Connecting Module Ports by Name.............................................................. 163 12.4.5 Real Numbers in Port Connections............................................................... 165 12.4.6 Port Collapsing ............................................................................................. 165 12.4.7 Port Connection Rules .................................................................................. 165 12.5 Hierarchical Names........................................................................................................ 167 12.5.1 Upwards Name Referencing......................................................................... 170 12.6 Scope Rules ................................................................................................................... 172 Specify Blocks 174 13.0 Specify Blocks Overview .............................................................................................. 174 13.1 Declaring Parameters in Specify Blocks........................................................................ 175 13.2 Module Path Delays....................................................................................................... 176 13.2.0 Module Path Delay Overview ...................................................................... 176 13.2.1 Describing Module Paths.............................................................................. 179 13.2.2 Declaring Multiple Module Paths in a Single Statement.............................. 182 13.2.3 Assigning Delays to Module Paths............................................................... 183 13.2.4 Specifying Transition Delays on Module Paths ........................................... 184 13.2.5 Handling X Transitions ................................................................................ 186 13.2.6 State Dependent Path Delays (SDPDs) ........................................................ 187 13.2.7 Driving Wired Logic .................................................................................... 192 13.2.8 Module Path Polarity .................................................................................... 193 13.2.9 Qualified Paths ............................................................................................. 195 Formal Syntax Definition 201 A.0 Syntax Overview............................................................................................................. 201 A.1 Source Text ..................................................................................................................... 201 A.2 Declarations .................................................................................................................... 204 A.3 Primitive instances .......................................................................................................... 206 A.4 Module Instantiations...................................................................................................... 207 A.5 Behavioral Statements .................................................................................................... 208 A.6 Specify Section ............................................................................................................... 210 A.7 Expressions ..................................................................................................................... 213 A.8 General............................................................................................................................ 215 System Tasks and Functions 216 B.0 System Tasks Overview.................................................................................................. 216 B.1 The Display and Write Tasks .......................................................................................... 216 B.1.1 Escape Sequences for Special Characters ...................................................... 217 B.1.2 Format Specifications .................................................................................... 218 B.1.3 Size of Displayed Data................................................................................... 219 B.1.4 Unknown and High Impedance Values.......................................................... 220 B.1.5 Strength Format ............................................................................................. 221 B.1.6 Hierarchical Name Format............................................................................. 223 B.1.7 String Format ................................................................................................. 223 B.2 Strobed Monitoring ......................................................................................................... 223 B.3 Continuous Monitoring ................................................................................................... 224 B.4 Timescale System Functions........................................................................................... 225 Verilog HDL LRM Contents • v B.4.1 The $time System Function ........................................................................... 225 B.4.2 The $realtime System Function ..................................................................... 226 B.4.3 The %t Format Specification ......................................................................... 227 B.5 Timescale System Tasks ................................................................................................. 227 B.5.1 The $printtimescale System Task .................................................................. 227 B.5.2 The $timeformat System Task ....................................................................... 228 B.6 Simulation Time—The $time Function .......................................................................... 231 B.7 Finish System Task ......................................................................................................... 231 B.8 Functions and Tasks for Reals ........................................................................................ 231 B.9 Timing Checks ................................................................................................................ 232 B.9.1 The $setup Timing Check.............................................................................. 233 B.9.2 The $hold Timing Check ............................................................................... 234 B.9.3 The $width Timing Check ............................................................................. 234 B.9.4 The $period Timing Check ............................................................................ 236 B.9.5 The $skew Timing Check .............................................................................. 236 B.9.6 The $recovery Timing Check ........................................................................ 237 B.9.7 The $setuphold Timing Check....................................................................... 238 B.9.8 Edge-Control Specifiers................................................................................. 239 B.9.9 Notifiers: User-Defined Responses to Timing Violations ............................. 240 B.9.10 Enabling Timing Checks with Conditioned Events ..................................... 242 Compiler Directives 245 C.0 Compiler Overview......................................................................................................... 245 C.1 `define ............................................................................................................................. 245 C.2 `default_nettype .............................................................................................................. 246 C.3 `unconnected_drive and `nounconnected_drive.............................................................. 247 C.4 `resetall............................................................................................................................ 247 C.5 `timescale ........................................................................................................................ 247 List of System Task and System Function Keywords 250 D.0 System Tasks Overview.................................................................................................. 250 D.1 $bitstoreal ....................................................................................................................... 251 D.2 $countdrivers .................................................................................................................. 251 D.3 $display........................................................................................................................... 253 D.4 Value Change Dump File Tasks ..................................................................................... 253 D.5 File Output ...................................................................................................................... 253 D.6 $finish ............................................................................................................................. 255 D.7 $getpattern ...................................................................................................................... 255 D.8 $history .......................................................................................................................... 257 D.9 $incsave ......................................................................................................................... 257 D.10 $input ........................................................................................................................... 257 D.11 $itor............................................................................................................................... 257 D.12 $key and $nokey .......................................................................................................... 257 D.13 $list ............................................................................................................................... 258 D.14 $log and $nolog ........................................................................................................... 258 D.15 $monitor, $monitoron, $monitoroff .............................................................................. 258 D.16 $printtimescale.............................................................................................................. 258 D.17 $readmemb and $readmemh ......................................................................................... 258 D.18 $realtime ....................................................................................................................... 260 D.19 $realtobits...................................................................................................................... 260 D.20 $reset, $reset_count and $reset_value........................................................................... 260 D.21 $restart .......................................................................................................................... 262 D.22 $rtoi............................................................................................................................... 262 D.23 Saving and Restarting ................................................................................................... 262 Verilog HDL LRM Contents • vi D.23.1 Incremental Save and Restart ...................................................................... 262 D.24 $scale ............................................................................................................................ 263 D.25 $scope ........................................................................................................................... 263 D.26 $showscopes ................................................................................................................. 264 D.27 $showvars ..................................................................................................................... 264 D.28 $sreadmemb and $sreadmemh ...................................................................................... 264 D.29 $stime............................................................................................................................ 265 D.30 $stop.............................................................................................................................. 265 D.31 $strobe........................................................................................................................... 265 D.32 $time, $stime and $realtime .......................................................................................... 265 D.33 $timeformat................................................................................................................... 265 D.34 $write ............................................................................................................................ 265 List of Compiler Directive Keywords 266 E.0 Compilier Directive Overview ........................................................................................ 266 E.1 `accelerate and `noaccelerate........................................................................................... 267 E.2 `autoexpand_vectornets................................................................................................... 267 E.3 `celldefine and `endcelldefine ......................................................................................... 267 E.4 `default_nettype............................................................................................................... 267 E.5 `define ............................................................................................................................. 267 E.6 `expand_vectornets.......................................................................................................... 267 E.7 `ifdef, `else, `endif ........................................................................................................... 267 E.7.1 Nesting the `ifdef, `else, and `endif Compiler Directives .............................. 269 E.7.2 Defining Variable Names to Control Conditional Compilation..................... 270 E.8 `include............................................................................................................................ 270 E.9 `noexpand_vectornets...................................................................................................... 271 E.10 `protect and `endprotect................................................................................................. 271 E.11 `protected and `endprotected ......................................................................................... 271 E.12 `remove_gatenames and `noremove_gatenames ........................................................... 271 E.13 `remove_netnames and `noremove_netnames............................................................... 272 E.14 `resetall.......................................................................................................................... 272 E.15 `timescale ...................................................................................................................... 272 E.16 `unconnected_drive and `nounconnected_drive ............................................................ 272 List of Keywords 273 Keywords............................................................................................................................... 273 Index Verilog HDL LRM 276 Contents • vii Introduction Cover Pages/Copyrights Verilog Hardware Description Language Reference Manual (LRM) Version 1.0 November, 1991 Open Verilog International Notice: This manual has been superceded by the IEEE 1364 specification for the Verilog Hardware Description Language, which can only be purchased from IEEE. Copyright© 1991 by Open Verilog International (OVI), Inc. All rights reserved. Copyright© 1995 for the electronic Help version of the OVI LRM 1.0 by Simucad, Inc. All rights reserved. No part of this work covered by the copyright hereon may be reproduced or used in any form or by any means --- graphic, electronic, or mechanical, including photocopying, recording, taping, or information storage and retrieval systems --- without the prior written approval of Open Verilog International and Simucad, Inc. Additional copies of this manual may be purchased by contacting Open Verilog International at the address shown below. Notices The information contained in this draft manual represents the definition of the Verilog hardware description language as it existed at the time Cadence Design Systems, Inc. transferred the language and its documentation to Open Verilog International (OVI). This manual does not contain any language changes or additions developed or approved by OVI. This information constitutes the basis from which OVI may make refinements and/or additions to the language. Open Verilog International makes no warranties whatsoever with respect to the completeness, accuracy, or applicability of the information in this draft manual to a user’s requirements. Open Verilog International reserves the right to make changes to the Verilog hardware description language and this manual at any time without notice. Open Verilog International does not endorse any particular simulator or other CAE tools that is based on the Verilog hardware description language. Verilog HDL LRM Introduction • 1 Suggestions for improvements to the Verilog hardware description language and/or to this manual will be welcome. They should be sent to the address below. Information about Open Verilog International and membership enrollment can be obtained by inquiring at the address below. Published as: Verilog Hardware Description Language Reference Manual, Release 1.0, November, 1991. Printed in the United States of America. Published by: Open Verilog International Suite 109071 15466 Los Gatos Boulevard Los Gatos, Ca. 95032 408-353-8899 (phone) 408-353-8869 (fax) ovi@netcom.com Electronic Help Version published by: Simucad, Inc. 32970 Alvarado-Niles Road Union City, Ca. 94587 510-487-9700 (phone) 510-487-9721 (fax) silos@simucad.com Verilog® is a registered trademark of Cadence Design Systems, Inc. 1.0 Overview The Verilog Hardware Description Language (HDL) describes a hardware design or part of a design. Descriptions of designs in the Verilog HDL are Verilog models. The Verilog HDL is both a behavioral and structural language. Models in the Verilog HDL can describe both the function of a design and the components and connections to the components in a design. Verilog models can be developed for different levels of abstraction. These levels of abstraction and their corresponding model types are as follows: algorithmic a model that implements a design algorithm in high-level language constructs RTL a model that describes the flow of data between registers and how a design processes that data Verilog HDL LRM Introduction • 2 gate-level a model that describes the logic gates and the connections between logic gates in a design switch-level a model that describes the transistors and storage nodes in a device and the connections between them The basic building block of the Verilog HDL is the module. The module format facilitates topdown and bottom-up design. A module contains a model of a design or part of a design. Modules can incorporate other modules to establish a model hierarchy that describes how parts of a design are incorporated in an entire design. The constructs of the Verilog HDL, such as its declarations and statements, are enclosed in modules. The Verilog HDL behavioral language is structured and procedural, like the C programming language. The behavioral language constructs are for algorithmic and RTL models. The behavioral language provides the following capabilities: • structured procedures for sequential or concurrent execution • explicit control of the time of procedure activation specified by both delay expressions and by value changes called event expressions • explicitly named events to trigger the enabling and disabling of actions in other procedures • procedural constructs for conditional, if-else, case, and looping operations • procedures called tasks that can have parameters and non-zero time duration • procedures called functions that allow the definition of new operators • arithmetic, logical, bit-wise, and reduction operators for expressions The Verilog HDL structural language constructs are for gate-level and switch-level models. The structural language provides the following capabilities: • a complete set of combinational primitives • primitives for bidirectional pass and resistive devices • the ability to model dynamic MOS models with charge sharing and charge decay Verilog structural language models can accurately model signal contention. In the Verilog HDL, structural modeling accuracy is enhanced by primitive delay and output strength specification. Signal values can have different strengths and a full range of ambiguous values to reduce the pessimism of unknown conditions. 1.1 Criteria for Selecting Material for This Manual The following criteria were used to select material for this book: 1. 2. 3. Include all information that is needed to define a design. Include enough information to support existing Verilog libraries. Include the basic syntax for a compiler directive, a system task, and a system function so that readers can implement new tools that process these constructs. Verilog HDL LRM Introduction • 3 4. List and describe, in appendices, a subset of compiler directives and system tasks, functions to support the goals in items 1 and 2. 5. Exclude simulation control and debug commands. To conform to these requirements, the manual describes certain restrictions necessary for compatibility with existing implementations. These implementation-specific details are labeled as such—as in the following example: 1.2 The Contents of the Reference Manual • Chapter 1 – Introduction This chapter discusses the major features of the Verilog HDL. It also discusses the contents of the reference manual. • Chapter 2 – Lexical Conventions This chapter describes how the language interprets and how to specify lexical tokens. A lexical token is one or more characters. Lexical tokens include white space, comments, numbers, character strings, identifiers, keywords, and operators. The chapter also describes the text macro substitution facility. • Chapter 3 – Data Types This chapter describes the Verilog HDL data types. The Verilog HDL has two main groups of data types: registers and nets. Registers and nets model storage devices and physical connections. The chapter also discusses the parameter data type for constant values and describes drive and charge strength of the values on nets. • Chapter 4 – Expressions This chapter describes the operators and operands that can be used in expressions. • Chapter 5 – Assignments This chapter compares the two main types of assignment statements in the Verilog HDL— continuous assignments and procedural assignments. It describes the continuous assignment statement that drives values onto nets. • Chapter 6 – Gate and Switch Level Modeling This chapter describes the gate and switch level primitives and their declarations and specifications. • Chapter 7 – User-Defined Primitives (UDPs) This chapter describes how a primitive can be defined in the Verilog HDL and how these primitives are included in Verilog models. • Chapter 8 – Behavioral Modeling This chapter describes procedural assignments and the behavioral language statements. • Chapter 9 – Tasks and Functions Verilog HDL LRM Introduction • 4 This chapter describes tasks and functions—procedures that can be called from more than one place in a behavioral model. It describes how tasks can be used like subroutines and how functions can be used to define new operators. • Chapter 10 – Disabling of Named Blocks and Tasks This chapter describes how to disable the execution of a task and a block of statements that has a specified name. • Chapter 11 – Procedural Continuous Assignments This chapter describes a type of procedural assignment called a procedural continuous assignment. • Chapter 12 – Hierarchical Structures This chapter describes how model hierarchies are created in the Verilog HDL and how parameter values declared in a module can be overridden. The chapter also discusses macro modules—a construct that saves memory and port collapsing—a technique that improves simulator efficiency. • Chapter 13 – Specify Blocks This chapter describes the Verilog HDL constructs that belong in a construct called a specify block. • Appendix A – Formal Syntax Definition This appendix describes, in the Backus-Naur Format (BNF), the syntax of the Verilog HDL. • Appendix B – System Tasks and Functions This appendix describes the system tasks and functions. • Appendix C – Compiler Directives This appendix describes the compiler directives. • Appendix D – List of System Task and System Function Keywords This appendix lists the predefined system tasks and functions. • Appendix E – List of Compiler Directive Keywords This appendix lists the compiler directives. • Appendix F – List of Keywords This appendix lists the Verilog HDL keywords. Verilog HDL LRM Introduction • 5 Lexical Conventions 2.0 Lexical Conventions Overview Verilog language source text files are a stream of lexical tokens. A token consists of one or more characters. The layout of tokens in a source file is free format—that is, spaces and newlines are not syntactically significant. However, spaces and newlines are very important for giving a visible structure and format to source descriptions. A good style of format, and consistency in that style, are an essential part of program readability. The types of lexical tokens in the language are as follows: • operator • white space • comment • number • string • identifier • keyword The rest of this chapter defines these tokens. This manual uses a syntax formalism based on the Backus-Naur Format (BNF) to define the Verilog language syntax. Appendix A contains the complete set of syntax definitions in this format, plus a description of the BNF conventions used in the syntax definitions. 2.1 Operators Operators are single, double, or triple character sequences and are used in expressions. Chapter 2 discusses the use of operators in expressions. Unary operators appear to the left of their operand. Binary operators appear between their operands. A ternary operator has two operator characters that separate three operands. The Verilog language has one ternary operator—the conditional operator. See "4.1.12 Conditional Operator" for an explanation of the conditional operator. 2.2 White Space and Comments White space can contain the characters for blanks, tabs, newlines, and formfeeds. The Verilog language ignores these characters except when they serve to separate other tokens. However, blanks and tabs are significant in strings. The Verilog language has two forms to introduce comments. A one-line comment starts with the two characters // and ends with a newline. A block comment starts with /* and ends with */. Block comments cannot be nested, but a one-line comment can be nested within a block comment. Verilog HDL LRM Lexical Conventions • 6 2.3 Numbers Constant numbers can be specified in decimal, hexadecimal, octal, or binary format. The Verilog language defines two forms to express numbers. The first form is a simple decimal number specified as a sequence of the digits 0 to 9 which can optionally start with a plus or minus. The second takes the following form: <size><base_format><number> The <size> element contains decimal digits that specify the size of the constant in terms of its exact number of bits. For example, the <size> specification for two hexadecimal digits is 8, because one hexadecimal digit requires four bits. The <size> specification is optional. The <base_format> contains a letter specifying the number’s base, preceded by the single quote character (’). Legal base specifications are one of d, h, o, or b, for the bases decimal, hexadecimal, octal, and binary respectively. (Note that these base identifiers can be upper- or lowercase.) The <number> element contains digits that are legal for the specified <base_format>. The <number> element must physically follow the <base_format>, but can be separated from it by spaces. No spaces can separate the single quote and the base specifier character. Alphabetic letters used to express the <base_format> or the hexadecimal digits a to f can be in upper- or lowercase. Example 2-1 shows unsized constant numbers. 659 // is a decimal number 'h 837FF // is a hexadecimal number 'o7460 // is an octal number 4af // is illegal (hexadecimal format requires 'h) Example 2- 1: Unsized constant numbers Example 2-2 shows sized constant numbers. 4'b1001 // is a 4-bit binary number 5 'D 3 // is a 5-bit decimal number 3'b01x // is a 3-bit number with the least // significant bit unknown 12'hx // is a 12-bit unknown number 16'hz // is a 16-bit high impedance number Example 2- 2: Sized constant numbers In the Verilog language, a plus or minus preceding the size constant is a sign for the constant number—the size constant does not take a sign. A plus or minus between the <base_format> and Verilog HDL LRM Lexical Conventions • 7 the <number> is illegal syntax. In Example 2-3, the first expression is a syntax error. The second expression legally defines an 8-bit number with a value of minus 6. 8 'd -6 // this is illegal syntax -8 'd 6 // this defines the two's complement of 6, // held in 8 bits-equivalent to -(8'd 6) Example 2- 3: A plus or minus between the <base_format> and the <number> is illegal Implementation specific detail: The number of bits that make up an unsized number (which is a simple decimal number or a number without the <size> specification) is host machine word size -for most machines this is 32 bits. In the Verilog language, an x expresses the unknown value in hexadecimal, octal, and binary constants. A z expresses the high impedance value. An x sets four bits to unknown in the hexadecimal base, three bits in the octal base, and one bit in the binary base. Similarly, a z sets four, three, and one bit, respectively, to the high impedance value. If the most significant specified digit of a constant number is an x or a z, then the tool automatically extends the x or z to fill the higher order bits of the constant. This makes it easy to specify complete vectors of the unknown and high impedance values. Example 2-4 illustrates this value extension: reg [11:0] a; initial begin a = 'h x; // yields xxx a = 'h 3x; // yields 03x a = 'h 0x; // yields 00x end Example 2- 4: Automatic extension of x values The question mark (?) character is a Verilog HDL alternative for the z character. It sets four bits to the high impedance value in hexadecimal numbers, three in octal, and one in binary. Use the question mark to enhance readability in cases where the high impedance value is a don’t-care condition. See the discussion of casez and casex in "8.4.1 Case Statement with Don’t-Cares". The underline character is legal anywhere in a number except as the first character. Use this feature to break up long numbers for readability purposes. Example 2-5 illustrates this feature. 27_195_000 16'b0011_0101_0001_1111 32 'h 12ab_f001 Example 2- 5: Use of underline in constant numbers Verilog HDL LRM Lexical Conventions • 8 Please note: A sized negative number is not sign-extended when assigned to a register data type. 2.4 Strings A string is a sequence of characters enclosed by double quotes and must all be contained on a single line. Verilog treats strings used as operands in expressions and assignments as a sequence of eight-bit ASCII values, with one eight-bit ASCII value representing one character. Examples of strings follow: "this is a string""print out a message\n""bell!\007" 2.4.1 String Variable Declaration To declare a variable to store a string, declare a register large enough to hold the maximum number of characters the variable will hold. For example, to store the string “Hello world!” requires a register 8*12, or 96 bits wide, as shown in Example 2-6. reg[8*12:1]stringvar; initial begin stringvar="Hello world!"; end Example 2- 6: Storage needed for strings 2.4.2 String Manipulation Verilog permits strings to be manipulated using the standard Verilog HDL operators. Keep in mind that the value being manipulated by an operator is a sequence of 8-bit ASCII values. The code in Example 2-7 declares a string variable large enough to hold 14 characters and assigns a value to it. The code then manipulates this string value using the concatenation operator. Note that when a variable is larger than required to hold a value being assigned, Verilog pads the contents on the left with zeros after the assignment. This is consistent with the padding that occurs during assignment of non-string values. module string_test; reg [8*14:1] stringvar; initial begin stringvar = "Hello world"; $display("%s is stored as %h", Verilog HDL LRM Lexical Conventions • 9 stringvar,stringvar); stringvar = {stringvar,"!!!"}; $display("%s is stored as %h", stringvar,stringvar); end endmodule Example 2- 7: String manipulation The following strings display as a result of executing Example 2-7: Hello world is stored as 00000048656c6c6f20776f726c64 Hello world!!! is stored as 48656c6c6f20776f726c64212121 2.4.3 Special Characters in Strings Certain characters can only be used in strings when preceded by an introductory character called an escape character. Table 2-1 lists these characters in the right-hand column with the escape sequence that represents the character in the left-hand column. Escape String Character Produced by Escape String \n \t \\ \" \ddd %% new line character tab character \ character " character a character specified in 1-3 octal digits (0 <= d <= 7) % character Table 2- 1: Specifying special characters in strings 2.5 Identifiers, Keywords, and System Names An identifier is used to give an object, such as a register or a module, a name so that it can be referenced from other places in a description. An identifier is any sequence of letters, digits, dollar signs ($), and the underscore (_) symbol. The first character must NOT be a digit or $; it can be a letter or an underscore. Upper- and lowercase letters are considered to be different. Implementation specific detail: Implementation may set a limit on the length of identifiers. Examples of identifiers follow: Verilog HDL LRM Lexical Conventions • 10 shiftreg_a busa_index error_condition merge_ab _bus3 n$657 2.5.1 Escaped Identifiers Escaped identifiers start with the backslash character (\) and provide a means of including any of the printable ASCII characters in an identifier (the decimal values 33 through 126, or 21 through 7E in hexadecimal). An escaped identifier ends with white space (blank, tab, newline). Neither the leading back-slash character nor the terminating white space is considered to be part of the identifier. The primary application of escaped identifiers is for translators from other hardware description languages and CAE systems, where special characters may be allowed in identifiers. Escaped identifiers should not be used under normal circumstances. Examples of escaped identifiers follow: \busa+index \-clock \***error-condition*** \net1/\net2 \{a,b} \a*(b+c) Please note: Verilog HDL LRM Remember to terminate escaped identifiers with white space, otherwise characters that should follow the identifier are considered as part of it. Lexical Conventions • 11 2.5.2 Keywords Keywords are predefined non-escaped identifiers that are used to define the language constructs. A Verilog HDL keyword preceded by an escape character is not interpreted as a keyword. All keywords are defined in lowercase only and therefore must be typed in lowercase in source files. ( Appendix F, Keywords, gives a list of all keywords defined.) 2.5.3 The $keyword Construct The $ character introduces a language construct that enables you to develop user-defined tasks and functions. Tools interpret the name following the $ as a system task or function. The syntax for a system task or function is as follows: <name_of_system_task> <name_of_system_function> ::=$<SYSTEM_IDENTIFIER> ; ||=$<SYSTEM_IDENTIFIER> (<parameter><,<parameter>>*); Syntax 2- 1: Syntax for system tasks and functions Any valid identifier, including keywords already in use in contexts other than this construct—for example, a compiler directive name—can be used as a system task name. Appendix D lists all of the keywords used as names of system tasks and functions. Appendix B describes some of the more useful tasks and functions. The $keyword construct is part of the Verilog Language. The individual system tasks and functions implemented with the $keyword construct are not part of the Verilog language. The following are examples of system task names: $display ("display $finish; a message"); 2.5.4 The `keyword Construct The ` character (the ASCII value 60, called open quote or accent grave) introduces a language construct used by tools to implement compiler directives. The compiler behavior dictated by a compiler directive takes effect as soon as the compiler reads the directive. The directive remains in effect for the rest of the compilation unless a different compiler directive specifies otherwise. A compiler directive in one description file can therefore control compilation behavior in multiple description files. Appendix C describes some compiler directives. Appendix E lists all the keywords used as names of compiler directives. The `keyword construct is part of the Verilog Language. The individual system tasks and functions implemented with the `keyword construct are not part of the Verilog language. An example of a compiler directive follows: Verilog HDL LRM Lexical Conventions • 12 `define wordsize 8 2.6 Text Substitutions A text macro substitution facility has been provided so that meaningful names can be used to represent commonly used pieces of text. For example, in the situation where a constant number is repetitively used throughout a description, a text macro would be useful in that only one place in the source description would need to be altered if the value of the constant needed to be changed. Text macros can also be defined and used in the interactive mode, where they can be helpful for predefining those interactive commands that you use often. The syntax for text macro definitions is as follows: <text_macro_definition> ::= `define <text_macro_name> <MACRO_TEXT> <text_macro_name> ::= <IDENTIFIER> Syntax 2- 2: Syntax for <text_macro_definition> <MACRO_TEXT> is any arbitrary text specified on the same line as the <text_macro_name>. If a one-line comment (that is, a comment specified with the characters //) is included in the text, then the comment does not become part of the text substituted. The text for <MACRO_TEXT> can be blank, in which case the text macro is defined to be empty and no text is substituted when the macro is used. The syntax for using a text macro is as follows: <text_macro_usage> ::=`<text_macro_name> Syntax 2- 3: Syntax for <text_macro_usage> Once a text macro name has been defined (that is, assigned <MACRO_TEXT>), it can be used anywhere in a source description or in an interactive command; that is, there are no scope restrictions. However, to use a text macro the compiler directive symbol ` (open quote, also known as “accent grave”) must precede the text macro name. Example 2-8 shows two definitions of macro text and a use of each of the defined macros. `define wordsize 8 reg [1:`wordsize] data; `define typ_nand nand #5 // define a nand w/typical delay `typ_nand g121 (q21, n10, n11); Example 2- 8: Using macro text Verilog HDL LRM Lexical Conventions • 13 The text specified for <MACRO_TEXT> must not be split across the following lexical tokens: • comments • numbers • strings • identifiers • keywords • double or triple character operators For example, the following is illegal syntax in the Verilog language because it is split across a string: `define first_half "start of string $display(`first_half end of string"); Note that the word define is known as a compiler directive keyword, and is not part of the normal set of keywords. Thus, normal identifiers in a Verilog HDL source description can be the same as compiler directive keywords (though this is not recommended). If you develop compiler directives, be aware of the following pitfall: • If you implement the compiler directive `foo and implement the directive `define, then if you write `define foo, the meaning of `foo is ambiguous. • Text macro names may not be the same as compiler directive keywords. • Text macro names can re-use names being used as ordinary identifiers. For example, signal_name and `signal_name are different. Redefinition of text macros is allowed; the latest definition of a particular text macro read by the compiler prevails when the macro name is encountered in the source text. Verilog HDL LRM Lexical Conventions • 14 Data Types 3.0 Data Types Overview The set of Verilog HDL data types is designed to represent the data storage and transmission elements found in digital hardware. 3.1 Value Set The Verilog HDL value set consists of four basic values: 0 - represents a logic zero, or false condition 1 - represents a logic one, or true condition x - represents an unknown logic value z - represents a high-impedance state The values 0 and 1 are logical complements of one another. When the z value is present at the input of a gate, or when it is encountered in an expression, the effect is usually the same as an x value. Notable exceptions are the MOS primitives, which can pass the z value. Almost all of the data types in the Verilog language store all four basic values. The exceptions are the event type, which has no storage, and the trireg net data type, which retains its first state when all of its drivers go to the high impedance value, and z. All bits of vectors can be independently set to one of the four basic values. The language includes strength information in addition to the basic value information for scalar net variables. This is described in detail in Chapter 6, 6.10 Logic Strength Modeling. 3.2 Registers and Nets There are two main groups of data types: the register data types and the net data types. These two groups differ in the way that they are assigned and hold values. They also represent different hardware structures. 3.2.1 Nets The net data types represent physical connections between structural entities, such as gates. A net does not store a value (except for the trireg net, discussed in Section 3.7.3). Instead, it must be driven by a driver, such as a gate or a continuous assignment. See Chapter 6, "Gate and Switch Level Modeling", and Chapter 5, "Assignments", for definitions of these constructs. If no driver is connected to a net, its value will be high-impedance (z)—unless the net is a trireg, in which case, it holds to the previously driven value. Verilog HDL LRM Data Types • 15 3.2.2 Registers A register is an abstraction of a data storage element. The keyword for the register data type is reg. A register stores a value from one assignment to the next. An assignment statement in a procedure acts as a trigger that changes the value in the data storage element. The Verilog language has powerful constructs that allow you to control when and if these assignment statements are executed. These control constructs are used to describe hardware trigger conditions, such as the rising edge of a clock, and decision-making logic, such as a multiplexer. Chapter 8, 8.1 Behavioral Model Overview, describes these control constructs. The default initialization value for a reg data type is the unknown value, x. CAUTION Registers can be assigned negative values, but, when a register is an operand in an expression, its value is treated as an unsigned (positive) value. For example, a minus one in a four-bit register functions as the number 15 if the register is an expression operand. For more information, see "4.1.2 Numeric Conventions in Expressions". 3.2.3 Declaration Syntax The syntax for net and register declarations is as follows: <net_declaration> ::= <NETTYPE> <expandrange>? <delay>? <list_of_variables> ; ||= trireg <charge_strength>? <expandrange>? <delay>? <list_of_variables> ; ||= <NETTYPE> <drive_strength>? <expandrange>? <delay>? <list_of_assignments> ; <reg_declaration> ::= reg <range>? <list_of_register_variables> ; <list_of_variables> ::= <name_of_variable> <,<name_of_variable>>* <name_of_variable> ::= <IDENTIFIER> <list_of_register_variables> ::= <register_variable> <,<register_variable>>* <register_variable> ::= <name_of_register> <name_of_register> Verilog HDL LRM Data Types • 16 ::= <IDENTIFIER> <expandrange> ::= <range> ||= scalared <range> ||= vectored <range> <range> ::= [ <constant_expression> : <constant_expression>] <list_of_assignments> ::= <assignment> <,<assignment>>* <charge_strength> ::= ( <CAPACITOR_SIZE> ) <drive_strength> ::= ( <STRENGTH0> , <STRENGTH1> ) ||= ( <STRENGTH1> , <STRENGTH0> ) Syntax 3- 1: Syntax for <net_declaration> <NETTYPE> is one of the following keywords: wire tri tri1 supply0 wand triand tri0 supply1 wor trior trireg <IDENTIFIER> is the name of the net that is being declared. See Chapter 2, "Lexical Conventions", for a discussion of identifiers. <delay> specifies the propagation delay of the net (as explained in Chapter 6, 6.15 Gate and Net Delays), or, when associated with a <list_of_assignments>, it specifies the delay executed before the assignment (as explained in Chapter 5, 5.1.3 Delays). <CAPACITOR_SIZE> is one of the following keywords: small medium large <STRENGTH0> is one of the following keywords: supply0 strong0 pull0 weak0 highz0 <STRENGTH1> is one of the following keywords: supply1 Verilog HDL LRM strong1 pull1 weak1 highz1 Data Types • 17 Syntax 3- 2: Definitions for <net_declaration> syntax 3.2.4 Declaration Examples The following are examples of register and net declarations: reg a; // a scalar register wand w; // a scalar net of type 'wand' reg[3:0] v; // a 4-bit vector register made up of // (from most to least significant) // v[3], v[2], v[1] and v[0] tri [15:0] busa; // a tri-state 16-bit bus reg [1:4] b; // a 4-bit vector register trireg (small) storeit; // a charge storage node // of strength small Example 3- 1: Register and net declarations If a set of nets or registers shares the same characteristics, they can be declared in the same declaration statement. For example: wire w1, w2; // declares 2 wires reg [4:0] x, y, z; // declares 3 5-bit registers 3.3 Vectors A net or reg declaration without a <range> specification is one bit wide; that is, it is scalar. Multiple bit net and reg data types are declared by specifying a <range>, and are known as vectors. 3.3.1 Specifying Vectors The <range> specification gives addresses to the individual bits in a multi-bit net or register. The most significant bit (msb) is the left-hand value in the <range> and the least significant bit (lsb) is the right-hand value in the <range>. The range is specified as follows: [ msb_expr : lsb_expr ] Verilog HDL LRM Data Types • 18 Both msb_expr and lsb_expr are non-negative constant expressions. There are no restrictions on the values of the indices. The msb and lsb expressions can be any value, and lsb_expr can be a greater value than msb_expr, if desired. Implementation specific detail: Implementation may set a limit on the length of a vector. Vector nets and registers obey laws of arithmetic modulo 2 to the power n, where n is the number of bits in the vector. Vector nets and registers are treated as unsigned quantities. 3.3.2 Vector Net Accessibility A vector can be used as a single entity or as a group of n scalars, where n is the number of bits in the vector. The keyword vectored allows you to specify that a vector can be modified only as an indivisible entity. The keyword scalared explicitly allows access to bit and parts. This is also the default case. The process of accessing bits within a vector is known as vector expansion. Only when a net is not specified as vectored can bit selects and part selects be driven by outputs of gates, primitives, and modules—or be on the left-hand side of continuous assignments. The following are examples of vector net declarations: tri1 scalared [63:0] bus64; tri vectored [31:0] data; //a bus that will be expanded //a bus that will not be expanded Example 3- 2: Vector net declarations 3.4 Strengths There are two types of strengths that can be specified in a net declaration. They are as follows: • charge strength • drive strength used when placing a continuous assignment on a net in the same statement that declares the net used when declaring a net of type trireg Gate declarations can also specify a drive strength. See Chapter 6, 6.10 Logic Strength Modeling through 6.14 Strengths of Net Types, for more information on gates and for important information on strengths. 3.4.1 Charge Strength The <charge_strength> specification can be used only with trireg nets. A trireg net is used to model charge storage; <charge_strength> specifies the relative size of the capacitance. The <CAPACITOR_SIZE> declaration is one of the following keywords: • small • medium Verilog HDL LRM Data Types • 19 • large When no size is specified in a trireg declaration, its size is medium. The following is a syntax example of a strength declaration: trireg (small) st1 ; A trireg net can model a charge storage node whose charge decays over time. The simulation time of a charge decay is specified in the trireg net’s delay specification (see "6.15.2 trireg Net Charge Decay"). 3.4.2 Drive Strength The <drive_strength> specification allows a continuous assignment to be placed on a net in the same statement that declares that net. See Chapter 5, 5.1.4 Strength, for more details. Net strength properties are described in detail in Chapter 6, 6.10 Logic Strength Modeling through 6.14 Strengths of Net Types. 3.5 Implicit Declarations The syntax shown in Section 3.2.3, Declaration Syntax, is used to explicitly declare variables. In the absence of an explicit declaration of a variable, statements for gate, user-defined primitive, and module instantiations assume an implicit variable declaration. This happens if you do the following: in the terminal list of an instance of a gate, a user-defined primitive, or a module, specify a variable that has not been explicitly declared previously in one of the declaration statements of the instantiating module. These implicitly declared variables are scalar nets of type wire. See Appendix C, C.2 `default_nettype, for a discussion of control of the type for implicitly declared nets with the ‘default_nettype compiler directive. 3.6 Net Initialization The default initialization value for a net is the value z. Nets with drivers assume the output value of their drivers, which defaults to x. The trireg net is an exception to these statements. The trireg defaults to the value x, with the strength specified in the net declaration (small, medium, or large). 3.7 Net Types There are several distinct types of nets. Each is described in the sections that follow. 3.7.1 wire and tri Nets The wire and tri nets connect elements. The net types wire and tri are identical in their syntax and functions; two names are provided so that the name of a net can indicate the purpose of the net in Verilog HDL LRM Data Types • 20 that model. A wire net is typically used for nets that are driven by a single gate or continuous assignment. The tri net type might be used where multiple drivers drive a net. Logical conflicts from multiple sources on a wire or a tri net result in unknown values unless the net is controlled by logic strength. Table 3-1 is a truth table for wire and tri nets. Note that it assumes equal strengths for both drivers. Please refer to Section 6.10 for a discussion of logic strength modeling. wire/ tri 0 1 x z 0 1 x z 0 x x 0 x 1 x 1 x x x x 0 1 x z Table 3- 1: Truth table for wire and tri nets 3.7.2 Wired Nets Wired nets are of type wor, wand, trior, and triand, and are used to model wired logic configurations. Wired nets resolve the conflicts that result when multiple drivers drive the same net. The wor and trior nets create wired or configurations, such that when any of the drivers is 1, the net is 1. The wand and triand nets create wired and configurations, such that if any driver is 0, the net is 0. The net types wor and trior are identical in their syntax and functionality—as are the wand and triand. Table 3-2 gives the truth tables for wired nets. Note that it assumes equal strengths for both drivers. Please refer to Section 6.10 for a discussion of logic strength modeling. wand/ triand 0 1 x z 0 1 x z 0 0 0 0 wor/ trior 0 1 x z 0 1 x z 0 1 x 0 Verilog HDL LRM 0 1 x 1 1 1 1 1 0 x x x x 1 x x 0 1 x z 0 1 x z Data Types • 21 Table 3- 2: Truth tables for wand/triand and wor/trior nets 3.7.3 trireg Net The trireg net stores a value and is used to model charge storage nodes. A trireg can be one of two states: the driven state When at least one driver of a trireg has a value of 1, 0 or x, that value propagates into the trireg and is the trireg’s driven value. the capacitive state When all the drivers of a trireg net are at the high impedance value (z), the trireg net retains its last driven value; the high impedance value does not propagate from the driver to the trireg. The strength of the value on the trireg net in the capacitive state is small, medium, or large, depending on the size specified in the declaration of the trireg. The strength of a trireg in the driven state is supply, strong, pull, or weak depending on the strength of the driver. Figure 3-1 shows a schematic that includes a trireg net whose size is medium, its driver, and the simulation results. Figure 3- 1: Simulation values of a trireg and its driver Simulation of the design in Figure 3-1 reports the following results: 1. At simulation time 0, wire a and wire b have a value of 1. A value of 1 with a strong strength propagates from the AND gate through the NMOS switches connected to each other by wire c, into trireg d. 2. At simulation time 10, wire a changes value to 0, disconnecting wire c from the AND gate. When wire c is no longer connected to the AND gate, its value changes to HiZ. The wire b’s value remains 1 so wire c remains connected to trireg d through the NMOS2 switch. The HiZ value does not propagate from wire c into trireg d. Instead, trireg d enters the capacitive state, storing its last driven value of 1. It stores the 1 with a medium strength. Capacitive networks A capacitive network is a connection between two or more triregs. In a capacitive network whose trireg’s are in the capacitive state, logic and strength values can propagate between triregs. Figure Verilog HDL LRM Data Types • 22 3-2 shows a capacitive network in which the logic value of some triregs change the logic value of other triregs of equal or smaller size. Figure 3- 2: Simulation results of a capacitive network In Figure 3-2, trireg la’s size is large, triregs m1 and m2 are size medium, and trireg s’s size is small. Simulation reports the following sequence of events: 1. At simulation time 0, wire a and wire b have a value of 1. The wire c drives a value of 1 into triregs la and sm, wire d drives a value of 1 into triregs me1 and me2. 2. At simulation time 10, wire b’s value changes to 0, disconnecting trireg sm and me2 from their drivers. These triregs enter the capacitive state and store the value 1, their last driven value. At simulation time 20, wire c drives a value of 0 into trireg la. At simulation time 30, wire d drives a value of 0 into trireg me1. At simulation time 40, wire a’s value changes to 0, disconnecting trireg la and me1 from their drivers. These triregs enter the capacitive state and store the value 0. At simulation time 50, the wire b’s value changes to 1. This change of value in wire b connects trireg sm to trireg la; these triregs have different sizes and stored different values. This connection causes the smaller trireg to store the larger trireg’s value and trireg sm now 3. 4. 5. 6. Verilog HDL LRM Data Types • 23 stores a value of 0.This change of value in wire b also connects trireg me1 to trireg me2; these triregs have the same size and stored different values. The connection causes both trireg me1 and me2 to change value to x. In a capacitive network, charge strengths propagate from a larger trireg to a smaller trireg. Figure 3-3 shows a capacitive network and its simulation results. Figure 3- 3: Simulation results of charge sharing In Figure 3-3, trireg la’s size is large and trireg sm’s size is small. Simulation reports the following results: 1. At simulation time 0, the value of wire a, b, and c is 1 and wire a drives a strong 1 into trireg la and sm. 2. At simulation time 10, wire b’s value changes to 0, disconnecting trireg la and sm from wire a. The triregs la and sm enter the capacitive state. Both triregs share the large charge of trireg la because they remain connected through tranif2. At simulation time 20, wire c’s value changes to 0, disconnecting trireg sm from trireg la. The trireg sm no longer shares trireg la’s large charge and now stores a small charge. At simulation time 30, wire c’s value changes to 1, connecting the two triregs. These triregs now share the same charge. At simulation time 40, wire c’s value changes again to 0, disconnecting trireg sm from trireg la. Once again, trireg sm no longer shares trireg la’s large charge and now stores a small charge. 3. 4. 5. Ideal capacitive state and charge decay A trireg net can retain its value indefinitely or its charge can decay over time. The simulation time of charge decay is specified in the trireg net’s delay specification. Verilog HDL LRM Data Types • 24 3.7.4 tri0 and tri1 Nets The tri0 and tri1 nets model nets with resistive pulldown and resistive pullup devices on them. When no driver drives a tri0 net, its value is 0. When no driver drives a tri1 net, its value is 1. The strength of this value is pull. See Chapter 6, 6.10 Logic Strength Modeling through 6.14 Strengths of Net Types, for a description of strength modeling. 3.7.5 supply Nets The supply0 and supply1 nets model the power supplies in a circuit. The supply0 nets are used to model Vss (ground) and supply1 nets are used to model Vdd or Vcc (power). These nets should never be connected to the output of a gate or continuous assignment, because the strength they possess will override the driver. They have supply0 or supply1 strengths. 3.8 Memories The Verilog HDL models memories as an array of register variables. These arrays can be used to model read-only memories (ROMs), random access memories (RAMs), and register files. Each register in the array is known as an element or word and is addressed by a single array index. There are no multiple dimension arrays in the Verilog Language. Memories are declared in register declaration statements by specifying the element address range after the declared identifier. Syntax 3-3 gives the syntax for a register declaration statement. Note that this syntax extends the <register_variable> definition given in Section 3.2.3, Declaration Syntax. <register_variable> ::= <name_of_register> ||= <name_of_memory> [ <constant_expression> : <constant_expression> ] <constant_expression> ::=<expression> <name_of_memory> ::= <IDENTIFIER> Syntax 3- 3: Syntax for <register_variable> The following example illustrates a memory declaration: reg[7:0] mema[0:255]; This example declares a memory called mema consisting of 256 eight-bit registers. The indices are 0 through 255. The expressions that specify the indices of the array must be constant expressions. Verilog HDL LRM Data Types • 25 Note that within the same declaration statement both registers and memories can be declared. This makes it convenient to declare both a memory and some registers that will hold data to be read from and written to the memory in the same declaration statement, as in Example 3-3. parameter //parameters are run-time constants-see Section 3.11 Parameters wordsize = 16, memsize = 256; // Declare 256 words of 16-bit memory plus two registers reg [wordsize-1:0] // equivalent to [15:0] mem [memsize-1:0], // equivalent to [255:0] writereg, readreg; Example 3- 3: Declaring memory Note that a memory of n 1-bit registers is different from an n-bit vector register, as in the following: An n-bit register can be assigned a value in a single assignment, but a complete memory cannot; thus the following assignment to rega is legal and the succeeding assignment that attempts to clear all of the memory mema is illegal: rega = 0; // legal syntax mema = 0; // illegal syntax To assign a value to a memory element, an index must be specified. For example: mema[1] = 0; // assigns 0 to the first element of mema The index can be an expression. This option allows you to reference different memory elements, depending on the value of other registers and nets in the circuit. For example, a program counter register could be used to index into a RAM. 3.9 Integers and Times In addition to modeling hardware, there are other uses for variables in an HDL model. Although you can use the reg variables for general purposes such as counting the number of times a particular net changes value, the integer and time register data types are provided for convenience and to make the description more self-documenting. The syntax for declaring integer and time variables is as follows: <time_declaration> Verilog HDL LRM Data Types • 26 ::= time <list_of_register_variables> ; <integer_declaration> ::= integer <list_of_register_variables> ; Syntax 3- 4: Syntax for time and integer declarations The <list_of_register_variables> item is defined in Section 3.2.3, Declaration Syntax. A time variable is used for storing and manipulating simulation time quantities in situations where timing checks are required and for diagnostics and debugging purposes. This data type is typically used in conjunction with the $time system function (see Appendix B, B.6 Simulation Time—The $time Function). The size of a time variable is 64 bits. An integer is a general purpose variable used for manipulating quantities that are not regarded as hardware registers. Implementation specific detail: An implemtation may limit the size of the integer variable, and the time variable. Arrays of integer and time variables are allowed. They are declared in the same manner as arrays of reg variables, as in the following example: integer a[1:64]; // an array of 64 integers time change_history[1:1000]; // an array of 1000 times The integer and time variables are assigned values in the same manner as reg variables. Procedural assignments are used to trigger their value changes. Time variables behave the same as 64 bit reg variables. They are unsigned quantities, and unsigned arithmetic is performed on them. In contrast, integer variables are signed quantities. Arithmetic operations performed on integer variables produce 2’s complement results. 3.10 Real Numbers The Verilog HDL supports real number constants and variables in addition to integers and time variables. The syntax for real numbers is the same as the syntax for register types, and is described in Section 3.10.1. Except for the following restrictions, real number variables can be used in the same places that integers and time variables are used. • Not all Verilog HDL operators can be used with real number values. See Table 4-2 in Section 4.1 Operators for lists of valid and invalid operators for real numbers. • Ranges are not allowed on real number variable declarations. • Real number variables default to an initial value of zero. Verilog HDL LRM Data Types • 27 3.10.1 Declaration Syntax for Real Numbers The syntax for declaring real number variables is as follows: <real_declaration> ::=real<list_of_variables>; Syntax 3- 5: Syntax for real number variable declarations The <list_of_variables> item is defined in Section 3.2.3 Declaration Syntax. 3.10.2 Specifying Real Numbers Real numbers can be specified in either decimal notation (for example, 14.72) or in scientific notation (for example, 39e8, which indicates 39 multiplied by 10 to the 8th power). Real numbers expressed with a decimal point must have at least one digit on each side of the decimal point. The following are some examples of valid real numbers in the Verilog language: 1.2 0.1 2394.26331 1.2E12 (the exponent symbol can be e or E) 1.30e-2 0.1e-0 23E10 29E-2 236.123_763_e-12 (underscores are ignored) The following are invalid real numbers in the Verilog HDL because they do not have a digit to the left of the decimal point: .12 .3E3 .2e-7 3.10.3 Operators and Real Numbers The result of using logical or relational operators on real numbers is a single-bit scalar value. Not all Verilog operators can be used with real number expressions. Table 4-2 in Section 4.1 lists the valid operators for use with real numbers. Real number constants and real number variables are also prohibited in the following contexts: • edge descriptors (posedge, negedge) applied to real number variables • bit-select or part-select references of variables declared as real • real number index expressions of bit-select or part-select references of vectors Verilog HDL LRM Data Types • 28 • real number memories (arrays of real numbers) 3.10.4 Conversion The Verilog language converts real numbers to integers by rounding a real number to the nearest integer, rather than by truncating it. For example, the real numbers 35.7 and 35.5 both become 36 when converted to an integer and 35.2 becomes 35. Implicit conversion takes place when you assign a real to an integer. See Appendix B, B.8 Functions and Tasks for Reals, for a discussion of system tasks that perform explicit conversion. 3.11 Parameters Verilog parameters do not belong to either the register or the net group. Parameters are not variables, they are constants. The syntax for parameter declarations is as follows: <parameter_declaration> ::= parameter <list_of_assignments> ; Syntax 3- 6: Syntax for <parameter_declaration> Implementation specific detail: Some implementations accept a range specification on the parameter declaration. The <list_of_assignments> is a comma-separated list of assignments, where the right-hand side of the assignment must be a constant expression, that is, an expression containing only constant numbers and previously defined parameters. Example 3-4 shows examples of parameter declarations: parameter msb = 7; // defines msb as a constant value 7 parameter e = 25, f = 9; // defines two constant numbers parameter r = 5.7; //declares r as a 'real' parameter parameter byte_size = 8, byte_mask = byte_size - 1; parameter average_delay = (r + f) / 2; Example 3- 4: Parameter declarations Even though they represent constants, Verilog parameters can be modified at compilation time to have values that are different from those specified in the declaration assignment. This allows you to customize module instances. You can modify the parameter with the defparam statement, or you can modify the parameter in the module instance statement. Typical uses of parameters are to Verilog HDL LRM Data Types • 29 specify delays and width of variables. See Chapter 12, 12.2 Overriding Module Parameter Values, for complete details on parameter value assignment. Verilog HDL LRM Data Types • 30 Expressions 4.0 Expressions Overview This chapter describes the operators and operands available in the Verilog HDL, and how to use them to form expressions. An expression is a construct that combines operands with operators to produce a result that is a function of the values of the operands and the semantic meaning of the operator. Alternatively, an expression is any legal operand—for example, a net bit-select. Wherever a value is needed in a Verilog HDL statement, an expression can be given. However, several statement constructs limit an expression to a constant expression. A constant expression consists of constant numbers and predefined parameter names only, but can use any of the operators defined in Table 4-1. For their use in expressions, integer and time data types share the same traits as the data type reg. Descriptions pertaining to register usage apply to integers and times as well. An operand can be one of the following: • number (including real) • net • register, integer, time • net bit-select • register bit-select • net part-select • register part-select • memory element • a call to a user-defined function or system defined function that returns any of the above 4.1 Operators The symbols for the Verilog HDL operators are similar to those in the C language. Table 4-1 lists these operators. Verilog Language Operators {} + - * / % > >= < <= ! && || Verilog HDL LRM concatenation arithmetic modulus relational logical negation logical and logical or Expressions • 31 == != === !== ~ & | ^ ^~ or ~^ & ~& | ~| ^ ~^ or ^~ << >> ?: logical equality logical inequality case equality case inequality bit-wise negation bit-wise and bit-wise inclusive or bit-wise exclusive or bit-wise equivalence reduction and reduction nand reduction or reduction nor reduction xor reduction xnor left shift right shift conditional Table 4- 1: Operators for Verilog language Not all of the operators listed above are valid with real expressions. Table 4-2 is a list of the operators that are legal when applied to real numbers. Operators for Real Expressions unary + unary + - * / > >= < <= ! && || == != ?: or unary operators arithmetic relational logical logical equality conditional logical Table 4- 2: Legal operators for use in real expressions The result of using logical or relational operators on real numbers is a single-bit scalar value. Table 4-3 lists operators that are not allowed to operate on real numbers. Disallowed Operators for Real Expressions {} Verilog HDL LRM concatenate Expressions • 32 % === ~ ^ & << !== & ^~ ~& >> | ~^ | modulus case equality bit-wise ~| reduction shift Table 4- 3: Operators not allowed for real expressions See Section 3.10.3 Operators and Real Numbers for more information on use of real numbers. 4.1.1 Binary Operator Precedence The precedence order of binary operators (and the ternary operator ?:) is the same as the precedence order for the matching operators in the C language. Verilog has two equality operators not present in C; they are discussed in Section 4.1.6 Equality Operators. Table 4-4 summarizes the precedence rules for Verilog’s binary and ternary operators. Operator Precedence Rules + - ! ~ (unary) * / % + - (binary) << >> < <= > >= == != === !== & ^ ^~ | && || ?: (ternary operator) highest precedence lowest precedence Table 4- 4: Precedence rules for operators Operators on the same line in Table 4-4 have the same precedence. Rows are in order of decreasing precedence, so, for example, *, /, and % all have the same precedence, which is higher than that of the binary + and - operators. All operators associate left to right with the exception of the ternary operator which associates right to left. Associativity refers to the order in which a language evaluates operators having the same precedence. Thus, in the following example B is added to A and then C is subtracted from the result of A+B. Verilog HDL LRM Expressions • 33 A + B - C When operators differ in precedence, the operators with higher precedence apply first. In the following example, B is divided by C (division has higher precedence than addition) and then the result is added to A. A + B / C Parentheses can be used to change the operator precedence. (A + B) / C // not the same as A + B / C 4.1.2 Numeric Conventions in Expressions Operands can be expressed as based and sized numbers—with the following restriction: The Verilog language interprets a number of the form sss ’f nnn, when used directly in an expression, as the unsigned number represented by the two’s complement of nnn. Example 4-1 shows two ways to write the expression “minus 12 divided by 3.” Note that -12 and -d12 both evaluate to the same bit pattern, but in an expression -d12 loses its identity as a signed, negative number. integer IntA; IntA = -12 / 3; // The result is -4. IntA = -'d 12 / 3; // The result is 1431655761. Example 4- 1: Number format in expressions 4.1.3 Arithmetic Operators The binary arithmetic operators are the following: + - * / % (the modulus operator) Integer division truncates any fractional part. The modulus operator, for example y % z, gives the remainder when the first operand is divided by the second, and thus is zero when z divides y exactly. The result of a modulus operation takes the sign of the first operand. Table 4-5 gives examples of modulus operations. Modulus Expression Verilog HDL LRM Result Comments Expressions • 34 10 % 3 1 10/3 yields a remainder of 1 11 % 3 2 11/3 yields a remainder of 2 12 % 3 0 12/3 yields no remainder -10 % 3 -1 the result takes the sign of the first operand 11 % -3 2 the result takes the sign of the first operand -4'd12 % 3 1 -4'd12 is seen as a large, positive number that leaves a remainder of 1 when divided by 3 Table 4- 5: Examples of modulus operations The unary arithmetic operators take precedence over the binary operators. The unary operators are the following: + - For the arithmetic operators, if any operand bit value is the unknown value x, then the entire result value is x. 4.1.4 Arithmetic Expressions with Registers and Integers An arithmetic operation on a register data type behaves differently than an arithmetic operation on an integer data type. The Verilog language sees a register data type as an unsigned value and an integer type as a signed value. As a result, when you assign a value of the form <size><base_format><number> to a register and then use that register as an expression operand, you are actually using a positive number that is the two’s complement of nnn. In contrast, when you assign a value of the form -<size><base_format><number> to an integer and then use that integer as an expression operand, the expression evaluates using signed arithmetic. Example 4-2 shows various ways to divide minus twelve by three—using integer and register data types in expressions. integer intA; reg [15:0] regA; intA = -4'd12; regA = intA / 3; regA = -4'd12; intA = regA / 3; Verilog HDL LRM // result is -4 because intA is an integer data type // result is 21841 because regA is an register data type Expressions • 35 intA = -4'd12 / 3; // result is 21841 because -4'd12 is effectively a register data type regA = -12 / 3; // result is -4 because -12 is effectively an integer data type Example 4- 2: Modulus operation with registers and integers 4.1.5 Relational Operators Table 4-6 lists and defines the relational operators. Relational Operators a<b a>b a<=b a>=b a a a a less than b greater than b less than or equal to b greater than or equal to b Table 4- 6: The relational operators defined These all yield the scalar value 0 if the specified relation is false, or the value 1 if it is true. If, due to unknown bits in the operands, the relation is ambiguous, then the result is the unknown value (x). All the relational operators have the same precedence. Relational operators have lower precedence than arithmetic operators. The following examples illustrate the implications of this precedence rule: a < a < size size size - 1 (size - 1) - (1 < a) - 1 < a // // // // this this this this construct is the same as construct, but . . . one is not the same as construct Note that when size - (1 < a) evaluates, the relational expression evaluates first and then either zero or one is subtracted from size. When size - 1 < a evaluates, the size operand is reduced by one and then compared with a. 4.1.6 Equality Operators The equality operators rank just lower in precedence than the relational operators. Table 4-7 lists and defines the equality operators. Equality Operators Verilog HDL LRM Expressions • 36 a a a a === !== == != b b b b a equal to b, including x and z a not equal to b, including x and z a equal to b, result may be unknown a not equal to b, result may be unknown Table 4- 7: The equality operators defined All four equality operators have the same precedence. These four operators compare operands bit for bit, with zero filling if the two operands are of unequal bit-length. As with the relational operators, the result is 0 if false, 1 if true. For the == and != operators, if either operand contains an x or a z, then the result is the unknown value (x). For the === and !== operators, the comparison is done just as it is in the procedural case statement. Bits which are x or z are included in the comparison and must match for the result to be true. The result of these operators is always a known value, either 1 or 0. 4.1.7 Logical Operators The operators logical AND (&&) and logical OR (||) are logical connectives. The result of the evaluation of a logical comparison is one (defined as true), zero (defined as false), or, if the result is ambiguous, then the result is the unknown value (x). For example, if register alpha holds the integer value 237 and beta holds the value zero, then the following examples perform as described: regA = alpha && beta; regB = alpha || beta; // regA is set to 0 // regB is set to 1 The precedence of && is greater than that of ||, and both are lower than relational and equality operators. The following expression ANDs three sub-expressions without needing any parentheses: a < size-1 && b != c && index != lastone However, it is recommended for readability purposes that parentheses be used to show very clearly the precedence intended, as in the following rewrite of the above example: (a < size-1) && (b != c) && (index != lastone) A third logical operator is the unary logical negation operator !. The negation operator converts a non-zero or true operand into 0 and a zero or false operand into 1. An ambiguous truth value remains as x. A common use of ! is in constructions like the following: if (!inword) Verilog HDL LRM Expressions • 37 In some cases, the preceding construct makes more sense to someone reading the code than the equivalent construct shown below: if (inword == 0) Constructions like if (!inword) read quite nicely (“if not inword”), but more complicated ones can be hard to understand. Implementation Specific Detail: Evaluation of expressions connected by && or || may stop evaluation as soon as the truth or falsehood of the result is known 4.1.8 Bit-Wise Operators The bit operators perform bit-wise manipulations on the operands— that is, the operator compares a bit in one operand to its equivalent bit in the other operand to calculate one bit for the result. The logic tables in Table 4-8 show the results for each possible calculation. bit-wise unary negation ~ 0 1 x 1 0 x bit-wise binary AND operator & 0 1 x 0 1 x 0 0 0 0 1 x 0 x x bit-wise binary inclusive Or operator | 0 1 x 0 1 x 0 1 x 1 1 1 x 1 x bit-wise binary exclusive Or operator Verilog HDL LRM Expressions • 38 ^ 0 1 x 0 1 x 0 1 x 1 0 x x x x bit-wise binary exclusive NOR operator ^~ 0 1 x 0 1 x 1 0 x 0 1 x x x x Table 4- 8: Bit-wise operators logic tables Care should be taken to distinguish the bit-wise operators & and | from the logical operators && and ||. For example, if x is 1 and y is 2, then x & y is 0, while x && y is 1. When the operands are of unequal bit length, the shorter operand is zero-filled in the most significant bit positions. 4.1.9 Reduction Operators The unary reduction operators perform a bit-wise operation on a single operand to produce a single bit result. The first step of the operation applies the operator between the first bit of the operand and the second—using the logic tables in Table 4-9. The second and subsequent steps apply the operator between the one-bit result of the prior step and the next bit of the operand—still using the same logic table. reduction unary AND operator & 0 1 x 0 1 x 0 0 0 0 1 x 0 x x reduction unary inclusive Or operator | 0 1 x 0 1 x 0 1 x 1 1 1 x 1 x Verilog HDL LRM Expressions • 39 reduction unary exclusive Or operator ^ 0 1 x 0 1 x 0 1 x 1 0 x x x x Table 4- 9: Reduction operators logic tables Note that the reduction unary NAND and reduction unary NOR operators operate the same as the reduction unary AND and OR operators, respectively, but with their outputs negated. The effective results produced by the unary reduction operators are listed in Table 4-10 and Table 4-11. Results of Unary &, |, ~&, and ~| Reduction Operations Operand & | ~& ~| no bits set 0 0 1 1 all bits set 1 1 0 0 some bits set, but not all 0 1 1 0 Table 4- 10: AND, OR, NAND, and NOR unary reduction operations Results of Unary ^ and ~^ Reduction Operators Operand ^ ~^ odd number of bits set even number of bits set (or none) 1 0 0 1 Table 4- 11: Exclusive OR and exclusive NOR unary reduction operations 4.1.10 Syntax Restrictions The Verilog language imposes two syntax restrictions intended to protect description files from a typographical error that is particularly hard to find. The error consists of transposing a space and a Verilog HDL LRM Expressions • 40 symbol. Note that the constructs on line 1 below do not represent the same syntax as the similar constructs on line 2. 1. 2. a a & &b && b a a | |b || b In order to protect users from this type of error, Verilog requires the use of parentheses to separate a reduction or or and operator from a bit-wise or or and operator. Table 4-12 shows the syntax that requires parentheses: Invalid Syntax Equivalent Syntax a & &b a | |b a & (&b) a | (|b) Table 4- 12: Syntax equivalents for syntax restriction 4.1.11 Shift Operators The shift operators, << and >>, perform left and right shifts of their left operand by the number of bit positions given by the right operand. Both shift operators fill the vacated bit positions with zeroes. Example 4-3 illustrates this concept. module shift; reg [3:0] start, result; initial begin start = 1; // Start is set to 0001 result = (start << 2); // Result is set to 0100 end endmodule Example 4- 3: Use of shift operator In this example, the register result is assigned the binary value 0100, which is 0001 shifted to the left two positions and zero filled. 4.1.12 Conditional Operator The conditional operator has three operands separated by two operators in the following format: Verilog HDL LRM Expressions • 41 cond_expr ? true_expr : false_expr If cond_expr evaluates to false, then false_expr is evaluated and used as the result. If the conditional expression is true, then true_expr is evaluated and used as the result. If cond_expr is ambiguous, then both true_expr and false_expr are evaluated and their results are compared, bit by bit, using Table 4-13 to calculate the final result. If the lengths of the operands are different, the shorter operand is lengthened to match the longer and zero filled from the left (the high-order end). ambiguous condition results for conditional operator ?: 0 1 x z 0 1 x z 0 x x x x 1 x x x x x x x x x x Table 4- 13: Conditional operator results The following example of a tri-state output bus illustrates a common use of the conditional operator. wire [15:0] busa = drive_busa ? data : 16’bz; The bus called data is driven onto busa when drive_busa is 1. If drive_busa is unknown, then an unknown value is driven onto busa. Otherwise, busa is not driven. 4.1.13 Concatenations A concatenation is the joining together of bits resulting from two or more expressions. The concatenation is expressed using the brace characters { and }, with commas separating the expressions within. The next example concatenates four expressions: {a, b[3:0], w, 3’b101} The previous example is equivalent to the following example: {a, b[3], b[2], b[1], b[0], w, 1’b1, 1’b0, 1’b1} Unsized constant numbers are not allowed in concatenations. This is because the size of each operand in the concatenation is needed to calculate the complete size of the concatenation. Verilog HDL LRM Expressions • 42 Concatenations can be expressed using a repetition multiplier as shown in the next example. {4{w}} // This is equivalent to {w, w, w, w} The next example illustrates nested concatenations. {b, {3{a, b}}} // This is equivalent to // {b, a, b, a, b, a, b} The repetition multiplier must be a constant expression. 4.2 Operands As stated before, there are several types of operands that can be specified in expressions. The simplest type is a reference to a net or register in its complete form—that is, just the name of the net or register is given. In this case, all of the bits making up the net or register value are used as the operand. If just a single bit of a vector net or register is required, then a bit-select operand is used. A partselect operand is used to reference a group of adjacent bits in a vector net or register. A memory element can be referenced as an operand. A concatenation of other operands, (including nested concatenations) can be specified as an operand. A function call is an operand. 4.2.1 Net and Register Bit Addressing Bit-selects extract a particular bit from a vector net or register. The bit can be addressed using an expression. The next example specifies the single bit of acc that is addressed by the operand index. acc[index] The actual bit that is accessed by an address is, in part, determined by the declaration of acc. For instance, each of the declarations of acc shown in the next example causes a particular value of index to access a different bit: reg [15:0] acc; reg [1:16] acc; If the bit select is out of the address bounds or is x, then the value returned by the reference is x. Verilog HDL LRM Expressions • 43 Several contiguous bits in a vector register or net can be addressed, and are known as part-selects. A part-select of a vector register or net is given with the following syntax: vect[ms_expr:ls_expr] Both expressions must be constant expressions. The first expression must address a more significant bit than the second expression. The next example and the bullet items that follow it illustrate the principles of bit addressing. The code declares an 8-bit register called vect and initializes it to a value of 4. The bullet items describe how the separate bits of that vector can be addressed. reg [7:0] vect = 4; vect; • if the value of addr is 2, then vect[addr] returns 1 • if the value of addr is out of bounds, then vect[addr] returns x • if addr is 0, 1, or 3 through 7, vect[addr] returns 0 • vect[3:0] returns the bits 0100 • vect[5:1] returns the bits 00010 • vect[<expression that returns x>] returns x • vect[<expression that returns z>] returns x • if any bit of addr is x/z, then the value of addr is x 4.2.2 Memory Addressing Section 3.8 discussed the declaration of memories. This section discusses memory addressing. The next example declares a memory of 1024 8-bit words: reg [7:0] mem_name[0:1023]; The syntax for a memory address consists of the name of the memory and an expression for the address—specified with the following format: mem_name[addr_expr] The addr_expr can be any expression; therefore, memory indirections can be specified in a single expression. The next example illustrates memory indirection: Verilog HDL LRM Expressions • 44 mem_name[mem_name[3]] In the above example, mem_name[3]addresses word three of the memory called mem_name. The value at word three is the index into mem_name that is used by the memory address mem_name[mem_name[3]]. As with bit-selects, the address bounds given in the declaration of the memory determine the effect of the address expression. If the index is out of the address bounds or is x, then the value of the reference is x. There is no mechanism to express bit-selects or part-selects of memory elements directly. If this is required, then the memory element has to be first transferred to an appropriately sized temporary register. 4.2.3 Strings String operands are treated as constant numbers consisting of a sequence of 8-bit ASCII codes, one per character. Any Verilog HDL operator can manipulate string operands. The operator behaves as though the entire string were a single numeric value. Example 4-4 declares a string variable large enough to hold 14 characters and assigns a value to it. The example then manipulates the string using the concatenation operator. Note that when a variable is larger than required to hold the value being assigned, the contents after the assignment are padded on the left with zeros. This is consistent with the padding that occurs during assignment of non-string values. module string_test; reg [8*14:1] stringvar; initial begin stringvar = "Hello world"; $display("%s is stored as %h", stringvar, stringvar); stringvar={stringvar, "!!!"}; $display("%s is stored as %h", stringvar, stringvar); end endmodule Example 4- 4: Concatenation of strings The result of running Verilog on the above description is: Hello world is stored as 00000048656c6c6f20776f726c64 Hello world!!! is stored as 48656c6c6f20776f726c64212121 Verilog HDL LRM Expressions • 45 4.2.4 String Operations The common string operations copy, concatenate, and compare are supported by Verilog operators. Copy is provided by simple assignment. Concatenation is provided by the concatenation operator. Comparison is provided by the equality operators. Example 4-4 and Example 4-5 illustrate assignment, concatenation, and comparison of strings. When manipulating string values in vector variables, at least 8*n bits are required in the vector, where n is the number of characters in the string. 4.2.5 String Value Padding and Potential Problems When strings are assigned to variables, the values stored are padded on the left with zeros. Padding can affect the results of comparison and concatenation operations. The comparison and concatenation operators do not distinguish between zeros resulting from padding and the original string characters. Example 4-5 illustrates the potential problem. reg [8*10:1] s1, s2; initial begin s1 = "Hello"; s2 = "world!"; if ( {s1,s2} == "Hello world!") $display("strings are equal"); end Example 4- 5: Comparing string variables The comparison in the example above fails because during the assignment the string variables get padded as illustrated in the next example: s1 s2 = = 000000000048656c6c6f 00000020776f726c6421 The concatenation of s1 and s2 includes the zero padding, resulting in the following value: 000000000048656c6c6f00000020776f726c6421 Since the string “Hello world” contains no zero padding, the comparison fails, as shown below: s1 s2 "Hello world!" 000000000048656c6c6f 00000020776f726c6421 == 48656c6c6f20776f726c6421 "Hello" "world!" Verilog HDL LRM Expressions • 46 The above comparison yields a result of zero, which is equivalent to false. 4.2.6 Null String Handling The null string ("") is equivalent to the value zero (0). 4.3 Minimum, Typical, Maximum Delay Expressions Verilog HDL delay expressions can be specified as three expressions separated by colons. This triple is intended to represent minimum, typical, and maximum values—in that order. The syntax is as follows: <mintypmax_expression> ::= <expression> ||= <expression1> : <expression2> : <expression3> Syntax 4- 1: Syntax for <mintypmax_expression> The three expressions follow these conventions: • expression1 is less than or equal to expression2 • expression2 is less than or equal to expression3 Verilog models typically specify three values for delay expressions. The three values allow a design to be tested with minimum, typical, or maximum delay values. Different tools may interpret the triple form of an expression in a different manner. In the following example, one of the three specified delays will be executed before the simulation executes the assignment; if the user does not select one, the simulator will take the default. always @A X = #(3:4:5) A; Values expressed in min:typ:max format can be used in expressions. The next example shows an expression that defines a single triplet of delay values. The minimum value is the sum of a+d; the typical value is b+e; the maximum value is c+f, as follows: (a:b:c) + (d:e:f) The next example shows some typical expressions that are used to specify min:typ:max format values: val - Verilog HDL LRM (32’d 50: 32’d 75: 32’d 100) Expressions • 47 The min:typ:max format can be used wherever expressions can appear, both in source text files and in interactive commands. See also 6.15.1 min/typ/max Delays 4.4 Expression Bit Lengths Controlling the number of bits that are used in expression evaluations is important if consistent results are to be achieved. Some situations have a simple solution, for example, if a bit-wise AND operation is specified on two 16-bit registers, then the result is a 16-bit value. However, in some situations it is not obvious how many bits are used to evaluate an expression, what size the result should be, or whether signed or unsigned arithmetic should be used. For example, when is it necessary to perform the addition of two 16-bit registers in 17 bits to handle a possible carry overflow? The answer depends on the context in which the addition takes place. If the 16-bit addition is modeling a real 16-bit adder that loses or does not care about the carry overflow, then the model must perform the addition in 16 bits. If the addition of two 16-bit unsigned numbers can result in a significant 17th bit, then assign the answer to a 17-bit register. 4.4.1 An Example of an Expression Bit Length Problem During the evaluation of an expression, interim results take the size of the largest operand (in the case of an assignment, this also includes the left-hand side). You must therefore take care to prevent loss of a significant bit during expression evaluation. This section describes an example of the problems that can occur. The expression (a + b >> 1) yields a 16-bit result, but cannot be assigned to a 16-bit register without the potential loss of the high-order bit. If a and b are 16-bit registers, then the result of (a+b) is 16 bits wide—unless the result is assigned to a register wider than 16 bits. If answer is a 17-bit register, then (answer = a + b) yields a full 17-bit result. But in the expression (a + b >> 1), the sum of (a + b) produces an interim result that is only 16 bits wide. Therefore, the assignment of (a + b >> 1) to a 16-bit register loses the carry bit before the evaluation performs the one-bit right shift. There are two solutions to a problem of this type. One is to assign the sum of (a+b) to a 17-bit register before performing the shift and then shift the 17-bit answer into the 16-bits that your model requires. An easier solution is to use the following trick: The problem: Evaluate the expression (a+b)>>1, assigning the result to a 16-bit register without losing the carry bit. Variables a and b are both 16-bit registers. The solution: Add the integer zero to the expression. The expression evaluates as follows: 1. 0 + (a+b) evaluates—the result is as wide as the widest term, which is the 32-bit zero 2. the 32-bit sum of 0 + (a+b) is shifted right one bit This trick preserves the carry bit until the shift operation can move it back down into 16 bits. Verilog HDL LRM Expressions • 48 4.4.2 Verilog Rules for Expression Bit Lengths In the Verilog language, the rules governing the expression bit lengths have been formulated so that most practical situations have a natural solution. The number of bits of an expression (known as the size of the expression) is determined by the operands involved in the expression and the context in which the expression is given. A self-determined expression is one where the bit length of the expression is solely determined by the expression itself—for example, an expression representing a delay value. A context-determined expression is one where the bit length of the expression is determined by the bit length of the expression and by the fact that it is part of another expression. For example, the bit size of the right-hand side expression of an assignment depends on itself and the size of the lefthand side. Table 4-14 shows how the form of an expression determines the bit lengths of the results of the expression. In Table 4-14, i, j, and k represent expressions of an operand, and L(i) represents the bit length of the operand represented by i. Expression Bit length unsized constant number same as integer (usually32) sized constant number as given i op j where op is: +-*/% & | ^ ^~ max (L(i), L(j)) +i and -i L(i) ~i L(i) I op j where op is === !== == != && || > >= < <= 1 bit all operands are self-determined op i where op is & ~& | ~| ^ ~^ 1 bit all operands are self-determined I >> j L(i) j is self-determined Verilog HDL LRM Comments Expressions • 49 I << j I ? j : k max(L(j),L(k)) I is self-determined {i,..,j} L(i)+..+L(j) self-determined all operands are { i { j, .. , k } } i*(L(j)+..+L(k)) all operands are self-determined Table 4- 14: Bit lengths resulting from expressions Verilog HDL LRM Expressions • 50 Assignments 5.0 Assignments Overview The assignment is the basic mechanism for getting values into nets and registers. There are two basic forms of the assignment: • the continuous assignment, which assigns values to nets • the procedural assignment, which assigns values to registers An assignment consists of two parts, a left-hand side and a right-hand side, separated by the equal (=) character. The right-hand side can be any expression that evaluates to a value. The left-hand side indicates the variable that the right-hand side is to be assigned to. The left-hand side can take one of the following forms, depending on whether the assignment is a continuous assignment or a procedural assignment. Statement type Left-hand side continuous assignment net (vector or scalar) constant bit select of a vector net constant part select of a vector net concatenation of any of the above 3 procedural assignment register (vector or scalar) bit select of a vector register constant part select of a vector register memory element concatenation of any of the above 4 Table 5- 1: Legal left-hand side forms in assignment statements 5.1 Continuous Assignments Continuous assignments drive values onto nets, both vector and scalar. The significance of the word “continuous” is that the assignment occurs whenever simulation causes the value of the righthand side to change. Continuous assignments provide a way to model combinational logic without specifying an interconnection of gates. Instead, the model specifies the logical expression that drives the net. The expression on the right-hand side of the continuous assignment is not restricted in any way. It can even contain a reference to a function. Thus, the result of a case statement, if statement, or other procedural construct can drive a net. The syntax for continuous assignments is as follows: <net_declaration> Verilog HDL LRM Assignments • 51 ::= <NETTYPE> <expandrange>? <delay>? <list_of_variables> ; ||= trireg <charge_strength>? <expandrange>? <delay>? <list_of_variables> ; ||= <NETTYPE> <drive_strength>? <expandrange>? <delay>? <list_of_assignments> ; <continuous_assign> ::= assign <drive_strength>? <delay>? <list_of_assignments> ; <expandrange> ::= <range> ||= scalared <range> ||= vectored <range> <range> ::= [ <constant_expression> : <constant_expression> ] <list_of_assignments> ::= <assignment> <,<assignment>>* <charge_strength> ::= ( small ) ||= ( medium ) ||= ( large ) <drive_strength> ::= ( <STRENGTH0> , <STRENGTH1> ) ||= ( <STRENGTH1> , <STRENGTH0> ) Syntax 5- 1: Syntax for <net_declaration> 5.1.1 The Net Declaration Assignment The first two alternatives in the <net_declaration> are discussed in Chapter 3, Data Types (see Section 3.2.3 Declaration Syntax). The third alternative, the net declaration assignment, allows a continuous assignment to be placed on a net in the same statement that declares that net. The following is an example of the <net_declaration> form of a continuous assignment: wire (strong1, pull0) mynet = enable ; Please note: Verilog HDL LRM Because a net can be declared only once, only one net declaration assignment can be made for a particular net. This contrasts with the continuous assignment Assignments • 52 statement; one net can receive multiple assignments of the continuous assignment form. 5.1.2 The Continuous Assignment Statement The <continuous_assign> statement places a continuous assignment on a net that has been previously declared, either explicitly by declaration or implicitly by using its name in the terminal list of a gate, user-defined primitive, or module instance. The following is an example of a continuous assignment to a net that has been previously declared: assign (strong1, pull0) mynet = enable ; Assignments on nets are continuous and automatic. This means that whenever an operand in the right-hand side expression changes value during simulation, the whole right-hand side is evaluated and assigned to the left-hand side. The following is an example of the use of a continuous assignment to model a four bit adder with carry. Note that the assignment could not be specified directly in the declaration of the nets because it requires a concatenation on the left-hand side. module adder (sum_out, carry_out, carry_in, ina, inb) ; output [3:0]sum_out; input [3:0]ina, inb; output carry_out; input carry_in; wire carry_out, carry_in; wire[3:0] sum_out, ina, inb; assign {carry_out, sum_out} = ina + inb + carry_in; endmodule Example 5- 1: Use of continuous assign statement The following example describes a module with one 16-bit output bus. It selects between one of four input busses and connects the selected bus to the output bus. module select_bus (busout, bus0, bus1, bus2, bus3, enable, s); parameter n=16; parameter Zee=16'bz; output [1:n ]busout; input[ 1:n] bus0, bus1, bus2, bus3; input enable; Verilog HDL LRM Assignments • 53 input 1:2] s; tri [1:n] data; tri [1:n] busou t= enable ? data : Zee; assign data = data = data = data = endmodule (s==0) (s==1) (s==2) (s==3) ? ? ? ? bus0 bus1 bus2 bus3 : : : : Zee, Zee, Zee, Zee; // net declaration. // net declaration with // continuous assignment. // assignment statement with // 4 continuous assignments. Example 5- 2: Net declaration assignment and continuous assign statement The following sequence of events is experienced during simulation of the description in Example 5-2: 1. The value of s, a bus selector input variable, is checked in the assign statement; based on the value of s, the net data receives the data from one of the four input busses. 2. The setting of data triggers the continuous assignment in the net declaration for busout; if enable is set, the contents of data are assigned to busout; if enable is clear, the contents of Zee are assigned to busout. 5.1.3 Delays A delay given to a continuous assignment specifies the time duration between a right-hand side operand value change and the assignment made to the left-hand side. If the left-hand side references a scalar net, then the delay is treated in the same way as for gate delays—that is, different delays can be given for the output rising, falling and changing to high impedance (see Chapter 6, 6.15 Gate and Net Delays). If the left-hand side references a vector net, then up to three delays can also be applied. The following rules determine which delay controls the assignment: • If the right-hand side was non-zero and becomes zero, then the falling delay is used. • If the right-hand side becomes z, then the turn-off delay is used. • For other cases, the rising delay is used. Note that specifying the delay in a continuous assignment that is part of the net declaration is different from specifying a net delay and then making a continuous assignment to the net. A delay value can be applied to a net in a net declaration, as in the following example: wire #10 wireA; Verilog HDL LRM Assignments • 54 This syntax, called a net delay, means that any value change that is to be applied to wireA by some other statement is delayed for ten time units before it takes effect. When there is a continuous assignment in a declaration, the delay is part of the continuous assignment and is not a net delay. Thus, it is not added to the delay of other drivers on the net. Furthermore, if the assignment is to an expanded vector net (a net not specified with the keyword vectored), then the rising and falling delays are not applied to the individual bits if the assignment is included in the declaration. In situations where a right-hand side operand changes before a previous change has had time to propagate to the left-hand side, then the latest value change is the only one to be applied. That is, only one assignment occurs. This effect is known as inertial delay. The following example implements a vector exclusive OR. The size and delay of the operation are controlled by parameters, which can be changed when instances of this module are created. See Section 12.2 Overriding Module Parameter Values for details on overriding parameter values. module modxor (axorb, a, b); parameter size=8, delay=15; output [size-1:0] axorb; input [size-1:0] a, b; wire [size-1:0] #delay axorb = a ^ b; endmodule Example 5- 3: Use of delays with assignments 5.1.4 Strength The driving strength of a continuous assignment can be specified by the user. This applies only to assignments to scalar nets of the types listed below: wire wand wor tri triand trior trireg tri0 tri1 Continuous assignments driving strengths can be specified in either a net declaration or in a standalone assignment, using the assign keyword. The strength specification, if provided, must immediately follow the keyword (either the keyword for the net type or the assign keyword) and must precede any delay specified. Whenever the continuous assignment drives the net, the strength of the value will simulate as specified. A <drive_strength> specification contains one strength value that applies when the value being assigned to the net is 1 and a second strength value that applies when the assigned value is 0. The follow- ing keywords specify the strength value for an assignment of 1: supply1 strong1 pull1 weak1 highz1 The following keywords specify the strength value for an assignment of 0: Verilog HDL LRM Assignments • 55 supply0 strong0 pull0 weak0 highz0 The order of the two strength specifications is arbitrary. The following two rules constrain the use of drive strength specifications: • The strength specifications (highz1, highz0) and (highz0, highz1) are illegal language constructs. • When the keyword vectored is specified together with a specification of strength on a continuous assignment, the keyword vectored is ignored. 5.2 Procedural Assignments The primary discussion of procedural assignments is in Section 8.2 Procedural Assignments and 11.1 The assign and deassign Procedural Statements. However, a description of the basic ideas here will highlight the differences between continuous assignments and procedural assignments. As stated above, continuous assignments drive nets in a manner similar to the way gates drive nets. The expression on the right-hand side can be thought of as a combinatorial circuit that drives the net continuously. In contrast, procedural assignments put values in registers. The assignment does not have duration; instead, the register holds the value of the assignment until the next procedural assignment to that register. Procedural assignments occur within procedures such as always, initial, task and function (these procedures are described in later chapters) and can be thought of as "triggered" assignments. The trigger occurs when the flow of execution in the simulation reaches an assignment within a procedure. Reaching the assignment can be controlled by conditional statements. Event controls, delay controls, if statements, case statements, and looping statements can all be used to control whether assignments get evaluated. Chapter 8, Behavioral Modeling, gives details and examples. Verilog HDL LRM Assignments • 56 Gate and Switch Level Modeling 6.0 Gate and Switch Level Modeling Overview A logic network can be modeled using continuous assignments or switches and logic gates. Modeling with switches and logic gates has these advantages: • Gates provide a much closer one to one mapping between the actual circuit and the network model. • There is no continuous assignment equivalent to the bidirectional transfer gate. A limitation in the use of gates and switches is that gates can only drive scalar output nets; they cannot drive nets declared with the keyword vectored. For your convenience, below is a hypertext list of the gatetype keywords: The <GATETYPE> Keywords and nand nor or xor xnor buf not bufif0 bufif1 notif0 notif1 nmos pmos cmos rnmos rpmos rcmos tran tranif0 tranif1 rtran rtranif0 rtranif1 pullup pulldown 6.1 Gate and Switch Declaration Syntax A gate or switch declaration names a gate or switch type and specifies its output signal strengths and delays. It contains one or more gate instances. Gate instances include an optional instance name and a required terminal connection list. The terminal connection list specifies how the gate or switch connects to other components in the model. All the instances contained in a gate or switch declaration have the same output strengths and delays. Syntax 6-1 presents the gate or switch declaration syntax: <gate_declaration> ::=<GATETYPE><drive_strength>?<delay>?<gate_instance> <,<gate_instance>>* ; <GATETYPE> is one of the following keywords: and nand or nor xor xnor buf bufif0 bufif1 not notif0 notif1 pulldown pullupnmos rnmos pmos rpmos cmos rcmos tran rtran tranif0 rtranif0 tranif1 rtranif1 <drive_strength> ::= ( <STRENGTH0> , <STRENGTH1> ) Verilog HDL LRM Gate and Switch Level Modeling • 57 ||= ( <STRENGTH1> , <STRENGTH0> ) <delay> ::= # <number> ||= # <identifier> ||= # ( <mintypmax_expression> <,<mintypmax_expression>>? <,<mintypmax_expression>>?) <gate_instance> ::= <name_of_gate_instance>? ( <terminal> <,<terminal>>* ) <name_of_gate_instance> ::= <IDENTIFIER> <terminal> ::= <IDENTIFIER> ||= <expression> Syntax 6- 1: Syntax for gate instantiation This section describes the following parts of a gate or switch declaration: • the keyword that names the type of gate or switch primitive • the drive strength specification • the delay specification • the identifier that names each gate or switch instance in gate or switch declarations • the terminal connection list in primitive gate or switch instances The gate type specification A gate declaration begins with the GATETYPE keyword. The keyword specifies the gate or switch primitive that is used by the instances that follow in the declaration. Table 6-1 lists the keywords that can begin a gate or switch declaration. The <GATETYPE> Keywords and nand nor or xor xnor Verilog HDL LRM buf not bufif0 bufif1 notif0 notif1 nmos pmos cmos rnmos rpmos rcmos tran tranif0 tranif1 rtran rtranif0 rtranif1 pullup pulldown Gate and Switch Level Modeling • 58 Table 6- 1: Keywords for the <GATETYPE> syntax item Explanations of the keywords in Table 6-1 begin in Section 6.2 and, nand, nor, or, xor, and xnor Gates. The drive strength specification The drive strength specifications specify the strengths of the values on the output terminals of the instances in the gate declaration. It is possible to specify the strength of the output signals from the gate primitives in Table 6-2. Gate Types That Support Driving Strength and nand or nor buf not xor xnor bufif0 notif0 bufif1 notif1 pullup pulldown Table 6- 2: Gate types that accept strength specifications The drive strength specification in Syntax 6-1 has two parts. A gate declaration must contain both parts or no parts, with the exception of pullup and pulldown sources. One of the parts specifies the strength of signals with a value of 1, and the other specifies the strength of signals with a value of 0. The STRENGTH1 specification, which specifies the strength of an output signal with a value of 1, is one of the following keywords: supply1 strong1 pull1 weak1 highz1 Specifying highz1 causes the gate to output a logic value of Z in place of a 1. The STRENGTH0 specification, which specifies the strength of an output signal with a value of 0, is one of the following: supply0 strong0 pull0 weak0 highz0 Specifying highz0 causes the gate to output a logic value of Z in place of a 0. The strength specifications must follow the gate type keyword and precede any delay specification. The STRENGTH0 specification can precede or follow the STRENGTH1 specification. In the absence of a strength specification, the instances have the default strengths strong1 and strong0. The strength specifications (highz0, highz1) and (highz1, highz0) are invalid: Verilog HDL LRM Gate and Switch Level Modeling • 59 The following example shows a drive strength specification in a declaration of an open collector nor gate: nor(highz1,strong0)(out1,in1,in2); In this example, the nor gate outputs a Z in place of a 1. Sections 6.10 Logic Strength Modeling through 6.12 Strength Reduction by Non-Resistive Devices discuss logic strength modeling in more detail. The delay specification The delay specifies the propagation delay through the gates and switches in a declaration. Gates and switches in declarations with no delay specification have no propagation delay. A delay specification can contain up to three delay values, depending on its gate type. Section 6.2 and, nand, nor, or, xor, and xnor Gates begins discussions of each type of gate that detail the applicable delays. Section 6.15 Gate and Net Delays discusses delays in more detail. pullup and pulldown source declarations do not include delay specifications. The primitive instance identifier The IDENTIFIER in Syntax 6-1 is an optional name given to a gate or switch instance. The name is useful in tracing the operation of the circuit during debugging. Primitive instance connection list The <terminal>s at the end of Syntax 6-1 are the terminal list. The terminal list describes how the gate or switch connects to the rest of the model. The gate or switch type limits these expressions. The output or bidirectional terminals always come first in the terminal list, followed by the input terminals. 6.2 and, nand, nor, or, xor, and xnor Gates Declarations of these gates begin with one of these keywords: and nand nor or xor xnor The delay specification can be zero, one, or two delays. If there is no delay, there is no delay through the gate. One delay specifies the delays for all output transitions. If the specification contains two delays, the first delay determines the rise delay, the second delay determines the fall delay, and the smaller of the two delays applies to transitions to X and Z. These six gates have one output and one or more inputs. The first terminal in the terminal list connects to the gate’s output and all other terminals connect to its inputs. The truth tables for these gates, showing the result of two input values, appear in Table 6-3. Verilog HDL LRM Gate and Switch Level Modeling • 60 Table 6- 3: Logic tables for and, nand, or, nor, xor, and xnor gates Versions of these six gates having more than two inputs behave identically with cascaded 2-input gates in producing logic results, but the number of inputs does not alter propagation delays. The following example declares a two input and gate: and (out,in1,in2); The inputs are in1 and in2. The output is out. 6.3 buf and not Gates Declarations of these gates begin with one of the following keywords: buf not The delay specification can be zero, one, or two delays. If there is no delay, there is no delay through the gate. One delay specifies the delays for all output transitions. If the specification Verilog HDL LRM Gate and Switch Level Modeling • 61 contains two delays, the first delay determines the rise delay, the second delay determines the fall delay, and the smaller of the two delays applies to transitions to X. These two gates have one input and one or more outputs. The last terminal in the terminal list connects to the gate’s input, and the other terminals connect outputs. Truth tables for versions of these gates with one input and one output appear in Table 6-4. Table 6- 4: Logic tables for buf and not gates The following example declares a two output buf: buf (out1,out2,in); The input is in. The outputs are out1 and out2. 6.4 bufif1, bufif0, notif1, and notif0 Gates Declarations of these gates begin with one of the following keywords: bufif0 bufif1 notif1 notif0 A strength specification follows the keyword and a delay specification follows the strength specification. The next item is the optional identifier. A terminal list completes the declaration. These four gates model three-state drivers. In addition to values of 1 and 0, these gates output Z. The delay specification can be zero, one, two, or three delays. If there is no delay, there is no delay through the gate. One delay specifies the delay of all transitions. If the specification contains two delays, the first delay determines the rise delay, the second delay determines the fall delay, and the smaller of the two delays specifies the delay of transitions to X and Z. If the specification contains three delays, the first delay determines the rise delay, the second delay determines the fall delay, the third delay determines the delay of transitions to Z, and the smallest of the three delays applies to transitions to X. Verilog HDL LRM Gate and Switch Level Modeling • 62 Some combinations of data input values and control input values cause these gates to output either of two values, without a preference for either value. These gates’ logic tables include two symbols representing such unknown results. The symbol L represents a result which has a value of 0 or Z. The symbol H represents a result which has a value of 1 or Z. Delays on transitions to H or L are the same as delays on transitions to X. These four gates have one output, one data input, and one control input. The first terminal in the terminal list connects to the output, the second connects to the data input, and the third connects to the control input. Table 6-5 presents these gates’ logic tables: Table 6- 5: Logic tables for bufif0, bufif1, notif0, and notif1 gates The following example declares a bufif1: bufif1 (outw, inw, controlw); The output is outw, the input is inw, and the control is controlw. 6.5 MOS Switches Models of MOS networks consist largely of the following four primitive types: nmos Verilog HDL LRM pmos rnmos rpmos Gate and Switch Level Modeling • 63 The pmos keyword stands for PMOS transistor and the nmos keyword stands for NMOS transistor. PMOS and NMOS transistors have relatively low impedance between their sources and drains when they conduct. The rpmos keyword stands for resistive PMOS transistor and the rnmos keyword stands for resistive NMOS transistor. Resistive PMOS and resistive NMOS transistors have significantly higher impedance between their sources and drains when they conduct than PMOS and NMOS transistors have. The load devices in static MOS networks are examples of rpmos and rnmos gates. These four gate types are unidirectional channels for data similar to the bufif gates. Declarations of these gates begin with one of the following keywords: pmos nmos rpmos rnmos A delay specification follows the keyword. The next item is the optional identifier. A terminal list completes the declaration. The delay specification can be zero, one, two, or three delays. If there is no delay, there is no delay through the switch. A single delay determines the delay of all output transitions. If the specification contains two delays, the first delay determines the rise delay, the second delay determines the fall delay, and the smaller of the two delays specifies the delay of transitions to Z and X. If there are three delays, the first delay specifies the rise delay, the second delay specifies the fall delay, the third delay determines the delay of transitions to Z, and the smallest of the three delays applies to transitions to X. Delays on transitions to H and L are the same as delays on transitions to X. These four switches have one output, one data input, and one control input. The first terminal in the terminal list connects to the output, the second terminal connects to the data input, and the third terminal connects to the control input. The nmos and pmos switches pass signals from their inputs and through their outputs with a change in the signals’ strengths in only one case, discussed in Section 6.12 Strength Reduction by NonResistive Devices. The rnmos and rpmos gates reduce the strength of signals that propagate through them, as discussed in Section 6.13 Strength Reduction by Resistive Devices. Some combinations of data input values and control input values cause these switches to output either of two values, without a preference for either value. These switches’ logic tables include two symbols representing such unknown results. The symbol L represents a result which has a value of 0 or Z. The symbol H represents a result which has a value of 1 or Z. Table 6-6 presents these switches’ logic tables: Verilog HDL LRM Gate and Switch Level Modeling • 64 Table 6- 6: Logic tables for pmos, rpmos, nmos, and rnmos gates The following example declares a pmos switch: pmos (out,data,control); The output is out, the data input is data, and the control input is control. 6.6 Bidirectional Pass Switches Declarations of these devices begin with one of the following keywords: tran rtran tranif1 rtranif1 tranif0 rtranif0 A delay specification follows the keywords in declarations of tranif1, tranif0, rtranif1, and rtranif0; the tran and rtran devices do not take delays. The next item is the optional identifier. A terminal list completes the declaration. The delay specifications for tranif1, tranif0, rtranif1, and rtranif0 devices can be zero, one, or two delays. If there is no delay, the device has no turn-on or turn-off delay. If the specification contains one delay, that delay determines both turn-on and turn-off delays. If there are two delays, the first delay specifies the turn-on delay, and the second delay specifies the turn-off delay. These six devices do not delay signals propagating through them. When these devices are turned off they block signals, and when they are turned on they pass signals. The tranif1, tranif0, rtranif1, and rtranif0 devices have three items in their terminal lists. Two are bidirectional terminals that conduct signals to and from the devices, and the other terminal connects to a control input. The terminals connected to inouts precede the terminal connected to the control input in the terminal list. The tran and rtran devices have terminal lists containing two bidirectional terminals. The bidirectional terminals of all six of these devices connect only to scalar nets or bit selects of expanded vector nets. The tran, tranif0, and rtranif1 devices pass signals with an alteration in their strength in only one case, discussed in Section 6.12 Strength Reduction by Non-Resistive Devices. The rtran, rtranif0, and rtranif1 devices reduce the strength of signals passing through them according to rules discussed in Section 6.13 Strength Reduction by Resistive Devices. The following example declares a tranif1: tranif1 (inout1,inout2,control); Verilog HDL LRM Gate and Switch Level Modeling • 65 The bidirectional terminals are inout1 and inout2. The control input is control. 6.7 cmos Gates Declarations of these gates begins with one of these keywords: cmos rcmos The delay specification can be zero, one, two, or three delays. If there is no delay, there is no delay through the gate. A single delay specifies the delay for all transitions. If the specification contains two delays, the first delay determines the rise delay, the second delay determines the fall delay, and the smaller of the two delays is the delay of transitions to Z and X. If the specification contains three delays, the first delay controls rise delays, the second delay controls fall delays, the third delay controls transitions to Z, and the smallest of the three delays applies to transitions to X. Delays in transitions to H or L are the same as delays in transitions to X. The cmos and rcmos gates have a data input, a data output, and two control inputs. In the terminal list, the first terminal connects to the data output, the second connects to the data input, the third connects to the n-channel control input, and the last connects to the p-channel control input. The cmos gate passes signals with an alteration in their strength in only one case, discussed in subsection 6.12 Strength Reduction by Non-Resistive Devices. The rcmos gate reduces the strength of signals passing through it according to rules that appear in Section 6.13 Strength Reduction by Resistive Devices. The cmos gate is the combination of a pmos gate and an nmos gate. The rcmos gate is the combination of an rpmos gate and an rnmos gate. The combined gates in these configurations share data input and data output terminals, but they have separate control inputs. The equivalence of the cmos gate to the pairing of an nmos gate and a pmos gate is detailed in the following explanation: cmos (w, datain, ncontrol, pcontrol); is equivalent to: nmos (w, datain, ncontrol); pmos (w, datain, pcontrol); 6.8 pullup and pulldown Sources Declarations of these sources begin with one of the following keywords: pullup Verilog HDL LRM pulldown Gate and Switch Level Modeling • 66 A strength specification follows the keyword, and an optional identifier follows the strength specification. A terminal list completes the declaration. A pullup source places a logic value of 1 on the nets listed in its terminal list. A pulldown source places a logic value of 0 on the nets listed in its terminal list. The signals that these sources place on nets have pull strength in the absence of a strength specification. There are no delay specifications for these sources because the signals they place on nets continue throughout simulation without variation. The following example declares two pullup instances: pullup (strong1)(neta),(netb); In this example, one gate instance drives neta and the other drives netb. 6.9 Implicit Net Declarations Including a previously unused identifier in a terminal list implicitly declares a new net of the wire type with zero delay. Each implicitly declared net must connect to one or more of the following: • gate output • tranif bidirectional terminal • module output port Refer to Section C.2 `default_nettype for a discussion of the compiler directive ‘default_nettype. 6.10 Logic Strength Modeling The Verilog HDL provides for accurate modeling of signal contention, bidirectional pass gates, resistive MOS devices, dynamic MOS, charge sharing, and other technology dependent network configurations by allowing scalar net signal values to have a full range of unknown values and different levels of strength or combinations of levels of strength. This multiple level logic strength modeling resolves combinations of signals into known or unknown values to represent the behavior of hardware with maximum accuracy. A strength specification has two components: 1. the strength of the 0 portion of the net value, designated <STRENGTH0> in Syntax 6-1 2. the strength of the 1 portion of the net value, designated <STRENGTH1> in Syntax 6-1 Despite this division of the strength specification, it is helpful to consider strength as a property occupying regions of a continuum in order to predict the results of combinations of signals. Verilog HDL LRM Gate and Switch Level Modeling • 67 Table 6-7 demonstrates the continuum of strengths in the Verilog HDL. The left column lists the keywords used in specifying strengths. The right column gives correlated strength levels: strength name supply0 strong0 pull0 large0 weak medium0 small0 highz0 highz1 small1 medium1 weak1 large1 pull1 strong1 supply1 strength level 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 Table 6- 7: Strength levels for scalar net signal values In the preceding table there are four driving strengths: supply strong pull weak Signals with driving strengths propagate from gate outputs and continuous assignment outputs. In the preceding table there are three charge storage strengths: large medium small Signals with the charge storage strengths originate in the trireg net type. It is possible to think of the strengths of signals in the preceding table as locations on the scale in Figure 6-1. Verilog HDL LRM Gate and Switch Level Modeling • 68 Figure 6- 1: Scale of strengths Discussions of signal combinations later in this document will employ graphics similar to Figure 6-1. If a net signal value is known, its strength levels are all in either the 0 strength part of the scale represented by Figure 6-1, or they are all in its 1 strength part. If a net signal value is unknown, it has strength levels in both the 0 strength and the 1 strength parts. A signal with a value of Z has a strength level only in one of the 0 subdivisions of the parts of the scale. 6.11 Strengths and Values of Combined Signals In addition to a value, a signal has either a single unambiguous strength level or it has an ambiguous strength, consisting of more than one level. When signals combine, their strengths and values determine the strength and value of the resulting signal in accord with the principles in the four subsections that follow. 6.11.1 Combined Signals of Unambiguous Strength This subsection deals with combinations of signals in which each signal has a known value and a single strength level. If two signals of unequal strength combine in a wired net configuration, the stronger signal is the result. This case appears in Figure 6-2. Figure 6- 2: Combining unequal strengths In Figure 6-2, the numbers in parentheses indicate the relative strengths of the signals. The combination of a pull 1 and a strong 0 results in a strong 0, which is the stronger of the two signals. Verilog HDL LRM Gate and Switch Level Modeling • 69 The combination of two signals of like value results in the same value with the greater of the two strengths. The combination of signals identical in strength and value results in the same signal. The combination of signals with unlike values and the same strength has three possible results. Two of the results occur in the presence of wired logic and the third occurs in its absence. Subsection 6.11.4 Wired Logic Net Types discusses wired logic. The result in the absence of wired logic is the subject of the first figure in the next subsection. 6.11.2 Ambiguous Strengths: Sources and Combinations There are several classifications of signals possessing ambiguous strengths: • signals with known values and multiple strength levels • signals with a value of X, which have strength levels consisting of subdivisions of both the strength 1 and the strength 0 parts of the scale of strengths in Figure 6-1 • signals with a value of L, which have strength levels that consist of high impedance joined with strength levels in the 0 strength part of the scale of strengths in Figure 6-1 • signals with a value of H, which have strength levels that consist of high impedance joined with strength levels in the 1 strength part of the scale of strengths in Figure 6-1 Many configurations can produce signals of ambiguous strength. When two signals of equal strength and opposite value combine, the result has a value of X and the strength levels of both signals and all the smaller strength levels. Figure 6-3 shows the combination of a weak signal with a value of 1 and a weak signal with a value of 0 yielding a signal with weak strength and a value of X. Figure 6- 3: Combination of signals of equal strength and opposite values This signal is described in Figure 6-4. Figure 6- 4: Weak X signal strength Verilog HDL LRM Gate and Switch Level Modeling • 70 An ambiguous signal strength can be a range of possible values. An example is the strength of the output from the tristate drivers with unknown control inputs in Figure 6-5. Figure 6- 5: Bufifs with control inputs of X The output of the bufif1 in Figure 6-5 is a strong H, composed of the range of values described in Figure 6-6. Figure 6- 6: Strong H range of values The output of the bufif0 in Figure 6-5 is a weak L, composed of the range of values described in Figure 6-7. Figure 6- 7: Weak L range of values The combination of two signals of ambiguous strength results in a signal of ambiguous strength. The resulting signal has a range of strength levels that includes the strength levels in its component signals. The combination of outputs from two tristate drivers with unknown control inputs, shown in Figure 6-8, is an example. Verilog HDL LRM Gate and Switch Level Modeling • 71 Figure 6- 8: Combined signals of ambiguous strength In Figure 6-8, the combination of signals of ambiguous strengths produces a range which includes the extremes of the signals and all the strengths between them, as described in Figure 6-9. Figure 6- 9: An unknown signal’s range of strengths The result is an X because its range includes the values of 1 and 0. The number 35, which precedes the X, is a concatenation of two digits. The first is the digit 3, which corresponds to the highest strength level for the result’s value of 0. The second digit, 5, corresponds to the highest strength level for the result’s value of 1. Switch networks can produce a ranges of strengths of the same value, such as the signals from the upper and lower configurations in Figure 6-10. Verilog HDL LRM Gate and Switch Level Modeling • 72 Figure 6- 10: Ambiguous strengths from switch networks In Figure 6-10, the upper combination of a register, a gate controlled by a register of unspecified value, and a pullup produces a signal with a value of 1 and a range of strengths (651) described in Figure 6-11. Figure 6- 11: Range of two strengths of a defined value In Figure 6-10 the lower combination of a pulldown, a gate controlled by a register of unspecified value, and an and gate produces a signal with a value of 0 and a range of strengths (530) described in Figure 6-12. Figure 6- 12: Range of three strengths of a defined value When the signals from the upper and lower configurations in Figure 6-10 combine, the result is an unknown with a range (56X) determined by the extremes of the two signals shown in Figure 6-13. Figure 6- 13: Unknown value with a range of strengths In Figure 6-10, replacing the pulldown in the lower configuration with a supply0 would change the range of the result to the range (StX) described in Figure 6-14. Verilog HDL LRM Gate and Switch Level Modeling • 73 Figure 6- 14: Strong X range The range in Figure 6-14 is strong X, because it is unknown and both of its components’ extremes are strong. The extreme of the output of the lower configuration is strong because the lower pmos reduces the strength of the supply0 signal. Section 6.12 discusses this modeling feature. Logic gates produce results with ambiguous strengths as well as tristate drivers. Such a case appears in Figure 6-15. Figure 6- 15: Ambiguous strength from gates In Figure 6-15, register b has an unspecified value, so its input to the upper and gate is strong X. The upper and gate has a strength specification including highz0. The signal from the upper and gate is a strong H composed of the values described in Figure 6-16. Figure 6- 16: Ambiguous strength signal from a gate HiZ0 is part of the result, because the strength specification for the gate in question specified that strength for an output with a value of 0. A strength specification other than high impedance for the 0 value output results in a gate output of X. The output of the lower and gate is a weak 0 described in Figure 6-17. Verilog HDL LRM Gate and Switch Level Modeling • 74 Figure 6- 17: Weak 0 When the signals combine, the result is the range (36X) described in Figure 6-18. Figure 6- 18: Ambiguous strength in combined gate signals This figure presents the combination of an ambiguous signal and an unambiguous signal. Such combinations are the topic of the next subsection of this document. 6.11.3 Ambiguous Strength Signals and Unambiguous Signals The combination of a signal with unambiguous strength and known value with another signal of ambiguous strength presents several possible cases. To understand a set of rules governing this type of combination, it is necessary to consider the strength levels of the ambiguous strength signal separately from each other and relative to the unambiguous strength signal. When a signal of known value and unambiguous strength combines with a component of a signal of ambiguous strength, these are the effects: Rule 1: The strength levels of the ambiguous strength signal that are greater than the strength level of the unambiguous signal remain in the result. Rule 2: The strength levels of the ambiguous strength signal that are smaller than or equal to the strength level of the unambiguous signal disappear from the result, subject to Rule 3. Rule 3: If the operation of Rule 1 and Rule 2 results in a gap in strength levels because the signals are of opposite value, the signals in the gap are part of the result. The following figures show some applications of the rules. Verilog HDL LRM Gate and Switch Level Modeling • 75 Figure 6- 19: Elimination of strength levels In Figure 6-19, the strength levels in the ambiguous strength signal that are smaller than or equal to the strength level of the unambiguous strength signal disappear from the result, demonstrating Rule 2. Figure 6- 20: Result demonstrating a range and the elimination of strength levels of two values Verilog HDL LRM Gate and Switch Level Modeling • 76 In Figure 6-20, Rule 1, Rule 2, and Rule 3 apply. The strength levels of the ambiguous strength signal that are of opposite value and lesser strength than the unambiguous strength signal disappear from the result. The strength levels in the ambiguous strength signal that are less than the strength level of the unambiguous strength signal, and of the same value, disappear from the result. The strength level of the unambiguous strength signal and the greater extreme of the ambiguous strength signal define a range in the result. Figure 6- 21: Result demonstrating a range and the elimination of strength levels of one value In Figure 6-21, Rule 1 and Rule 2 apply. The strength levels in the ambiguous strength signal that are less than the strength level of the unambiguous strength signal disappear from the result. The strength level of the unambiguous strength signal and the strength level at the greater extreme of the ambiguous strength signal define a range in the result. Verilog HDL LRM Gate and Switch Level Modeling • 77 Figure 6- 22: A range of both values In Figure 6-22, Rule 1, Rule 2, and Rule 3 apply. The greater extreme of the range of strengths for the ambiguous strength signal is larger than the strength level of the unambiguous strength signal. The result is a range defined by the greatest strength in the range of the ambiguous strength signal and by the strength level of the unambiguous strength signal. 6.11.4 Wired Logic Net Types The net types triand, wand, trior, and wor resolve conflicts when multiple drivers are at the same level of strength. These net types resolve signal values by treating signals as inputs of logic functions. For example, consider the combination of two signals of unambiguous strength in Figure 6-23. Verilog HDL LRM Gate and Switch Level Modeling • 78 Figure 6- 23: Wired logic with unambiguous strength signals The combination of the signals in Figure 6-23, using wired AND logic, produces a result with the same value as the result produced by an AND gate with the two signals’ values as its inputs. The combination of signals using wired OR logic produces a result with the same value as the result produced by an OR gate with the two signals’ values as its inputs. The strength of the result is the same as the strength of the combined signals in both cases. If the value of the upper signal changes so that both signals in Figure 6-23 possess a value of 1, then the results of both types of logic have a value of 1. When ambiguous strength signals combine in wired logic, it is necessary to consider the results of all combinations of each of the strength levels in the first signal with each of the strength levels in the second signal, as shown in Figure 6-24. Figure 6- 24: Wired logic and ambiguous strengths Verilog HDL LRM Gate and Switch Level Modeling • 79 6.12 Strength Reduction by Non-Resistive Devices The nmos, pmos, and cmos gates pass through the strength from the data input to the output, except that a supply strength is reduced to a strong strength. The tran, tranif0, and tranif1 gates do not affect signal strength across the bidirectional terminals, except that a supply strength is reduced to a strong strength. 6.13 Strength Reduction by Resistive Devices The rnmos, rpmos, rcmos, rtran, rtranif1, and rtranif0 devices reduce the strength of signals that pass through them according to Table 6-8. input strength reduced strength supply drive strong drive pull drive weak drive large capacitor medium capacitor small capacitor high impedance pull drive pull drive weak drive medium capacitor medium capacitor small capacitor small capacitor high impedance Table 6- 8: Strength reduction rules 6.14 Strengths of Net Types The tri0, tri1, supply0, and supply1 net types generate signals with specific strength levels. The trireg declaration can specify either of two signal strength levels other than a default strength level. 6.14.1 tri1 Net Strengths The tri0 net type models a net connected to a resistive pulldown device. Its signal has a value of 0 and a pull strength in the absence of an overriding source. The tri1 net type models a net connected to a resistive pullup device: its signal has a value of 1 and a pull strength in the absence of an overriding source.tri0 and 6.14.2 trireg Strength The trireg net type models charge storage nodes. The strength of the drive resulting from a trireg net that is in the charge storage state (that is, a driver charged the net and then went to high impedance) is one of these three strengths: large, medium, or small. The specific strength associated with a particular trireg net is specified by the user in the net declaration. The default is medium. The syntax of this specification is described in Section 3.4.1 Charge Strength3.4.1. Verilog HDL LRM Gate and Switch Level Modeling • 80 6.14.3 supply0 and supply1 Net Strengths The supply0 net type models ground connections. The supply1 net type models connections to power supplies. The supply0 and supply1 net types have supply driving strengths. 6.15 Gate and Net Delays Gate and net delays provide a means of accurately describing delays through a circuit. The gate delays specify the signal propagation delay from any gate input to the gate output. Up to three values per output can be specified. The descriptions in this chapter of each gate type give the rules for which gates can take how many delays—see Section 6.2 and, nand, nor, or, xor, and xnor Gates through Section 6.7 cmos Gates. Net delays refer to the time it takes from any driver on the net changing value to the time when the net value is updated and propagated further. Up to three delay values per net can be specified. For both gates and nets, the default delay is zero when no delay specification is given. When one delay value is given, then this value is used for all propagation delays associated with the gate or net. The following is an example of a delay specification with one delay: and #(10) (out, in1, in2); The following is an example of a delay specification with two delays: and #(10, 12) (out, in1, in2); When two delays are given, the first specifies the rise delay and the second specifies the fall delay. The delay when the signal changes to high impedance or to unknown is the lesser of the two delay values. The following is an example of a delay specification with three delays: and #(10, 12, 11) (out, in1, in2); For a three delay specification: • the first delay refers to the transition to the 1 value (rise delay) • the second delay refers to the transition to the 0 value (fall delay) • the third delay refers to the transition to the high impedance value When a value changes to the unknown (X) value, the delay is the smallest of the three delays. Table 6-9 summarizes the from-to propagation delay choice for the two and three delay specifications. Verilog HDL LRM Gate and Switch Level Modeling • 81 from value: 0 0 0 1 1 1 x x x z z z to value: 1 x z 0 x z 0 1 z 0 1 x delay used if there are: 2 delays 3 delays d1 min(d1, d2) min(d1, d2) d2 min(d1, d2) min(d1, d2) d2 d1 min(d1, d2) d2 d1 min(d1, d2) d1 min(d1, d2, d3) d3 d2 min(d1, d2, d3) d3 d2 d1 d3 d2 d1 min(d1, d2, d3) Table 6- 9: Rules for propagation delays The following example specifies a simple latch module with tri-state outputs, where individual delays are given to the gates. The propagation delay from the primary inputs to the outputs of the module will be cumulative, and depends on the signal path through the network. module tri_latch (qout, nqout, clock ,data, enable); output qout, nqout; input clock, data, enable; tri qout, nqout; not #5 (ndata, data); nand #(3,5) (wa, data, clock), (wb, ndata, clock); nand #(12,15) (q, nq, wa), (nq, q, wb); bufif1 #(3,7,13) q_drive (qout, q, enable), nq_drive (nqout, nq, enable); endmodule Example 6- 1: Using delay values Verilog HDL LRM Gate and Switch Level Modeling • 82 6.15.1 min/typ/max Delays The syntax for delays on gate primitives (including User-Defined Primitives), nets, and continuous assignments allows three values each for the rising, falling, and turn-off delays. The minimum, typical, and maximum values for each are specified as constant expressions separated by colons. The following example shows min/typ/max values for rising, falling, and turn-off delays: module iobuf(io1, io2, dir); • . • . • . bufif0 #(5:7:9, 8:10:12, 15:18:21) (io1, io2, dir); bufif1 #(6:8:10, 5:7:9, 13:17:19) (io2, io1, dir); • . • . • . endmodule Example 6- 2: Syntax example for delay expressions Tools typically default to one set of delay values (usually the typical set) for the processing of one model. A tool may or may not allow the user to select one set for a processing run. The syntax for delay controls in procedural statements also allows minimum, typical, and maximum values. These are specified by expressions separated by colons. Example 6-3 illustrates this concept. parameter min_hi = 97, typ_hi = 100, max_hi = 107; reg clk; always begin #(95:100:105) clk = 1; #(min_hi:typ_hi:max_hi) clk = 0; end Example 6- 3: Delay controls in procedural statements 6.15.2 trireg Net Charge Decay Like all nets, a trireg declaration’s delay specification can contain up to three delays. The first two delays specify the simulation time that elapses in a transition to the 1 and 0 logic states when the Verilog HDL LRM Gate and Switch Level Modeling • 83 trireg is driven to these states by a driver. The third delay specifies the charge decay time instead of the time that elapses in a transition to the z logic state. The charge decay time specifies the simulation time that elapses between when a trireg’s drivers turn off and when its stored charge can no longer be determined. A trireg needs no turn-off delay specification because a trireg never makes a transition to the z logic state. When a trireg’s drivers make transitions from the 1, 0, or x logic states to off, the trireg retains the previous 1, 0, or x logic state that was on its drivers. The z value does not propagate from a trireg’s drivers to a trireg. A trireg can only hold a z logic state when z is the trireg’s initial logic state or when it is forced to the z state with a force statement. A delay specification for charge decay models a charge storage node that is not ideal, a charge storage node whose charge leaks out through its surrounding devices and connections. This section describes the charge decay process and the delay specification for charge decay. The charge decay process Charge decay is the cause of transition of a 1 or 0 that is stored in a trireg to an unknown value (x) after a specified number of time units. The charge decay time is that specified number of time units. The charge decay process begins when the trireg’s drivers turn off and the trireg starts to hold charge. The charge decay process ends under the following two conditions: 1. The specified number of time units elapse and the trireg makes a transition from 1 or 0 to x. 2. The trireg’s drivers turn on and propagate a 1, 0 or x into the trireg. The delay specification for charge decay time The third delay in a trireg declaration specifies the charge decay time. A three-valued delay specification in a trireg declaration has the following form: #(d1, // d2, three d3) delays //(rising_delay,falling_delay,charge_decay_time) The specification in a trireg declaration of the charge decay time must be preceded by a rise and fall delay specification. The following example shows a specification of the charge decay time in a trireg declaration: trireg (large) #(0,0,50) cap1; This example declares a trireg with the identifier cap1. This trireg stores a large charge. The delay specifications for the rise delay is 0, the fall delay is 0, and the charge decay time specification is 50 time units. Verilog HDL LRM Gate and Switch Level Modeling • 84 Example 6-4 presents a source description file that contains a trireg declaration with a charge decay time specification. Figure 6-25 assists you in reading the source description file. Figure 6- 25: This figure accompanies the example below Example 6- 4: Trireg with a charge decay Verilog HDL LRM Gate and Switch Level Modeling • 85 User-Defined Primitives (UDPs) 7.0 UDP Overview This chapter describes a modeling technique whereby the user can effectively augment the set of predefined gate primitives by designing and specifying new primitive elements called user-defined primitives (UDPs). Instances of these new UDPs can then be used in exactly the same manner as the gate primitives to represent the circuit being modeled. The following two types of behavior can be represented in a user-defined primitive: • combinational—modeled by a combinational UDP • sequential—modeled by a sequential UDP A sequential UDP uses the value of its inputs and the current value of its output to determine the next value of its output. Sequential UDPs provide an easy way to model sequential circuits such as flip-flops and latches. A sequential UDP can model both level-sensitive and edge-sensitive behavior. Implementation Specific Detail: In sources compatible with some existing tools the number of inputs of each user-defined primitive may be limited by the implementation. Each UDP has exactly one output, which can be in one of three states: 0, 1, or x. The tri-state value z is not supported. In sequential UDPs, the output always has the same value as the internal state. Implementation Specific Detail: The maximum number of UDPs that a user can define in a model may be limited by the implementation. 7.1 Syntax The formal syntax of the UDP definition is as follows: <UDP> ::=primitive<name_of_UDP>(<output_terminal_name>, <input_terminal_name> <,<input_terminal_name>>*); <UDP_declaration>+ <UDP_initial_statement>? <table_definition> endprimitive <name_of_UDP> ::=<IDENTIFIER> <UDP_declaration> Verilog HDL LRM User-Defined Primitives (UDPs) • 86 ::=<UDP_output_declaration> ||=<reg_declaration> ||=<UDP_input_declaration> <UDP_output_declaration> ::= output <output_terminal _name>; <reg_declaration> reg <output_terminal_name> ; <UDP_input_declaration> ::= input <input_terminal _name> <,<input_terminal_name>>*); <UDP_initial_statement> ::= initial <output_terminal_name> = <init_val> ; <init_val> ::= 1'b0 ||= 1'b1 ||= 1'bx ||= 1 ||= 0 <table_definition> ::=table <table_entries> endtable <table_entries> ::=<combinational_entry>+ ||=<sequential_entry>+ <combinational_entry> ::=<level_input_list>:<OUTPUT_SYMBOL>; <sequential_entry> ::=<input_list>:<state>:<next_state>; <input_list> ::=<level_input_list> ||=<edge_input_list> <level_input_list> ::=<LEVEL_SYMBOL>+ Verilog HDL LRM User-Defined Primitives (UDPs) • 87 <edge_input_list> ::=<LEVEL_SYMBOL>*<edge><LEVEL_SYMBOL>* <edge> ::=(<LEVEL_SYMBOL><LEVEL_SYMBOL>) ||=<EDGE_SYMBOL> <state> ::=<LEVEL_SYMBOL> <next_state> ::=<OUTPUT_SYMBOL> ||=- (This is a literal hyphen, see Section 7.12 Summary of Symbols for more details) Lexical tokens: <OUTPUT_SYMBOL> is one of the following: 0 1 x X <LEVEL_SYMBOL> is one of the following: 0 1 x X ? b B <EDGE_SYMBOL> is one of the following: r R f F p P n N * Syntax 7- 1: Syntax for user-defined primitivess 7.2 UDP Definition UDP definitions are independent of modules; they are at the same level as module definitions in the syntax hierarchy. They can appear anywhere in the source text, either before or after they are used inside a module. They MAY NOT appear between the keywords module and endmodule. A UDP definition begins with the keyword primitive. This is followed by an identifier, which is the name of the UDP. This in turn is followed by a comma separated list of terminals enclosed in parentheses, which is followed by a semicolon. The UDP definition header described previously is followed by terminal declarations and a state table. The UDP definition is terminated by the keyword endprimitive. 7.2.1 UDP Terminals UDPs have multiple input terminals and exactly one output terminal; they cannot have bidirectional inout terminals. The output terminal MUST be the first terminal in the terminal list. All UDP terminals are scalar. No vector terminals are allowed. Verilog HDL LRM User-Defined Primitives (UDPs) • 88 The output terminal of a sequential UDP requires an additional declaration as type reg. It is illegal to declare a reg for the output terminal of a combinational UDP. 7.2.2 UDP Declarations UDPs must contain input and output terminal declarations. The output terminal declaration begins with the keyword output, followed by one output terminal name. The input terminal declaration begins with the keyword input, followed by one or more input terminal names. Sequential UDPs must contain a reg declaration for the output terminal. Combinational UDPs cannot contain a reg declaration. The initial value of the output terminal reg can be specified in an initial statement in a sequential UDP. 7.2.3 Sequential UDP initial Statement The sequential UDP initial statement specifies the value of the output terminal when simulation begins. This statement begins with the keyword initial. The statement that follows must be an assignment statement that assigns a single bit literal value to the output terminal reg. 7.2.4 UDP State Table The state table which defines the behavior of a UDP begins with the keyword table and is terminated with the keyword endtable. Each row of the table is created using a variety of characters which indicate input and output states. Three states—0, 1, and x—are supported. The z state is explicitly excluded from consideration in user-defined primitives. A number of special characters are defined to represent certain combinations of state possibilities. These are detailed in this chapter, in Section 7.8 Symbols to Enhance Readability. The order of the input state fields of each row of the state table is taken directly from the terminal list in the UDP definition header. It is NOT related to the order of the input declarations. Combinational UDPs have one field per input and one field for the output. The input fields are separated from the output field by a colon. Sequential UDPs have an additional field inserted between the input fields and the output field. This additional field represents the current state of the UDP and is considered equivalent to the current output value. It is delimited by colons. Each row defines the output for a particular combination of input states. If all inputs are specified as x, then the output must be specified as x. All combinations that are not explicitly specified result in a default output state of x. Each row of the table is terminated by a semicolon. Consider the following entry from a UDP state table: 0 1 Verilog HDL LRM : ? : 1 ; User-Defined Primitives (UDPs) • 89 In this entry the ? represents a don’t care condition—it is replaced by cases of the entry when the ? is replaced by 1, 0 and x. This specifies that when the inputs are 0 and 1, no matter what the value of the current state, the output is 1; It is not necessary to explicitly specify every possible input combination. All combinations which are not explicitly specified result in a default output state of x. It is illegal to have the same combination of inputs, including edges, specified for different outputs. 7.3 Combinational UDPs In combinational UDPs, the output state is determined solely as a function of the current input states. Whenever an input changes state, the UDP is evaluated and one of the state table rows is matched. The output state is set to the value indicated by that row. Consider the following example, which defines a multiplexer with two data inputs, and a control input. Remember, there can only be a single output. primitive multiplexer (mux, control, dataA, dataB); output mux; input control, dataA, dataB; table //control dataA dataB mux 0 1 0 : 1; 0 1 1 : 1; 0 1 x : 1; 0 0 0 : 0; 0 0 1 : 0; 0 0 x : 0; 1 0 1 : 1; 1 1 1 : 1; 1 x 1 : 1; 1 0 0 : 0; 1 1 0 : 0; 1 x 0 : 0; x 0 0 : 0; x 1 1 : 1; endtable endprimitive Example 7- 1: Combinational form of user-defined primitive The first entry in the table above can be explained as follows: when control equals 0, and dataA equals 1, and dataB equals 0, then output mux equals 1. Verilog HDL LRM User-Defined Primitives (UDPs) • 90 All combinations of the inputs that are not explicitly specified will drive the output to the unknown value x. For example, in the table for multiplexer above (Example 7-1), the input combination 0xx (control=0, dataA=x, dataB=x) is not specified. If this combination occurs during simulation, the value of output mux will become x. To improve the readability and to ease writing of the table, several special symbols are provided. A ? represents iteration of the table entry over the values 0, 1, and x—a ? generates cases of that entry where the ? is replaced by a 0, 1, or x. It represents a don’t-care condition on that input. Using ?, the description of a multiplexer given in Example 7-1 can be abbreviated as implemented in Example 7-2. primitive multiplexer (mux, control, dataA, dataB); output mux; input control, dataA, dataB; table //control dataA dataB mux 0 1 ? : 1 ; //?=0,1,x 0 0 ? : 0 ; 1 ? 1 : 1 ; 1 ? 0 : 0 ; x 0 0 : 0 ; x 1 1 : 1 ; endtable endprimitive Example 7- 2: Special symbols in user-defined primitive 7.4 Level-Sensitive Sequential UDPs Level-sensitive sequential behavior is represented the same way as combinational behavior, except that the output is declared to be of type reg, and there is an additional field in each table entry. This new field represents the current state of the UDP. The output field in a sequential UDP represents the next state. Consider the example of a latch in Example 7-3. primitive latch (q, clock, output q; reg q; input clock, data; table //clock data q 0 1 : ? 0 0 : ? 1 ? : ? Verilog HDL LRM data); q+ : 1; : 0; : - ; //-=nochange User-Defined Primitives (UDPs) • 91 endtable endprimitive Example 7- 3: UDP for a latch This description differs from a combinational UDP model in two ways. First, the output identifier q has an additional reg declaration to indicate that there is an internal state q. The output value of the UDP is always the same as the internal state. Second, a field for the current state, which is separated by colons from the inputs and the output, has been added. 7.5 Edge-Sensitive UDPs In level-sensitive behavior, the values of the inputs and the current state are sufficient to determine the output value. Edge sensitive behavior differs in that changes in the output are triggered by specific transitions of the inputs. This makes the state table a transition table as illustrated in Example 7-4. primitive d_edge_ff (q, clock, data); output q; reg q; input clock, data; table //obtain output on rising edge of clock // clock data : q : q+ (01) 0 : ? : 0 (01) 1 : ? : 1 (0?) 1 : 1 : 1 (0?) 0 : 0 : 0 //ignore negative edge of clock (?0) ? : ? : //ignore data changes on steady ? (??) : ? : endtable endprimitive ; ; ; ; ; clock ; Example 7- 4: UDP for an edge-sensitive D-type flip-flop Example 7-4 has terms like (01) in the input fields. These terms represent transitions of the input values. Specifically, (01) represents a transition from 0 to 1. The first line in the table of the above UDP definition can be interpreted as follows: when clock changes value from 0 to 1, and data equals 0, the output goes to 0 no matter what the current state. Please note: Verilog HDL LRM Each table entry can have a transition specification on, at most, one input. Entries such as the one shown below are illegal: User-Defined Primitives (UDPs) • 92 (01)(01)0 : 0 : 1 As in the combinational and the level-sensitive entries, a ? implies iteration of the entry over the values 0, 1, and x. A dash (-) in the output column indicates no value change. All unspecified transitions default to the output value x. Thus, in the previous example, transition of clock from 0 to x with data equal to 0 and current state equal to 1 will result in the output q going to x. All transitions that should not affect the output MUST be explicitly specified. Otherwise, they will cause the value of the output to change to x. If the UDP is sensitive to edges of any input, the desired output state must be specified for all edges of all inputs. 7.6 Sequential UDP Initialization The value on the output terminal of a sequential UDP can be specified with an initial statement that contains a procedural assignment statement. The initial statement is optional. Like initial statements in modules, the initial statement in UDPs begin with the keyword initial. The valid contents of initial statements in UDPs and the valid left and right hand sides of their procedural assignment statements differ from initial statements in modules. The difference between these two types of initial statements is described in Table 7-1. Table 7- 1: Initial statements in UDPs and modules Example 7-5 shows a sequential UDP that contains an initial statement that specifies that output terminal q has a value of 1 at the start of the simulation primitive srff (q,s,r); output q; input s,r; reg q; initial q = 1'b1; table Verilog HDL LRM User-Defined Primitives (UDPs) • 93 // s r q q+ 1 0:?:1; f 0:1:-; 0 r:?:0; 0 f:0:-; 1 1:?:0; endtable endprimitive Example 7- 5: Sequential UDP initial statement In Example 7-5, the output q has an initial value of 1 at the start of the simulation; a delay specification in the UDP instance does not delay the simulation time of the assignment of this initial value to the output. When simulation starts, this value is the current state in the state table. The following example and figure show how values are applied in a module that instantiates a sequential UDP with an initial statement. Example 7-6 shows the source description for the module and UDP. This UDP shows an initial statement “initial q = 1'b1;” and UDP instances where “qi” is an output and “q” and “qb” are in the fanout of “qi”. primitive dff1 (q,clk,d); input clk,d; output q; reg q; initial q = 1'b1; table // clk r r f ? d 0 1 ? * : : : : q ? ? ? ? : : : : q+ 0 1 - ; ; ; ; endtable endprimitive module dff (q,qb,clk,d); input clk,d; output q,qb; dff1 g1 (qi, clk, d); buf #3 g2 (q, qi); not #5 g3 (qb, qi); endmodule Verilog HDL LRM User-Defined Primitives (UDPs) • 94 Example 7- 6: Instance of a sequential UDP with an initial statement In Example 7-6, UDP dff1 contains an initial statement that sets the initial value of its output to 1. Module dff contains an instance of UDP dff1. In this instance, the UDP output is qi; the output’s fanout includes nets q and qb. Figure 7-1 shows the schematic of the module in Example 7-6 and the simulation times of the propagation of the initial value of the output of the UDP. Figure 7- 1: Module schematic and the simulation times of initial value propagation In Figure 7-1, the fanout from the UDP output qi includes nets q and qb. At simulation time 0, qi changes value to 1. That initial value of qi does not propagate to net q until simulation time 3, and does not propagate to net qb until simulation time 5. 7.7 UDP Instances Instances of user-defined primitives are specified inside modules in the same manner as for gates. The instance name is optional, just as for gates. The terminal order is as specified in the UDP definition. Only two delays can be specified, because z is not supported for UDPs. Example 7-7 creates an instance of the D-type flip-flop d_edge_ff (defined in Example 7-4). module flip; reg clock, data; parameter p1=10; parameter p2 = 33; Verilog HDL LRM User-Defined Primitives (UDPs) • 95 parameter p3 = 12; d_edge_ff #p3 d_inst(q, clock, data); initial begin data = 1; clock = 1; end always #p1 clock = ~clock; always #p2 data = ~data; endmodule Example 7- 7: UPD for a D-type flip-flop 7.8 Symbols to Enhance Readability Like ?, there are several symbols that can be used in UDP definitions to make the description more readable. The symbols described in Table 7-2 are used in Example 7-8. Symbol Interpretation Explanation b 0 or 1 like ?, except x is excluded r (01) rising edge on an input f (10) falling edge on an input p (01) or (0x) or (x1) or (1z) or (z1) rising edges, including unknown n (10) or (1x) or (x0) or (0z) or (z0) falling edges, including unknown * (??) all transitions Table 7- 2: Symbols for readability Verilog HDL LRM User-Defined Primitives (UDPs) • 96 7.9 Mixing Level and Edge-Sensitive Descriptions UDP definitions allow a mixing of the level-sensitive and the edge-sensitive constructs in the same description. An edge-triggered JK flip-flop with asynchronous preset and clear needs such a mixture. Example 7-8 illustrates this concept. primitive jk_edge_ff (q, clock, j, k, preset, clear); output q; reg q; input clock, j, k, preset, clear; table //clock jk pc state output/next state ? ?? 01 : ? : 1 ; //presetlogic ? ?? *1 : 1 : 1 ; ? ?? 10 : ? : 0 ; //clearlogic ? ?? 1* : 0 : 0 ; r 00 00 : 0 : 1 ; //normalclockingcases r 00 11 : ? : - ; r 01 11 : ? : 0 ; r 10 11 : ? : 1 ; r 11 11 : 0 : 1 ; r 11 11 : 1 : 0 ; f ?? ?? : ? : - ; b *? ?? : ? : - ; //jandktransition cases b ?* ?? : ? : - ; endtable endprimitive Example 7- 8: Sequential UDP for level-sensitive and edge-sensitive behavior In this example, the preset and clear logic is level-sensitive. Whenever the preset and clear combination is 01, the output has value 1. Similarly, whenever the preset and clear combination has value 10, the output has value 0. The remaining logic is sensitive to edges of the clock. In the normal clocking cases, the flip-flop is sensitive to the rising clock edge as indicated by an r in the clock field in those entries. The insensitivity to the falling edge of clock is indicated by a hyphen (-) in the output field (see Section 7.12 Summary of Symbols) for the entry with an f as the value of clock. Remember that the desired output for this input transition must be specified to avoid unwanted x values at the output. The last two entries show that the transitions in j and k inputs do not change the output on a steady low or high clock. Verilog HDL LRM User-Defined Primitives (UDPs) • 97 7.10 Reducing Pessimism Three-valued logic tends to make pessimistic estimates of the output when one or more inputs are unknown. User-defined primitives can be used to reduce this pessimism. The following is an extension of the previous latch example illustrating reduction of pessimism. primitive latch(q, clock, data); output q; reg q; input clock, data; table //clock data state 0 1 : ? 0 0 : ? 1 ? : ? //ignore x on clock x 0 : 0 x 1 : 1 endtable endprimitive output / next state : 1 ; : 0 ; : - ; //-=no change when data equals state : - ; : - ; Example 7- 9: Latch UDP illustrating pessimism The last two entries specify what happens when the clock input has value x. If these are omitted, the output will go to x whenever the clock is x. This is a pessimistic model, as the latch should not change its output if it is already 0 and the data input is 0. Similar analysis is true for the situation when the data input is 1 and the current output is 1. Consider the jk flip-flop with preset and clear in Example 7-10. primitive jk_edge_ff (q, clock, j, k, preset, clear); output q; reg q; input clock, j, k, preset, clear; table // clock jk pc state output / next state // preset logic ? ?? 01 : ? : 1 ; ? ?? *1 : 1 : 1 ; // clearlogic ? ?? 10 : ? : 0 ; ? ?? 1* : 0 : 0 ; // normal clocking cases r 00 00 : 0 : 1 ; r 00 11 : ? : - ; r 01 11 : ? : 0 ; Verilog HDL LRM User-Defined Primitives (UDPs) • 98 r 10 11 : ? : r 11 11 : 0 : r 11 11 : 1 : f ?? ?? : ? : // j and k cases b *? ?? : ? : b ?* ?? : ? : // cases reducing pessimism p 00 11 : ? : p 0? 1? : 0 : p ?0 ?1 : 1 : (?0) ?? ?? : ? : (1x) 00 11 : ? : (1x) 0? 1? : 0 : (1x) ?0 ?1 : 1 : x *0 ?1 : 1 : x 0* 1? : 0 : endtable endprimitive 1 1 0 - ; ; ; ; - ; ; - ; ; ; ; ; ; ; ; ; Example 7- 10: UDP for a JK flip-flop with preset and clear This example has additional entries for the positive clock (p) edges, the negative clock edges (?0 and 1x), and with the clock value x. In all of these situations, the output is deduced to remain unchanged rather than going to x. Thus, this model is less pessimistic than the previous example. 7.11 Level-Sensitive Dominance In the Verilog HDL, edge-sensitive cases are processed first, followed by level-sensitive cases. When level-sensitive and edge-sensitive cases specify different output values, the result is specified by the level-sensitive case. The following table shows level-sensitive and edge-sensitive entries in Example 7-10, their level-sensitive or edge-sensitve behavior, and a case that each includes. Table 7- 3: The level-sensitive and edge-sensitive entries in Example 7-10 Verilog HDL LRM User-Defined Primitives (UDPs) • 99 The included cases specify opposite next state values for the same input and current state combination. The level-sensitive included case specifies that when the inputs clock, jk and pc values are 0 01, and the current state is 0, the output changes to 1. 00 The edge-sensitive included case specifies that when clock falls from 1 to 0, and the other inputs jk and pc are 00 01, and the current state is 0, the output changes to 0. When the edge-sensitive case is processed first, followed by the level-sensitive case, the output changes to 1. 7.12 Summary of Symbols The following table summarizes the meaning of all the value symbols that are valid in the table part of a UDP definition. Symbol 0 1 x ? b (vw) * r f p n Interpretation logic 0 logic 1 unknown iteration of 0, 1, and x iteration of 0 and 1 no change value change from v to w same as (??) same as (01) same as (10) iteration of (01), (0x) and (x1) iteration of (10), (1x) and (x0) and (x0) Notes cannot be given in output field cannot be given in output field can only be given In the output field of a sequential UDP v and w can be anyone of 0, 1, x, ? or b. any value change on input rising edge on input falling edge on input potential positive edge on the input potential Negative edge on the input Table 7- 4: UDP table symbols Verilog HDL LRM User-Defined Primitives (UDPs) • 100 7.13 Examples //Description of an AND-OR gate. // out = (a1 & a2 & a3) | (b1 & b2). primitive and_or (out, a1, a2, a3, b1, b2); output out; input a1, a2 ,a3, b1, b2; table // a b : out ; 111 ?? : 1 ; ??? 11 : 1 ; 0?? 0? : 0 ; 0?? ?0 : 0 ; ?0? 0? : 0 ; ?0? ?0 : 0 ; ??0 0? : 0 ; ??0 ?0 : 0 ; endtable endprimitive Example 7- 11: UDP for a and-or gate //Majority function for carry // carryout = (a & b) | (a & carryin) | (b & carryin) primitive carry (carryout, carryin, a, b); output carryout; input carryin, a, b; table 0 00 : 0 ; 0 01 : 0 ; 0 10 : 0 ; 0 11 : 1 ; 1 00 : 0 ; 1 01 : 1 ; 1 10 : 1 ; 1 11 : 1 ; // the following cases reduce pessimism 0 0x : 0 ; 0 x0 : 0 ; x 00 : 0 ; 1 1x : 1 ; Verilog HDL LRM User-Defined Primitives (UDPs) • 101 1 x x1 11 : : 1 1 ; ; endtable endprimitive Example 7- 12: UDP for a majority function for carry //Description of a 2-channel multiplexer with storage. //The storage is level sensitive. primitive mux_with_storage (out, clk, control, dataA, dataB); output out; reg out; input clk, control, dataA, dataB; table // clk control dataA dataB : current-state : next state 1 0 1 ? : ? : 1 1 0 0 ? : ? : 0 1 1 ? 1 : ? : 1 1 1 ? 0 : ? : 0 1 x 0 0 : ? : 0 1 x 1 1 : ? : 1 0 ? ? ? : ? : x 0 1 ? : 1 : x 0 0 ? : 0 : x 1 ? 1 : 1 : x 1 ? 0 : 0 : endtable endprimitive ; ; ; ; ; ; ; ; ; ; ; ; Example 7- 13: UDP for a 2-channel multiplexor with storage Verilog HDL LRM User-Defined Primitives (UDPs) • 102 Behavioral Modeling 8.1 Behavioral Model Overview The language constructs introduced so far allow hardware to be described at a relatively detailed level. Modeling a circuit with logic gates and continuous assignments reflects quite closely the logic structure of the circuit being modeled; however, these constructs do not provide the power of abstraction necessary for describing complex high level aspects of a system. The procedural constructs described in this chapter are well suited to tackling problems such as describing a microprocessor or implementing complex timing checks. The chapter starts with a brief overview of a behavioral model to provide a context in which the reader can understand the many types of behavioral statements in Verilog. The behavioral constructs are then discussed in an order that allows us to introduce them before using them in examples. Verilog behavioral models contain procedural statements that control the simulation and manipulate variables of the data types previously described. These statements are contained within procedures. Each procedure has an activity flow associated with it. The activity starts at the control constructs initial and always. Each initial statement and each always statement starts a separate activity flow. All of the activity flows are concurrent, allowing the user to model the inherent concurrence of hardware. Example 8-1 is a complete Verilog behavioral model. module behave; reg[1:0] a, b; initial begin a = 'b1; b = 'b0; end always begin #50 a = ~a; end always begin #100 b = ~b; end endmodule Example 8- 1: Simple example of behavioral modeling Verilog HDL LRM Behavioral Modeling • 103 During simulation of this model, all of the flows defined by the initial and always statements start together at simulation time zero. The initial statements execute once, and the always statements execute repetitively. In this model, the register variables a and b initialize to binary 1 and 0 respectively at simulation time zero. The initial statement is then complete and does not execute again during this simulation run. This initial statement contains a begin-end block (also called a sequential block) of statements. In this begin-end block a is initialized first, followed by b. The always statements also start at time zero, but the values of the variables do not change until the times specified by the delay controls (introduced by #) have gone by. Thus, register a inverts after 50 time units, and register b inverts after 100 time units. Since the always statements repeat, this model produces two square waves. Register a toggles with a period of 100 time units, and register b toggles with a period of 200 time units. The two always statements proceed concurrently throughout the entire simulation run. 8.2 Procedural Assignments As described in Chapter 5, 5.2 Procedural Assignments, procedural assignments are for updating reg, integer, time, and memory variables. There is a significant difference between procedural assignments and continuous assignments: • Continuous assignments drive net variables and are evaluated and updated whenever an input operand changes value. • Procedural assignments update the value of register variables under the control of the procedural flow constructs that surround them. The right-hand side of a procedural assignment can be any expression that evaluates to a value. However, part-selects on the right-hand side must have constant indices. The left-hand side indicates the variable that receives the assignment from the right-hand side. The left-hand side of a procedural assignment can take one of the following forms: • register, integer, real, or time variable: an assignment to the name reference of one of these data types • bit-select of a register, integer, real, or time variable: an assignment to a single bit that leaves the other bits untouched • part-select of a register, integer, real, or time variable: a part-select of two or more contiguous bits that leaves the rest of the bits untouched. For the part-select form, only constant expressions are legal • memory element: a single word of a memory. Note that bit and part selects are illegal on memory element references • concatenation of any of the above: Verilog HDL LRM Behavioral Modeling • 104 a concatenation of any of the previous four forms can be specified, which effectively partitions the result of the right-hand side expression and assigns the partition parts, in order, to the various parts of the concatenation Please note: Assignment to a register differs from assignment to a real, time, or integer variable when the right-hand side evaluates to fewer bits than the left-hand side. Assignment to a register does not sign-extend. The Verilog HDL contains two type of procedural assignment statements: • blocking procedural assignment statements • non-blocking procedural assignment statements Blocking and non-blocking procedural assignment statements specify different procedural flow in sequential blocks. 8.2.1 Blocking Procedural Assignments A blocking procedural assignment statement must be executed before the execution of the statements that follow it in a sequential block (see Section 8.7.1 Sequential Blocks). A blocking procedural assignment statement does not prevent the execution of statements that follow it in a parallel block (see Section 8.7.2 Parallel Blocks). Syntax: The syntax for a blocking procedural assignment is as follows: <lvalue> = <timing_control> <expression> Where lvalue is a data type that is valid for a procedural assignment statement, = is the assignment operator, and timing_control is the optional intra-assignment delay. The timing_control delay can be either a delay control (for example, #6) or an event control (for example, @(posedge clk)). The expression is the right-hand side value the simulator assigns to the left-hand side. The = assignment operator used by blocking procedural assignments is also used by procedural continuous assignments and continuous assignments. Example 8-2 shows examples of blocking procedural assignments. rega = 0; rega[3] = 1; // a bit-select rega[3:5] = 7; // a part-select mema[address] = 8'hff; // assignment to a memory element {carry, acc} = rega + regb; // a concatenation Example 8- 2: Examples of blocking procedural assignments Verilog HDL LRM Behavioral Modeling • 105 8.2.2 The Non-Blocking Procedural Assignment The non-blocking procedural assignment allows you to schedule assignments without blocking the procedural flow. You can use the non-blocking procedural statement whenever you want to make several register assignments within the same time step without regard to order or dependance upon each other. Syntax: The syntax for a non-blocking procedural assignment is as follows: <lvalue> <= <timing_control> <expression> Where lvalue is a data type that is valid for a procedural assignment statement, <= is the nonblocking assignment operator, and timing_control is the optional intra-assignment timing control. The timing_control delay can be either a delay control (for example, #6) or an event control (for example, @(posedge clk)). The expression is the right-hand side value the simulator assigns to the left-hand side. The non-blocking assignment operator is the same operator the simulator uses for the less-thanor-equal relational operator. The simulator interprets the <= operator to be a relational operator when you use it in an expression, and interprets the <= operator to be an assignment operator when you use it in a non-blocking procedural assignment construct. How the simulator evaluates non-blocking procedural assignments When the simulator encounters a non-blocking procedural assignment, the simulator evaluates and executes the non-blocking procedural assignment in two steps. 1. The simulator evaluates the right-hand side and schedules the assignment of the new value to take place at a time specified by a procedural timing control. 2. At the end of the time step, in which the given delay has expired or the appropriate event has taken place, the simulator executes the assignment by assigning the value to the lefthand side. These two steps are shown in Example 8-3. Verilog HDL LRM Behavioral Modeling • 106 Example 8- 3: How the simulator evaluates non-blocking procedural assignments At the end of the time step means that the non-blocking assignments are the last assignments executed in a time step—with one exception. Non-blocking assignment events can create blocking assignment events. The simulator processes these blocking assignment events after the scheduled non-blocking events. Unlike a regular event or delay control, the non-blocking assignment does not block the procedural flow. The non-blocking assignment evaluates and schedules the assignment, but does not block the execution of subsequent statements in a begin end block, as shown in Example 8-4. Verilog HDL LRM Behavioral Modeling • 107 Example 8- 4: Non-blocking assignments do not block execution of sequential statements Please note: As shown in Example 8-5, the simulator evaluates and schedules assignments for the end of the current time step and can perform swapping operations with the new non-blocking procedural assignments. Example 8- 5: The simulator performs swapping operations with the new non-blocking procedural assignments Verilog HDL LRM Behavioral Modeling • 108 When you schedule multiple non-blocking assignments to occur in the same register in a particular time slot, the simulator cannot guarantee the order in which it processes the assignments—the final value of the register is indeterminate. As shown in Example 8-6, the value of register a is not known until the end of time step 4. Example 8- 6: Multiple non-blocking assignments made in a single time step If the simulator executes two procedural blocks concurrently, and these procedural blocks contain non-blocking assignment operators, the final value of the register is indeterminate. For example, in Example 8-7 the value of register a is indeterminate. Example 8- 7: Processing two procedural assignments concurrently When multiple non-blocking assignments with timing controls are made to the same register, the assignments can be made without cancelling previous non-blocking assignments. In Example 8-8, the simulator evaluates the value of i[0] to r1 and schedules the assignments to occur after each time delay. Verilog HDL LRM Behavioral Modeling • 109 Example 8- 8: Multiple non-blocking assignments with timing controls 8.2.3 How the Simulator Processes Blocking and Non-Blocking Procedural Assignments For each time slot during simulation, blocking and non-blocking procedural assignments are processed in the following way: 1. Evaluate the right-hand side of all assignment statements in the current time slot. 2. Execute all blocking procedural assignments. At the same time, all non-blocking procedural assignments are set aside for processing. Execute all non-blocking procedural assignments that have no timing controls. Check for procedures that have timing controls and execute if timing control is set for the current time unit. Advance the simulation clock. 3. 4. 5. 8.3 Conditional Statement The conditional statement (or if-else statement) is used to make a decision as to whether a statement is executed or not. Formally, the syntax is as follows: <statement> ::= if ( <expression> ) <statement_or_null> ||= if ( <expression> ) <statement_or_null> else <statement_or_null> Verilog HDL LRM Behavioral Modeling • 110 <statement_or_null> ::= <statement> ||= ; Syntax 8- 1: Syntax of if statement The <expression> is evaluated; if it is true (that is, has a non-zero known value), the first statement executes. If it is false (has a zero value or the value is x or z), the first statement does not execute. If there is an else statement and <expression> is false, the else statement executes. Since the numeric value of the if expression is tested for being zero, certain shortcuts are possible. For example, the following two statements express the same logic: if (expression) if (expression != 0) Because the else part of an if-else is optional, there can be confusion when an else is omitted from a nested if sequence. This is resolved by always associating the else with the closest previous if that lacks an else. In Example 8-9, the else goes with the inner if, as we have shown by indentation. if (index > 0) if (rega > regb) result = rega; else // else applies to preceding if result = regb; Example 8- 9: Association of else in nested if If that association is not what you want, use a begin-end block statement to force the proper association, as shown in Example 8-10. if(index>0) begin if(rega>regb) result=rega; end else result=regb; Example 8- 10: Forcing correct association of else with if Verilog HDL LRM Behavioral Modeling • 111 Begin-end blocks left out inadvertently can change the logic behavior being expressed, as shown in Example 8-11. if(index>0) for(scani=0;scani<index; scani=scani+1) if(memory[scani]>0) begin $display("..."); memory[scani]=0; end else/*WRONG*/ $display("error-indexiszero"); Example 8- 11: Erroneous association of else with if The indentation in Example 8-11 shows unequivocally what you want, but the compiler does not get the message and associates the else with the inner if. This kind of bug can be very hard to find. Notice that in Example 8-12, there is a semicolon after result = rega. This is because a <statement> follows the if, and a semicolon is an essential part of the syntax of a <statement>. if (rega>regb) result=rega; else result=regb; Example 8- 12: Use of semicolon in if statement 8.3.1 if-else-if Construct The following construction occurs so often that it is worth a brief separate discussion: if (<expression>) <statement> else if (<expression>) <statement> else if (<expression>) <statement> else <statement> Syntax 8- 2: Syntax of if-else-if construct Verilog HDL LRM Behavioral Modeling • 112 This sequence of if’s (known as an if-else-if construct) is the most general way of writing a multiway decision. The expressions are evaluated in order; if any expression is true, the statement associated with it is executed, and this terminates the whole chain. Each statement is either a single statement or a block of statements. The last else part of the if-else-if construct handles the ‘none of the above’ or default case where none of the other conditions was satisfied. Sometimes there is no explicit action for the default; in that case, the trailing “else<statement>” can be omitted or it can be used for error checking to catch an impossible condition. 8.3.2 Example The module fragment of Example 8-13 uses the if-else statement to test the variable index to decide whether one of three modify_segn registers must be added to the memory address, and which increment is to be added to the index register. The first ten lines declare the registers and parameters. // Declare registers and parameters reg[31:0] instruction, segment_area reg[7:0 ]index; reg[5:0] modify_seg1, modify_seg2, modify_seg3; parameter segment1 = 0, inc_seg1=1, segment2 = 20, inc_seg2=2, segment3 = 64, inc_seg3=4, data = 128; // Test the index variable if (index < segment2) begin instruction = segment_area index = index + inc_seg1; end else if ( index < segment3) begin instruction = segment_area index = index + inc_seg2; end else if (index < data) begin instruction = segment_area index = index + inc_seg3; end Verilog HDL LRM [255:0]; [index + modify_seg1]; [index + modify_seg2]; [index + modify_seg3]; Behavioral Modeling • 113 else instruction = segment_area [index]; Example 8- 13: Use of if-else-if construct 8.4 Case Statement The case statement is a special multi-way decision statement that tests whether an expression matches one of a number of other expressions, and branches accordingly. The case statement is useful for describing, for example, the decoding of a microprocessor instruction. The case statement has the following syntax: <statement> ::= case ( <expression> ) <case_item>+ endcase ||= casez ( <expression> ) <case_item>+ endcase ||= casex ( <expression> ) <case_item>+ endcase <case_item> ::= <expression> <,<expression>>* : <statement_or_null> ||= default : <statement_or_null> ||= default <statement_or_null> Syntax 8- 3: Syntax for case statement The default statement is optional. Use of multiple default statements in one case statement is illegal syntax. A simple example of the use of the case statement is the decoding of register rega to produce a value for result as follows: reg[15:0] rega; reg [9:0] result; • • • case (rega) 16'd0: result 16'd1: result 16'd2: result 16'd3: result 16'd4: result 16'd5: result Verilog HDL LRM = = = = = = 10'b0111111111; 10'b1011111111; 10'b1101111111; 10'b1110111111; 10'b1111011111; 10'b1111101111; Behavioral Modeling • 114 16'd6: result = 10'b1111110111; 16'd7: result = 10'b1111111011; 16'd8: result = 10'b1111111101; 16'd9: result = 10'b1111111110; default result = 'bx; endcase Example 8- 14: Use of the case statement The case expressions are evaluated and compared in the exact order in which they are given. During the linear search, if one of the case item expressions matches the expression in parentheses, then the statement associated with that case item is executed. If all comparisons fail, and the default item is given, then the default item statement is executed. If the default statement is not given, and all of the comparisons fail, then none of the case item statements is executed. Apart from syntax, the case statement differs from the multi-way if-else-if construct in two important ways: 1. The conditional expressions in the if-else-if construct are more general than comparing one expression with several others, as in the case statement. 2. The case statement provides a definitive result when there are x and z values in an expression. In a case comparison, the comparison only succeeds when each bit matches exactly with respect to the values 0, 1, x, and z. As a consequence, care is needed in specifying the expressions in the case statement. The bit length of all the expressions must be equal so that exact bit-wise matching can be performed. The length of all the case item expressions, as well as the controlling expression in the parentheses, will be made equal to the length of the longest <case_item> expression. The most common mistake made here is to specify ´bx or ´bz instead of n’bx or n’bz, where n is the bit length of the expression in parentheses. Implementation Specific Detail: The default length of x and z is the word size of the host machine, usually 32 bits. The reason for providing a case comparison that handles the x and z values is that it provides a mechanism for detecting such values and reducing the pessimism that can be generated by their presence. Example 8-15 illustrates the use of case to properly handle x and Z values. case (select[1:2]) 2'b00: result 2'b01: result 2'b0x, 2'b0z: result 2'b10: result 2'bx0, 2'bz0: result Verilog HDL LRM = 0; = flaga; = flaga?'bx:0; = flagb; = flagb ? 'bx : 0; Behavioral Modeling • 115 default result = 'bx; endcase Example 8- 15: Detecting x and z values with the case statement In Example 8-15, if select[1] is 0 and flaga is 0, then whatever the value of select[2] result should be 0—which is resolved by the third case. Example 8-16 shows another way to use a case statement to detect x and z values. case(sig) 1'bz: $display("signal is floating"); 1'bx: $display("signal is unknown"); default: $display("signal is %b", sig); endcase Example 8- 16: Another example of detecting x and z with case 8.4.1 Case Statement with Don’t-Cares Two other types of case statements are provided to allow handling of don’t-care conditions in the case comparisons. One of these treats high-impedance values (z) as don’t-cares, and the other treats both high-impedance and unknown (x) values as don’t-cares. These case statements are used in the same way as the traditional case statement, but they begin with new keywords casez and casex respectively. Don’t-care values (z values for casez, z and x values for casex) in any bit of either the case expression or the case items are treated as don’t-care conditions during the comparison, and that bit position is not considered. Note that allowing don’t-cares in the case items means that you can dynamically control which bits of the case expression are compared during simulation. The syntax of literal numbers allows the use of the question mark (?) in place of z in these case statements. This provides a convenient format for specification of don’t-care bits in case statements. Example 8-17 is an example of the casez statement. It demonstrates an instruction decode, where values of the most significant bits select which task should be called. If the most significant bit of ir is a 1, then the task instruction1 is called, regardless of the values of the other bits of ir. reg [7:0] ir; • Verilog HDL LRM Behavioral Modeling • 116 • • casez (ir) 8'b1???????: instruction1(ir); 8'b01??????: instruction2(ir); 8'b00010???: instruction3(ir); 8'b000001??: instruction4(ir); endcase Example 8- 17: Using the casez statement Example 8-18 is an example of the casex statement. It demonstrates an extreme case of how don’tcare conditions can be dynamically controlled during simulation. In this case, if r = 8´b01100110, then the task stat2 is called. reg [7:0] r, mask; • • • mask = 8'bx0x0x0x0; casex (r ^ mask) 8'b001100xx: stat1; 8'b1100xx00: stat2; 8'b00xx0011: stat3; 8'bxx001100: stat4; endcase Example 8- 18: Using the casex statement 8.5 Looping Statements There are four types of looping statements. They provide a means of controlling the execution of a statement zero, one, or more times. 1. forever continuously executes a statement. 2. repeat executes a statement a fixed number of times. 3. while executes a statement until an expression becomes false. If the expression starts out false, the statement is not executed at all. 4. for controls execution of its associated statement(s) by a three-step process, as follows: a. executes an assignment normally used to initialize a variable that controls the number of loops executed Verilog HDL LRM Behavioral Modeling • 117 b. evaluates an expression—if the result is zero, the for-loop exits, and if it is not zero, the for-loop executes its associated statement(s) and then performs step c c. executes an assignment normally used to modify the value of the loop-control variable, then repeats step b The following are the syntax rules for the looping statements: <statement> ::=forever<statement> ||=forever begin <statement>+ end <statement> ::=repeat(<expression>)<statement> ||=repeat(<expression>) begin <statement>+ end <statement> ::=while(<expression>)<statement> ||=while(<expression>) begin <statement>+ end <statement> ::=for(<assignment>;<expression>;<assignment>) <statement> ||=for(<assignment>;<expression>;<assignment>) begin <statement>+ end Syntax 8- 4: Syntax for the looping statements The rest of this section presents examples for three of the looping statements. 8.5.1 forever Loop The forever loop should only be used in conjunction with the timing controls or the disable statement, therefore, this example is presented in Section 8.6.2 Event Control. Verilog HDL LRM Behavioral Modeling • 118 8.5.2 repeat Loop Example In the following example of a repeat loop, add and shift operators implement a multiplier. parameter size = 8, longsize = 16; reg [size:1] opa, opb; reg [longsize:1] result; begin :mult reg [longsize:1] shift_opa, shift_opb; shift_opa = opa; shift_opb = opb; result = 0; repeat(size) begin if (shift_opb[1]) result = result + shift_opa; shift_opa = shift_opa <<1; shift_opb = shift_opb >>1 end end Example 8- 19: Use of the repeat loop to implement a multiplier 8.5.3 while Loop Example An example of the while loop follows. It counts up the number of logic 1 values in rega. begin :count1s reg [7:0] tempreg; count = 0; tempreg = rega; while (tempreg) begin if (tempreg[0]) count = count + 1; tempreg = tempreg >> 1; end end Example 8- 20: Use of the while loop to count logic values Verilog HDL LRM Behavioral Modeling • 119 8.5.4 for Loop Examples The for loop construct accomplishes the same results as the following pseudo-code that is based on the while loop: begin initial_assignment; while(condition) begin statement step_assignment; end end Example 8- 21: Pseudo code equivalent of a for loop The for loop implements the logic in the preceding 8 lines while using only two lines, as shown in the pseudo code in Example 8-22. for (initial_assignment; condition; step_assignment) statement Example 8- 22: Pseudo code for a for loop Example 8-23 uses a for loop to initialize a memory. begin :init_mem reg [7:0] tempi; for (tempi = 0; tempi < memsize; tempi = tempi + 1) memory[tempi] = 0; end Example 8- 23: Use of the for loop to initialize a memory Here is another example of a for loop statement. It is the same multiplier that was described in Example 8-19 using the repeat loop. parameter size = 8, longsize = 16; reg [size:1] opa, opb; reg [longsize:1] result; begin :mult integer bindex; Verilog HDL LRM Behavioral Modeling • 120 result = 0; for (bindex = 1; bindex <= size; bindex = bindex + 1) if (opb[bindex]) result = result + (opa << (bindex-1)); end Example 8- 24: Use of the for loop to implement a multiplier Note that the for loop statement can be more general than the normal arithmetic progression of an index variable, as in Example 8-25. This is another way of counting the number of logic 1 values in rega (see Example 8-20). begin :count1s reg [7:0] tempreg; count = 0; for (tempreg = rega; tempreg; tempreg = tempreg >>1) if (tempreg[0]) count = count + 1; end Example 8- 25: Use of the for loop to count logic values 8.6 Procedural Timing Controls The Verilog language provides two types of explicit timing control over when in simulation time procedural statements are to occur. The first type is a delay control in which an expression specifies the time duration between initially encountering the statement and when the statement actually executes. The delay expression can be a dynamic function of the state of the circuit, but is usually a simple number that separates statement executions in time. The delay control is an important feature when specifying stimulus waveform descriptions. It is described in Sections 8.6.1, and 8.6.6. The second type of timing control is the event expression, which allows statement execution to wait for the occurrence of some simulation event occurring in a procedure executing concurrently with this procedure. A simulation event can be a change of value on a net or register (an implicit event), or the occurrence of an explicitly named event that is triggered from other procedures (an explicit event). Most often, an event control is a positive or negative edge on a clock signal. Sections 8.6.2 through 8.6.6 discuss event control. A general principle of the Verilog language is that “where you do not see a timing control, then simulation time does not advance.” Though we are talking here of procedural timing controls, note that gate and net delays also advance simulation time. The procedural statements encountered so far all execute in zero time. Simulation time can only progress by one of the following three methods: • a delay control, which is introduced by the number symbol (#) Verilog HDL LRM Behavioral Modeling • 121 • an event control, which is introduced by the at symbol (@) • the wait statement, which operates like a combination of the event control and the while loop The next subsections discuss these three methods. 8.6.1 Delay Control The execution of a procedural statement can be delay-controlled by using the following syntax: <statement> ::= <delay_control> <statement_or_null> <delay_control> ::= # <NUMBER> ||= # <identifier> ||= # ( <mintypmax_expression> ) Syntax 8- 5: Syntax for delay_control The following example delays the execution of the assignment by 10 time units: #10 rega = regb; The next three examples provide an expression following the number sign (#). Execution of the assignment delays by the amount of simulation time specified by the value of the expression. #d rega = regb; // d is defined as a parameter #((d+e)/2) rega = regb; // delay is the average of d and e #regr regr = regr + 1; // delay is the value in regr 8.6.2 Event Control The execution of a procedural statement can be synchronized with a value change on a net or register, or the occurrence of a declared event, by using the following event control syntax: <statement> ::= <event_control> <statement_or_null> <event_control> ::= @ <identifier> ||= @ ( <event_expression> ) <event_expression> Verilog HDL LRM Behavioral Modeling • 122 ::= <expression> ||= posedge <SCALAR_EVENT_EXPRESSION> ||= negedge <SCALAR_EVENT_EXPRESSION> ||= <event_expression> <or <event_expression>>* <SCALAR_EVENT_EXPRESSION> is an expression that resolves to a one bit value. Syntax 8- 6: Syntax for event_control Value changes on nets and registers can be used as events to trigger the execution of a statement. This is known as detecting an implicit event. See item 1 in Example 8-26 for a syntax example of a wait for an implicit event. Verilog syntax also allows you to detect change based on the direction of the change—that is, toward the value 1 (posedge) or toward the value 0 (negedge). The behavior of posedge and negedge for unknown expression values is as follows: • a negedge is detected on the transition from 1 to unknown and from unknown to 0 • a posedge is detected on the transition from 0 to unknown and from unknown to 1 Items 2 and 3 in Example 8-26 show illustrations of edge controlled statements. Item 1 @ rrega = regb; //controlled by any value changes in the register rrega Item 2 @ (posedge clock) rega = regb; //controlled by positive edge on clock Item 3 forever @ (negedge clock) rega = regb; // controlled by negative edge Example 8- 26: Event controlled statements 8.6.3 Named Events Verilog also provides syntax to name an event and then to trigger the occurrence of that event. A model can then use an event expression to wait for the triggering of this explicit event. Named events can be made to occur from a procedure. This allows control over the enabling of multiple actions in other procedures. Named events and event control give a powerful and efficient means of describing the communication between, and synchronization of, two or more concurrently active processes. A basic example of this is a small waveform clock generator that synchronizes control of a synchronous circuit by signalling the occurrence of an explicit event periodically while the circuit waits for the event to occur. An event name must be declared explicitly before it is used. The following is the syntax for declaring events. <event_declaration> Verilog HDL LRM Behavioral Modeling • 123 ::= event <name_of_event> <,<name_of_event>>* ; <name_of_event> ::= <IDENTIFIER> - the name of an explicit event Syntax 8- 7: Syntax for event_declaration Note that an event does not hold any data. The following are the characteristics of a Verilog event: • it can be made to occur at any particular time • it has no time duration • its occurrence can be recognized by using the <event_control> syntax described in Section 8.6.2 The power of the explicit event is that it can represent any general happening. For example, it can represent a positive edge of a clock signal, or it can represent a microprocessor transferring data down a serial communications channel. A declared event is made to occur by the activation of an event triggering statement of the following syntax: -> <name_of_event> ; An event controlled statement (for example, @trig rega = regb;) causes simulation of its containing procedure to wait until some other procedure executes the appropriate event triggering statement (for this example, ->trig). 8.6.4 Event OR Construct The ORing of any number of events can be expressed such that the occurrence of any one will trigger the execution of the statement. The next two examples show the ORing of two and three events respectively. @(trig or enable) rega = regb; // controlled by trig or enable @(posedge clock_a or posedge clock_b or trig) rega = regb; 8.6.5 Level-Sensitive Event Control The execution of a statement can also be delayed until a condition becomes true. This is accomplished using the wait statement, which is a special form of event control. The nature of the wait statement is level-sensitive, as opposed to basic event control (specified by the @ character), which is edge-sensitive. The wait statement checks a condition, and, if it is false, causes the procedure to pause until that condition becomes true before continuing. The wait statement has the following form: wait(condition_expression) statement Verilog HDL LRM Behavioral Modeling • 124 Example 8-27 shows the use of the wait statement to accomplish level-sensitive event control. begin wait(!enable) #10 a = b; #10 c = d; end Example 8- 27: Use of wait statement If the value of enable is one when the block is entered, the wait statement delays the evaluation of the next statement (#10 a = b;) until the value of enable changes to zero. If enable is already zero when the begin-end block is entered, then the next statement is evaluated immediately and no delay occurs. 8.6.6 Intra-Assignment Timing Controls The delay and event control constructs previously described precede a statement and delay its execution. The intra-assignment delay and event controls are contained within an assignment statement and modify the flow of activity in a slightly different way. Encountering an intra-assignment delay or event control delays the assignment just as a regular delay or event control does, but the right-hand-side expression is evaluated before the delay, instead of after the delay. This allows data swap and data shift operations to be described without the need for temporary variables. This section describes the purpose of intra-assignment timing controls and the repeat timing control that can be used in intra-assignment delays. Figure 8-1 illustrates the philosophy of intra-assignment timing controls by showing the code that could accomplish the same timing effect without using intra-assignment. Figure 8- 1: Equivalents to intra-assignment timing controls Verilog HDL LRM Behavioral Modeling • 125 The next three examples use the fork-join behavioral construct. All statements between the keywords fork and join execute concurrently. Section 8.7.2 Parallel Blocks describes this construct in more detail. The following example shows a race condition that could be prevented by using intra-assignment timing control: fork #5 a = b; #5 b = a; join The code in the example above samples the values of both a and b at the same simulation time, thereby creating a race condition. The intra-assignment form of timing control used in the example below prevents this race condition: fork // data swap a = #5 b; b = #5 a; join Intra-assignment timing control works because the intra-assignment delay causes the values of a and b to be evaluated before the delay, and the assignments to be made after the delay. Some existing tools that implement intra-assignment timing control use temporary storage in evaluating each expression on the right-hand side. Intra-assignment waiting for events is also effective. In the example below, the right-hand-side expressions are evaluated when the assignment statements are encountered, but the assignments are delayed until the rising edge of the clock signal. fork // data shift a = @(posedge clk) b; b = @(posedge clk) c; join The repeat event control The repeat event control specifies an intra-assignment delay of a specified number of occurrences of an event. This construct is convenient when events must be synchronized with counts of clock signals. Syntax 8-8 presents the repeat event control syntax: <repeat_event _controlled_assignment> Verilog HDL LRM Behavioral Modeling • 126 ::=<lvalue> = <repeat_event_control><expression>; ||=<lvalue> <= <repeat_event_control><expression>; <repeat_event_control> ::=repeat(<expression>)@(<identifier>) ||=repeat(<expression>)@(<event_expression>) <event_expression> ::=<expression> ||=posedge<SCALAR_EVENT_EXPRESSION> ||=negedge<SCALAR_EVENT_EXPRESSION> ||=<event_expression>or<event_expression> Syntax 8- 8: Syntax of the repeat event control The event expression must resolve to a one bit value. A scalar event expression is an expression which resolves to a one bit value. The following is an example of a repeat event control as the intra-assignment delay of a nonblocking assignment: a <= repeat(5) @(posedge clk) data; Figure 8-2 illustrates the activities that result from this repeat event control: Figure 8- 2: Repeat event control utilizing a clock edge In this example, the value of data is evaluated when the assignment is encountered. After five occurrences of posedge clk, a is assigned the value of data. The following is an example of a repeat event control as the intra-assignment delay of a procedural assignment: Verilog HDL LRM Behavioral Modeling • 127 a = repeat(num)@(clk)data; In this example, the value of data is evaluated when the assignment is encountered. After the number of transitions of clk equals the value of num, a is assigned the value of data. The following is an example of a repeat event control with expressions containing operations to specify both the number of event occurrences and the event that is counted: a <= repeat(a+b)@(posedge phi1 or negedge phi2)data; In the example above, the value of data is evaluated when the assignment is encountered. After the sum of the positive edges of phi1 and the negative edges of phi2 equals the sum of a and b, a is assigned the value of data. 8.7 Block Statements The block statements are a means of grouping two or more statements together so that they act syntactically like a single statement. We have already introduced and used the sequential block statement which is delimited by the keywords begin and end. Section 8.7.1 Sequential Blocks discusses sequential blocks in more detail. A second type of block, delimited by the keywords fork and join, is used for executing statements in parallel. A fork-join block is known as a parallel block, and enables procedures to execute concurrently through time. Section 8.7.2 Parallel Blocks discusses parallel blocks. 8.7.1 Sequential Blocks A sequential block has the following characteristics: • statements execute in sequence, one after another • delay values for each statement are relative to the simulation time of the execution of the previous statement • control passes out of the block after the last statement executes The following is the formal syntax for a sequential block: <seq_block> ::= begin <statement>* end ||= begin : <name_of_block> <block_declaration>* <statement>* end <name_of_block> ::=<IDENTIFIER> Verilog HDL LRM Behavioral Modeling • 128 <block_declaration> ::=<parameter_declaration> ||=<reg_declaration> ||=<integer_declaration> ||=<real_declaration> Syntax 8- 9: Syntax for the sequential block A sequential block enables the following two assignments to have a deterministic result: begin areg = breg; creg = areg; // creg becomes the value of breg end Here the first assignment is performed and areg is updated before control passes to the second assignment. Delay control can be used in a sequential block to separate the two assignments in time. begin areg = breg; #10 creg = areg; // this gives a delay of 10 time end // units between assignments Example 8-28 shows how the combination of the sequential block and delay control can be used to specify a time-sequenced waveform. parameter d = 50; // d declared as a parameter reg [7:0] r; // and r declared as an 8-bit register begin // a waveform controlled by sequential delay #d r = 'h35; #d r = 'hE2; #d r = 'h00; #d r = 'hF7; #d -> end_wave;// trigger the event called end_wave end Example 8- 28: A waveform controlled by sequential delay Example 8-29 shows three examples of sequential blocks. Verilog HDL LRM Behavioral Modeling • 129 Example 8- 29: Three examples of sequential blocks 8.7.2 Parallel Blocks A parallel block has the following characteristics: • statements execute concurrently • delay values for each statement are relative to the simulation time when control enters the block • delay control is used to provide time-ordering for assignments • control passes out of the block when the last time-ordered statement executes or a disable statement executes Syntax 8-10 gives the formal syntax for a parallel block. <par_block> ::= fork <statement>* join ||= fork : <name_of_block <block_declaration>* <statement>* join <name_of_block> ::=<IDENTIFIER> <block_declaration> ::=<parameter_declaration> ||=<reg_declaration> ||=<integer_declaration> ||=<real_declaration> Verilog HDL LRM Behavioral Modeling • 130 ||=<time_declaration> ||=<event_declaration> Syntax 8- 10: Syntax for the parallel block Example 8-30 codes the waveform description shown in Example 8-28 by using a parallel block instead of a sequential block. The waveform produced on the register is exactly the same for both implementations. fork #50 r = 'h35; #100 r = 'hE2; #150 r = 'h00; #200 r = 'hF7; #250 -> end_wave; join Example 8- 30: Use of the fork-join construct 8.7.3 Block Names Note that blocks can be named by adding: name_of_block after the keywords begin or fork. The naming of blocks serves several purposes: • It allows local variables to be declared for the block. • It allows the block to be referenced in statements like the disable statement (as discussed in Chapter 10.0 Disabling Blocks and Tasks Overview). • In the Verilog language, all variables are static—that is, a unique location exists for all variables and leaving or entering blocks does not affect the values stored in them. Thus, block names give a means of uniquely identifying all variables at any simulation time. 8.7.4 Start and Finish Times Both forms of blocks have the notion of a start and finish time. For sequential blocks, the start time is when the first statement is executed, and the finish time is when the last statement has finished. For parallel blocks, the start time is the same for all the statements, and the finish time is when the last time-ordered statement has finished executing. When blocks are embedded within each other, the timing of when a block starts and finishes is important. Execution does not continue to the statement following a block until the block’s finish time has been reached—that is, until the block has completely finished executing. Moreover, the timing controls in a fork-join block do not have to be given sequentially in time. Example 8-31 shows the statements from Example 8-30 written in the reverse order and still producing the same waveform. Verilog HDL LRM Behavioral Modeling • 131 fork #250 -> end_wave; #200 r = 'hF7; #150 r = 'h00; #100 r = 'hE2; #50 r = 'h35; join Example 8- 31: Timing controls in a parallel block Sequential and parallel blocks can be embedded within each other allowing complex control structures to be expressed easily and with a high degree of structure. One simple example of this is when an assignment is to be made after two separate events have occurred. This is known as the ‘joining’ of events. begin fork @Aevent; @Bevent; join areg=breg; end Example 8- 32: The joining of events Note that the two events can occur in any order (or even at the same time) and the fork-join block will complete and the assignment will be made. In contrast to this, if the fork-join block was a begin-end block and the Bevent occurred before the Aevent, then the block would be deadlocked waiting for the Bevent. Example 8-33 shows two sequential blocks, each of which will execute when its controlling event occurs. Because the wait statements are within a fork-join block, they execute in parallel and the sequential blocks can therefore also execute in parallel. fork @enable_a begin #tawa=0; #tawa=1; #tawa=0; end @enable_b Verilog HDL LRM Behavioral Modeling • 132 begin #tbwb=1; #tbwb=0; #tbwb=1; end join Example 8- 33: Enabling sequential blocks to execute in parallel 8.8 Structured Procedures All procedures in Verilog are specified within one of the following four statements: initial statement • always statement • task • function The initial and always statements are enabled at the beginning of simulation. The initial statement executes only once and its activity dies when the statement has finished. In contrast, the always statement executes repeatedly. Its activity dies only when the simulation is terminated. There is no limit to the number of initial and always blocks that can be defined in a module. Tasks and functions are procedures that are enabled from one or more places in other procedures. Tasks and functions are covered in detail in Chapter 9. 8.8.1 initial Statement The syntax for the initial statement is as follows: <initial_statement> ::=initial<statement> Syntax 8- 11: Syntax for <initial_statement> Example 8-34 illustrates use of the initial statement for initialization of variables at the start of simulation. initial begin areg = 0; // initialize a register for (index = 0; index < size; index = index+1) memory[index] = 0; // initialize a memory word Verilog HDL LRM Behavioral Modeling • 133 end Example 8- 34: Use of initial statement Another typical usage of the initial statement is specification of waveform descriptions that execute once to provide stimulus to the main part of the circuit being simulated. Example 8-35 illustrates this usage. initial begin inputs = 'b000000; // initialize at time zero #10 inputs = 'b011001; // first pattern #10 inputs = 'b011011; // second pattern #10 inputs = 'b011000; // third pattern #10 inputs = 'b001000; // last pattern end Example 8- 35: Another use for initial statement 8.8.2 always Statement The always statement repeats continuously throughout the whole simulation run. Syntax 8-12 gives the syntax for the always statement. <always_statement> ::= always <statement> Syntax 8- 12: Syntax for always_statement The always statement, because of its looping nature, is only useful when used in conjunction with some form of timing control. If an always statement provides no means for time to advance, the always statement creates a simulation deadlock condition. The following code, for example, creates an infinite zero-delay loop. always areg = ~areg; Providing a timing control to the above code creates a potentially useful description—as in the following example: always #half_period areg = ~areg; Verilog HDL LRM Behavioral Modeling • 134 8.8.3 Examples We have now introduced enough statement types for some complete and more practical examples to be given. These examples are given as complete descriptions enclosed in modules—such that they can be simulated and the results observed. Example 8-36 is that of a simple traffic light sequencer described with its own clock generator. module traffic_lights; reg clock, red, amber, green; parameter on = 1, off = 0, red_tics = 350, amber_tics = 30, green_tics = 200; // the sequence to control the lights always begin red = on; amber = off; green = off; repeat (red_tics) @(posedge clock); red = off; green = on; repeat (green_tics) @(posedge clock); green = off; amber = on; repeat (amber_tics) @(posedge clock); end // waveform for the clock always begin #100 clock = 0; #100 clock = 1; end // simulate for 10 changes on the red light initial begin Verilog HDL LRM Behavioral Modeling • 135 repeat (10) @ red; $finish; end // display the time and changes made to the lights always @ ( red or amber or green ) $display ("%d red=%b amber=%b green=%b", $time, red, amber, green); endmodule Example 8- 36: Behavioral model of traffic light sequencer Example 8-37 shows a use of variable delays. The module has a clock input and produces two synchronized clock outputs. Each output clock has equal mark and space times, is out of phase from the other by 45 degrees, and has a period half that of the input clock. Note that the clock generation is independent of the simulation time unit, except as it affects the accuracy of the divide operation on the input clock period. module synch_clocks; reg clock, phase1, phase2; time clock_time; initial clock_time = 0; always @ (posedge clock) begin :phase_gen timed; //a local declaration is possible //because the block is named d = ($time - clock_time) / 8; clock_time = $time; phase1 = 0; #d phase2 = 1; #d phase1 = 1; #d phase2 = 0; #d phase1 = 0; #d phase2 = 1; #d phase1 = 1; #d phase2 = 0; end // setup a clock waveform, finish time, Verilog HDL LRM Behavioral Modeling • 136 // and display always begin #100 clock = 0; #100 clock = 1; end initial #1000 $finish; // end simulation at time 1000 always @ (phase1 or phase2) $display ($time,, "clock = %b phase1 = %b phase2 = %b", clock, phase1, phase2); endmodule Example 8- 37: Behavioral model with variable delays Verilog HDL LRM Behavioral Modeling • 137 Tasks and Functions 9.0 Tasks and Functions Overview Tasks and functions provide the ability to execute common procedures from several different places in a description. They also provide a means of breaking up large procedures into smaller ones to make it easier to read and debug the source descriptions. Input, output, and inout argument values can be passed into and out of both tasks and functions. The next section discusses the differences between tasks and functions. Subsequent sections describe how to define and invoke tasks and functions and present examples of each. 9.1 Distinctions between Tasks and Functions The following rules distinguish tasks from functions: • A function must execute in one simulation time unit; a task can contain time-controlling statements. • A function cannot enable a task; a task can enable other tasks and functions. • A function must have at least one input argument; a task can have zero or more arguments of any type. • A function returns a single value; a task does not return a value. The purpose of a function is to respond to an input value by returning a single value. A task can support multiple goals and can calculate multiple result values. However, only the output or inout arguments pass result values back from the invocation of a task. A Verilog model uses a function as an operand in an expression; the value of that operand is the value returned by the function. For example, you could define either a task or a function to switch bytes in a 16-bit word. The task would return the switched word in an output argument, so the source code to enable a task called switch_bytes could look like the following example: switch_bytes (old_word, new_word); The task switch_bytes would take the bytes in old_word, reverse their order, and place the reversed bytes in new_word. A word-switching function would return the switched word directly. Thus, the function call for the function switch_bytes might look like the following example: new_word = switch_bytes (old_word); 9.2 Tasks and Task Enabling A task is enabled from a statement that defines the argument values to be passed to the task and the variables that will receive the results. Control is passed back to the enabling process after the task has completed. Thus, if a task has timing controls inside it, then the time of enabling can be different from the time at which control is returned. A task can enable other tasks, which in turn Verilog HDL LRM Tasks and Functions • 138 can enable still other tasks—with no limit on the number of tasks enabled. Regardless of how many tasks have been enabled, control does not return until all enabled tasks have completed. 9.2.1 Defining a Task The following is the syntax for defining tasks: <task> ::= task <name_of_task> ; <tf_declaration>* <statement_or_null> endtask <name_of_task> ::= <IDENTIFIER> <tf_declaration> ::= <parameter_declaration> ||= <input_declaration> ||= <output_declaration> ||= <inout_declaration> ||= <reg_declaration> ||= <time_declaration> ||= <integer_declaration> ||= <real_declaration> ||= <event_declaration> Syntax 9- 1: Syntax for task Task and function declarations specify the following: • local variables • IO ports • registers • times • integers • real • events These declarations all have the same syntax as for the corresponding declarations in a module definition. Verilog HDL LRM Tasks and Functions • 139 9.2.2 Task Enabling and Argument Passing The statement that enables a task passes the IO arguments as a comma-separated list of expressions enclosed in parentheses. The following is the formal syntax of the task enabling statement: <task_enable> ::= <name_of_task> ; ||= <name_of_task> ( <expression> <,<expression>>* ) ; Syntax 9- 2: Syntax of the task enabling statement The first form of a task enabling statement applies when there are no IO arguments declared in the task body. In the second form, the list of <expression> items is an ordered list that must match the order of the list of IO arguments in the task definition. If an IO argument is an input, then the corresponding <expression> can be any expression. If the IO argument is an output or an inout, then Verilog restricts it to an expression that is valid on the left-hand side of a procedural assignment. The following items satisfy this requirement: • reg, integer, real, and time variables • memory references • concatenations of reg, integer, real, and time variables • concatenations of memory references • bit-selects and part-selects of reg, integer, real, and time variables The execution of the task enabling statement passes input values from the variables listed in the enabling statement to the variables specified within the task. Execution of the return from the task passes values from the task output and inout variables to the corresponding variables in the task enabling statement. Verilog passes all arguments by value (that is, Verilog passes the value rather than a pointer to the value). Example 9-1 illustrates the basic structure of a task definition with five arguments. task my_task; input a, b; inout c; output d, e; begin <statement> c = foo1; d = foo2; e = foo3; end endtask Verilog HDL LRM // the set of statements that // performs the work of the task // the assignments that initialize // the results variables Tasks and Functions • 140 Example 9- 1: Task definition with arguments The following statement enables the task in Example 9-1: my_task (v, w, x, y, z); The calling arguments (v, w, x, y, z) correspond to the IO arguments (a, b, c, d, e) defined by the task. At task enabling time, the input and inout arguments (a, b, and c) receive the values passed in v, w, and x. A tool processing the HDL source code performs this assignment. Thus, execution of the task enabling call effectively causes the following assignments: a = v; b = w; c = x; As part of the processing of the task, the task definition for my_task must place the computed results values into c, d, and e. When the task completes, the processing software performs the following assignments to return the computed values to the calling process: x = c; y = d; z = e; 9.2.3 Task Example Example 9-2 illustrates the use of tasks by redescribing the traffic light sequencer that was introduced in Chapter 8. module traffic_lights; reg clock, red, amber, green; parameter on = 1, off = 0, red_tics = 350, amber_tics = 30, green_tics = 200; // initialize colors initial red = off; initial amber = off; initial green = off; // sequence to control the lights always begin red = on; // turn red light on light(red, red_tics); // and wait. green = on; // turn green light on light(green, green_tics); // and wait. amber = on; // turn amber light on light(amber, amber_tics); // and wait. end Verilog HDL LRM Tasks and Functions • 141 // task to wait for 'tics' positive edge clocks // before turning 'color' light off task light; output color; input [31:0] tics; begin repeat (tics) @(posedge clock); color = off; // turn light off end endtask // waveform for the clock always begin #100 clock = 0; #100 clock = 1; end endmodule // traffic_lights Example 9- 2: Using tasks 9.2.4 Effect of Enabling an Already Active Task Implementation Specific Detail: Because Verilog supports concurrent procedures, and tasks can have non-zero time duration, you can write a model that invokes a task when that task is already executing (a special case of invoking a task that is already active is where a task recursively calls itself). Some tools allow multiple copies of a task to execute concurrently, but it does not copy or otherwise preserve the task arguments or local variables. Some tools use the same storage for each invocation of the task. This means that when the simulator interrupts a task to process another instance of the same task, it overwrites the argument values from the first call with the values from the second call. The user must manage what happens to the variables of a task that is invoked while it is already active. 9.3 Functions and Function Calling The purpose of a function is to return a value that is to be used in an expression. The rest of this chapter explains how to define and use functions. Verilog HDL LRM Tasks and Functions • 142 9.3.1 Defining a Function To define functions, use the following syntax: <function> ::= function <range_or_type>? <name_of_function> ; <tf_declaration>+ <statement> endfunction <range_or_type> ::= <range> ||= integer ||= real <name_of_function> ::= <IDENTIFIER> <tf_declaration> ::= <parameter_declaration> ||= <input_declaration> ||= <output_declaration> ||= <inout_declaration> ||= <reg_declaration> ||= <time_declaration> ||= <integer_declaration> ||= <real_declaration> ||= <event_declaration> Syntax 9- 3: Syntax for function Note that the <range_or_type> item is optional. A function specified without <range_or_type> defaults to a one-bit register for the return value. If used, <range_or_type> can specify that the function’s return value is a real, an integer, or a value with a range of [n:m] bits. Example 9-3 defines a function called getbyte, using a <range> specification. function [7:0] getbyte; input [15:0] address; begin <statements> // code to extract low-order // byte from addressed word getbyte = result_expression; end endfunction Verilog HDL LRM Tasks and Functions • 143 Example 9- 3: A function definition using range 9.3.2 Returning a Value from a Function The function definition implicitly declares a register, internal to the function, with the same name as the function. This register either defaults to one bit or is the same type as the <range_or_type> specified in the function declaration. The function definition initializes the function’s return value by assigning the function result to the internal variable with the same name as the function. The following line from Example 9-3 illustrates this concept: getbyte = result_expression; 9.3.3 Calling a Function A function call is an operand within an expression. The operand has the following syntax: <function_call> ::= <name_of_function> ( <expression> <,<expression>>* ) <name_of_function> ::= <identifier> Syntax 9- 4: Syntax for function_call The following example creates a word by concatenating the results of two calls to the function getbyte (defined in Example 9-3). word = control ? {getbyte(msbyte), getbyte(lsbyte)} : 0; 9.3.4 Function Rules Functions are more limited than tasks. The following four rules govern their usage: 1. A function definition cannot contain any time controlled statements—that is, any statements introduced with #, @, or wait. 2. 3. 4. Functions cannot enable tasks. A function definition must contain at least one input argument. A function definition must include an assignment of the function result value to the internal variable that has the same name as the function. Verilog HDL LRM Tasks and Functions • 144 9.3.5 Function Example Example 9-4 defines a function called factorial that returns a 32-bit register. The factorial function then calls itself recursively and prints some results. module tryfact; // define function function [31:0] factorial; input [3:0] operand; reg [3:0] index; begin factorial = operand ? 1 : 0; for (index = 2; index <= operand; index = index + 1) factorial = index * factorial; end endfunction //Test the function reg [31:0] result; reg [3:0] n; initial begin result=1; for( n=2; n<=9; n=n+1) begin $display("Partial result n=%d result=%d", n,result); result = n * factorial (n) / ((n*2)+1); end $display ("Final result=%d", result); end endmodule // tryfact Example 9- 4: Defining and calling a function Verilog HDL LRM Tasks and Functions • 145 Disabling of Named Blocks and Tasks 10.0 Disabling Blocks and Tasks Overview The disable statement provides the ability to terminate the activity associated with concurrently active procedures, while maintaining the structured nature of Verilog HDL procedural descriptions. The disable statement gives a mechanism for returning from a task before it executes all its statements, breaking from a looping statement, or skipping statements in order to continue with another iteration of a looping statement. It is useful for handling exception conditions such as hardware interrupts and global resets. The disable statement has one of the following two syntax forms: <disable_statement> ::= disable <name_of_task> ; ||= disable <name_of_block> ; Syntax 10- 1: Syntax of <disable_statement> Either form of disable causes all current activity in the named block or task to be terminated. The disable statement removes evaluated and scheduled non blocking procedural assignments from the schedule of events. Execution resumes at the statement following the block or following the task enabling statement. The termination of activity also applies to all activity enabled within the named block or task. If task enable statements are nested—that is, one task enables another, and that one enables yet another—then disabling a task within the chain disables all tasks downward on the chain. The disable statement is also used within blocks and tasks to disable the particular block or task containing the disable statement. The following example, in which a block disables itself, illustrates this concept: begin :block_name rega = regb; disable block_name; regc = rega; // this assignment will never execute end Example 10- 1: A block disabling itself The next five examples illustrate the disable statement in situations representative of features found in other languages. shows the disable statement being used within a named block in a manner similar to a forward goto. The next statement executed after the disable statement is the one following the named block. begin :block_name Verilog HDL LRM Disabling of Named Blocks and Tasks • 146 • . • . • . if (a == 0) disable block_name; • . • . • . end // end of named block // continue with code following named block • . • . • . Example 10- 2: disable statement used as “goto” Example 10-3 shows the disable statement being used as an early return from a task. task proc_a; begin • . • . • . if (a == 0)disable proc_a; // return if true • . • . • . end endtask Example 10- 3: disable statement used as return Example 10-4 shows the disable statement being used in an equivalent way to the two statements continue and break in the C language. The example illustrates control code that would allow a named block to execute until a loop counter reaches n iterations or until the variable a gets set to a value of b. The named block break contains the code that executes until a == b, at which point the disable break; statement terminates execution of that block. The named block continue contains the Verilog HDL LRM Disabling of Named Blocks and Tasks • 147 code that executes for each iteration of the for loop. Each time this code executes the disable continue; statement, the continue block terminates and execution passes to the next iteration of the for loop. For each iteration of the continue block, a set of <statements> executes if (a != 0). Another set of <statements> executes if(a!=b). begin :break for (I = 0; I < n; I = I + 1) begin :continue @ clk if (a == 0); // "continue" loop disable continue <statements> <statements> @clk if ( a == b ) // "break" from loop disable break; <statements> <statements> end end Example 10- 4: disable statement as “continue” and “break” Example 10-5 shows the disable statement being used to concurrently disable a sequence of timing controls and the task action, when the reset event occurs. The example shows a fork/join block within which is a named sequential block (event_expr) and a disable statement that waits for occurrence of the event reset. The sequential block and the wait for reset execute in parallel. The event_expr block waits for one occurrence of event ev1 and three occurrences of event trig. When these four events have happened, plus a delay of d time units, the task action executes. When the event reset occurs, regardless of events within the sequential block, the fork/join block terminates—including the task action. fork begin :event_expr @ ev1; repeat (3) @ trig; #d action (areg, breg); end @ reset disable event_expr; join Verilog HDL LRM Disabling of Named Blocks and Tasks • 148 Example 10- 5: disable statement in a fork/join block Example 10-6 is a behavioral description of a retriggerable monostable. The named event retrig restarts the monostable time period. If retrig continues to occur within 250 time units, then q will remain at 1. always begin: monostable #250 q = 0; end always @retrig begin disable monostable; q=1; end Example 10- 6: disable statement in retriggerable monostable Example 10-6 is a combination lock that is implemented with the disable statement and event controls. The events are key_a, key_b, and key_c. The combination lock opens when simulation detects these events in the following sequence: 1. key_b 2. key_a 3. key_c always begin :lock @key_b fork reg flag; flag=1; @key_a fork flag=0; @key_c -> open; @(key_a or key_b) disable lock; join @(key_b or key_c) if (flag) disable lock; join end Verilog HDL LRM Disabling of Named Blocks and Tasks • 149 always @open begin disable lock; open_it_up; end Example 10- 7: disable statement used with event controls Verilog HDL LRM Disabling of Named Blocks and Tasks • 150 Procedural Continuous Assignments 11.0 Procedural Continuous Assignment Overview The procedural continuous assignments are procedural statements that allow expressions to be driven continuously onto registers or nets. The syntax for these statements follows: <statement> ::= assign <assignment> ; <statement> ::= deassign <lvalue> ; <force_statement> ::= force <assignment> ; <release_statement> ::= release <lvalue> ; Syntax 11- 1: Syntax for procedural continuous assignments The left-hand side of the assignment in the assign statement is restricted to be a register reference or a concatenation of registers. It cannot be a memory element (array reference) or a bit-select or a part-select of a register. In contrast, the left-hand side of the assignment in the force statement can be a register reference or a net reference, a bit-select or part-select of an expanded vector net. It can be a concatenation of any of the above. Bit-selects and part-selects of vector registers or unexpanded vector nets are not allowed, and will result in an error. 11.1 The assign and deassign Procedural Statements The assign and deassign procedural statements allow continuous assignments to be placed onto registers for controlled periods of time. The assign procedural assignment statement overrides procedural assignments to a register. The deassign procedural statement ends a continuous assignment to a register. The assign and deassign procedural statements allow, for example, modeling of asynchronous clear/preset on a D-type edge-triggered flip-flop, where the clock is inhibited when the clear or preset is active. Example 11-1 shows a use of the assign and deassign procedural statements in a behavioral description of a D-type flip-flop with preset and clear inputs. Verilog HDL LRM Procedural Continuous Assignments • 151 Example 11- 1: Use of assign and deassign If either clear or preset is low, then the output q will be held continuously to the appropriate constant value and a positive edge on the clock will not affect q. When both the clear and preset are high, then q is deassigned. If the keyword assign is applied to a register for which there is already a procedural continuous assignment, this new procedural continuous assignment automatically deassigns the register before making the new procedural continuous assignment. 11.2 The force and release Procedural Statements Another form of procedural continuous assignment is provided by the force and release procedural statements. These statements have a similar effect to the assign-deassign pair, but a force can be applied to nets as well as to registers. The left-hand side of the assignment can be a register, a net, a constant bit select of an expanded vector net, a part select of an expanded vector net, or a concatenation. It cannot be a memory element (array reference) or a bit-select or a partselect of a vector register or non-expanded vector net. A force procedural statement to a register overrides a procedural assignment or procedural continuous assignment that takes place on the register until a release procedural statement is executed on the register. After the release procedural statement is executed, the register does not immediately change value (as would a net that is forced). The value specified in the force statement is maintained in the register until the next procedural assignment takes place, except in the case where a procedural continuous assignment is active on the register. A force procedural statement on a net overrides all drivers of the net—gate outputs, module outputs, and continuous assignments—until a release procedural statement is executed on the net. Releasing a register that currently has an active assign will re-establish the assign statement. The reason for having a two-level override system for registers is that assign-deassign is meant for actual descriptions of hardware, and the force-release is meant for debugging purposes. Example 11-2 shows part of a log file from a simulation that included interactively entered force and release procedural statements. Verilog HDL LRM Procedural Continuous Assignments • 152 Example 11- 2: Use of force and release In Example 11-2, an AND gate is “patched” as an OR gate by a force procedural statement that forces its output to the value of its ORed inputs, and an assign procedural statement of ANDed values is “patched” as an assign procedural statement of ORed values. Verilog HDL LRM Procedural Continuous Assignments • 153 Hierarchical Structures 12.0 Hierarchical Structures Overview The Verilog HDL supports a hierarchical hardware description structure by allowing modules to be embedded within other modules. Higher-level modules create instances of lower-level modules and communicate with them through input, output, and bidirectional ports. These module input/output ports can be scalar or vector. As an example of a module hierarchy, consider a system consisting of printed circuit boards. The system would be represented as the top-level module and would create instances of modules that represent the boards. The board modules would, in turn, create instances of modules that represent ICs, and the ICs could, in turn, create instances of modules that represent predefined cells such as flip-flops, mux’s, and alu’s. To describe a hierarchy of modules, the user provides textual definitions of the various modules. Each module definition stands alone; the definitions are not nested. Statements within the module definitions create instances of other modules, thus describing the hierarchy. 12.1 Modules This section gives the formal syntax for a module definition and then gives the syntax for module instantiation, along with an example of a module definition and a module instantiation. A module definition is enclosed between the keywords module and endmodule, where the <IDENTIFIER> after module gives the name of the module. The optional <list_of_ports> specifies an ordered list of the module’s IO ports. The order used can be significant when instantiating the module (see Section 12.1.2 Module Instantiation). The identifiers in this list must be declared in input, output, and inout statements within the module definition. The <module_items> define what constitutes a module, and include many different types of declarations and definitions; many of them have already been introduced. <module> ::= module <name_of_module><list_of_ports>? ; <module_item>* endmodule <name_of_module> ::=<IDENTIFIER> <list_of_ports> ::=(<port><,<port>>*) <module_item> ::=<parameter_declaration> ||=<input_declaration> ||=<output_declaration> Verilog HDL LRM Hierarchical Structures • 154 ||=<inout_declaration> ||=<net_declaration> ||=<reg_declaration> ||=<time_declaration> ||=<integer_declaration> ||=<real_declaration> ||=<event_declaration> ||=<gate_instantiation> ||=<primitive_instantiation> ||=<module_instantiation> ||=<parameter_override> ||=<continuous_assign> ||= <specify_block> ||=<initial_statement> ||=<always_statement> ||=<task> ||=<function> Syntax 12- 1: Syntax definitions for <module> See Section 12.4 Ports for the definitions of the syntax item <port>. See Section 12.1.3 Module Definition and Instance Example. 12.1.1 Top-Level Modules Top-level modules are modules that are included in the source text supplied as input to a particular simulation run, but are not instantiated, as described in Section 12.1.2 Module Instantiation. 12.1.2 Module Instantiation Instantiation allows one module to incorporate a copy of another module into itself. Module definitions do not nest. That is, one module definition cannot contain the text of another module definition within its module/endmodule keyword pair. A module definition nests another module by instantiating it. The <module_instantiation> statement creates one or more named instances of a defined module. For example, a counter module might instantiate a D flip-flop module to create eight instances of the flip-flop. The following is the syntax for specifying instantiations of modules: <module_instantiation> ::= <name_of_module> <parameter_value_assignment>? <module_instance> <,<module_instance>>* ; <name_of_module> Verilog HDL LRM Hierarchical Structures • 155 ::= <IDENTIFIER> <parameter_value_assignment> ::= # ( <expression> <,<expression>>* ) <module_instance> ::= <name_of_instance> ( <list_of_module_connections>? ) <name_of_instance> ::= <IDENTIFIER> <list_of_module_connections> ::= <module_port_connection> <,<module_port_connection>>* ||= <named_port_connection> <,<named_port_connection>>* <module_port_connection> ::= <expression> ||= <NULL> <named_port_connection> ::= .<IDENTIFIER> ( <expression> ) Syntax 12- 2: Definitions for <module_instantiation> The definition for <named_port_connection> includes an <IDENTIFIER> token that can be satisfied only with a port name from the definition of the module being instantiated. See Section 12.4.4 Connecting Module Ports by Name for more details. 12.1.3 Module Definition and Instance Example The code in Example 12-1 illustrates a circuit (the lower-level module) being driven by a simple waveform description (the higher-level module) where the circuit module is instantiated inside the waveform module. // THE LOWER-LEVEL MODULE: //module description of an and flip-flop circuit module ffnand (q, qbar, preset, clear); output q, qbar; //declares 2 circuit output nets input preset, clear; //declares 2 circuit input nets nand // declaration of two nand gates and // their interconnections g1 (q, qbar, preset), g2 (qbar ,q, clear); Verilog HDL LRM Hierarchical Structures • 156 endmodule // THE HIGHER-LEVEL MODULE: //a wave form description for the nand flip-flop module ffnand_wave; wire out1, out2; //outputsfromthecircuit reg in1, in2; //variablestodrivethecircuit // instantiate the circuit ffnand, name it "ff", // and specify the IO port interconnections ffnandff (out1, out2, in1, in2); // define the wave form to stimulate the circuit parameter d=10; initial begin #d in1 = 0; in2 = 1; #d in1 = 1; #d in2 = 0; #d in2 = 1; end endmodule Example 12- 1: Module definition and instantiation One or more module instances (identical copies of a module) can be specified in a single module instantiation statement. Example 12-2 illustrates this statement. The list of module terminals is provided only for modules defined with terminals. The parentheses, however, are always required. When a list of module terminals is given, the first element in the list connects to the first port, the second to the second port, and so on. See Section 12.4 Ports for a more detailed discussion of ports and port connection lists. A terminal can be a simple reference to a variable, an expression, or blank. An expression can be used for supplying a value to a module input port. A blank module terminal represents the situation where the IO port is not to be connected (blanks are not allowed when connecting ports by name). The code in Example 12-2 creates two instances of the flip-flop module ffnand defined above, and connects only to the q output in one instance and only to the qbar output in the other instance. //a wave form description for testing the nand flip-flop //without the outputs module ffnand_wave; reg in1, in2; //variables to drive the circuit //make two copies of the circuit ffnand //and connect to one output for each ffnand Verilog HDL LRM Hierarchical Structures • 157 ff1 (out1, , in1, in2), ff2(, out2, in1, in2); //define the waveform to stimulate the circuit parameter d=10; initial begin #d in1 = 0; in2 = 1; #d in1 = 1; #d in2 = 0; #d in2 = 1; end endmodule Example 12- 2: Instantiation with unconnected ports 12.2 Overriding Module Parameter Values When one module instantiates another module, it can alter the values of any parameters declared within the instantiated module. There are two ways to alter parameter values: the defparam statement, which allows assignment to parameters using their hierarchical names, and module instance parameter value assignment, which allows values to be assigned inline during module instantiation. The next two sections describe these two methods. 12.2.1 defparam Statement Using the defparam statement, parameter values can be changed in any module instance throughout the design using the hierarchical name of the parameter. The defparam statement is particularly useful for grouping all of the parameter value override assignments together in one module. The code in Example 12-3 illustrates the use of a defparam. module top; reg clk; reg [0:4] in1; reg [0:9] in2; wire [0:4] o1; wire [0:9] o2; vdff m1 (o1, in1, clk); vdff m2 (o2, in2, clk); endmodule module vdff (out, in, clk); parameter size = 1, delay = 1; input [0:size-1] in; Verilog HDL LRM Hierarchical Structures • 158 input clk; output [0:size-1] out; reg [0:size-1] out; always @(posedge clk) # delay out = in; endmodule module annotate; defparam top.m1.size = 5, top.m1.delay = 10, top.m2.size = 10, top.m2.delay = 20; endmodule Example 12- 3: Use of defparam statement The expressions on the right-hand side of the defparam assignments must be constant expressions involving only numbers and references to parameters. The referenced parameters (on the right-hand side of the defparam) must be declared in the same module as the defparam statement. The modules top and annotate would both be considered top-level modules. 12.2.2 Module Instance Parameter Value Assignment An alternative method for assigning values to parameters within module instances is similar in appearance to the assignment of delay values to gate instances. It uses the syntax # (<expression> <,<expression>>*) to supply values for particular instances of a module to any parameters that have been specified in the definition of that module. Consider Example 12-4, where the parameters within module instance mod_a are changed during instantiation. The name of the module being instantiated is vdff. The construct #(10,15) assigns values to parameters used in the mod_a instance of vdff. module m; reg clk; wire [1:10 ]out_a, in_a; wire [1:5] out_b, in_b; // create an instance and set parameters vdff #(10, 15) mod_a (out_a, in_a, clk); // create an instance leaving default values vdff mod_b(out_b, in_b, clk); endmodule Verilog HDL LRM Hierarchical Structures • 159 module vdff (out, in, clk); parameter size = 1, delay = 1; input [0:size-1] in; input clk; output [0:size-1] out; reg [0:size-1] out; always @(posedge clk) # delay out = in; endmodule Example 12- 4: Setting parameters during instantiation The order of the assignments in module instance parameter value assignment follows the order of declaration of the parameters within the module. In the example above, size is assigned the value 10 and delay is assigned the value 15 for the instance of module vdff called mod_a. It is not necessary to assign values to all of the parameters within a module when using this method. However, it is not possible to skip over a parameter. This means that if you want to assign values to a subset of the parameters declared within a module, then the declarations of the parameters that make up this subset must precede the declarations of the parameters to which you do not want to assign values. An alternative is to assign values to all of the parameters, but use the default value (the same value assigned in the declaration of the parameter within the module definition) for those parameters that you do not want to affect. 12.2.3 Parameter Dependence A parameter (for example, memory_size) can be defined with an expression containing another parameter (for example, word_size). Since memory_size depends on the value of word_size, a modification of word_size changes the value of memory_size. For example, in the following parameter declaration, an update of word_size, whether by defparam or in an instantiation statement for the module that defined these parameters, automatically updates memory_size. parameter word_size = 32, memory_size = word_size * 4096; 12.3 Macro Modules The Verilog language includes a construct called a macro module. A macro module serves the same functions as a standard module, but because it conforms to certain limitations, it can simulate much faster in some implementations. When the simulator compiles an instance of a macro module, it merges the macro module definition with the definition of the module that contains the macro instance. It creates no name scope and makes no port connections. Instead, it places the macro definition at the same Verilog HDL LRM Hierarchical Structures • 160 hierarchical level as the containing module. This process is called macro module expansion. A compiled macro module instance is said to be expanded. 12.3.1 Specifying Macro Modules Macro modules are specified by using the keyword macromodule in place of the keyword module in the module definition. Example 12-5 defines a macro module called NAND2. macromodule NAND2 (q, a, b); output q; input a, b; nand (q,a,b); endmodule Example 12- 5: Defining a macro module 12.3.2 Instances of Macro Modules Instances of macro modules are specified in exactly the same way as instances of normal modules. 12.4 Ports Ports provide a means of interconnecting a hardware description consisting of modules, primitives, and macro modules. For example, module A can instantiate module B, using port connections appropriate to module A. These port names can differ from the names of the internal nets and registers specified in the definition of module B, but the connection is still made. 12.4.1 Port Definition The syntax for a port is given below (this is the completion of the syntax presented in Section 12.1 Modules). <port> : :=<port_expression>? ||=.<name_of_port>( <port_expression>? ) <port_expression> ::=<port_reference> ||={ <port_reference> <,<port_reference>>* } <port_reference> ::= <name_of_variable> ||= <name_of_variable> [ <constant_expression> ] ||= <name_of_variable> [ <constant_expression> : <constant_expression> ] Verilog HDL LRM Hierarchical Structures • 161 <name_of_port> ::= <IDENTIFIER> Syntax 12- 3: Definitions for <port> The <port_expression> syntax item in the <port> definition can be one of the following: • a simple identifier • a bit-select of a vector declared within the module • a part-select of a vector declared within the module • a concatenation of any of the above Note that the <port_expression> is optional because ports can be defined that do not connect to anything internal to the module. Note also that the two types of module port connections cannot be mixed; connections to the ports of a particular module instance must be all by position or all by name. 12.4.2 Port Declarations Each port listed in the module definition’s <list_of_ports> must be declared in the body of the module as an input, output, or bidirectional inout. This is in addition to any other declaration for a particular port— for example, a net, reg, or wire. The syntax for port declarations is as follows: <input_declaration> ::=input<range>?<list_of_variables>; <output_declaration> ::=output<range>?<list_of_variables>; <inout_declaration> ::=inout<range>?<list_of_variables>; Syntax 12- 4: Definitions for <port_declarations> 12.4.3 Connecting Module Ports by Ordered List One method of making the connection between the ports listed in a module instantiation and the ports defined by the instantiated module is the ordered list—that is, the ports listed for the module instance are in the same order as the ports listed in the module definition. Example 12-6 illustrates a top-level module (topmod) that instantiates a second module (modB). Module modB has ports that are connected by an ordered list. The connections made are as follows: Verilog HDL LRM Hierarchical Structures • 162 • Port wa in the modB definition connects to the bit-select v[0] in the topmod module. • Port wb connects to v[3]. • Port c connects to w. • Port d connects to v[4]. In the modB definition, ports wa and wb are declared as inouts while ports c and d are declared as input. module topmod; wire [4:0] v; wire a, b, c, w; • . • . • . modB b1 (v[0], v[3], w, v[4]); • . • . • . endmodule module modB (wa, wb, c, d); inout wa, wb; input c, d; tranif1 g1(wa, wb, cinvert); not #(2, 6) (cinvert, int); and #(6, 5) g2 (int, c, d); endmodule Example 12- 6: Port connections using ordered list During simulation of the b1 instance of modb, the and gate activates first to produce a value on int. This value triggers the not gate to produce output on cinvert, which then activates the tranif1 gate g1. 12.4.4 Connecting Module Ports by Name The second way to connect module ports consists of explicitly linking the two names for each side of the connection—the name used in the module definition, followed by the name used in the instantiating module. This compound name is then placed in the list of module connections. The following is the syntax for connection by name: Verilog HDL LRM Hierarchical Structures • 163 .<name_of_port>(<port_expression>?) The <name_of_port> is the name specified in the module definition. The <name_of_port> cannot be a bit select, part select, or a concatenation of ports. The <port_expression> is the name used by the instantiating module and can be one of the following: • a simple identifier • a bit-select of a vector declared within the module • a part-select of a vector declared within the module • a concatenation of any of the above The <port_expression> is optional so that the instantiating module can document the existence of the port without connecting it to anything. The parentheses are not optional. In the following example, the instantiating module connects its signals topA and topB to the ports In1 and Out defined by the module ALPHA. At least one port provided by ALPHA is unused; it is named In2. There could be other unused ports not mentioned in the instantiation. ALPHA instance1 (.Out(topB),.In1(topA),.In2()); Example 12-7 defines the modules modB and topmod and then topmod instantiates modB using ports connected by name. module topmod; wire [4:0] v; wire a, b, c, w; modB b1 (.wb(v[3]), .wa(v[0]), .d(v[4]), .c(w)); endmodule module modB (wa, wb, c, d); inout wa, wb; input c, d; tranif1 g1(wa, wb, cinvert); not #(6, 2) (cinvert, int); and #(5, 6) g2(int, c, d) endmodule Example 12- 7: Connecting ports by name Note that because these connections are made by name, the order in which they appear is irrelevant. Verilog HDL LRM Hierarchical Structures • 164 12.4.5 Real Numbers in Port Connections The real data type cannot be directly connected to a port, but rather must be connected indirectly, as shown in Example 12-8. The system functions $realtobits and $bitstoreal are used for passing the bit patterns across module ports. (See Appendix B, B.8 Functions and Tasks for Reals, for a description of these system tasks.) module driver (net_r); output net_r; real r; wire [64:1] net_r = $realtobits(r); endmodule module receiver (net_r); input net_r; wire [64:1] net_r; real r; initial assign r = $bitstoreal(net_r); endmodule Example 12- 8: Connecting reals to a port 12.4.6 Port Collapsing A port of a module can be viewed as providing a link or connection between two items (nets, registers, expressions, and so on)—one internal to the module instance and one external to the module instance. Wherever it is possible, the some tools collapse port connections during processing—that is, the two items become one entity. Both names continue to exist for reference purposes, but, internally, the simulator eliminates one of the items. This corresponds to the physical case where a net described at two levels of a Verilog HDL hierarchy is actually just one wire. Examination of the port connection rules described below will show that the item receiving the value of the port (the inside item for inputs, the outside item for outputs) must be a net. The item which provides the value can be any expression, but port collapsing is only possible if both items are nets. Expressions such as (a+b) as the outside item in a module port connection preclude collapsing of that port. 12.4.7 Port Connection Rules The following rules govern the way module ports are declared and the way they are interconnected: Rule 1: An input or inout port must be declared as a net type. Rule 2: Verilog HDL LRM Hierarchical Structures • 165 Each port connection is a continuous “assignment” of source to sink, where one connected item is a signal source and the other is a signal sink. Only nets are permitted to be the sinks in an assignment. Both scalar and vector nets are permitted. The output and input ports of a module are by definition connected to signal source items internal to the module. The following external items cannot be connected to the output or input ports of modules: • registers • expressions other than: • a scalar net • a vector net • a constant bit select of a vector net • a part select of a vector net • a concatenation of the expressions listed above In port collapsing, the two items that are connected through a module port—one being external to the module, the other being internal to the module—are merged into a single item. Not every port can be collapsed. The following rule defines when port collapsing occurs: Rule 3: A module port is collapsed only if: • the port connects two nets, and • the connected nets are either both scalars or have the same vector size. Vector nets are split into scalar bits in order to increase the amount of port collapsing that occurs in a circuit. Splitting causes a vector net to be internally represented as a collection of scalars, thus allowing Rule 3 to be applied. This occurs whenever the items on both sides of the port are nets, and at least one of them is a bit select or part select of a vector net or the net is specified with the keyword scalared. Given Rule 3, it is clear that only ports that connect nets can be collapsed. But what happens if the nets on either side of the port are of different net types—for example, one is a triand and the other is a tri? When different net types are connected through a module port and the port can be collapsed, the resulting net type is determined based on Rule 4. In Rule 4, the term “dominating net type” is used in the following sense: A net type A “dominates” a net type B if, with identical signal sources on the two net types, either (a) the state on B is the same as that on A or (b) the state on B is not completely known but does not conflict with the state on A (for example, X does not conflict with 1 or 0; H does not conflict with Z or 1; and so on). Rule 4: When the two nets connected by a collapsed port are of different net type, the resulting single net is assigned one of the following: Verilog HDL LRM Hierarchical Structures • 166 • the dominating net type if one of the two nets is “dominating”, or else • the net type external to the module. When a dominating net type does not exist, the external net type is used. Table 12-1 shows the net type dictated by Rule 4 as a result of collapsing a module port that connects two nets. The simulated net takes the net type specified in the table plus the delay specified for that net. If the simulated net selected is a trireg, any strength value specified for the trireg applies to the simulated net. Table 12- 1: Net types resulting from port collapsing 12.5 Hierarchical Names Every identifier in a Verilog description has a unique hierarchical path name. The hierarchy of modules and the definition of items such as tasks and named blocks within the modules define these names. The hierarchy of names can be viewed as a tree structure, where each module instance, task, function, or named begin-end or fork-join block defines a new hierarchical level, or scope, in a particular branch of the tree. At the top of the name hierarchy are the names of modules of which no instances have been created. It is the root of the hierarchy. Inside any module, each module instance, task definition, Verilog HDL LRM Hierarchical Structures • 167 function definition, and named begin-end or fork-join block defines a new branch of the hierarchy. Named blocks within named blocks and within tasks and functions also create new branches. Each node in the hierarchical name tree is a separate scope with respect to identifiers. A particular identifier can be declared at most once in any scope. See Section 12.6 Scope Rules, for a discussion of scope rules. Any named Verilog object can be referenced uniquely in its full form by concatenating the names of the modules, tasks, functions, or blocks that contain it. Use the period character to separate each of the names in the hierarchy. The complete path name to any object starts at a top-level module. This path name can be used from any level in the description. The first node name in this path name can also be the top of a hierarchy that starts at the level where the path is being used. The code in Example 12-9 defines a hierarchy of module instances and named blocks. Figure 12-1 illustrates the hierarchy implicit in this Verilog code. Figure 12-2 is a list of the hierarchical forms of the names of all the objects defined in the code. module mod ( in ); input in; always @ ( posedge in ) begin :keep reg hold; hold = in; end endmodule module cct (stim1, stim2); input stim1, stim2; // instantiate mod modamod (stim1), bmod (stim2); endmodule module wave; reg stim1, stim2; // instantiate cct ccta (stim1, stim2); initial begin :wave1 #100 fork :innerwave reg hold; join #150 begin stim1=0; Verilog HDL LRM Hierarchical Structures • 168 end end endmodule Example 12- 9: A hierarchy of module instances and named blocks Figure 12- 1: Hierarchy in a model The following list gives the hierarchical path names for all the objects in the preceding description (Example 12-9): wave wave.stim1 wave.stim2 wave.a wave.a.stim1 wave.a.stim2 wave.a.amod wave.a.amod.in wave.a.amod.keep wave.a.amod.keep.hold wave.a.bmod wave.a.bmod.in wave.a.bmod.keep wave.a.bmod.keep.hold wave.wave1 wave.wave1.innerwave wave.wave1.innerwave.hold Figure 12- 2: Hierarchical path names in a model Hierarchical name referencing allows free data access to any object from any level in the hierarchy. If the unique hierarchical path name of an item is known, its value can be sampled or changed from anywhere within the description. Example 12-10 shows how a pair of named blocks can refer to items declared within each other. Verilog HDL LRM Hierarchical Structures • 169 begin fork :mod_1 reg x; mod_2.x = 1; • . • . • . join fork :mod_2 reg x; mod_1.x = 0; • . • . • . join end Example 12- 10: Using hierarchical names across blocks 12.5.1 Upwards Name Referencing The name of a module is sufficient to identify the module and its location in the hierarchy. A lower-level module can reference items in a module above it in the hierarchy if the name of the higher-level module is known. The syntax for an upward reference is as follows: <name_of_module>.<name_of_item> There can be no spaces within the reference. Example 12-11 demonstrates upward referencing. In this example, there are four modules, mod_a, mod_b, mod_c, and mod_d. Each module contains an integer x. The highest-level modules in this segment of a model hierarchy are mod_a and mod_d. There are two copies of module mod_b.x because both mod_a and mod_d both instantiate mod_b.x. There are four copies of mod_c.x because each of the two copies of mod_b.x instantiates mod_c.x twice. module mod_a; integer x; mod_b inst_b1(); endmodule module mod_b; integer x; mod_c inst_c1(), inst_c2(); Verilog HDL LRM Hierarchical Structures • 170 initial #10 inst_c1.x = 2; //downward path //references 2 copies of x: //mod_a.inst_b1.inst_c1.x //mod_d.inst_b1.inst_c1.x endmodule module mod_c; integer x; initial begin x = 1; mod_b.x = 1; //local name references //4 copies of x: //mod_a.inst_b1.inst_c1.x //mod_a.inst_b1.inst_c2.x //mod_d.inst_b1.inst_c1.x //mod_d.inst_b1.inst_c2.x //upward path references 2 //copies of x: //mod_a.inst_b1..x //mod_a.inst_b1.inst_c2.x end endmodule module mod_d; integer x; mod_b inst_b1(); initial begin mod_a.x = 1; // full path name references each // copy of x mod_a.inst_b1.x = 2; mod_a.inst_b1.inst_c1.x = 3; mod_a.inst_b1.inst_c2.x = 4; mod_d.x = 5; mod_d.inst_b1.x = 6; mod_d.inst_b1.inst_c1.x = 7; mod_d.inst_b1.inst_c2.x = 8; end endmodule Example 12- 11: Upwards name referencing Verilog HDL LRM Hierarchical Structures • 171 12.6 Scope Rules The following four elements define a new scope in Verilog: • modules • tasks • functions • named blocks An identifier can be used to declare only one item within a scope. This rule means, for example, that it is illegal to declare two variables that have the same name, or to name a task the same as a variable within the same module, or to give a gate the same instance name as the name of the net connected to its output. If an identifier is referenced directly (without a hierarchical path) within a task, function, or named block, it must be declared either locally within the task, function, or named block, or within a module, task or named block that is higher in the same branch of the name tree that contains the task, function, or named block. If it is declared locally, then the local item is used; if not, then Verilog will search upward until it finds an item by that name or until it finds a module boundary. Searching crosses named block, task, and function boundaries, but not module boundaries. This fact means that tasks and functions can use and modify the variables within the containing module by name, without going through their ports. In Figure 12-3, each rectangle represents a local scope. The scope available to upward searching extends outward to all containing rectangles—with the boundary of the module A as the outer limit. Thus block G can directly reference identifiers in F, E, and A; it cannot directly reference identifiers in H, B, C, and D. Figure 12- 3: Scopes available to upward name referencing Verilog HDL LRM Hierarchical Structures • 172 Because of the upward searching, path names that are not strictly downward can be used, and will work. However, these should be avoided as they are confusing. Figure 12-4 shows an incompletely defined downward reference that compiles correctly. task t; reg r; begin :b // redundant assignments to reg r t.b.r = 0; //fully defined downward // reference t.r = 0; //poorly defined but // found by upward search end endtask Figure 12- 4: Incompletely defined downward reference Verilog HDL LRM Hierarchical Structures • 173 Specify Blocks 13.0 Specify Blocks Overview It is often necessary to assign delays to paths across a module—apart from any gate-level or other distributed delays specified inside that module. The delays assigned to paths across a module can apply in all conditions, or they can apply only under specified conditions. Section 13.2 Module Path Delays begins the discussion of delays that apply in all conditions. The type of delay that applies only under specified conditions is the state dependent path delay. Section 13.2.6 State Dependent Path Delays (SDPDs) discusses state dependent path delays. A block statement called the specify block is the vehicle for adding timing specifications to paths across a module. Bounded by the keywords specify and endspecify, each specify block must appear inside the module it modifies. It is inside the specify block that you do the following modeling tasks: • Describe various paths across the module. • Assign delays to those paths. • Perform timing checks to ensure that events occurring at the module inputs satisfy the timing constraints of the device described in the module. In the Verilog HDL, paths across a module are called module paths. To describe module paths, you must pair a module input with a module output. The module input can be unidirectional (an input) or bidirectional (an inout) and is referred to as the path source. Similarly, the module output can be unidirectional (an output) or bidirectional (an inout) and is referred to as the path destination. Syntax 13-1 demonstrates the specify block syntax. <specify_block> ::= specify <specify_item>* endspecify <specify_item> ::= <specparam_declaration> ||= <path_declaration> ||= <level_sensitive_path_declaration> ||= <edge_sensitive_path_declaration> ||= <sdpd> Syntax 13- 1: Syntax of specify block Example 13-1 demonstrates a specify block. specify Verilog HDL LRM Specify Blocks • 174 specparam tRise_clk_q=150, tFall_clk_q=200; specparam tSetup=70; (clk=>q)=(tRise_clk_q, tFall_clk_q); $setup(d, posedge clk, tSetup); endspecify Example 13- 1: Example of a specify block In Example 13-1, the first two lines following the keyword specify declare specify parameters, which are discussed in Section 13.1 Declaring Parameters in Specify Blocks. The line following the declarations of specify parameters describes a module path and assigns delays to that module path. The specify parameters employed determine the delay assigned to the module path. Section 13.2.3 Assigning Delays to Module Paths discusses assigning delays to module paths. The line preceding the keyword endspecify institutes one of the system timing checks, discussion of which are discussed further in Section 13.3. 13.1 Declaring Parameters in Specify Blocks The keyword specparam declares parameters within specify blocks—called specify parameters or specparams, to distinguish them from module parameters. Unlike specify parameters, module parameters are declared outside the specify block with the keyword parameter. Syntax 13-2 demonstrates the syntax for declaring specify parameters. <specparam_declaration> ::= specparam <list_of_param_assignments> ; <list_of_param_assignments> ::=<param_assignment><,<param_assignment>>* <param_assignment> ::=<<identifier> = <constant_expression>> Syntax 13- 2: Syntax of the specparam declaration Example 13-2 demonstrates specparam declarations. specify specparam tRise_clk_q = 150, tFall_clk_q = 200; specparam tRise_control=40, tFall_control = 50; endspecify Example 13- 2: Example of specparam declarations Verilog HDL LRM Specify Blocks • 175 In Example 13-2, the lines between the keywords specify and endspecify each declare two specify parameters. It is important not to confuse specparams (specify parameters) with parameters (module parameters). They are not interchangeable. Table 13-1 summarizes the differences between the two types of parameter declarations. Table 13- 1: Differences between specparams and parameters 13.2 Module Path Delays 13.2.0 Module Path Delay Overview The Verilog HDL can describe two types of delays: • module path delays, which describe the time it takes an event at a module path source (input or inout) to propagate to a module path destination (output or inout) • distributed delays, which specify the time it takes events to propagate through gates and nets inside the module. Figure 13-1 illustrates module path delays. Note that more than one source (A, B, C, and D) may have a module path to the same destination (Q). Verilog HDL LRM Specify Blocks • 176 Figure 13- 1: Module path delays Figure 13-2 illustrates distributed delays. Figure 13- 2: Distributed delays Here, the delay on the module path from input D to output Q = 22, while the sum of the distributed delays = 0 + 1 = 1. Therefore, an event on Q caused by an event on D will occur 22 time units after the event on D. Consider the example in Figure 13-3. Verilog HDL LRM Specify Blocks • 177 Figure 13- 3: Mixing module path delays and distributed delays In Figure 13-3, the delay on the module path from D to Q = 22, but the distributed delays along that module path now add up to 10 + 20 = 30. Therefore, an event on Q caused by an event on D will occur 30 time units after the event on D. This section focuses on module path delays. (See Section 6.15 Gate and Net Delays, for more information on distributed delays.) You must follow the two steps below to set up module path delays in specify blocks: 1. describe the paths 2. assign delays to those paths Syntax 13-3 demonstrates the syntax of the module path declaration. <path_declaration> ::= (<path_description>) = (<path_delay_value>); <path_description> ::= ( <specify_input_terminal_descriptor> => <specify_output_terminal_descriptor> ) ||= ( <list_of_path_inputs> *> <list_of_path_outputs> ) <path_delay_value> ::= <path_delay_expression> ||= ( <path_delay_expression>, <path_delay_expression> ) ||= ( <path_delay_expression>, <path_delay_expression>, <path_delay_expression> ) ||= ( <path_delay_expression>, <path_delay_expression>, <path_delay_expression>, <path_delay_expression>, <path_delay_expression>, <path_delay_expression> ) Syntax 13- 3: Syntax of the module path declaration Example 13-3 demonstrates module path declarations. specify (clk => q) = (tRise_clk_q, tFall_clk_q); (clr, pre *> q) = (tRise_control, tFall_control); endspecify Example 13- 3: Example of module path declarations Verilog HDL LRM Specify Blocks • 178 Example 13-3 contains two module path declarations. For more specific information on describing module paths, refer to Section 13.2.1 Describing Module Paths and Section 13.2.2 Declaring Multiple Module Paths in a Single Statement; to learn how to assign delays to module path descriptions, refer to Section 13.2.2 Declaring Multiple Module Paths in a Single Statement and Section 13.2.4 Specifying Transition Delays on Module Paths. 13.2.1 Describing Module Paths A module path is defined inside a specify block as a connection between a source signal and a destination signal. Module paths may connect any combination of vectors and scalars. However, there are two restrictions: 1. The module path source must be a net that is declared as a module input or inout. 2. The module path destination must be a net that is declared as a module output or inout and is driven only by a gate-level primitive. Figure 13-4 demonstrates these restrictions: Figure 13- 4: Signals that do not follow the rules for module paths Implementation Specific Detail: Some implementations may place restrictions on the module path source and destination declarations. Syntax 13-4 demonstrates the syntax of the module path description. <path_description> ::= ( <specify_input_terminal_descriptor> => <specify_output_terminal_descriptor> ) ||= ( <list_of_path_inputs> *> <list_of_path_outputs> ) <specify_input_terminal_descriptor> ::= <input_identifier> Verilog HDL LRM Specify Blocks • 179 ||= <input_identifier> [ <constant_expression> ] ||= <input_identifier> [ <constant_expression> : <constant_expression> ] <specify_output_terminal_descriptor> ::= <output_identifier> ||= <output_identifier> [ <constant_expression> ] ||= <output_identifier> [ <constant_expression> : <constant_expression> ] <input_identifier> ::= the <IDENTIFIER> of a module input or inout terminal <output_identifier> ::= the <IDENTIFIER>of a module input or inout terminal Syntax 13- 4: Syntax for the module path description Example 13-4 demonstrates module path descriptions. (in1*>q) (s=>q) Example 13- 4: Module path descriptions Example 13-4 demonstrates two ways to describe module paths: 1. source *> destination 2. source => destination The symbols *> and => each represent a different kind of connection between the module path source and the module path destination. The operator *> establishes a full connection between source and destination. In a full connection, each bit in the source connects to every bit in the destination. The module path source need not have the same number of bits as the module path destination. The operator => sets up a parallel connection between source and destination. In a parallel connection, each bit in the source connects to its one corresponding bit in the destination. You can create parallel module paths only between sources and destinations that contain the same number of bits. Table 13-2 illustrates how a parallel connection differs from a full connection between two 4-bit vectors. Verilog HDL LRM Specify Blocks • 180 Table 13- 2: The difference between parallel and full connections between vectors of equal size The full connection will handle most types of module paths, since it does not restrict the size or number of source signals and destination signals. Here are the situations in which you must use *> to set up full connections: • to describe a module path between a vector and a scalar • to describe a module path between vectors of different sizes • to describe a module path with multiple sources or multiple destinations in a single statement (see Section 13.2.2 Declaring Multiple Module Paths in a Single Statement, for more details) In Example 13-4 the module path from s to q uses *> because it connects a scalar source—the 1bit select line—to a vector destination—the 8-bit output bus. Parallel connections are more restrictive than full connections. They only connect one source to one destination, where each signal contains the same number of bits. Therefore, the one special case in which you must use => to set up a parallel connection is to describe a module path between two vectors of the same size. Since scalars are one bit wide, you may use either *> or => to set up bit-to-bit connections between two scalars. Note that in Example 13-4 the module paths from both input lines In1 and In2 to q use => because they set up parallel connections between two 8-bit busses. Figure 13-5 summarizes the guidelines for using *> and =>. Use *> for full connections: Verilog HDL LRM Specify Blocks • 181 • between one vector and one scalar • between two vectors of the same size or different sizes • between multiple sources or multiple destinations in a single statement Use => for parallel connections: • between two scalars • between two vectors of the same size Figure 13- 5: Guidelines for describing module paths Figure 13-6 summarizes the rules to follow when describing module paths. Rules for describing module paths: Rule 1: Paths must be described inside specify blocks. Rule 2: A path source must be a module input net or module inout net that is either scalar or vector. Rule 3: A path destination must be an output net or inout net that is either scalar or vector and is driven only by a gate-level primitive that is not a bidirectional transfer gate. Rule 4: Path destinations may have only one driver inside the module. Rule 5: Follow the guidelines in Figure 13-5 for using *> and => . Figure 13- 6: Rules for describing module paths As rule 4 states, module path output nets may not have multiple drivers within the module. Refer to Section 13.2.7 Driving Wired Logic for a discussion of how to work around this limitation. 13.2.2 Declaring Multiple Module Paths in a Single Statement You can define multiple module paths in a single statement by using the symbol *> to connect a list of sources separated by commas to a list of destinations separated by commas. Here is an example: (a, b, c *> q1, q2) = 10; This statement is equivalent to the following six individual module path assignments in Example 13-5: (a *> q1) = 10 ; (b *> q1) = 10 ; Verilog HDL LRM Specify Blocks • 182 (c *> q1) = 10 ; (a *> q2) = 10 ; (b *> q2) = 10 ; (c *> q2) = 10 ; Example 13- 5: Module path equivalents of single statement When describing multiple module paths in one statement, the lists of sources and destinations may contain a mix of scalars and vectors of any size. However, all sources must be net inputs or inouts, and all destinations must be net outputs or inouts that follow the restrictions given in Section 13.2.1 Describing Module Paths. As the use of *> implies, the connection in a multiple module path declaration is always a full connection. 13.2.3 Assigning Delays to Module Paths You can specify the delays that occur at the module outputs where paths terminate by assigning delay values to the module path descriptions. In module path delay assignments, a module path description appears on the left-hand side, and one or more delay values appear on the right-hand side. Delay values can be constant expressions that contain literals or specparams. Syntax 13-5 demonstrates the syntax of the module path delay assignment. <path_declaration> ::= <path_description> = <path_delay_value>; <path_delay_value> ::= <path_delay_expression> ||= ( <path_delay_expression>, <path_delay_expression> ) ||= ( <path_delay_expression>, <path_delay_expression>, <path_delay_expression> ) ||= ( <path_delay_expression>, <path_delay_expression>, <path_delay_expression>, <path_delay_expression>, <path_delay_expression>, <path_delay_expression> ) <path_delay_expression> ::= <constant_mintypmax_expression> Syntax 13- 5: Syntax for specifying module path delays Verilog HDL LRM Specify Blocks • 183 Example 13-6 demonstrates module path delay assignments. specify specparam tRise_clk_q=45:150:270, tFall_clk_q=60:200:350; specparam tRise_Control=35:40:45, tFall_control=40:50:65; (clk=>q)=(tRise_clk_q,tFall_clk_q); (clr,pre*>q)=(tRise_control,tFall_control); Example 13- 6: Example of module path delay assignments In Example 13-6, the specify parameters declared following the specparam keyword specify module path delays. The module path assignments assign those module path delays to the module paths. 13.2.4 Specifying Transition Delays on Module Paths You can assign delay values independently for each of the six output transitions between 0, 1, and Z. As Syntax 13-5 illustrates, delays must be specified as a list of one, two, three, or six <path_delay_expressions> separated by commas. Each <path_delay_expression> can be a single value—representing the typical delay—or a colonseparated list of three values—representing a minimum, typical, and maximum delay, in that order. The next four figures (Figure 13-7 through Figure 13-10) summarize the general syntax for each type of transition delay assignment statement. Figure 13- 7: How to assign one delay value for all transitions Verilog HDL LRM Specify Blocks • 184 Figure 13- 8: How to assign different delays for rising and falling transitions Figure 13- 9: How to assign different delays for rising, falling, and z transitions Verilog HDL LRM Specify Blocks • 185 Figure 13- 10: How to assign six different transition delays The order in which you specify delays for all six transitions in a single statement is based on the diagram in Figure 13-11. Figure 13- 11: Left-to-right order of the six transitions Any transition delay associated with a module path can be triggered at run time by the appropriate state change at the module path destination net. For instance, the usage example shown in Example 13-6 assigns one set of minimum:typical:maximum delays for the rising transitions and another set of minimum:typical:maximum delays for the falling transitions. Please note: Sources may only specify one delay or three. The format delay1:delay2 is illegal in a module path delay assignment. 13.2.5 Handling X Transitions Verilog has specific rules for handling module path delays for x transitions, based on other delays assigned to the module path. The following two x transitions are considered: 1. transition from a known state to x: 2. transition from x to a known state: x -> s Verilog HDL LRM s -> x Specify Blocks • 186 The calculation of delay values for x transitions is based on the following two pessimistic rules: 1. Transitions from a known state to x should occur as quickly as possible—that is, they receive the shortest possible delay. 2. Transitions from x to a known state should take as long as possible—that is, they receive the longest possible delay. Table 13-3 presents the general algorithm for calculating delay values for x transitions, along with specific examples. Table 13- 3: The algorithm for calculating delays for x transitions 13.2.6 State Dependent Path Delays (SDPDs) An SDPD makes it possible to assign a delay to a module path that affects signal propagation through the path only if specified conditions are true. SDPDs assist primarily in modeling small to medium-scale modules because SDPDs function best in modules without distributed delays. Syntax Verilog HDL LRM Specify Blocks • 187 An SDPD includes the following items: • a conditional expression that enables assignment if true • a module path description • a delay expression that applies to the module path Syntax 13-6 presents the syntax for the SDPD. <sdpd> ::=if(<sdpd_conditional _expression>)(<path_description>)=(<path_delay_value>) <sdpd_conditional_expression> ::=(<expression><BINARY_OPERATOR><expression>) ||=(<UNARY_OPERATOR><expression>) <path_description> ::= (<specify_input_terminal_descriptor> => specify_output_terminal_descriptor>) ||= (<list_of_path_inputs> *> <list_of_path_outputs>) <path_delay_value> ::=<path_delay_expression> ||=(<path_delay_expression>,<path_delay_expression>) ||=(<path_delay_expression>,<path_delay_expression>, <path_delay_expression>) ||=(<path_delay_expression>,<path_delay_expression>, <path_delay_expression>,<path_delay_expression>, <path_delay_expression>,<path_delay_expression>) Syntax 13- 6: Syntax of the SDPD The SDPD conditional expression The operands in the SDPD conditional expression must be one of the following: • scalar or vector module input or inout ports in their entirety or in bit-select or part-select form • compile time constants The following is a list of the valid operators in SDPD expressions: ~ bit-wise negation & bit-wise AND | bit-wise OR ^ bit-wise XOR Verilog HDL LRM Specify Blocks • 188 ~^ bit-wise XNOR & reduction AND ~& reduction NAND | reduction OR ^ reduction XOR ~^ reduction XNOR ~| reduction NOR == logical equality != logical inequality && logical AND || logical OR ! logical NOT {} concatenation {{}} duplicate concatenation ?: conditional An SDPD conditional expression must evaluate to one bit. The Verilog HDL treats the results X and Z as TRUE to facilitate signal propagation. The SDPD conditional expression may have any number of operands and operators. Examples Consider the use of an SDPD in describing an XOR in Example 13-7. module sdpdexample (a, b, out); input a,b: output out; xor (out, a, b); specify specparam noninvrise = 1, noninvfall = 2 specparam invertrise = 3, invertfall = 4; Verilog HDL LRM Specify Blocks • 189 if(a) (b=>out) = (invertrise, invertfall); if(~a) (b=>out) = (noninvrise, noninvfall); if(b) (a=>out) = (invertrise,invertfall); if(~b) (a=>out) = (noninvrise,noninvfall); endspecify endmodule Example 13- 7: SDPD XOR example In Example 13-7, SDPDs allow you to describe a pair of output rise and fall delay times when the XOR inverts a changing input. When the XOR buffers a changing input, SDPDs allow you to describe another pair of output rise and fall delay times. Example 13-8 models a partial ALU. SDPDs specify different sets of path delays for different ALU operations. `timescale 1ns / 100ps module ALU(o1, I1, I2, opcode); input [7:0] I1, i2; input [2:1] opcode; output [7:0] o1; //functional description omitted specify // add operation if (opcode == 2'b00) (i1,i2 *> o1) = (25.0,25.0); // pass-through i1 operation if (opcode == 2'b01) (i1 => o1) = (5.6,8.0); // pass-through i2 operation if (opcode == 2'b10) (i2 => o1) = (5.6,8.0); // delays on opcode changes (opcode => o1) = (6.1,6.5); endspecify endmodule Example 13- 8: ALU operations with different path delays Verilog HDL LRM Specify Blocks • 190 In this example, the first three path declarations declare paths extending from operand inputs to the o1 output. The delays on these paths are assigned to operations on the basis of the operation specified by the inputs on opcode. The last path declaration declares a path from the opcode input to the o1 output. Multiple path delays When the same output terminates multiple paths, some combinations of module path declarations that include that output can cause unexpected modeling results. If more than one SDPD can apply to a path, you must write the SDPDs so that only one applies to the path at a time. An unconditional path delay is like an SDPD whose conditional expression always is enabled, so it is not appropriate to specify an SDPD and an unconditional path delay for the same path. Even if you follow these guidelines, there is a situation in which models may not replicate hardware behavior, shown in Figure 13-12. Figure 13- 12: Internal logic disabling a possible output change In Figure 13-12, the output change occurs at 40 in response to the change on input B. An output change at 20 in response to the change on input A may model the hardware under study more correctly. This choice occurs because the times of output changes are scheduled when an edge initially propagates to a module output. The transition on input A occurs later than the transition on input B, and does not cause a change in the value of the signal propagating from the internal logic. Consequently, the transition on input A does not initiate any scheduling of an output event. Distributed delays and SDPDs Verilog HDL LRM Specify Blocks • 191 For realistic modeling, larger modules tend to necessitate gate and net delays, and behavioral models require procedural delays. These delays can have an undesirable impact on the choice of path delays, which you can avoid by following this rule: Larger cells and modules that require distributed delays and SDPDs should meet this test: the inputs should not change before an edge generated by the most recent input change has propagated to the outputs. This rule exists because a choice among path delays occurs when an edge initially arrives at an output, and distributed delays retard the initial arrival of the edge at an output. If the input state is a component of an SDPD conditional expression that specifies a delay for the path that the edge follows, a change in the input state before the choice of a delay can result in the choice of an inappropriate delay. The situation described in this case can also lead to output values that do not accurately model hardware. When you apply the following pairs of delays to a path, the larger of the two delays schedules the appearance of an output change: • a distributed delay and an unconditional delay • a distributed delay and an SDPD 13.2.7 Driving Wired Logic Module path output nets may not have more than one driver within the module. Therefore, wired logic is not allowed at module path outputs. Figure 13-13 and Figure 13-14 illustrate two violations of this rule. Figure 13- 13: Illegal module paths: Two module path outputs with multiple output drivers In Figure 13-13, any module path to Q or R is illegal. Figure 13- 14: Illegal module paths: One module path output with multiple output drivers Verilog HDL LRM Specify Blocks • 192 In Figure 13-14, any module path to S is illegal. Assuming signal S in Figure 13-14 is a wired AND, you can circumvent this limitation by replacing wired logic with gated logic to create a single driver to the output. Figure 13-15 shows how adding a third AND gate—the shaded one—solves the problem for the module in Figure 1314. Figure 13- 15: Legal module paths: One output driver Note, however, that although multiple output drivers are prohibited inside the module, they are allowed outside the module, as in Figure 13-16. Figure 13- 16: Legal module paths: Multiple output drivers outside the module Here, all module paths to R and all paths to Q are legal. 13.2.8 Module Path Polarity The polarity of a module path determines how a signal transition at its source propagates to its destination when there are no logic simulation events. Polarity has no effect on the scheduling of simulation events; a timing analysis tool can use polarity when performing path tracing. Module paths can exhibit any of three polarities: 1. unknown 2. positive Verilog HDL LRM Specify Blocks • 193 3. negative Unknown polarity By default, module paths have unknown polarity—that is, a transition at the path source propagates to the destination in an unpredictable way, as follows: • A rise at the source causes either a rise or a fall at the destination. • A fall at the source causes either a rise or a fall at the destination. Whether a rise or a fall propagates to the destination depends on the states of the module’s other inputs and internal logic. By contrast, in module paths with known polarity—either positive or negative—the signal transition at the source directly determines the signal transition at the destination. Positive polarity For module paths with positive polarity, any transition at the source causes the same transition at the destination, as follows: • A rise at the source always causes a rise at the destination. • A fall at the source always causes a fall at the destination. Negative polarity Conversely, in module paths with negative polarity, any transition at the source causes the opposite transition at the destination, as follows: • A rise at the source always causes a fall at the destination. • A fall at the source always causes a rise at the destination. To set up module paths with positive polarity, add the prefix + to the connection operators *> and =>; for negative polarity, add the prefix -; for unknown polarity, add no prefix. The following examples show each type of path polarity: Example 13- 9: The three path polarity types Verilog HDL LRM Specify Blocks • 194 The first and second lines in Example 13-9 demonstrate positive polarity. The second and third lines demonstrate negative polarity. The last two lines demonstrate unknown polarity. In addition, you can assign the same polarity to multiple module paths in a single statement, as follows: Example 13- 10: Assigning one polarity to many paths in one statement In Example 13-10, the first line assigns positive polarity to six different paths. The second line assigns negative polarity to six different paths. 13.2.9 Qualified Paths A construct called a qualified path lets you set up conditions for dynamically controlling how state changes propagate through module paths. A brief discussion of qualified paths is presented here. There are two kinds of qualified paths: • level-sensitive • edge-sensitive Level-sensitive paths Level-sensitive paths depend on the state of one or more conditioning signals. Whenever the specified conditions are satisfied, changes will flow through the path; otherwise, the path is effectively broken. Level sensitive paths are also enabled when the specified conditions evaluate to unknown (x). Syntax 13-7 shows the syntax of the level-sensitive path declaration. <level_sensitive_path_declaration> ::=if (<conditional_port_expression>)(<specify_terminal_descriptor> <polarity_operator>?=><specify_terminal_descriptor>)= (<path_delay_value>); ||= if (<conditional_port_expression>) (<list_of_path_inputs> <polarity_operator>? *> <list_of_path_outputs>) = <path_delay_value>; <conditional_port_expression> ::=<port_reference ||=<UNARY_OPERATOR><port_reference> Verilog HDL LRM Specify Blocks • 195 ||=<port_reference><BINARY_OPERATOR><port_reference> Syntax 13- 7: Syntax of the level-sensitive path declaration Verilog HDL LRM Specify Blocks • 196 Note that you can use *> for full connections or => for parallel connections. In addition, you can specify polarity and declare more than one level-sensitive path in a single statement. Signals in the expression in Syntax 13-7 must be ports of the module that contains the path, but can be any combination of the following constructs: scalar or vector input and inout ports, or bitselects and part-selects of those ports. Example 13-11 demonstrates two level-sensitive path declarations without polarity operators that have the same meaning. if (clock == 1) (in => out) = (3:4:5); if (clock) (in => out) = (3:4:5); Example 13- 11: Level-sensitive path declarations without polarity operators The delay from in to out in this example will have the minimum, typical, or maximum value as selected if clock has a value of 1. Example 13-12 demonstrates two level-sensitive path declarations with polarity operators which have the same meaning: if (clock==0) (in+=>out) = 10; if (!clock) (in+=>out) = 10; Example 13- 12: Level-sensitive path declarations with polarity operators In Example 13-12, a rise at in causes a rise at out, and a fall at in causes a fall at out. The delay from in to out is 10 if the value of clock is 0. The following example declares multiple level-sensitive paths: if(!clock)(in1,in2*>out1,out2)=20; In this example, if the value of clock is 0, four paths have a delay of 20. Implementation Specific Detail: Some tools many not allow the assignment of different delays. Edge-sensitive paths The other type of qualified path is edge-sensitive. In edge-sensitive paths, the path source is an edge-triggered conditioning signal. Changes flow through an edge-sensitive path when the specified edge occurs at the conditioning signal. Syntax 13-8 shows the syntax of the edge sensitive path declaration. <edge_sensitive_path_declaration> Verilog HDL LRM Specify Blocks • 197 ::=<if (<expression>)>? (<edge_identifier>? <specify_terminal_descriptor>=> (<specify_terminal_descriptor> <polarity_operator> ?: <data_source_expression>))=<path_delay_value> ||=<if (<expression>)>? (<edge_identifier>? <specify_terminal_descriptor> *> (<list_of_path_outputs> <polarity_operator> ?: <data_source_expression>))=<path_delay_value> <edge_identifier> ::= posedge ||= negedge <data_source_expression> Any expression, including constants and lists. Its width must be one bit or equal to the destination's width. If the destination is a list, the data source must be as wide as the sum of the bits of the members. Syntax 13- 8: Syntax of the edge-sensitive path declaration The edge-sensitive path’s edge—given in Syntax 13-8 as the <specify_terminal_descriptor> to the left of the connection operator—can be any scalar input or inout port, or bit-select of that port. Since the edge must be one bit wide, you can specify edge-sensitive paths with full connections (*>) or parallel connections (=>), according to the rules for connection operators described in Section 13.2.1 Describing Module Paths. There are two ways to specify the path destination—the signal or signals to the left of the colon (:)—depending on the connection operator used: • For parallel connections (=>), the destination can be any scalar output or inout port, or one of its bit-selects. • For full connections (*>), the destination can be a list of one or more of the following signals: vector or scalar output and inout ports, and bit-selects or part-selects of those ports. Signals in the edge-sensitive path condition given in Syntax 13-8 as the <expression> following the literal “if”—can be any scalar signals or bit-selects. The following example demonstrates an edge-sensitive path declaration with a positive polarity operator: ( posedge clock => ( out +: in ) ) = (10, 8); In this example, at the positive edge of clock, a module path extends from clock to out using the rise delay (10) if in is 1 and the fall delay (8) if in is 0. The following example demonstrates an edge-sensitive path declaration with no polarity operator: ( clock => ( out : in ) ) = (10, 8); Verilog HDL LRM Specify Blocks • 198 In this example, at any change in clock, a module path extends from clock to out using the worst case delay, which is the rise delay (10), because no polarity is specified. The following example demonstrates an edge-sensitive path declaration with a negative polarity operator: ( negedge clock[0] => ( out -: in ) ) = (10, 8); In this example, at the negative edge of clock[0], a module path extends from clock[0] to out using the rise delay (10) if in is 0 and the fall delay (8) if in is 1. The following example demonstrates an edge-sensitive path declaration with a binary operation conditioning the delays: ( posedge clock*> ( ( out[0:3], out[4:7] ) +: in1 && in2 )) = (10, 8); In this example, at the positive edge of clock, a module path extends from clock to out[0:3], and from clock to out[4:7] using the rise delay (10) if (in1 && in2) is 1, and the fall delay (8) if (in1 && in2) is 0. The following example demonstrates an edge-sensitive path declaration preceded by a conditional expression: if ( !reset ) (posedge clock => ( out +: in ) ) = (10, 8); In this example, if the positive edge of clock occurs when reset is low, a module path extends from clock to out using the rise delay (10) if in is 1, and the fall delay (8) if in is 0. Note that conditions in edge-sensitive paths are optional and need not be ports. The preceding usage example shows a condition defined with one scalar signal. In Example 13-13, a condition combines two scalars. if ( !reset && !clear ) (posedge clock => ( out +: in ) ) = (10, 8) ; Example 13- 13: Edge-sensitive path with three conditions You can assign different delays to the same edge-sensitive path as long as the following criteria are met: • The edge, condition, or both make each declaration unique. • A signal is always referenced in the same way. Verilog HDL LRM Specify Blocks • 199 In Example 13-14, the following four edge-sensitive path declarations are legal because each one has a unique edge or condition, all edges and data sources are specified as scalar inputs, and all destinations are specified as bit selects of a vector output. specify (posedge clk => (q[0]:data))= (10, 5); (negedge clk => (q[0]:data)) = (20, 12); if (reset) (posedge clk => (q[0]:data)) = (15, 8); if (!reset && cntrl) (posedge clk => (q[0]:data)) = (6, 2); endspecify Example 13- 14: Four edge-sensitive path declarations To a timing analysis tool, the four declarations in Example 13-14 define a different set of delays for each of the four states affecting the path from clk to q[0]. However, a simulator does not care about the various states and instead uses the largest delays specified—in this case, a rise delay of 20 and a fall delay of 12. The two declarations in Example 13-15 are not legal because even though they have different conditions, the destinations are not specified in the same way: the first destination is a part-select, the second is a bit-select. Example 13- 15: Example of conflicting destination specifications Verilog HDL LRM Specify Blocks • 200 Formal Syntax Definition A.0 Syntax Overview The following items summarize the format of the formal syntax descriptions: 1. White space may be used to separate lexical tokens. 2. Angle brackets surround each description item and are not literal symbols—that is, they do not appear in a source example of a syntax item. 3. <name> in lower case is a syntax construct item defined by other syntax construct items or by lexical token items (see next item). 4. <NAME> in upper case is a lexical token item. Its definition is a terminal node in the description hierarchy—that is, its definition does not contain any syntax construct items. 5. <name>? is an optional item. 6. <name>* is zero, one or more items. 7. <name>+ is one or more items. 8. <name> <,<name>>* is a comma-separated list of items with at least one item in the list. 9. if [condition] is a condition placed on one of several definitions 10. <name> ::= gives a syntax definition to an item. 11. ||= introduces an alternative syntax definition. 12. name is a literal (a keyword). For example, the definition <event_declaration> ::= event <name_of_event> stipulates that the keyword “event” precedes the name of an event in an event declaration. 13. ( . . . ) places parenthesis symbols in a definition. These parentheses are literals required by the syntax being defined. Other literal symbols can also appear in a definition (for example, . and :). Please note: In Verilog syntax, a period (.) may not be preceded or followed by a space. A.1 Source Text <source_text> ::= <description>* <description> ::= <module> ||= <primitive> <module> ::= module <name_of_module> <list_of_ports>? ; <module_item>* endmodule Verilog HDL LRM Formal Syntax Definition • 201 ||= macromodule <name_of_module> <list_of_ports>? ; <module_item>* endmodule <name_of_module> ::= <IDENTIFIER> Defined in Section 2.5 Identifiers, Keywords, and System Names. <list_of_ports> ::= ( <port> <,<port>>* ) <port> ::= <port_expression>? ||= . <name_of_port> ( <port_expression>? ) <port_expression> ::= <port_reference> ||= { <port_reference> <,<port_reference>>* } <port_reference> ::= <name_of_variable> ||= <name_of_variable> [ <constant_expression> ] ||= <name_of_variable> [ <constant_expression> : <constant_expression> ] <name_of_port> ::= <IDENTIFIER> <name_of_variable> ::= <IDENTIFIER> <module_item> ::= <parameter_declaration> Defined in Section 3.11 Parameters. ||= <input_declaration> Defined in Section 12.4.2 Port Declarations. ||= <output_declaration> Defined in Section 12.4.2 Port Declarations. ||= <inout_declaration> Defined in Section 12.4.2 Port Declarations. ||= <net_declaration> Defined in Section 3.2.3 Declaration Syntax. ||= <reg_declaration> Defined in Section 3.2.3 Declaration Syntax. ||= <time_declaration> Defined in Section 3.9 Integers and Times. ||= <integer_declaration> Defined in Section 3.9 Integers and Times. ||= <real_declaration> Defined in Section 3.10.1 Declaration Syntax for Real Numbers. ||= <event_declaration> Defined in Section 8.6.2 Event Control. ||= <gate_declaration> Defined in Section 6.1 Gate and Switch Declaration Syntax. ||= <UDP_instantiation> Defined in Section 7.1 Syntax. ||= <module_instantiation> Defined in Section 12.1.2 Module Instantiation. ||= <parameter_override> Defined in Section 12.2 Overriding Module Parameter Values. ||= <continuous_assign> Defined in Section 5.1 Continuous Assignments. ||= <specify_block> Defined in Chapter 13, Specify Blocks. ||= <initial_statement> Defined in Section 8.8.1 initial Statement. ||= <always_statement> Defined in Section 8.8.2 always Statement. ||= <task> ||= <function> Verilog HDL LRM Formal Syntax Definition • 202 <UDP> ::= primitive <name_of_UDP> ( <name_of_variable> <,<name_of_variable>>* ) ; <UDP_declaration>+ <UDP_initial_statement>? <table_definition> endprimitive <name_of_UDP> ::= <IDENTIFIER> <UDP_declaration> ::= <output_declaration> Defined in Section 7.1 Syntax. ||= <reg_declaration> Defined in Section 7.1 Syntax. ||= <input_declaration> Defined in Section 7.1 Syntax. <UDP_initial_statement> ::= initial <output_terminal_name> = <init_val> ; <init_val> ::= 1’b0 ||= 1’b1 ||= 1’bx ||= 1 ||= 0 <table_definition> ::= table <table_entries> endtable <table_entries> ::= <combinational_entry>+ ||= <sequential_entry>+ <combinational_entry> ::= <level_input_list> : <OUTPUT_SYMBOL> ; <sequential_entry> ::= <input_list> : <state> : <next_state> ; <input_list> ::= <level_input_list> ||= <edge_input_list> <level_input_list> ::= <LEVEL_SYMBOL>+ <edge_input_list> ::= <LEVEL_SYMBOL>* <edge> <LEVEL_SYMBOL>* <edge> ::= ( <LEVEL_SYMBOL> <LEVEL_SYMBOL> ) ||= <EDGE_SYMBOL> <state> ::= <LEVEL_SYMBOL> <next_state> Verilog HDL LRM Formal Syntax Definition • 203 ::= <OUTPUT_SYMBOL> ||= - (This is a literal hyphen, see Chapter 7, User-Defined Primitives (UDPs), for details). <OUTPUT_SYMBOL> is one of the following characters: 0 1 x X <LEVEL_SYMBOL> is one of the following characters: 0 1 x X ? b B <EDGE_SYMBOL> is one of the following characters: r R f F p P n N * <task> ::= task <name_of_task> ; <tf_declaration>*<statement_or_null> endtask <name_of_task> ::= <IDENTIFIER> <function> ::= function <range_or_type>? <name_of_function> ; <tf_declaration>+ <statement> endfunction <range_or_type> ::= <range> Defined in Section 9.3.1 Defining a Function. ||= integer ||= real <name_of_function> ::= <IDENTIFIER> <tf_declaration> ::= <parameter_declaration> Defined in Section 3.11 Parameters. ||= <input_declaration> Defined in Section 12.4.2 Port Declarations. ||= <output_declaration> Defined in Section 12.4.2 Port Declarations. ||= <inout_declaration> Defined in Section 12.4.2 Port Declarations. ||= <reg_declaration> Defined in Section 3.2.3 Declaration Syntax. ||= <time_declaration> Defined in Section 3.9 Integers and Times. ||= <integer_declaration> Defined in Section 3.9 Integers and Times. ||= <real_declaration> Defined in Section 3.10.1 Declaration Syntax for Real Numbers. ||= <event_declaration> Defined in Section 8.6.2 Event Control. A.2 Declarations <parameter_declaration> ::= parameter <list_of_param_assignments> ; <list_of_param_assignments> ::=<param_assignment><,<param_assignment>* <param_assignment> ::=<<identifier> = <constant_expression>> Verilog HDL LRM Formal Syntax Definition • 204 <input_declaration> ::= input <range>? <list_of_variables> ; <output_declaration> ::= output <range>? <list_of_variables> ; <inout_declaration> ::= inout <range>? <list_of_variables> ; <net_declaration> ::= <NETTYPE> <expandrange>? <delay>? <list_of_variables> ; ||= trireg <charge_strength>? <expandrange>? <delay>? <list_of_variables> ; <NETTYPE> is one of the following keywords: wire tri tri1 supply0 wand triand tri0 supply1 wor trior trireg <expandrange> ::= <range> ||= scalared <range> ||= vectored <range> <delay> ::= Defined in Section 8.6.1 Delay Control. <reg_declaration> ::= reg <range>? <list_of_register_variables> ; <time_declaration> ::= time <list_of_register_variables> ; <integer_declaration> ::= integer <list_of_register_variables> ; <real_declaration> ::= real <list_of_variables> ; <event_declaration> ::= event <name_of_event> <,<name_of_event>>* ; <continuous_assign> ::= assign <drive_strength>? <delay>? <list_of_assignments> ; ||= <NETTYPE> <drive_strength>? <expandrange>? <delay>? <list_of_assignments> ; <parameter_override> ::= defparam <list_of_param_assignments> ; <list_of_variables> ::= <name_of_variable> <,<name_of_variable>>* <name_of_variable> ::= <IDENTIFIER> <list_of_register_variables> ::= <register_variable> <,<register_variable>>* <register_variable> ::= <name_of_register> Verilog HDL LRM Formal Syntax Definition • 205 ||= <name_of_memory> [ <constant_expression> : <constant_expression> ] <constant_expression> ::= Defined in Chapter 4,Expressions. <name_of_register> ::= <IDENTIFIER> Defined in Section 2.5 Identifiers, Keywords, and System Names. <name_of_memory> ::= <IDENTIFIER> Defined in Section 2.5 Identifiers, Keywords, and System Names. <name_of_event> ::= <IDENTIFIER> Defined in Section 2.5 Identifiers, Keywords, and System Names. <charge_strength> ::= ( small ) ||= ( medium ) ||= ( large ) <drive_strength> ::= ( <STRENGTH0> , <STRENGTH1> ) ||= ( <STRENGTH1> , <STRENGTH0> ) <STRENGTH0> is one of the following keywords: supply0 strong0 pull0 weak0 highz0 <STRENGTH1> is one of the following keywords: supply1 strong1 pull1 weak1 highz1 <range> ::= [ <constant_expression> : <constant_expression> ] <list_of_assignments> ::= <assignment> <,<assignment>>* <expression> ::= Defined in Chapter 4, Expressions. <assignment> ::= Defined in Chapter 8, 8.2 Procedural Assignments. A.3 Primitive instances <gate_declaration> ::= <GATETYPE> <drive_strength>? <delay>? <gate_instance> <,<gate_instance>>* ; <GATETYPE> is one of the following keywords: and nand or nor xor xnor buf bufif0 bufif1 not notif0 notif1 pulldown pullup nmos rnmos pmos rpmos cmos rcmos tran rtran tranif0 rtranif0 tranif1 rtranif1 <drive_strength> ::= (<STRENGTH0>,<STRENGTH1>) ||=(<STRENGTH1>,<STRENGTH0>) <delay> ::= Verilog HDL LRM # <number> Formal Syntax Definition • 206 ||= # <identifier> ||= # (<mintypmax_expression> <,<mintypmax_expression>>? <,<mintypmax_expression>>?) <gate_instance> ::= <name_of_gate_instance>? ( <terminal> <,<terminal>>* ) <name_of_gate_instance> ::= <IDENTIFIER> Defined in Section 2.5 Identifiers, Keywords, and System Names. <UDP_instantiation> ::= <name_of_UDP> <drive_strength>? <delay>? <UDP_instance> <,<UDP_instance>>* ; <name_of_UDP> ::= <IDENTIFIER> Defined in Section 2.5 Identifiers, Keywords, and System Names. <UDP_instance> ::= <name_of_UDP_instance>? ( <terminal> <,<terminal>>* ) <name_of_UDP_instance> ::= <IDENTIFIER> Defined in Section 2.5 Identifiers, Keywords, and System Names. <terminal> ::= <expression> ||= <IDENTIFIER> A.4 Module Instantiations <module_instantiation> ::= <name_of_module> <parameter_value_assignment>? <module_instance> <,<module_instance>>* ; <name_of_module> ::= <IDENTIFIER> Defined in Section 2.5 Identifiers, Keywords, and System Names. <parameter_value_assignment> ::= # ( <expression> <,<expression>>* ) <module_instance> ::= <name_of_instance> ( <list_of_module_connections>? ) <name_of_instance> ::= <IDENTIFIER> Defined in Section 2.5 Identifiers, Keywords, and System Names. <list_of_module_connections> ::= <module_port_connection> <,<module_port_connection>>* ||= <named_port_connection> <,<named_port_connection>>* <module_port_connection> ::= <expression> Defined in Chapter 4, Expressions. ||= <NULL> <NULL> ::= nothing—this form covers the case of an empty item in a list—for example: (a, b, , d) Verilog HDL LRM Formal Syntax Definition • 207 <named_port_connection> ::= .< IDENTIFIER> ( <expression> ) <expression> ::= Defined in Chapter 4, Expressions. A.5 Behavioral Statements <initial_statement> ::= initial <statement> <always_statement> ::= always <statement> <statement_or_null> ::= <statement> ||= ; <statement> ::=<blocking assignment> ; ||= <non-blocking assignment> ; ||= if ( <expression> ) <statement_or_null> ||= if ( <expression> ) <statement_or_null> else <statement_or_null> ||= case ( <expression> ) <case_item>+ endcase ||= casez ( <expression> ) <case_item>+ endcase ||= casex ( <expression> ) <case_item>+ endcase ||= forever <statement> ||= repeat ( <expression> ) <statement> ||= while ( <expression> ) <statement> ||= for ( <assignment> ; <expression> ; <assignment> ) <statement> ||= <delay_control> <statement_or_null> Defined in Section 8.6.1 Delay Control. ||= <event_control> <statement_or_null> Defined in Section 8.6.2 Event Control. ||= wait ( <expression> ) <statement_or_null> ||= -> <name_of_event> ; ||= <seq_block> ||= <par_block> ||= <task_enable> ||= <system_task_enable> ||= disable <name_of_task> ; ||= disable <name_of_block> ; ||= force <assignment> ; ||= release <lvalue> ; <assignment> Verilog HDL LRM Formal Syntax Definition • 208 ::= <lvalue> = <expression> <blocking assignment> ::= <lvalue> = <expression> ||= <lvalue> = <delay_control> <expression> ; ||= <lvalue> = <event_control> <expression> ; <non-blocking assignment> ::= <lvalue> <= <expression> ||= <lvalue> <= <delay_control> <expression> ; ||= <lvalue> <= <event_control> <expression> ; <lvalue> ::= Defined in Section 8.2 Procedural Assignments. <expression> ::= Defined in Chapter 4, Expressions. <case_item> ::= <expression> <,<expression>>* : <statement_or_null> ||= default : <statement_or_null> ||= default <statement_or_null> <seq_block> ::= begin <statement>* end ||= begin : <name_of_block> <block_declaration>* <statement>* end <par_block> ::= fork <statement>* join ||= fork : <name_of_block> <block_declaration>* <statement>* join <name_of_block> ::= <IDENTIFIER> <block_declaration> ::= <parameter_declaration> Defined in Section 3.11 Parameters. ||= <reg_declaration> Defined in Section 3.2.3 Declaration Syntax. ||= <integer_declaration> Defined in Section 3.9 Integers and Times. ||= <real_declaration> Defined in Section 3.10 Real Numbers. ||= <time_declaration> Defined in Section 3.9 Integers and Times. ||= <event_declaration> Defined in Section 8.6.2 Event Control. <task_enable> ::= <name_of_task> ; Defined in Section 9.2.1 Defining a Task. ||= <name_of_task> ( <expression> <,<expression>>* ) ; <system_task_enable> ::= <name_of_system_task> ; ||= <name_of_system_task> ( <expression> <,<expression>>* ) ; <name_of_system_task> ::= $<SYSTEM_IDENTIFIER> Please note: The $ may not be followed by a space. Verilog HDL LRM Formal Syntax Definition • 209 <SYSTEM_IDENTIFIER> ::= An <IDENTIFIER> assigned to an existing system task or function. A.6 Specify Section <specify_block> ::= specify <specify_item>* endspecify <specify_item> ::= <specparam_declaration> ||= <path_declaration> ||= <level_sensitive_path_declaration> ||= <edge_sensitive_path_declaration> ||= <system_timing_check> ||= <sdpd> <specparam_declaration> ::= specparam <list_of_param_assignments> ; <list_of_param_assignments> ::=<param_assignment><,<param_assignment>>* <param_assignment> ::=<<identifier>=<constant_expression>> <path_declaration> ::= <path_description> = <path_delay_value> ; <path_description> ::= ( <specify_input_terminal_descriptor> => <specify_output_terminal_descriptor> ) ||= ( <list_of_path_inputs> *> <list_of_path_outputs> ) <list_of_path_inputs> ::= <specify_input_terminal_descriptor> <,<specify_input_terminal_descriptor>>* <list_of_path_outputs> ::= <specify_output_terminal_descriptor> <,<specify_output_terminal_descriptor>>* <specify_input_terminal_descriptor> ::= <input_identifier> ||= <input_identifier> [ <constant_expression> ] ||= <input_identifier> [ <constant_expression> : <constant_expression> ] <specify_output_terminal_descriptor> ::= <output_identifier> ||= <output_identifier> [ <constant_expression> ] ||= <output_identifier> [ <constant_expression> : <constant_expression> ] <input_identifier> ::= the <IDENTIFIER> of a module input or inout terminal <output_identifier> ::= the <IDENTIFIER> of a module output or inout terminal. Verilog HDL LRM See Section 13.2.1 Describing Module Paths for rules that govern <output_identifier>. Formal Syntax Definition • 210 <path_delay_value> ::= <path_delay_expression> ||= ( <path_delay_expression>, <path_delay_expression> ) ||= ( <path_delay_expression>, <path_delay_expression>, <path_delay_expression> ) ||= ( <path_delay_expression>, <path_delay_expression>, <path_delay_expression>, <path_delay_expression>, <path_delay_expression>, <path_delay_expression> ) <path_delay_expression> ::= <constant_mintypmax_expression> <system_timing_check> ::= $setup( <timing_check_event>, <timing_check_event>, <timing_check_limit> <,<notify_register>>? ) ; ||= $hold( <timing_check_event>, <timing_check_event>, <timing_check_limit> <,<notify_register>>? ) ; ||= $period( <controlled_timing_check_event>, <timing_check_limit> <,<notify_register>>? ) ; ||= $width( <controlled_timing_check_event>, <timing_check_limit> <,<constant_expression>,<notify_register>>? ) ; ||= $skew( <timing_check_event>, <timing_check_event>, <timing_check_limit> <,<notify_register>>? ) ; ||= $recovery( <controlled_timing_check_event>, <timing_check_event>, <timing_check_limit> <,<notify_register>>? ) ; ||= $setuphold( <timing_check_event>, <timing_check_event>, <timing_check_limit>, <timing_check_limit> <,<notify_register>>? ) ; <timing_check_event> ::= <timing_check_event_control>? <specify_terminal_descriptor> <&&& <timing_check_condition>>? <specify_terminal_descriptor> ::= <specify_input_terminal_descriptor> ||=<specify_output_terminal_descriptor> <controlled_timing_check_event> ::= <timing_check_event_control> <specify_terminal_descriptor> <&&& <timing_check_condition>>? <timing_check_event_control> ::= posedge ||= negedge ||= <edge_control_specifier> <edge_control_specifier> ::= edge [ <edge_descriptor><,<edge_descriptor>>*] <edge_descriptor> Verilog HDL LRM Formal Syntax Definition • 211 ::= 01 || 10 || 0x || x1 || 1x || x0 <timing_check_condition> ::= <SCALAR_EXPRESSION> ||= ~<SCALAR_EXPRESSION> ||= <SCALAR_EXPRESSION> == <scalar_constant> ||= <SCALAR_EXPRESSION> === <scalar_constant> ||= <SCALAR_EXPRESSION> != <scalar_constant> ||= <SCALAR_EXPRESSION> !== <scalar_constant> <SCALAR_EXPRESSION> is a one bit net or a bit select of an expanded vector net. ::= <timing_check_limit> ::= <expression> <scalar_constant> ::= 1’b0 ||= 1’b1 ||= 1’B0 ||= 1’B1 <notify_register> ::= <identifier> <level_sensitive_path_declaration> ::= if (<conditional_port_expression>) (<specify_terminal_descriptor> <polarity_operator>?=> <specify_terminal_descriptor>) = <path_delay_value>; ||= if (<conditional_port_expression>) (<list_of_path_inputs> <polarity_operator>? *> <list_of_path_outputs>) = <path_delay_value>; Please note: The following two symbols are literal symbols, not syntax description conventions: *> => <conditional_port_expression> ::= <port_reference> ||= <UNARY_OPERATOR><port_reference> ||= <port_reference><BINARY_OPERATOR><port_reference> <polarity_operator> ::= + ||= <edge_sensitive_path_declaration> Verilog HDL LRM Formal Syntax Definition • 212 ::=<if (<expression>)>? (<edge_identifier>? <specify_terminal_descriptor>=> (<specify_terminal_descriptor> <polarity_operator> ?: <data_source_expression>)) = <path_delay_value>; ||=<if (<expression>)>? (<edge_identifier>? <specify_terminal_descriptor> *> (<list_of_path_outputs> <polarity_operator> ?: <data_source_expression>)) =<path_delay_value>; <data_source_expression> Any expression, including constants and lists. Its width must be one bit or equal to the destination’s width. If the destination is a list, the data source must be as wide as the sum of the bits of the members. <edge_identifier> ::= posedge ||= negedge <sdpd> ::=if(<sdpd_conditional_expression>)<path_description>= <path_delay_value>; <sdpd_conditional_expresssion> ::=<expression><BINARY_OPERATOR><expression> ||=<UNARY_OPERATOR><expression> A.7 Expressions <lvalue> ::= <identifier> Defined in Section 2.5 Identifiers, Keywords, and System Names. ||= <identifier> [ <expression> ] ||= <identifier> [ <constant_expression> : <constant_expression> ] ||= <concatenation> <constant_expression> ::=<expression> <mintypmax_expression> ::= <expression> ||= <expression> : <expression> : <expression> <expression> ::= <primary> ||= <UNARY_OPERATOR> <primary> ||= <expression> <BINARY_OPERATOR> <expression> ||= <expression> <QUESTION_MARK> <expression> : <expression> ||= <STRING> <UNARY_OPERATOR> is one of the following tokens: + - ! ~ & ~& | ^| ^ ~^ <BINARY_OPERATOR> is one of the following tokens: + - * / % == != === !== && || < <= > >= & | ^ ^~ >> << <QUESTION_MARK> is ? (a literal question mark). Verilog HDL LRM Formal Syntax Definition • 213 <STRING> is text enclosed in "" and contained on one line. <primary> ::= <number> ||= <identifier> Defined in Section 2.5 Identifiers, Keywords, and System Names. ||= <identifier> [ <expression> ] ||= <identifier> [ <constant_expression> : <constant_expression> ] ||= <concatenation> ||= <multiple_concatenation> ||= <function_call> ||= ( <mintypmax_expression> ) <number> ::= <DECIMAL_NUMBER> ||= <UNSIGNED_NUMBER>? <BASE> <UNSIGNED_NUMBER> ||= <DECIMAL_NUMBER>.<UNSIGNED_NUMBER> ||= <DECIMAL_NUMBER><.<UNSIGNED_NUMBER>>?E<DECIMAL_NUMBER> ||= <DECIMAL_NUMBER><.<UNSIGNED_NUMBER>>?e<DECIMAL_NUMBER> Please note: embedded spaces are illegal in Verilog numbers, but embedded underscore characters can be used for spacing in any type of number. <DECIMAL_NUMBER> ::= A number containing a set of any of the following characters, optionally preceded by + or 0123456789_ <UNSIGNED_NUMBER> ::= A number containing a set of any of the following characters: 0123456789_ <NUMBER> Numbers can be specified in decimal, hexadecimal, octal or binary, and may optionally start with a + or -. The <BASE> token controls what number digits are legal. <BASE> must be one of d, h, o, or b, for the bases decimal, hexadecimal, octal, and binary respectively. A number can contain any set of the following characters that is consistent with <BASE>: 0123456789abcdefABCDEFxXzZ? <BASE> is one of the following tokens: ’b ’B ’o ’O ’d ’D ’h ’H <concatenation> ::= { <expression> <,<expression>>* } <multiple_concatenation> ::= { <expression> { <expression> <,<expression>>* } } <function_call> ::= <name_of_function> ( <expression> <,<expression>>* ) ||= <name_of_system_function> ( <expression> <,<expression>>* ) ||= <name_of_system_function> <name_of_function> Verilog HDL LRM Formal Syntax Definition • 214 ::= <identifier> <name_of_system_function> ::= $<SYSTEM_IDENTIFIER> Please note: The $ may not be followed by a space. <SYSTEM_IDENTIFIER> ::= An <IDENTIFIER> assigned to an existing system task or function A.8 General <identifier> ::= <IDENTIFIER><.<IDENTIFIER>>* Please note: The period may not be preceded or followedby a space. <IDENTIFIER> An identifier is any sequence of letters, digits, dollar signs ($), and underscore (_) symbol, except that the first must be a letter or the underscore; the first character may not be a digit or $. Upper and lower case letters are considered to be different. Identifiers may be up to 1024 characters long. Some Verilog-based tools do not recognize identifier characters beyond the 1024th as a significant part of the identifier. Escaped identifiers start with the backslash character (\) and may include any printable ASCII character. An escaped identifier ends with white space. The leading backslash character is not considered to be part of the identifier. <delay> ::= # <number> Defined in Section 2.3 Numbers2.3 Numbers. ||= # <identifier> ||= # ( <mintypmax_expression> <,<mintypmax_expression>>?<,<mintypmax_expression>>?) <mintypmax_expression> ::= Defined in Section 6.15.1 min/typ/max Delays. <delay_control> ::= # <number> Defined in Section 2.3 Numbers. ||= # <identifier> ||= # ( <mintypmax_expression> ) Defined in Section 6.14.1 tri1 Net Strengths. <event_control> ::= @ <identifier> ||= @ ( <event_expression> ) <event_expression> ::= <expression> Defined in Chapter 4, Expressions. ||= posedge <SCALAR_EVENT_EXPRESSION> ||= negedge <SCALAR_EVENT_EXPRESSION> ||= <event_expression> or <event_expression>* <SCALAR_EVENT_EXPRESSION> is an expression that resolves to a one bit value. Verilog HDL LRM Formal Syntax Definition • 215 System Tasks and Functions B.0 System Tasks Overview This section describes system tasks and functions that are tool implementation specific. Below is a list of the tasks and functions described. For the function marked with an asterisk, the host machine native arithmetic is used. $bitstoreal $rtoi $display $setup $finish $skew $hold $setuphold $itor $strobe $period $time $printtimescale $timeformat $realtime $width $realtobits $write $recovery These utility tasks and functions provide some broadly useful capabilities. The following sections describe the behavior of these tasks and functions—without giving the complete implementation details. B.1 The Display and Write Tasks Syntax: $display(P1, P2, ... , Pn); $write(P1, P2, ... , Pn); These are the main system task routines for displaying information. The two tasks are identical except that $display automatically adds a newline character to the end of its output, whereas the $write task does not. Thus, if you want to print several messages on a single line, you should use the $write task. The $display and $write tasks display their parameters in the same order they appear in the parameter list. Each parameter can be a quoted string, an expression that returns a value, or a null parameter. The contents of string parameters are output literally except when certain escape sequences are inserted to display special characters or specify the display format for a subsequent expression. Escape sequences are inserted into a string in three ways: Verilog HDL LRM System Tasks and Functions • 216 • The special character \ indicates that the character to follow is a literal or non-printable character (see Table B-1). • The special character % indicates that the next character should be interpreted as a format specification that establishes the display format for a subsequent expression parameter (Table B-2). For each % character that appears in a string, a corresponding expression parameter must be supplied after the string. • The special character string %% indicates the display of the percent sign character % (see Table B-1). Any null parameter produces a single space character in the display. (A null parameter is characterized by two adjacent commas in the parameter list.) The $display task, when invoked without parameters, simply prints a newline character. A $write task supplied without parameters prints nothing at all. Note that because $write does not produce a newline character after outputting its text, most operating systems simply buffer the text rather than flush it directly to the output. For these operating systems, you should use the $display task instead of the $write task, or else include an explicit newline character (\n) in the $write task in order to ‘see’ the text in the output immediately. B.1.1 Escape Sequences for Special Characters The following escape sequences, when included in a string parameter, cause special characters to be displayed: \n \t \\ \" \o %% is the newline character is the tab character is the \ character is the " character is a character specified in 1-3 octal digits is the percent character Table B- 1: Escape sequences for printing special characters Example B-1 shows these escape sequences in a string parameter and their results. module disp; initial begin $display("\\\t%%\n\"\123"); end endmodule Highest level modules: disp Verilog HDL LRM System Tasks and Functions • 217 \% "S Example B- 1: Using escape sequences B.1.2 Format Specifications Table B-2 shows the escape sequences used for format specifications. Each escape sequence, when included in a string parameter, specifies the display format for a subsequent expression. For each % character (except %m) that appears in a string, a corresponding expression must follow the string in the parameter list. The value of the expression replaces the format specification when the string is displayed. Any expression parameter that has no corresponding format specification is displayed using the default decimal format. %h or %H %d or %D %o or %O %b or %B %c or %C %v or %V %m or %M %s or %S %t or %T display in hexadecimal format display in decimal format display in octal format display in binary format display in ASCII character format display net signal strength display hierarchical name display as a string display in current time format Table B- 2: Escape sequences for format specifications Example B-2 shows how escape sequences are used to provide format specifications. module disp; reg [31:0] rval; pulldown (pd); initial begin rval = 101; $display("rval = %h hex %d decimal",rval,rval); $display("rval = %o octal %b binary",rval,rval); $display("rval has %c ascii character value",rval); $display("pd strength value is %v",pd); $display("current scope is %m"); $display("%s is ascii value for 101",101); $display("simulation time is %t", $time); end Verilog HDL LRM System Tasks and Functions • 218 endmodule Highest level modules: disp rval = 00000065 hex 101 decimal rval = 00000000145 octal 00000000000000000000000001100101 binary rval has e ascii character value pd strength value is StX current scope is disp e is ascii value for 101 simulation time is 0 Example B- 2: Format specifications The format specifications in Table B-3 are used with real numbers and have the full formatting capabilities available in the C language. For example, the format specification %10.3g specifies a minimum field width of 10 with 3 fractional digits. %e or %E %f or %F %g or %G display `real' in an exponential format display `real' in a decimal format display `real' in exponential or decimal format, whichever format results in the shorter printed output Table B- 3: Format specifications for real numbers The net signal strength, hierarchical name, and string format specifications are described in sections B.1.5 Strength Format through B.1.7 String Format. The %t format specification works with the $timeformat system task to specify a uniform time unit, time precision, and format for reporting timing information from various modules that use different time units and precisions. The $timeformat task and %t format specification are described in Section B.4 Timescale System Functions Timescale System Functions. B.1.3 Size of Displayed Data For expression parameters, the values written to the output file (or terminal) are usually sized automatically. Verilog reserves just enough characters to hold the largest possible value that can be returned by the expression, given the expression’s bit length and specified display format. For instance, the result of a 12-bit expression would be allocated three characters when displayed in hexadecimal format and four characters when displayed in decimal format, since the expression’s largest possible value is FFF (hexadecimal) and 4095 (decimal). When displaying decimal values, leading zeros are suppressed and replaced by spaces. In other radices, leading zeros are always displayed. You can override the automatic sizing of displayed data by inserting a zero between the % character and the letter that indicates the radix, as shown below: Verilog HDL LRM System Tasks and Functions • 219 $display("d=%0h a=%0h", data, addr); In response, Verilog allocates the exact number of characters required to display the current expression result, instead of the expression’s largest possible value. Consider the following Verilog description and results: Example B- 3: Displayed value sizes In this example, the result of a 12-bit expression is displayed. The first call to $display uses the standard format specifier syntax and produces results requiring four and three columns for the decimal and hexadecimal radices, respectively. The second $display call uses the %0 form of the format specifier syntax and produces results requiring two columns and one column, respectively. B.1.4 Unknown and High Impedance Values When the result of an expression contains an unknown or high impedance value, the following rules apply to displaying that value. In decimal (%d) format: • If all bits are at the unknown value, a single lowercase ‘x’ character is displayed. • If all bits are at the high impedance value, a single lowercase ‘z’ character is displayed. • If some, but not all, bits are at the unknown value, the uppercase ‘X’ character is displayed. • If some, but not all, bits are at the high impedance value, the uppercase ‘Z’ character is displayed. Verilog HDL LRM System Tasks and Functions • 220 • Decimal numerals always appear right-justified in a fixed-width field. (The fixed -width format is used so that the output produced is consistent with the $monitor task output, which requires a fixed-columnar format.) In hexadecimal (%h) and octal (%o) formats: • Each group of 4 bits is represented as a single hexadecimal digit; each group of 3 bits is represented as a single octal digit. • If all bits in a group are at the unknown value, a lowercase ‘x’ is displayed for that digit. • If all bits in a group are at a high impedance state, a lowercase ‘z’ is printed for that digit. • If some, but not all, bits in a group are unknown, an uppercase ‘X’ is displayed for that digit. • If some, but not all, bits in a group are at a high impedance state, then an uppercase ‘Z’ is displayed for that digit. In binary (%b) format, each bit is printed separately using the characters 0, 1, x, and z. Some of these rules are illustrated in Example B-4 below: STATEMENT RESULT $display("%d", 1'bx); $display("%h", 14'bx01010); $display("%h %o", 12'b001xxx101x01, 12'b001xxx101x01); x xxXa XXX 1x5X Example B- 4: Displaying unknown values B.1.5 Strength Format The %v format specification is used to display the strength of scalar nets. For each %v specification that appears in a string, a corresponding scalar reference must follow the string in the parameter list. The parameter must be an explicit scalar reference; that is, it can not be an expression, or a bit-select. The strength of a scalar net is reported in a three-character format. The first two characters indicate the strength. The third character indicates the scalar’s current logic value and may be any one of the following: 0 1 X Z L H for a logic 0 value for a logic 1 value for an unknown value for a high impedance value for a logic 0 or high impedance value for a logic 1 or high impedance value Table B- 4: Logic value component of strength format Verilog HDL LRM System Tasks and Functions • 221 The first two characters—the strength characters—are either a two-letter mnemonic or a pair of decimal digits. Usually, a mnemonic is used to indicate strength information; however, in less typical cases, a pair of decimal digits may be used to indicate a range of strength levels. Table B-5 shows the mnemonics used to represent the various strength levels. Mnemonic Su St Pu La We Me Sm Hi Strength Name Supply drive Strong drive Pull drive Large capacitor Weak drive Medium capacitor Small capacitor High impedance Strength Level 7 6 5 4 3 2 1 0 Table B- 5: Mnemonics for strength levels Note that there are four driving strengths, and three charge storage strengths. The driving strengths are associated with gate outputs and continuous assignment outputs. The charge storage strengths are associated with the trireg type net. (See Chapter 6, 6.11 Strengths and Values of Combined Signals, for more details on strength modeling.) For the logic values 0 and 1, a mnemonic is used when there is no range of strengths in the signal. Otherwise, the logic value is preceded by two decimal digits, which indicate the maximum and minimum strength levels. For the unknown value, a mnemonic is used when both the 0 and 1 strength components are at the same strength level. Otherwise, the unknown value X is preceded by two decimal digits, which indicate the 0 and 1 strength levels respectively. The high impedance strength can not have a known logic value; the only logic value allowed for this level is Z. For the values L and H, a mnemonic is always used to indicate the strength level. Consider the following call to $monitor: $monitor($time,,"group=%b signals=%v %v %v", {sig1,sig2,sig3}, sig1, sig2, sig3); Example B-5 shows the output that might result from such a call, while Table B-6 explains the various strength formats that appear in the output. 0 15 30 31 Verilog HDL LRM group=111 group=011 group=0xz group=0xx signals=St1 signals=Pu0 signals=520 signals=Pu0 Pu1 Pu1 PuH 65X St1 St1 HiZ StX System Tasks and Functions • 222 45 group=000 signals=Me0 St0 St0 Example B- 5: Displayed strength St1 Pu0 HiZ Me0 StX PuH 65X means a strong driving 1 value means a pull driving 0 value means the high impedance state means a 0 charge storage of medium capacitor strength means a strong driving unknown value means a pull driving 1 or high impedance means an unknown value with a strong driving 0 component and a pull driving 1 component means an 0 value with a range of possible strength from pull driving to medium capacitor 520 Table B- 6: Explanation of strength formats in Example B-5 B.1.6 Hierarchical Name Format The %m format specifier does not accept a parameter. Instead, it causes Verilog to print the hierarchical name of the module, task, function, or named block that invokes the system task containing the format specifier. This is very useful when there are many instances of the module that calls the system task. One obvious application is timing check messages in a flip-flop or latch module; the %m format specifier will pinpoint the module instance responsible for generating the timing check message. B.1.7 String Format The %s format specifier is used to print ASCII codes as characters. For each %s specification that appears in a string, a corresponding parameter must follow the string in the parameter list. The associated parameter is interpreted as a sequence of 8-bit hexadecimal ASCII codes, with each 8 bits representing a single character. If the parameter is a variable, its value should be right-justified so that the right-most bit of the value is the least-significant bit of the last character in the string. No termination character or value is required at the end of a string, and leading zeros are never printed. B.2 Strobed Monitoring Syntax: $strobe(P1, P2, ..., Pn); The system task $strobe provides the ability to display simulation data at a selected time, but at the end of the current simulation time, when all the simulation events that have occurred for that simulation time, just before simulation time is advanced. The parameters for this task are specified Verilog HDL LRM System Tasks and Functions • 223 in exactly the same manner as for the $display system task—including the use of escape sequences for special characters and format specifications (see Section B.1 The Display and Write Tasks). The following example shows how the $strobe system task is used: forever @(negedge clock) $strobe ("At time %d, data is %h",$time,data); In this example, $strobe will write the time and data information to the standard output and the log file at each negative edge of the clock. The action will occur just before simulation time is advanced, after all other events at that time have occurred, so that the data written is sure to be the correct data for that simulation time. The strobe tasks produce output when they are executed and there is no on/off control necessary. B.3 Continuous Monitoring Syntax: $monitor(P1, P2, ..., Pn); $monitor; $monitoron; $monitoroff; The $monitor task provides the ability to monitor and display the values of any variables or expressions specified as parameters to the task. The parameters for this task are specified in exactly the same manner as for the $display system task—including the use of escape sequences for special characters and format specifications (see Section B.1 The Display and Write Tasks). When you invoke a $monitor task with one or more parameters, the simulator sets up a mechanism whereby each time a variable or an expression in the parameter list changes value–with the exception of the $time, $stime or $realtime system functions–the entire parameter list is displayed at the end of the time step as if reported by the $display task. If two or more parameters change value at the same time, however, only one display is produced that shows the new values. Note that only one $monitor display list can be active at any one time; however, you can issue a new $monitor task with a new display list any number of times during simulation. The $monitoron and $monitoroff tasks control a monitor flag that enables and disables the monitoring, so that you can easily control when monitoring should occur. Use $monitoroff to turn off the flag and disable monitoring. Use $monitoron to turn on the flag so that monitoring is enabled and the most recent call to $monitor can resume its display. A call to $monitoron always produces a display immediately after it is invoked, regardless of whether a value change has taken place; this is used to establish the initial values at the beginning of a monitoring session. By default, the monitor flag is turned on at the beginning of simulation. Verilog HDL LRM System Tasks and Functions • 224 For $monitor tasks issued interactively, there is an alternative method for controlling when monitoring should occur. The method involves using the disable command to turn off a $monitor command and then re-executing the command to turn monitoring back on. Example B-6 illustrates this technique. C3> C4> C4: C5> $monitor($time,,"rxd=%btxd=%b",rxd,txd); #100 $stop;. 0 rxd=1 txd=1 20 rxd=0 txd=1 60 rxd=0 txd=0 80 rxd=0 txd=1 $stop at simulation time 100 -3 Example B- 6: Using $monitor interactively In this example, monitoring is allowed to occur for the first 100 time units of the simulation before the disable command is issued at C5. The disable command is issued by identifying the command number of the interactive command you wish to disable and typing a minus sign before it. Here, by typing -3, we disable command 3, which invokes the $monitor task. Later in the simulation, by typing a 3 at the interactive command prompt, we can re-execute command 3 to resume monitoring. B.4 Timescale System Functions The following are timescale system functions: • $time • $realtime The $time and $realtime system functions allow you to access the current simulation time. B.4.1 The $time System Function The $time system function returns an integer that is a 64-bit time, scaled to the timescale unit of the module that invoked it. Here is an example: `timescale 10 ns / 1 ns module test; reg set; parameter p = 1.55; initial begin $monitor($time,,"set=",set); Verilog HDL LRM System Tasks and Functions • 225 #p set = 0; #p set = 1; end endmodule // The output from this example is as follows: // 0 set=x // 2 set=0 // 3 set=1 Example B- 7: $time system function In this example, the tool assigns to reg set the value 0 at simulation time 16 nanoseconds, and the value 1 at simulation time 32 nanoseconds. Note that these times do not match the times reported by $time. The time values returned by the $time system function are determined by the following steps: 1. The tool scales the simulation times 16 and 32 nanoseconds to 1.6 and 3.2 because the time unit for the module is 10 nanoseconds, so time values reported by this module are multiples of 10 nanoseconds. 2. The tool rounds 1.6 to 2, and 3.2 to 3 because the $time system function returns an integer. The time precision does not cause the tool to round these values. B.4.2 The $realtime System Function The $realtime system function returns a real number time that, like $time, is scaled to the time unit of the module that invoked it. For example: `timescale 10 ns / 1 ns module test; reg set; parameter p = 1.55; initial begin $monitor($realtime,,"set=",set); #p set = 0; #p set = 1; end endmodule // The output from this example is as follows: // 0 set=x // 1.6 set=0 // 3.2 set=1 Example B- 8: $realtime system function Verilog HDL LRM System Tasks and Functions • 226 In this example, the event times in the register set are multiples of 10 nanoseconds because 10 nanoseconds is the time unit of the module. They are real numbers because $realtime returns a real number. B.4.3 The %t Format Specification The %t format specification works with the $timeformat system task to specify a uniform time unit, time precision and format that the tool uses to report timing information from various modules that have different time units and precisions. Like other format specifications, %t can be used with the $display, $monitor, $write, $strobe, $fdisplay, $fmonitor, $fwrite, and $fstrobe system tasks to display information. B.5 Timescale System Tasks The following system tasks display and set timescale information: • $printtimescale • $timeformat B.5.1 The $printtimescale System Task The $printtimescale system task displays the time unit and precision for a particular module. Syntax: $printtimescale <hierarchical_name>; This system task can be specified with or without an argument. • When no argument is specified, $printtimescale displays the time unit and precision of the module that is the current scope (as set by $scope). • When an argument is specified, $printtimescale displays the time unit and precision of the module passed to it. The timescale information appears in the following format: Time scale of (module_name) is unit / precision The following example B-9 shows the use of this system task: `timescale 1 ms / 1 us module a_dat; initial $printtimescale(b_dat.c1); endmodule Verilog HDL LRM System Tasks and Functions • 227 `timescale 10 fs /1 fs module b_dat; c_dat c1 (); endmodule `timescale 1 ns / 1 ns module c_dat; • . • . • . endmodule Example B- 9: $printtimescale system task In this example, module a_dat invokes the $printtimescale system task to display timescale information about another module c_dat, which is instantiated in module b_dat. The information about c_dat is displayed in the following format: Time scale of (b_dat.c1) is 1ns / 1ns B.5.2 The $timeformat System Task The $timeformat system task performs the following two functions: 1. It specifies how the %t format specification reports time information for the $write, $display, $strobe, $monitor, $fwrite, $fdisplay, $fstrobe, and $fmonitor system tasks. 2. It specifies the time unit for delays entered interactively. Syntax: $timeformat (<units_number>, <precision_number>, <suffix_string>, <minimum_field_width>); The units_number argument must be an integer in the range from 0 to 15. This argument represents the time unit as follows: Unit Number 0 -1 -2 -3 -4 -5 Verilog HDL LRM Time Unit 1s 100 ms 10 ms 1 ms 100 us 10 us Unit Number -8 -9 -10 -11 -12 -13 Time Unit 10 ns 1 ns 100 ps 10 ps 1 ps 100 fs System Tasks and Functions • 228 -6 -7 1 us 100 ns -14 -15 10 fs 1 fs Table B- 7: $timeformat units_number arguments The $timeformat system task performs the following two operations: 1. It sets the time unit for all later entered delays entered interactively. 2. It sets the time unit, precision number, suffix string, and minimum field width for all %t formats specified in all modules that follow in the source description until another $timeformat system task is invoked. The default $timeformat system task arguments are as follows: Table B- 8: $timeformat system tasks arguments The following example shows the use of %t with the $timeformat system task to specify a uniform time unit, time precision, and format for timing information. `timescale 1 ms / 1 ns module cntrl; initial $timeformat(-9, 5, " ns", 10); endmodule `timescale 1 fs / 1 fs module a1_dat; reg in1; integer file; buf #10000000 (o1,in1); initial begin file = $fopen("a1.dat"); #00000000 $fmonitor(file,"%m: %t in1=%d Verilog HDL LRM System Tasks and Functions • 229 o1=%h", $realtime,in1,o1); #10000000 in1 = 0; #10000000 in1 = 1; end endmodule `timescale 1 ps / 1 ps module a2_dat; reg in2; integer file2; buf #10000 (o2,in2); initial begin file2=$fopen("a2.dat"); #00000 $fmonitor(file2,"%m: %t in2=%d o2=%h", $realtime,in2,o2); #10000 in2 = 0; #10000 in2 = 1; end endmodule Example B- 10: %t used with $timeformat The contents of file a1.dat is as follows: a1_dat: 0.00000 ns in1= x o1=x a1_dat: 10.00000 ns in1= 0 o1=x a1_dat: 20.00000 ns in1= 1 o1=0 a1_dat: 30.00000 ns in1= 1 o1=1 The contents of file a2.dat are as follows: a2_dat: 0.00000 ns in2=x o2=x a2_dat: 10.00000 ns in2=0 o2=x a2_dat: 20.00000 ns in2=1 o2=0 a2_dat: 30.00000 ns in2=1 o2=1 In this example, the times of events written to the files by the $fmonitor system task in modules a1_dat and a2_dat are reported as multiples of 1 nanosecond—even though the time units for these Verilog HDL LRM System Tasks and Functions • 230 modules are 1 femtosecond and 1 picosecond respectively—because the first argument of the $timeformat system task is -9 and the %t format specification is included in the arguments to $fmonitor. This time information is reported after the module names with five fractional digits, followed by an “ns” character string in a space wide enough for 10 ASCII characters. B.6 Simulation Time—The $time Function Syntax: $time $stime $realtime The $time and $realtime system functions return the current simulation time. The function $time returns a 64 bit value, scaled to the time unit of the module that invoked it. If the time value is a fraction of an integer, $time returns zero. The function $realtime returns a real number that is scaled to the time unit of the module that invoked it. B.7 Finish System Task Syntax: $finish; $finish (n); The $finish system task simply makes the simulator exit and pass control back to the host operating system. If a parameter expression is supplied to this task, then its value determines the diagnostic messages that are printed before the prompt is issued. If no parameter is supplied, then a value of 1 is taken as the default. Parameter Value Diagnostic Message 0 prints nothing 1 prints simulation time and location 2 prints simulation time, location, and statistics about the memory and CPU time used in simulation Table B- 9: Diagnostic messages for $stop and $finish B.8 Functions and Tasks for Reals The following functions handle “real” values: $rtoi converts real values to integers by truncating the real value (for example, 123.45 becomes 123) $itor converts integers to real values (for example, 123 becomes 123.0) $realtobits passes bit patterns across module ports; converts from a real number to the 64-bit representation (vector) of that real number Verilog HDL LRM System Tasks and Functions • 231 $bitstoreal is the reverse of $realtobits; converts from the bit pattern to a real number Example B-11 shows how the $realtobits and $bitstoreal functions are used in port connections. module driver (net_r); output net_r; real r; wire [64:1] net_r = $realtobits(r); endmodule module receiver (net_r); input net_r; wire [64:1] net_r; real r; initial assign r =$bitstoreal(net_r); endmodule Example B- 11: Using $realtobits and $bitstoreal B.9 Timing Checks You may invoke timing checks in specify blocks to verify the timing performance of your design by making sure critical events occur within given time limits. Timing checks perform the following steps: 1. Determine the elapsed time between two events. 2. Compare the elapsed time to a specified limit. 3. If the elapsed time does not fall within the specified time window, report a timing violation. Here is a sample timing check message from SILOS III: "pdmf2.vo", 10164: Timing violation at 2548 in top.pdmf2_inst.MUX_SEL_SYNC1 $setup(D:2545, (posedge CLK)&&&legal:2548, "3 < 13"); The $setup system task is in file pdmf2.vo at line 10164. The setup violation occurred at time=2548 in instance top.pdmf2_inst.MUX_SEL_SYNC1. The "D" net changed at time=2545, and the expression (posedge CLK)&&&legal changed at time=2548. This delta of 3 is less than the specified setup time of 13. Here is a list of system tasks available for performing timing checks: $setup( data_event, reference_event, limit , notifier ); $hold( reference_event, data_event, limit , notifier ); $width( reference_event, limit , threshold, notifier ); $period(reference_event, limit , notifier ); $skew( reference_event, data_event, limit , notifier ); $recovery( reference_event, data_event, limit , notifier ); $setuphold( reference_event, data_event, setup_limit, hold_limit, notifier; Verilog HDL LRM System Tasks and Functions • 232 Please Note: These tasks may only be invoked inside specify blocks. As you can see, $width and $period do not require a data_event argument. For these tasks, the tool derives the data_event from the reference_event. Table B- 10: System timing check arguments B.9.1 The $setup Timing Check The $setup system task has the following format: $setup( data_event, reference_event, limit, notifier ); Table B-11 defines the $setup system task arguments. Verilog HDL LRM System Tasks and Functions • 233 Table B- 11: $setup arguments The $setup timing check reports a timing violation in the following case: (time of reference_event)-(time of data_event) < limit If the reference_event and data_event occur simultaneously, $setup performs the timing check before it records the new data_event value, therefore no violation occurs. B.9.2 The $hold Timing Check The $hold system task has the following format: $hold(reference_event,data_event,limit,notifier); Table B-12 defines the $hold system task arguments. Table B- 12: Arguments of $hold $hold reports a violation in the following case: (time of data_event) - (time of reference_event) < limit $hold always records the new reference_event time before it performs the timing check. Therefore, if simultaneous events occur, there will be a violation. B.9.3 The $width Timing Check The $width system task has the following format: $width(reference_event,limit,threshold,notifier); Verilog HDL LRM System Tasks and Functions • 234 Table B-13 defines the $width system task arguments. Table B- 13: Arguments of $width The $width timing check monitors the width of signal pulses by timing the duration of signal levels from one clock edge to the opposite clock edge. Since you do not pass a data_event to $width, the tool derives it from the reference_event, as follows: data_event = reference_event signal with opposite edge Because of the way the tools derive the data_event for $width, you must pass an edge triggered event as the reference_event. A compilation error will occur if the reference_event is not an edge specification. The $width timing check reports a violation in the following case: (time of data_event) - (time of reference_event) < limit In other words, the pulse width must be greater than or equal to limit in order to avoid a timing violation. Note that the data_event and the reference_event will never occur simultaneously because they are triggered by opposite transitions. It is important to note that the tools do not accept null arguments for $width. Therefore, if you pass a notifier to $width, you must also supply the threshold argument. It is permissible, however, to drop both the threshold and notifier arguments when invoking $width. Example B-12 demonstrates some examples of legal and illegal calls: Verilog HDL LRM System Tasks and Functions • 235 Example B- 12: Legal and illegal $width calls B.9.4 The $period Timing Check The $period system task has the following format: $period(reference_event,limit,notifier); Table B-14 defines the $period system task arguments. Table B- 14: Arguments of $period Since you do not pass a data_event to $period, the tool derives it from the reference_event, as follows: data_event = reference_event signal with the same edge Because of the way the tool derives the data_event for $period, you must pass an edge triggered event as the reference_event. A compilation error will occur if the reference_event is not an edge specification. The $period timing check reports a violation in the following case: (time of data_event) - (time of reference_event) < limit B.9.5 The $skew Timing Check The $skew system task has the following format: $skew(reference_event,data_event,limit,notifier); Table B-15 defines the $skew system task arguments. Verilog HDL LRM System Tasks and Functions • 236 Table B- 15: Arguments of $skew The $skew timing check reports a violation in the following case: (time of data event) - (time of reference event) > limit The $skew timing check always records the new time of reference_event before it performs the timing check. If the data_event and the reference_event occur at the same time, $skew does not report a timing violation. B.9.6 The $recovery Timing Check The $recovery system task has the following format: $recovery(reference_event,data_event,limit,notifier); Table B-16 defines the $recovery system task arguments. Table B- 16: Arguments of $recovery You must specify an edge for the reference_event you pass to $recovery since it needs either rising or falling edges, but not both. Omitting the edge specification is the same as specifying all edges— an illegal reference_event argument for $recovery. The $recovery timing check reports a timing violation in the following case: (time of data_event) - (time of reference_event) < limit Verilog HDL LRM System Tasks and Functions • 237 If the data_event and reference_event occur simultaneously, $recovery performs the timing check before it records the new reference_event time and, therefore, no violation occurs. B.9.7 The $setuphold Timing Check The $setuphold system task has the following format: $setuphold(reference_event,data_event,setup_limit, hold_limit,notifier); Table B-17 defines the $setuphold system task arguments. Table B- 17: Arguments of $setuphold The $setuphold timing check is a shorthand way to combine the functionality of $setup and $hold into one system task call. Therefore, the following invocation of $setuphold: $setuphold( posedge clk, data, tSU, tHLD ); is equivalent in functionality to the following: $setup( data, posedge clk, tSU ); $hold( posedge clk, data, tHLD ); Verilog HDL LRM System Tasks and Functions • 238 B.9.8 Edge-Control Specifiers You may use edge-control specifiers to control events in timing checks based on specific edge transitions between 0, 1, and x. Edge-control specifiers contain the keyword edge followed by a square bracketed list of from one to six pairs of edge transitions between 0, 1 and x, as follows: 01 transition from 0 to 1 0x transition from 0 to x 10 transition from 1 to 0 1x transition from 1 to x x0 transition from x to 0 x1 transition from x to 1 Edge transitions involving z are treated the same way as edge transitions involving x. Syntax B-1 demonstrates the edge-control specifier syntax. <edge_control_specifier> ::= edge [ <edge_descriptor><,<edge_descriptor>>*] <edge_descriptor> ::= 01 || 10 || 0x || x1 || 1x || x0 Syntax B- 1: Syntax of edge-control specifier You can use the posedge and negedge constructs as a shorthand for certain edge control specifiers. For example, the construct: posedge clr is equivalent to the following: edge[01, 0x, x1] clr Similarly, the construct: Verilog HDL LRM System Tasks and Functions • 239 negedge clr is the same as the following: edge[10, x0, 1x] clr However, edge-control specifiers offer the flexibility to declare edge transitions other than posedge and negedge (see examples in Section B.9.9 Notifiers: User-Defined Responses to Timing Violations). B.9.9 Notifiers: User-Defined Responses to Timing Violations Timing check notifiers let you detect timing check violations behaviorally, and, therefore, take an action as soon as they occur. For example, you may print an informative error message describing the violation, or you may propagate an x value at the output of the device that reported the violation. The notifier is a register—declared in the module where timing checks will occur—that you pass as the last argument to a system timing check. Whenever a timing violation occurs, the system task toggles the value of the notifier. It is important to remember that the notifier is an optional argument to all system timing checks and can be omitted from the system task call without adversely affecting its operation. Table B-18 shows how the notifier values are toggled when timing violations occur. Table B- 18: Notifier toggle values Example B-13 demonstrates some simple examples of timing checks with notifier arguments. $setup( data, posedge clk, 10, notify_reg ) ; $width( posedge clk, 16, notify_reg ) ; Example B- 13: Timing checks with notifier arguments Now consider a more complex example of how to use notifiers in a behavioral model. The example that follows uses a notifier to set the D flip-flop output to x when a timing violation occurs in an edge- sensitive user-defined primitive (UDP). Verilog HDL LRM System Tasks and Functions • 240 primitive posdff_udp (q, clock, data, preset, clear, notifier); output q; reg q; input clock, data, preset, clear, notifier; table //clock data p c notifier state q //------------------------------------r 0 1 1 ? : ? : 0 ; r 1 1 1 ? : ? : 1 ; p p 1 0 ? 1 1 ? ? ? : : 1 0 : 1 ; : 0 ; n ? ? * ? ? ? ? ? ? : : ? ? : - ; : - ; ? ? ? ? 0 1 * 1 ? ? : : ? 1 : 1 ; : 1 ; ? ? ? ? ? ? 1 0 1 * ? ? ? ? * : : : ? 0 ? : 0 ; : 0 ; : x ; // At any //notifier event //output to x endtable endprimitive module dff(q, qbar, clock, data, preset, clear); output q, qbar; input clock, data, preset, clear; reg notifier; and (enable, preset,clear); not (qbar, ffout); buf (q, ffout); posdff_udp (ffout, clock, data, preset, clear, notifier); specify // Define timing check specparam values specparam tSU = 10, tHD = 1, tPW = 25, tWPC = 10, tREC = 5; // Define module path delay rise and fall specparam // min:typ:max values Verilog HDL LRM System Tasks and Functions • 241 specparam tPLHc = 4:6:9 , tPHLc = 5:8:11; specparam tPLHpc = 3:5:6 , tPHLpc = 4:7:9; // Specify module path delays (clock *> q,qbar) = (tPLHc, tPHLc); (preset,clear *> q,qbar) = (tPLHpc, tPHLpc); // Setup time : data to clock, only when preset and //clear are 1 $setup(data, posedge clock &&& enable, tSU, notifier); // Hold time : clock to data, only when preset and clear are 1 $hold(posedge clock, data &&& enable, tHD, notifier); // Clock period check $period(posedge clock, tPW, notifier); // Pulse width : preset, clear $width(negedge preset, tWPC, 0, notifier); $width(negedge clear, tWPC, 0, notifier); // Recovery time: clear or preset to clock $recovery(posedge preset, posedge clock, tREC, notifier); $recovery(posedge clear, posedge clock, tREC, notifier); endspecify endmodule Example B- 14: Notifier setting a register in response to a timing violation It is important to remember that this model applies to edge-sensitive UDPs only; for level-sensitive models, you must generate an additional UDP for x propagation. B.9.10 Enabling Timing Checks with Conditioned Events A construct called a conditioned event ties the occurrence of timing checks to the value of a conditioning signal. Syntax B-2 demonstrates the conditioned event syntax. <controlled_timing_check_event> ::= <timing_check_event_control> <specify_terminal_descriptor> < &&& <timing_check_condition>>? <timing_check_condition> ::= <scalar_expression> ||= ~<scalar_expression> Verilog HDL LRM System Tasks and Functions • 242 ||= <scalar_expression>==<scalar_constant> ||= <scalar_expression>===<scalar_constant> ||= <scalar_expression>!=<scalar_constant> ||= <scalar_expression>!==<scalar_constant> Syntax B- 2: Syntax of conditioned event To illustrate the difference between conditioned and unconditioned timing check events, consider the following unconditioned version of the first line in Example B-15: $setup( data, posedge clk, 10 ); Here, a setup check will occur every time there is a positive edge on signal clk. To trigger the setup check on the positive clk edge only when signal clr is high, rewrite the command as it appears in Example B-15’s first line. $setup( data, posedge clk &&& clr, 10 ) ; setup( data, posedge clk &&& (~clr), 10 ) ; $setup( data, posedge clk &&& (clr===0), 10 ); Example B- 15: Example of conditioned event The second and third lines of Example B-15 show two ways to trigger the same timing check on the positive clk edge only when clr is low. The comparisons used in the condition may be deterministic—as in ===, !==, ~, or no operation, or non-deterministic—as in == or !=. In the second example above, note that the comparison uses === and is therefore deterministic. When comparisons are deterministic, an x value on the conditioning signal will not enable the timing check. For non-deterministic comparisons, an x on the conditioning signal will enable the timing check. There are two constraints to bear in mind when using conditioned events: 1. The conditioning signal must be a scalar net; the conditioning signal cannot be a vector or expression. 2. Because conditioning signals cannot be expressions, you may use only one conditioning signal per event. If you need more than one conditioning signal for conditioning timing checks, you can combine the appropriate logic in a separate signal outside the specify block, and then use that single signal as the conditioning signal. For example, to perform the previous sample setup check on the positive clk edge only when clr and set are high, add the following statement outside the specify block: Verilog HDL LRM System Tasks and Functions • 243 and( clr_and_set, clr, set ); Then, add the condition to the timing check using the signal clr_and_set as follows: $setup( data, posedge clk &&& clr_and_set, 10 ); Verilog HDL LRM System Tasks and Functions • 244 Compiler Directives C.0 Compiler Overview This section describes implementation-specific compiler directives requiring standardization. All Verilog compiler directives are preceded by the (` ) character. This character is called accent grave. It is different from the character (’), which is the single quote character. The scope of compiler directives extends from the point where it is processed, across all files processed, to the point where another compiler directive supersedes it or the processing completes. See the section on C.4 `resetall for a discussion of the impact this has on libraries. This appendix describes the following compiler directives: • `define • `default_nettype • `unconnected_drive • `nounconnected_drive • `resetall • `timescale C.1 `define The directive `define creates macros for text substitution (see also E.7.2 Defining Variable Names to Control Conditional Compilation). It can be used both inside and outside module definitions. After a text macro is defined, it can be used in the source description by using the (`) character, followed by the macro name. The compiler will substitute the text of the macro for the string ‘macro_name. A text macro substitution facility allows meaningful names to represent commonly used pieces of text. The syntax for text macro definitions is as follows: <text_macro_definition> ::=`define <text_macro_name> <MACRO_TEXT> <text_macro_name> ::= <IDENTIFIER> <MACRO_TEXT> is any arbitrary text up to the end of the line. Items <text_macro_name> and <MACRO_TEXT> must be specified on the same line. If a line comment (that is, a comment using the characters //) is included in the text, then the comment does not become part of the text substituted. The text for <MACRO_TEXT> may be blank, in which case the text macro is defined to be empty and no text is substituted when the macro is used. The syntax for using a text macro is as follows: Verilog HDL LRM Compiler Directives • 245 <text_macro_usage>::= `<text_macro_name> Examples: `define reg wordsize 8 [1:`wordsize] `define typ_nand `typ_nand g121 data; nand #5 (q21, //define n10, a nand w/typical delay n11); The text comprising <MACRO_TEXT> must not be split across the following lexical tokens: • comments • numbers • strings • identifiers • keywords • double or triple character operators For example, the following two lines are illegal specifications: `define first_half $display(`first_half "start end of of string string"); If you develop compiler directives, be aware of the following: • If you implement the compiler directive `foo—and if you implement the directive `define as some tools do—then if you write `define foo, the meaning of `foo is ambiguous. • In source written for some tools, text macro names may not be the same as compiler directive keywords. • Text macro names can be the same as ordinary identifiers. For example, signal_name and `signal_name are different. All text macro names are put into one symbol table. Redefinition of text macros is allowed; the newest definition of a particular text macro will prevail when the macro name is used in the source text. C.2 `default_nettype The directive `default_nettype controls the net type created for implicit net declarations. It can be used only outside of module definitions. It affects all modules that follow the directive, even across source file boundaries. Multiple `default_nettype directives are allowed. The latest one encountered controls the type of nets that will be implicitly declared. The following is the syntax of the directive: `default_nettype <type_of_net> Verilog HDL LRM Compiler Directives • 246 The following are the keywords for the net types that can be specified as arguments for the directive: wire tri tri0 wand triand tri1 wor trior trireg When no `default_nettype directive is present, implicit nets are of type wire. See the chapters on 3.5 Implicit Declarations and 6.9 Implicit Net Declarations for a discussion of implicit net declarations. C.3 `unconnected_drive and `nounconnected_drive The directive `unconnected_drive causes all unconnected input ports between it and `nounconnected_drive to be pulled up or down instead of floating to the high impedance value z. `unconnected_drive takes one of two arguments—pull1 or pull0. When pull1 is specified, all unconnected input ports are automatically pulled up. When pull0 is specified, unconnected ports are pulled down. These directives must be specified outside modules only. C.4 `resetall This compiler directive resets all compiler directives to the default values that are active when it is encountered during compilation. This is useful for ensuring that only those directives that are desired in compiling a particular source file are active. The recommended usage is to place `resetall at the beginning of each source text file, followed immediately by the directives desired in the file. This directive is particularly important in library files and library directory files. ` C.5 `timescale This directive specifies the time unit and time precision of the modules that follow it. The time unit is the unit of measurement for time values such as the simulation time and delay values. The time precision specifies how the tool rounds time values. The rounded values the tool uses are accurate to within the unit of time specified as the time precision. Timescales let you use modules that were developed with different time units together in the same design. The tool can, for example, simulate a design that contains both a module whose delays are specified in nanoseconds and a module whose delays are specified in picoseconds. To use modules with different time units in the same design, you need the following timescale constructs: • the `timescale compiler directive to specify the unit of measurement for time and precision of time in the modules in your design • the $printtimescale system task to display the time unit and precision of a module Verilog HDL LRM Compiler Directives • 247 • the $time and $realtime system functions, the $timeformat system task, and the %t format specification to specify how the tool reports time information The `timescale compiler directive specifies the unit of measurement for time and delay values and the degree of accuracy for delays in all modules that follow this directive until the tool reads another `timescale compiler directive. Syntax: `timescale <time_unit> / <time_precision> The time_unit argument specifies the unit of measurement for times and delays. The time_precision argument specifies how the tool rounds delay values before using them in simulation. The values the tool uses will be accurate to within the unit of time that is specified here. The smallest time_precision argument of all the `timescale compiler directives in the design determines the time unit of the simulation. The time_precision argument must be at least as precise as the time_unit argument; it cannot specify a longer unit of time than time_unit. The integers in these arguments specify an order of magnitude for the size of the value; the valid integers are 1, 10, and 100. The character strings represent units of measurement; the valid character strings are s, ms, us, ns, ps, and fs. The units of measurement specified by these character strings are as follows: Table 2- 19: Arguments of time_precision The following example shows how this directive is used: `timescale 1ns / 1ps Verilog HDL LRM Compiler Directives • 248 Here, all time values in the modules that follow the directive are multiples of 1 nanosecond because the time_unit argument is “1 ns”. Delays are rounded to real numbers with three decimal places—or, precise to within one thousandth of a nanosecond—because the time_precision argument is “1 ps,” or one thousandth of a nanosecond. Consider the following example: `timescale 10 us / 100 ns The time values in the modules that follow this directive are multiples of 10 microseconds because the time_unit argument is “10 us”. Delays are rounded to within one tenth of a microsecond because the time_precision argument is “100 ns,” or one tenth of a microsecond. The following example shows a `timescale directive in the context of an actual source description: `timescale 10 ns / 1 ns module test; reg set; parameter d = 1.55; initial begin #d set = 0; #d set = 1; end endmodule Example 2- 16: Example of the ‘timescale directive The `timescale 10 ns / 1 ns compiler directive specifies that the time unit for module test is 10 nanoseconds. As a result, the time values in the module are multiples of 10 nanoseconds, rounded to the nearest 1 nanosecond and, therefore, the value stored in parameter d is scaled to a delay of 16 nanoseconds. This means that the tool assigns the value 0 to reg set at simulation time 16 nanoseconds (1.6 x 10 ns), and assigns the value 1 at simulation time 32 nanoseconds. Parameter d retains its value no matter what timescale is in effect. These simulation times are determined as follows: 1. The value of parameter d is rounded from 1.55 to 1.6 according to the time precision. 2. The time unit of the module is 10 nanoseconds, and the precision is 1 nanoseconds, so the tool scales the delay of parameter d from 1.6 to 16. The tool schedules the assignment of 0 to reg set at simulation time 16 nanoseconds (the tool adds 16 nanoseconds to the current simulation time of 0) and the assignment of 1 at simulation time 32 nanoseconds (the tool adds 16 nanoseconds to the current simulation time of 16 nanoseconds). The tool does not round time values when it schedules these assignments. 3. Verilog HDL LRM Compiler Directives • 249 List of System Task and System Function Keywords D.0 System Tasks Overview The following is a list of some of the keywords currently used by tools for names of system tasks and system functions, with a brief description of each keyword. See Appendix B, System Tasks and Functions, for descriptions of some frequently used tasks and functions. $bitstoreal $countdrivers $display $fclose $fdisplay $fmonitor $fopen $fstrobe $fwrite $finish $getpattern $history $incsave $input $itor $key $list $log $monitor $monitoroff $monitoron $nokey $nolog $printtimescale $readmemb Verilog HDL LRM 250 • List of System Task and System Function Keywords $readmemh $realtime $realtobits $reset $reset_count $reset_value $restart $rtoi $save $scale $scope $showscopes $showvariables $showvars $sreadmemb $sreadmemh $stime $stop $strobe $time $timeformat $write D.1 $bitstoreal See Appendix B, B.8 Functions and Tasks for Reals, for details. D.2 $countdrivers Syntax: $countdrivers(net, net_is_forced, number_of_01x_drivers, number_of_0_drivers, number_of_1_drivers, number_of_x_drivers); Verilog HDL LRM 251 • List of System Task and System Function Keywords The $countdrivers system function is provided to count the number of drivers on a specified net so that bus contention can be identified. The $countdrivers system function is provided to count the number of drivers on a specified net so that bus contention can be identified. This system function returns a 0 if there is no more than one driver on the net and returns a 1 otherwise (indicating contention). The specified “net” must be a scalar or a bit-select of an expanded vector net. The number of parameters to the system function may vary according to how much information is desired. If you supply additional parameters to the $countdrivers function, each parameter returns the information described in Table D-1. Parameter Return Value net_is_forced returns a "1" if the net is forced and a "0" if the net is not forced returns an integer representing the number of drivers that are in a 0, 1, or x state; this represents the total number of drivers on the net that are not forced returns an integer representing the number of drivers on the net that are in the "0" state returns an integer representing the number of drivers on the net that are in the "1" state returns an integer representing the number of drivers on the net that are in the "x" state number_of_01x_drivers number_of_0_drivers number_of_1_drivers number_of_x_drivers Table D- 1: Parameter return value for $countdrivers function Verilog HDL LRM 252 • List of System Task and System Function Keywords D.3 $display See Appendix B, B.1 The Display and Write Tasks, for details. D.4 Value Change Dump File Tasks Seven system tasks are provided to create and format the value change dump file. Syntax: $dumpfile(<filename>); $dumpvars(<levels> <,<module|var>>* ); $dumpoff; $dumpon; $dumpall; $dumplimit(<filesize>); $dumpflush; The $dumpfile system task specifies the name of the value change dump file. The $dumpvars system task specifies the variables whose changing values a tool records in the value change dump file. The $dumpvars when invoked with no arguments dumps all variables in the design. The $dumpoff system task stops a tool from recording value changes in the value change dump file. The $dumpon system task allows a tool to resume recording value changes in the value change dump file. The $dumpall system task creates a checkpoint that shows the current value of all variables being recorded in the value change dump file. The $dumplimit system task sets the size of the value change dump file. The $dumpflush system task empties the dump file buffer and ensures that all the data in that buffer is stored in the value change dump file. D.5 File Output Each of the four formatted display tasks—$display, $write, $monitor, and $strobe—has a counterpart that writes to specific files as opposed to the log file and standard output. These counterpart tasks—$fdisplay, $fwrite, $fmonitor, and $fstrobe—accept the same type of parameters as the tasks they are based upon, with one exception: The first parameter must be a multichannel descriptor that indicates where to direct the file output. A multichannel descriptor is either a variable or the result of an expression that takes the form of a 32-bit unsigned integer value. This value determines which open files the task will write to. Verilog HDL LRM 253 • List of System Task and System Function Keywords Syntax: $fdisplay(<multi_channel_descriptor>, P1, P2, ... , Pn); $fwrite(<multi_channel_descriptor>, P1, P2, ... , Pn); $fstrobe(<multi_channel_descriptor>, P1, P2, ..., Pn); $fmonitor(<multi_channel_descriptor>, P1, P2, ..., Pn); $fopen("<name_of_file>") $fclose(<multichannel_descriptor>); The function $fopen opens the file specified as a parameter and returns a 32-bit unsigned multichannel descriptor that is uniquely associated with the file. It returns 0 if the file could not be opened for writing. The multichannel descriptor should be thought of as a set of 32 flags, where each flag represents a single output channel. The least significant bit (bit 0) of a multichannel descriptor always refers to the standard output—that is, the log file and the screen (unless it has been redirected to a file). The standard output is also called channel 0. The other bits refer to channels that have been opened by the $fopen system function. The first call to $fopen opens channel 1 and returns a multichannel descriptor value of 2—that is, bit 1 of the descriptor is set. A second call to $fopen opens channel 2 and returns a value of 4—that is, only bit 2 of the descriptor is set. Subsequent calls to $fopen open channels 3, 4, 5, and so on and returns values of 8, 16, 32, and so on, up to a maximum of 31 channels. Thus, a channel number corresponds to an individual bit in a multichannel descriptor. The advantage of multichannel descriptors is that they allow a single system task to write the same information to multiple outputs simultaneously. This is accomplished by setting more than one bit in the multichannel descriptor, and can be done by combining the values returned by $fopen in a bit-wise OR operation. Another advantage of multichannel descriptors is that it is easy to set up descriptions where the channels that receive diagnostic information can be dynamically altered during simulation, and even controlled in interactive commands. Note that the number of simultaneous output channels that may be active at any one time is dependent on the operating system and is not determined by the tool. The $fclose system task closes the channels specified in the multichannel descriptor, and does not allow any further output to the closed channels. The $fopen task will reuse channels that have been closed. Example D-1 shows how to set up multichannel descriptors. In this example, three different channels are opened using the $fopen function. The three multichannel descriptors that are returned by the function are then combined in a bit-wise OR operation and assigned to the integer variable messages. The messages variable can then be used as the first parameter in a file output task to direct output to all three channels at once. To create a descriptor that directs output to the standard output as well, the messages variable is bit-wise ORed with the constant 1, which effectively enables channel 0. integer messages, Verilog HDL LRM 254 • List of System Task and System Function Keywords broadcast, cpu_chann, alu_chann, mem_chann; initial begin cpu_chann = $fopen("cpu.dat"); if(cpu_chann == 0) $finish; alu_chann = $fopen("alu.dat"); if(alu_chann == 0) $finish; mem_chann = $fopen("mem.dat"); if(mem_chann == 0) $finish; messages = cpu_chann | alu_chann | mem_chann; broadcast = 1 | messages; // includes standard output end Example D- 1: Setting up multichannel descriptors The following file output tasks show how the channels opened in Example D-1 might be used: $fdisplay( broadcast, "system reset at time %d", $time ); $fdisplay( messages, "Error occurred on address bus at time %d, address = %h", $time, address ); forever @(posedge clock) $fdisplay( alu_chann, "acc= %h f=%h a=%h b=%h",acc, f, a, b ); Example D- 2: Using multichannel descriptors The $fstrobe and $fmonitor system tasks work just like their counterparts, $strobe and $monitor, except that they write to files using the multichannel descriptor for control. Unlike $monitor, any number of $fmonitor tasks can be set up to be simultaneously active. Thus, if you need to have more than one monitor task report to the standard output, then use a $fmonitor with a multichannel descriptor of 1. D.6 $finish See Appendix B, B.7 Finish System Task, for details. D.7 $getpattern Syntax: $getpattern (<mem_element>); Verilog HDL LRM 255 • List of System Task and System Function Keywords The system function $getpattern provides for fast processing of stimulus patterns that must be propagated to a large number of scalar inputs. The function reads stimulus patterns that have been loaded into a memory using the $readmemb or $readmemh system tasks. Use of this function is limited however: It may only be used in a continuous assignment statement where the left-hand side is a concatenation of scalar nets, and the parameter to the system function is a memory element reference. Example D-3 shows how stimuli stored in a file can be read into a Verilog memory using $readmemb and applied to the circuit one pattern at a time using $getpattern. The memory in_mem is initialized with the stimulus patterns by the $readmemb task. The integer variable index selects which pattern is being applied to the circuit. The for loop increments the integer variable index periodically to sequence the patterns. module top; parameter in_width=10, patterns=200, step=20; reg [1:in_width] in_mem[1:patterns]; integer index; // declare scalar inputs wire i1,i2,i3,i4,i5,i6,i7,i8,i9,i10; // assign patterns to circuit scalar inputs (a new pattern // is applied to the circuit each time index changes value) assign {i1,i2,i3,i4,i5,i6,i7,i8,i9,i10} = $getpattern(in_mem[index]); initial begin // read stimulus patterns into memory $readmemb("patt.mem", in_mem); // step through patterns (note that each assignment // to index will drive a new pattern onto the circuit // inputs from the $getpattern system task specified // above for(index = 1; index <= patterns; index = index + 1) #step; end // instantiate the circuit module mod1cct(o1,o2,o3,o4,o5,o6,o7,o8,o9,o10, i1,i2,i3,i4,i5,i6,i7,i8,i9,i10); Verilog HDL LRM 256 • List of System Task and System Function Keywords endmodule Example D- 3: Using $getpattern D.8 $history The $history system task prints out a list of all interactive commands that have been entered to a tool. D.9 $incsave See section D.23 Saving and Restarting in this Appendix for details. D.10 $input Syntax: $input("<filename>"); The $input system task allows command input text to come from a named file instead of from the terminal. At the end of the command file the input is automatically switched back to the terminal. D.11 $itor See Appendix B, B.8 Functions and Tasks for Reals, for more details. D.12 $key and $nokey Syntax: $key(“<filename>”);$key;$nokey; A key file is created by a tool whenever interactive mode is entered for the first time. The key file contains all of the text that has been typed in from the standard input. The file also contains information about asynchronous interrupts. The $nokey and $key system tasks are used to disable and re-enable output to the key file. An optional file name parameter for $key causes the old key file to be closed, a new file to be created, and output to be directed to the new file. Verilog HDL LRM 257 • List of System Task and System Function Keywords D.13 $list Syntax: $list;$list (<name>); When invoked without a parameter, $list produces a listing of the module, task, function, or named block that is defined as the current scope setting. If an optional parameter is supplied, it must refer to a specific module, task, function or named block, in which case the specified object will be listed. D.14 $log and $nolog Syntax: $log(“<filename>”);$log;$nolog; Tools may create a log file that contains a copy of all the text that is printed to the standard output. The log file may also contain, at the beginning of the file, the host command that was used to run the tool. The $nolog and $log system tasks are used to disable and re-enable output to the log file. The $nolog task disables output to the log file, while the $log task re-enables the output. An optional file name parameter for $log causes the old file to be closed, a new log file to be created, and output to be directed to the new log file. D.15 $monitor, $monitoron, $monitoroff See Appendix B, B.3 Continuous Monitoring, for details. D.16 $printtimescale See Appendix B, B.5.1 The $printtimescale System Task, for details. D.17 $readmemb and $readmemh Syntax: $readmemb("<filename>", <memname>); $readmemb("<filename>", <memname>, <start_addr>); $readmemb("<filename>", <memname>, <start_addr>, <finish_addr>); $readmemh("<filename>", <memname>);$readmemh("<filename>", <memname>, <start_addr>); Verilog HDL LRM 258 • List of System Task and System Function Keywords $readmemh("<filename>", <memname>, <start_addr>, <finish_addr>); Two system tasks—$readmemb and $readmemh—read and load data from a specified text file into a specified memory. Either task may be executed at any time during simulation. The text file to be read must contain only the following: • white space (spaces, new lines, tabs, and form-feeds) • comments (both types of comment are allowed) • binary or hexadecimal numbers The numbers must have neither the length nor the base format specified. For $readmemb, each number must be binary. For $readmemh, the numbers must be hexadecimal. The unknown value (x or X), the high impedance value (z or Z), and the underscore (_) can be used in specifying a number as in a Verilog source description. White space and/or comments must be used to separate the numbers. In the following discussion, the term “address” refers to an index into the array that models the memory. As the file is read, each number encountered is assigned to a successive word element of the memory. Addressing is controlled both by specifying start and/or finish addresses in the system task invocation, and by specifying addresses in the data file. When addresses appear in the data file, the format is an “at” character (@) followed by a hexadecimal number as follows: @hh...h Both upper and lower case digits are allowed in the number. No white space is allowed between the @ and the number. You may use as many address specifications as you need within the data file. When the system task encounters an address specification, it loads subsequent data starting at that memory address. If no addressing information is specified within the system task, and no address specifications appear within the data file, then the default start address is the left-hand address given in the declaration of the memory, and consecutive words are loaded until either the memory is full or the data file is completely read. If the start address is specified in the task without the finish address, then loading starts at the specified start address and continues towards the right-hand address given in the declaration of the memory. If both start and finish addresses are specified as parameters to the task, then loading begins at the start address and continues toward the finish address, regardless of how the addresses are specified in the memory declaration. When addressing information is specified both in the system task and in the data file, the addresses in the data file must be within the address range specified by the system task parameters, otherwise an error message is issued and the load operation is terminated. Verilog HDL LRM 259 • List of System Task and System Function Keywords A warning message is issued if the number of data words in the file differs from the number of words in the range implied by the start and finish addresses. For example, consider the following declaration of memory mem: reg[7:0] mem[1:256]; Given this declaration, each of the following statements will load data into mem in a different manner: initial $readmemh("mem.data", mem);initial $readmemh("mem.data", mem, 16);initial $readmemh("mem.data", mem, 128, 1); The first statement will load up the memory at simulation time 0 starting at the memory address 1. The second statement will begin loading at address 16 and continue on towards address 256. For the third and final statement, loading will begin at address 128 and continue down towards address 1. In the third case, when loading is complete, a final check is performed to ensure that exactly 128 numbers are contained in the file. If the check fails, a tool issues a warning message. D.18 $realtime See $time in Appendix B.4.2 The $realtime System Function for details. D.19 $realtobits See Appendix B, B.8 Functions and Tasks for Reals, for details. D.20 $reset, $reset_count and $reset_value The $reset system task enables a tool to be reset to its “Time 0” state so that processing (e.g., simulation) can begin again. The $reset_count system function keeps track of the number of times the tool is reset. The $reset_value system function returns the value specified by the reset_value parameter argument to the $reset system task. The $reset_value system function is used to communicate information from before a reset of a tool to the time 0 state to after the reset. The following are some of the simulation methods that you can employ with this system task and these system functions: • determine the force statements your design needs to operate correctly, reset the simulation time to 0, enter these force statements, and start to simulate again • reset the simulation time to 0 and apply new stimuli Verilog HDL LRM 260 • List of System Task and System Function Keywords • determine that debug system tasks, such as $monitor and $strobe, are keeping track of the correct nets or registers, reset the simulation time to 0, and begin simulation again The $reset system task tells a tool (for example a simulator) to return the processing of your design to its logical state at time 0. When a tool executes the $reset system task, it takes the following actions to stop the process (e.g., simulation): • disables all concurrent activity, initiated in either initial and always procedural blocks in the source description or through interactive mode (disables, for example, all force and assign statements, the current $monitor system task, and any other active task) • cancels all scheduled simulation events After a simulation tool executes the $reset system task, the simulation is in the following state: • The simulation time is 0. • All registers and nets contain their initial values. • The tool begins to execute the first procedural statements in all initial and always blocks. Syntax: $reset; $reset(<stop_value>); $reset(<stop_value>,<reset_value>); $reset(<stop_value>,<reset_value>,<diagnostics_value>); The stop_value argument The stop_value argument indicates whether interactive mode or processing is entered immediately after resetting of the tool. A value of 0 or no argument causes interactive mode to be entered after resetting the tool. A non-zero value passed to $reset causes the tool to begin processing immediately. The reset_value argument The reset_value is an integer that you specify whose value is returned by the $reset_value system function after you reset the tool. You cannot declare an integer that keeps its value after a reset. All declared integers return to their initial value after reset, but entering an integer as this argument allows you to access what its value was before the reset with the $reset_value system function. This argument provides you with a means of communicating information from before the reset of a tool to after the reset of the tool. The diagnostic_value argument The diagnostic_value is the third argument. It specifies the kind of diagnostic messages a tool displays before it resets the time to 0. Increasing integer values result in increased information. A value of zero results in no diagnostic message. Verilog HDL LRM 261 • List of System Task and System Function Keywords D.21 $restart See section D.23 Saving and Restarting for details. D.22 $rtoi See Appendix B, B.8 Functions and Tasks for Reals, for details. D.23 Saving and Restarting Three system tasks, $save, $restart, and $incsave, work in conjunction with one another to save the complete state of a tool into a permanent file such that the tool state can be reloaded at a later time and the tool can continue processing where it left off. Syntax: $save("<name_of_file>"); $restart("<name_of_file>"); $incsave("<incremental_filename>"); These system tasks work in conjunction with one another to save the complete state of a tool into a permanent file such that the tool state can be reloaded at a later time and the tool can continue processing where it left off.They are often used during long runs of a tool to save checkpoint versions of the internal state at regular intervals. They are also useful to perform quick “try and see” experiments without having to repeat the entire processing each time. All three system tasks take a file name as a parameter. The file name must be supplied as a string enclosed in quotation marks. The $save system task saves the complete state into the host operating system file specified as a parameter. The $incsave system task saves only what has changed since the last invocation of $save. It is not possible to do an incremental save on any file other than the one produced by the last $save. The $restart system task restores a previously saved state from a specified file. The state description to be restarted does not have to be related in any way to the description being replaced. It should be noted that interactive commands are also saved by the $save task; thus, when you use $restart to restore a tool’s state, you also replace the current set of commands with the saved set of commands. D.23.1 Incremental Save and Restart Restarting from an incremental save is similar to restarting from a full save, except that the name of the incremental save file is specified in the restart command. The full save file that the incremental save file was based upon must still be present, as it is required for a successful restart. If the full save file has been changed in any way since the incremental save was performed, errors will result. Verilog HDL LRM 262 • List of System Task and System Function Keywords The incremental restart is useful for going back in time. If a full save is performed near the beginning of processing, and an incremental save is done at regular intervals, then going back in time is as simple as restarting from the appropriate file. The module shown in Example D-4 saves the incremental state of the simulation every 10,000 time units. The files are recycled as time advances. module checkpoint; initial #500 $save("save.dat"); always begin #100000 $incsave("inc1.dat"); #100000 $incsave("inc2.dat"); #100000 $incsave("inc3.dat"); #100000 $incsave("inc4.dat"); end endmodule Example D- 4: Using incremental save D.24 $scale Syntax: $scale(<hierarchical_name>); The $scale function allows the user to take a time value from a module with one time unit to be used in a module with a different time unit. The time value is converted from the time unit of one module to the time unit of the module that invokes $scale. D.25 $scope Syntax: $scope("<name>"); The $scope system task allows a particular level of hierarchy to be specified as the interactive scope for identifying objects. This task accepts a single parameter argument that must be the complete hierarchical name of a module, task, function, or named block. The initial setting of the interactive scope is the first top-level module. Verilog HDL LRM 263 • List of System Task and System Function Keywords D.26 $showscopes Syntax: $showscopes;$showscopes(n); The $showscopes system task produces a complete list of modules, tasks, functions, and named blocks that are defined at the current scope level. An optional integer parameter can be given to $showscopes. A nonzero parameter causes all the modules, tasks, functions and named blocks in or below the current hierarchical scope to be listed. No parameter or a zero results in only objects at the current scope level to be listed. D.27 $showvars Syntax: $showvars;$showvars(<list_of_variables>); The $showvars system task produces status information for register and net variables, both scalar and vector. When invoked without parameters, $showvars displays the status of all variables in the current scope. When invoked with a <list_of_variables>, $showvars shows only the status of the specified variables. If the <list_of_variables> includes a bit-select or part-select of a register or net then the status information for all the bits of that register or net are displayed. The system task $showvariables displays information similar to that of $showvars, but allows more control over the information displayed. D.28 $sreadmemb and $sreadmemh Syntax: $sreadmemb(<mem_name>,<start_addr>,<finish_addr>, <string1>,<string2>,,,); $sreadmemh(<mem_name>,<start_addr>,<finish_addr>, <string1>,<string2>,,,); Where: <mem_name> name of the memory structure <start_addr> memory start address <finish_addr> memory end address Verilog HDL LRM 264 • List of System Task and System Function Keywords <stringN> the string value containing the actual data to be placed into memory, beginning at <start_addr> The system tasks $sreadmemb and $sreadmemh load data into memory from a Verilog source character string. The $sreadmemh and $sreadmemb system tasks take memory data values and addresses as string arguments. These strings take the same format as the strings that appear in the input files passed as arguments to $readmemb and $readmemh. D.29 $stime See $time in Appendix B.4.1 The $time System Function for details. D.30 $stop Syntax: $stop; $stop(n); The $stop system task puts the tool (for example a simulator) into halt mode, issues an interactive command prompt, and passes control to the user. This task takes an optional expression parameter (0, 1, or 2) that determines what type of diagnostic message is printed. The amount of diagnostic messages output increases with the value of the optional parameter passed to $stop. D.31 $strobe See Appendix B, B.2 Strobed Monitoring, for details. D.32 $time, $stime and $realtime See $time in Appendix B.4.1 The $time System Function, B.4.2 The $realtime System Function, and B.6 Simulation Time—The $time Function for details. D.33 $timeformat See Appendix B, B.5.2 The $timeformat System Task for details. D.34 $write See Appendix B, B.1 The Display and Write Tasks, for details. Verilog HDL LRM 265 • List of System Task and System Function Keywords List of Compiler Directive Keywords E.0 Compilier Directive Overview The following list gives all the keywords currently used by the Verilog family of products for names of compiler directives. See Appendix C, Compiler Directives, for descriptions of some frequently used compiler directives. • `accelerate • `autoexpand_vectornets • `celldefine • `default_nettype • `define • `else • `endcelldefine • `endif • `endprotect • `endprotected • `expand_vectornets • `ifdef • `include • `noaccelerate • `noexpand_vectornets • `noremove_gatenames • `noremove_netnames • `nounconnected_drive • `protect • `protected • `remove_gatenames • `remove_netnames • `resetall • `timescale Verilog HDL LRM 266 • List of Compiler Directive Keywords • `unconnected_drive E.1 `accelerate and `noaccelerate The directive `accelerate results in an acceleration algorithm being applied to modules following the directive. There is also a `noaccelerate directive that causes those modules which follow to use a normal algorithm. These directives can only be specified outside the module definitions. Any number of these directives may appear in the source description. E.2 `autoexpand_vectornets This directive lets the compiler expand vectors as needed to form proper connections between elements of the description. This directive may only appear outside a module boundary. E.3 `celldefine and `endcelldefine The directives `celldefine and `endcelldefine tag modules as cell modules. Cells are used by certain PLI routines for applications such as delay calculations. It is advisable to pair each `celldefine with an `endcelldefine. More than one of these pairs may appear in a single source description. These directives may appear anywhere in the source description but it is recommended that the directives are specified outside the module definition. E.4 `default_nettype See Appendix C, C.2 `default_nettype, for details. E.5 `define See Appendix C, C.1 `define, for details. E.6 `expand_vectornets This directive causes all vector nets to be expanded into a group of scalar nets, except those with the keyword vectored in their declarations. This directive may only appear outside a module boundary. E.7 `ifdef, `else, `endif These conditional compilation compiler directives are used to optionally include lines of a Verilog HDL source description during compilation. The `ifdef compiler directive checks for the definition of a variable name. If the variable name is defined then the lines following the `ifdef directive are included. If the variable name is not defined and an `else directive exists then this source is compiled. Verilog HDL LRM 267 • List of Compiler Directive Keywords Note: SILOS III has a reserved keyword “silos” that is always true. This enables you to enclose Silos specific code and commands with a `ifdef … `else … `endif compiler directive so they can be run in SILOS III but not other simulators or synthesis tools. These directives may appear anywhere in the source description. Situations where the `ifdef, `else, and `endif compiler directives may be useful include: • selecting different representations of a module such as behavioral, structural, or switch level • choosing different timing or structural information • selecting different stimulus for a given run of a tool Syntax: The `ifdef, `else, and `endif compiler directives have the following syntax: `ifdef <text_macro_name> <first_group_of_lines> `else <second_group_of_lines> `endif The text_macro_name is a Verilog HDL identifier. The first_group_of_lines and second_group_of_lines are any parts of a Verilog HDL source description. The `else compiler directive and second_group_of_lines are optional. The `ifdef, `else, and `endif compiler directives work in the following manner: • When an `ifdef is encountered, the text_macro_name is tested to see if it is defined as a text macro name using `define within the Verilog HDL source description. • If the text_macro_name is defined, the first_group_of_lines is compiled as part of the description. If there is an `else compiler directive, the second_group_of_lines is ignored. • If the text_macro_name has not been defined, the first_group_of_lines is ignored. If there is an `else compiler directive the second_group_of_lines is compiled. Example E-1 shows the `ifdef, `else, and `endif compiler directives in a module. module and_op (a, b, c); output a; input b, c; `ifdef behavioral wire a = b & c; `else Verilog HDL LRM 268 • List of Compiler Directive Keywords and (a,b,c); `endif endmodule Example E- 1: An example of the conditional compilation specification Syntax checking Any group of lines that the compiler ignores still must follow the Verilog HDL lexical conventions for white space, comments, numbers, strings, identifiers, keywords, and operators. E.7.1 Nesting the `ifdef, `else, and `endif Compiler Directives You can nest the `ifdef, `else, and `endif compiler directives as shown in Example E-2. module test(out); output out; `define wow `define nest_one `define second_nest `define nest_two `ifdef wow initial $display("wow is defined"); `ifdef nest_one initial $display("nest_one is defined"); `ifdef nest_two initial $display("nest_two is defined"); `else initial $display("nest_two is not defined"); `endif `else initial $display("nest_one is not defined"); `endif `else initial $display("wow is not defined"); `ifdef second_nest initial $display("nest_two is defined"); `else initial $display("nest_two is not defined"); `endif `endif endmodule Verilog HDL LRM 269 • List of Compiler Directive Keywords Example E- 2: Nested `ifdef, `else, and `endif compiler directives E.7.2 Defining Variable Names to Control Conditional Compilation The `ifdef variables are defined using the compiler directive (`define) to define a text macro. The `define compiler directive The `define compiler directive allows you to create macros for text substitution (see also C.1 `define). Text macros may be placed both inside and outside module definitions. When a tool encounters the `ifdef compiler directive, it checks to see if its variable name matches a text macro name in a `define compiler directive. The syntax for this usage of the `define compiler directive is as follows: `define <text_macro_name> [<macro_contents>] E.8 `include The file inclusion (`include) compiler directive is used to insert the entire contents of a source file in another file during compilation. The result is as though the contents of the included source file appear in place of the `include command. The `include compiler directive can be used to include global or commonly used definitions and tasks without encapsulating repeated code within module boundaries. Advantages of using the `include compiler directive include the following: • providing an integral part of configuration management • improving the organization of Verilog HDL source descriptions • facilitating the maintenance of Verilog HDL source descriptions Syntax: The syntax for the `include compiler directive is as follows: `include "<filename>" The compiler directive `include can be specified anywhere within the Verilog HDL description. The <filename> is the name of the file to be included in the source file. The <filename> can be a full or relative path name, as in the following example: `include "parts/count.v" Verilog HDL LRM 270 • List of Compiler Directive Keywords Only white space or a comment may appear on the same line as the `include compiler directive. Examples of legal comments for the `include compiler directive are as follows: `include "fileB"`include "fileB" // including fileB Nested `include Compiler Directives An `include file can contain other `include compiler directives. Recursive `include directives are considered an error. E.9 `noexpand_vectornets This directive causes no expansion to take place except where explicitly specified by the keyword scalared in a vector net declaration. This directive may only appear outside a module boundary. E.10 `protect and `endprotect These directives are used to mark regions in a source description that will be processed by a tool into an intermediate form. This allows proprietary Verilog source descriptions to be protected from being accessed or modified. These directives may appear anywhere in the source description. E.11 `protected and `endprotected The directive `protected and `endprotected bound a region once it has been compiled into a protected form. A tool is passed a file containing a Verilog source description with the directives `protect and `endprotect. After processing, a new source file is created that differs from the original file in two ways: • the directive `protect and `endprotect become `protected and `endprotected respectively. • the regions marked for protection in the original source description become unreadable. E.12 `remove_gatenames and `noremove_gatenames The directive `remove_gatenames causes any gate instance names that have been specified in modules affected by this directive to be eliminated from the second and all subsequent instances of each module. This directive cannot be used if it is necessary to refer to gates by hierarchical name. The directive `noremove_gatenames stops the elimination of gate names. These directives must be specified outside the module definition. All the modules between `remove_gatenames and `noremove_gatenames are affected. Verilog HDL LRM 271 • List of Compiler Directive Keywords E.13 `remove_netnames and `noremove_netnames The directive `remove_netnames causes any net names that have been specified in modules affected by this directive to be eliminated from the second and all subsequent instances of each module. This directive cannot be used if it is necessary to refer to nets by hierarchical name. The directive `noremove_netnames stops the elimination of names. These directives must be specified outside of modules. All modules between `remove_netnames and `noremove_netnames are affected. E.14 `resetall See Appendix C, C.4 `resetall, for details. E.15 `timescale See Appendix C, C.5 `timescale, for details. E.16 `unconnected_drive and `nounconnected_drive The directive `unconnected_drive causes unconnected input ports to be automatically pulled up (if pull1 is specified) or down (if pull0 is specified) instead of floating to the high impedance value z. Inputs are pulled up or down in all modules between the directives `unconnected_drive and `nounconnected_drive. This directive may only appear outside a module boundary. Verilog HDL LRM 272 • List of Compiler Directive Keywords List of Keywords Keywords Keywords are pre-defined non-escaped identifiers which define the language constructs. An escaped identifier is never treated as a keyword. All keywords are defined in lower-case unless the upper-case option is used when compiling. always and assign (see also assign) begin buf bufif0 bufif1 case casex casez cmos deassign default defparam disable edge else end endcase endmodule endfunction endprimitive endspecify endtable endtask event for force forever fork function highz0 highz1 273 • List of Keywords Verilog HDL LRM if initial inout input integer join large macromodule medium module nand negedge nmos nor not notif0 notif1 or output parameter pmos posedge primitive pull0 pull1 pullup pulldown rcmos reg release repeat rnmos rpmos rtran rtranif0 rtranif1 scalared small specify specparam 274 • List of Keywords Verilog HDL LRM strength strong0 strong1 supply0 supply1 table task time tran tranif0 tranif1 tri tri0 tri1 triand trior trireg vectored wait wand weak0 weak1 while wire wor xnor xor 275 • List of Keywords Verilog HDL LRM Index i in state table 93 ! ! compared to ‘==0’ 38 logical negation operator 38 " "" null string 47 $ $bitstoreal 166, 234 $countdrivers 255 syntax 255 $display 225 compared to $monitor 226 compared to $write 218 escape sequences 219 size of displayed data 222 syntax 218 $dumpall 256 $dumpfile 256 $dumpflush 256 $dumplimit 256 $dumpoff 256 $dumpon 256 $dumpvars 256 $fclose 258 syntax 257 $fdisplay 258 syntax 257 $finish 233 syntax 233 $fmonitor 258 syntax 257 $fopen 258 syntax 257 $fstrobe 258 syntax 257 $fwrite 258 syntax 257 $getpattern 259 $hold 236 $incsave syntax 265 276 • Index $input syntax 260 $itor 234 $keepcommands 260 $list syntax 261 $monitor 226 and fixed width format 223 compared to $display 226 syntax 226 turn off 227 $monitoroff 226 syntax 226 $monitoron 226 syntax 226 $period 238 $printtimescale 230 $readmemb 262 syntax 262 $readmemh 262 syntax 262 $realtime 228 $timeformat 230 $realtobits 166, 234 $recovery 239 $restart syntax 265 $rtoi 234 $save syntax 265, 267 $setup 236 $setuphold 240 $skew 239 $stime syntax 233 $strobe 226 compared to $display 226 syntax 226 $time 27, 228, 233 $timeformat 230 syntax 233 $timeformat 233 $width 238 $write 225 compared to $display 218 escape sequences 219 size of displayed data 222 syntax 218 % % in format specifications 219, 222 Verilog HDL LRM logical OR operator 37 & && logical AND operator 37 < , << left shift operator 41 ,, in null expressions 219 = = in assignment statement 51 : :concatenation operator 43 :for escape sequences in strings 219 > ? >> right shift operator 41 ? equivalent to z in literal number values 8, 118 in state table 91, 93 @ @ for addressing memory 262 ` ` in compiler directives 247 `accelerate compiler directive 271 `autoexpand_vectornets compiler directive 271 `celldefine compiler directive 271 `default_nettype 248 syntax 249 `define 247 and text macro substitutions 14 `else compiler directive 271 `endcelldefine compiler directive 271 `endif compiler directive 271 `expand_vectornets compiler directive 271 `ifdef compiler directive 271 `include compiler directive 274 `noaccelerate compiler directive 271 `noexpand_vectornets compiler directive 275 `nounconnected_drive 249 `protect compiler directive 275 `remove_gatenames compiler directive 275 `remove_netnames compiler directive 276 `resetall 249 `timescale 249 `unconnected_drive 249 `unconnected_drive compiler directive 276 | || 277 • Index 0 0 for minimizing bit lengths of expressions 222 logic zero 15 01 transition 93 1 1 logic one 15 A acceleration and module path destinations 181 always and activity flow 104, 105 as structured procedure 134 syntax 136 ambiguous strength 79 arguments for system timing checks 235 arithmetic operators 35 % 34 * 34 / 34 + 34 and unknown logic values 35 arrays element 25 index 25 no multiple dimension 25 of integers 27 of time variables 27 word 25 assign keyword 51, 153 assignment 56 continuous 51, 105 Verilog HDL LRM left hand side 51 of delays to module paths 189 procedural 107 procedural versus continuous 105 right hand side 51 B b binary number format 7 base format binary 7 decimal 7 hexadecimal 7 octal 7 begin-end block statement 112, 130 behavioral modeling 138 bidirectional pass gate 65 binary display format 7 and high impedance state 223 and unknown logic value 223 binary operators 33 precedence 33 binary operators: 43 bit-select of vector net or register 44 out of bounds 44, 45 references of real numbers 29 bit-wise operators 39 compared to logical operators 39 blank module terminal 158 block statement 134 definition 129 fork-join 129 naming of 133 parallel 129 sequential 129, 131 start and finish times 134 timing for embedded blocks 133 blocking procedural assignment 106 processing assignments 111 syntax 106 bufif gate 63 C capacitive networks 24 case statement compared to if-else-if statement 116 syntax 115 casex 117 casez 117 cells 155 charge storage strength 20 charge storage strength 68 278 • Index checkpoints 265 cmos 66 cmos gate 66 collapsing ports 169 chart of resulting net types 168 rules 168 that connect nets of different types 168 combinational UDPs 86 compared to level-sensitive sequential 92 input and output fields in state table 89 combined signal strengths 79 combined signal values 79 comments 6 compare string operation 46 compiler directives 247 concatenation and repetition multiplier 43 and unsized numbers 43 of names 169 of operands 43 operator 43 string operation 46 concurrency of activity flow 104 condition deterministic 246 non-deterministic 246 conditional operator 42 and ambiguous results 42 modeling tri-state output busses 42 syntax 42 conditional statement syntax 111 conditioned event 246 constraints 246 versus unconditioned event 245 conflicts 21 connecting ports by name 166 by position with ordered list 164 rules 168 connection difference between full and parallel 184 full 184 parallel 184 constant expression 31 continuous assignment 51 and $getpattern 259 and connecting ports 167 and driving strength 68, 224 and net variables 105 and supply nets 25 and wire nets 21 driving strength of 55 explicit declaration 53 Verilog HDL LRM implicit declaration 53 syntax 51 versus procedural assignment 56 continuous monitoring 226 copy string operation 46 counting number of drivers 255 D d decimal number format 7 data types 30 deassign keyword 153 decimal display format 7 and high impedance state 222 and unknown logic value 222 compatibility with $monitor 223 decimal notation 28 declaring events 125 multiple module paths in a single statement 185 parameters in specify blocks 178 default in case statement 115 in if-else-if statements 114 defparam 30, 160 delay calculating for high impedance (z) transitions 81 calculating for unknown logic value (x) transitions 81 control 122, 123 distributed 180 fall 81 falling 83 gate 83 inertial 55 module path 202 propagation 60, 81 rise 81, 83 specify one value 81 specify three values 81 specify two values 81 syntax for delay control 123 turn-off 83 delay specification 60 describing module paths 184 diagnostic messages from $stop and $finish 233 disable and turning off monitoring tasks 227 named blocks 151 syntax 147 tasks 151 use of 147 displaying information 225 distributed delays and SDPDs 194 279 • Index dominating net 168 don’t-care bits in case statements 118 don’t-care condition in state table 91 drive strength specification 59 driving strength 68 compared to charge storage strength 224 keywords 55 E edge control specifiers 242 edge descriptors 29 edge transitions 241 edge-sensitive paths 202 syntax 200 edge-sensitive UDPs 93 compared to level-sensitive UDPs 92 element of array 25 embedding modules 155, 156 enable 126 enabling tasks 141, 143 endmodule keyword 155 endprimitive keyword 88 endtable keyword 89 equality operators 37 and ambiguous results 37 and operands of different sizes 37 precedence 37 escape sequences 218, 219 escaped identifiers 11 event control 123, 124 declaration syntax 125 explicit 123 expression 123 implicit 123 level sensitive control 126 named 125 OR construct 126 syntax of triggering statement 125 event control repeat 129 examples "joining" events 133 $monitor 224 $strobe 226 $width timing check 238 ‘timescale compiler directive 251 begin-end block 130 behavioral model 104 bit-select 44 calculating delays for unknown logic value transitions 189 Verilog HDL LRM case statement 116 casex 118 casez in instruction decoder 118 delay control 123 disable statement 151 edge-sensitive paths 200 edge-sensitive UDP 93 escaped identifiers 11 event OR construct 126 factorial function 146 for loop 121 for loop in multiplier 122 hierarchical path names 171 identifiers 11 if-else statement 114 infinite zero-delay loop 136 intra-assignment timing controls 127 level-sensitive paths 199 loading memories from text files 263 memory addressing 45 memory declaration 26 minimum typical maximum values 48 module instance 157 part-select 45 passing module parameters to tasks 142 problem in string value padding 47 race condition 127 real numbers 28 register and net declarations 18, 19 repeat loop in multiplier 120 SDPDs 193 sized constant numbers 8 specify block 177 specify parameters 178 specparams 178 strength outputs 224 strings 9 system tasks 12 text macro substitutions 248 time-sequenced waveform 131 traffic light sequencer 137 tri-state output bus 42 two sequential events working in parallel 134 variable delays for synchronizing clock 138 vector XOR 55 while loop in counter 120 exit simulator 233 expansion of macro modules 162 of vector nets 19 explicit event 123 expressions 50 bit lengths 50 constant 31 280 • Index self-determined 49 F fall delay 81, 83 files output to 258 finish time in parallel block statements 133 in sequential block statements 133 for loop 119 force keyword 154 force keyword:precedence over assign 153 forever loop 119 fork-join block statement 129 format specifications timescales 221 format specifications string 225 format specifications t or T 221 full connection 184 function syntax 144 functions and scope 174 as structured procedures 134 definition 135 purpose 139 returning a value 145 rules 145 syntax for function call 145 G gate level modeling logic gate syntax 60 gate type specification 58 gates bidirectional pass 65 bufif 63 cmos 66 compared to continuous assignments 57 connection list 60 delay 83 notif 63 notif0 63 notif1 63 pulldown 66 pullup 66 syntax 60 terminal list 60 ground 25 guidelines for connection operators 183 Verilog HDL LRM H K h keywords 12 compiler directive 270 system function 253 system task 253 Verilog 277 hexadecimal number format 7 hexadecimal display format 7 and high impedance state 223 and unknown logic value 223 hierarchy level 169 of modules 155 scope 169 scope rules for naming 174 top level names 169 high impedance state and numbers 8 and trireg nets 22 and user-defined primitives 96 effect in different bases 8 symbolic representation 15 highz0 59 highz1 59 I identifiers 11 definition 10 escaped 11 keywords 12 if-else statement omitting else from nested if 112 purpose 111 if-else-if statement compared to case statement 116 syntax 113 implicit declarations 20, 248 event 123 incremental restart 266 incremental save 265 index of array 25 of memory 26 inertial delay 55 initial 135 and activity flow 104, 105 for specifying waveforms 135 syntax 135 initial statements in UDPs 95 instantiation macro module 162 of modules 155 integers 27 division 34 intra-assignment timing controls 129 281 • Index L left shift operator 41 Legal module paths One output driver 195 level-sensitive event control 126 paths 199 sequential UDPs 92 versus combinational UDP 92 level-sensitive UDPs compared to edge-sensitive UDPs 92 lexical conventions 14, 248 lexical token comment 6 definition of 6 number 7 operator 6 types 6 white space 6 libraries and ‘resetall 249 logic gates bidirectional pass 65 bufif 63 cmos 66 compared to continuous assignments 57 delay 83 notif 63 pulldown 66 pullup 66 syntax 60 logic one 15 logic strength modeling 81 logic zero 15 logical operators 37 ! 38 && 37 || 37 and ambiguous results 37 and unknown logic value 37 compared to bit-wise operators 39 precedence 37 looping statement for loop 119 forever loop 119 repeat loop 119 while loop 119 Verilog HDL LRM lsb (least significant bit) 18 M macro module 162 expansion 162 instantiation 162 macromodule keyword 162 syntax 162 macros and ‘define 247 memory 26 addressing 45 assigning values to 26 declaration syntax 25 index 26 real number memories 29 using temporary registers for bit- and part-selects 45 minimum typical maximum values for module path delays 186, 188 format 48 modeling asynchronous clear/preset on an edge-triggered D flip-flop 152 behavioral 138 logic strength 81 module and user-defined primitives 88 hierarchy 155 instance parameter value assignment 161 keyword 155 macro 162 overriding parameter values 162 parameter dependencies 161 port 158 syntax 156 for specifying instantiations 156 terminal 158 top-level 156 module parameter as delay 30 as width of variables 30 compared to specify parameter 177, 178 dependencies 161 overriding values 162 passing to tasks 142 syntax 29 module path definition 181 delay 202 delay assignment 185 description syntax 182 destination 181, 185 polarity 197 282 • Index source 178, 181, 185 modulus operator definition 34 monitor flag 227 monitoring continuous 226 strobed 226 msb (most significant bit) 18 multi-channel descriptor 256, 257 multiple drivers at same strength level 78 driving the same net 21 inside a module 184, 195 outside a module 195 multiple module path delays assigning in one statement 185 multi-way decisions case statement 115 if-else-if statement 114 N named blocks and hierarchical names 169 and scope 174 purpose 133 named events 125 used with event expressions 125 negedge 242 net and register bit addressing 44 nets 25 delay 83 implicit declaration 67 initialization 20 scalar 167 trireg strength 68 types of 25 wired logic 78 nmos 65 node in hierarchical name tree 169 non_blocking procedural assignment 111 evaluating assignments 107 multiple assignments 110 processing assignments 111 syntax 107 notif gate 63 notifier 245 toggle values 243 null expression 219 string 47 numbers 7 base format 7 size specification 7 Verilog HDL LRM O o octal number format 7 octal display format 7 on/off control of monitoring tasks 227 operands 47 bit-select 43 concatenation 43 definition 31 function call 43 part-select 43 strings 47 operators 43 ! 38 && 37 *> 185 || 37 << 41 = 51 => 185 >> 41 and real numbers 29 arithmetic 35 binary 6, 33 bit-wise 39 concatenation 43 conditional 42 definition 6 equality 37 left shift operator 41 logical 37 reduction 41 relational 36 right shift operator 41 shift 41 ternary 6 unary 6 operators: 43 optimization of processing stimulus patterns 259 output to files 258 overriding module parameter values 162 assigning values in-line within module instances 161 defparam 162 compared to assignmesions 161 P parallel block statement finish time 133 fork-join 129 start time 133 syntax 132 283 • Index parallel connection 184 parameter keyword for module parameters 177 module type 29 syntax 29 parentheses and changing operator precedence 34 part-select of vector net or register 44 references of real numbers 29 syntax 44 pmos 65 polarity 197 negative 196 positive 197 unknown 196 port 169 collapsing 167 connecting by name 166 by position with ordered list 164 rules for 168 declaration 163 definition 162 module 158 of user-defined primitives 89 rules for collapsing 168 posedge 242 power supplies modeled by supply nets 25 precedence binary operators 33 equality operators 37 logical operators 37 relational operators 36 primitive instance identifier 60 primitive keyword 88 procedural assignment 107 and integers 27 and time variables 27 blocking 106 non_blocking 111 versus continuous assignment 56 procedural continuous assignments 153, 154 assign 153 deassign 153 definition 152 syntax 152 procedural continuous assignments: release 154 procedural continuous assignments:force 154 procedural continuous assignments:precedence 153 procedural statements in behavioral models 104 procedural timing controls 129 delay control 123 event control 123 Verilog HDL LRM fork-join block 133 intra-assignment timing controls 129 procedure always statement 134 function 134 initial statement 134 task 134 propagation delay for gates and nets 81 in logic gate syntax 60 pull0 59 pull1 59 pulldown source 66 pullup source 66 Q qualified paths 202 edge-sensitive 202 level-sensitive 199 R race condition 127 random access memory(RAM) modeled by register arrays 25 range syntax 19 rcmos 66 read-only memory(ROM) modeled by register arrays 25 real numbers 29, 234 and operators 29 conversion to integers 29 format specifications used with 221 in port connections 166 operators with real number operands 33 specifying 28 syntax 28 reducing pessimism 99, 116 reduction operators 41 syntax restrictions 41 unary NAND 40 unary NOR 40 registers 19 and level-sensitive sequential UDPs 91 declaration syntax 25 for modeling memories 25 notifier 243 used in procedural assignments 56 relational operators 36 and unknown bit values 36 precedence 36 release keyword 154 repeat event control 129 repeat loop 119 284 • Index repetition multiplier 43 resistive devices modeled with tri0 and tri1 nets 25 restrictions on data types in continuous assignments 51, 56, 167 in port collapsing 167 in procedural assignments 51, 56, 105 when connecting ports 167 right shift operator 41 rise delay 81, 83 rnmos 65 rpmos 65 rtranif0 65 rtranif1 65 rules for describing module paths 184 S s in string display format 225 scalars compared to vectors 18 scalar nets and driving strength of continuous assignment 55 scientific notation 28 scope and hierarchical names 169 rules 174 SDPDs 194 and multiple path delays 193 SDPDs and distributed delays 194 self-determined expression 49 sequential block statement 131 finish time 133 start time 133 syntax 130 sequential UDP initialization 95 sequential UDPs input and output fields in state table 89 set of values (0, 1, x, z) 15 shift operators 41 << 41 >> 41 signed arithmetic bit length rules 49 integers signed arithmetic 27 losing bits 48 registers are unsigned arithmetic 16 silos keyword 271 simulating module path delays when driving wired logic 195 simulation going back with incremental restart 266 simulation time and timing controls 123 time 233 Verilog HDL LRM size of displayed data 222 sized numbers 7 source pulldown 66 pullup 66 specify block system tasks $hold 236 $period 238 $recovery 239 $setup 236 $setuphold 240 $skew 239 $width 238 specify parameter 178 advantages over module parameters 178 specify parameters as run time constant in specify block 177 specifying transition delays on module paths 189 assigning one value 186 assigning six values 188 assigning three values 187 assigning two values 187 x transitions 189 specparam 178 advantages over module parameter 178 syntax 177 versus module parameter 178 standard output 257 start time in parallel block statements 133 in sequential block statements 133 state dependent path delays 194 state dependent path delays and distributed delays 194 strength 60 ambiguous 79 and logic conflicts 21 and scalar net variables 15 charge storage 68 driving 68 gates that accept specifications 59 of combined signals 79 on trireg nets 22 range of possible values 71 reduction by non-resistive devices 80 reduction by resistive devices 80 scale of strengths 69 supply net 81 tri0 80 tri1 80 trireg 81 strings 47 definition 9 display format 225 in vector variables 46 manipulation 9 285 • Index operations 46 padding 9 special characters 10 value padding 47 variable declaration 9 strobed monitoring 226 strong0 59 strong1 59 structured procedure 138 always statement 134 function 134 initial statement 134 task 134 supply net strength 81 supply nets 25 supply0 59 supply1 59 switches MOS 65 syntax $display 218 $fclose 257 $fdisplay 257 $finish 233 $fmonitor 257 $fopen 257 $fstrobe 257 $fwrite 257 $getpattern 259 $incsave 265, 267 $keepcommands 260 $list 260, 261 $monitor 226 $monitoroff 226 $monitoron 226 $readmemb 262 $readmemh 262 $restart 265, 267 $save 265, 267 $stime 233 $stop 233 $strobe 226 $time 233 $write 218 ‘default_nettype 249 always 136 assign 152 behavioral statements 211 case statement 115 conditional operator 42 conditional statement 111 continuous assignment 51 deassign 152 declarations 208 declaring events 125 delay control 123 Verilog HDL LRM disable statement 147 edge-sensitive paths 200 event control 124 event triggering statement 125 expressions 217 for addressing memory 45 for enabling tasks 141 for loop 119 force 152 forever loop 119 formal definition 217 function 144 function call 145 general 217 if-else-if statement 113 initial statement 135 integer declaration 27 level-sensitive paths 198 logic gates 60 macro module 162 memory declaration 25 module 156 module instantiation 156, 209 module parameter 29 module path delay assignment 185 module path description 182 parallel block statement 132 part-select 44 port declaration 163 definition 162 primitive instances 208 procedural continuous assignments 152 range 19 real numbers 28 register declaration 25 release 152 repeat loop 119 SDPD 190 sequential block statement 130 source text 206 specify block 176 specify parameter 177 specify section 215 specparam 177 state dependent path delays 190 text macro definitions 13, 247 usage 13, 247 time variable declaration 27 UDPs 88 wait statement 126 while loop 119 system functions 246 system tasks 246 for continuous monitoring 226 286 • Index for displaying information 225 for fetching simulation time 233 for interrupting the simulator 233 for processing stimulus patterns faster 259 for showing number of drivers 255 for writing formatted output to files 258 showing the timescale of a module 230 specifying how %t reports time information 233 specifying the time unit of delays entered interactively 233 system tasks and functions 246 T t timescale format 221, 229 table keyword 89 tasks and hierarchical names 169 and scope 173 as structured procedures 134 definition 135 disabling within a nested chain 147 enabling 141, 143 passing parameters 142 purpose 139 syntax for enabling 141 terminal in logic gate syntax 60 module 158 ternary operators ?: 33 text macro substitutions 14, 248 and ‘define 247 definition syntax 13, 247 in interactive mode 13 redefinition 14, 248 usage syntax 13, 247 time 233 and incremental restart 266 arithmetic operations performed on time variables 27 simulation 123 variables 27 time precision 250 time unit 250 timeformat $timeformat 230 timing checks 246 $hold 236 $period 238 $recovery 239 $setup 236 $setuphold 240 $skew 239 $width 238 Verilog HDL LRM arguments 235 data_event 235 end_edge_offset 235 hold_limit 235 limit 235 list of system tasks 235 notifier 235 reference_event 235 setup_limit 235 start_edge_offset 235 threshold 235 top-level module 156 tran 65 tranif0 65 tranif1 65 transistors 65 transitions 01 93 order for module path delay assignment 188 unspecified 93 tree structure of hierarchical names 169 tri nets 25 trireg and charge storage strength 68 turn-off delay 83 types of nets supply nets 25 tri nets 21 tri0 80 tri0 nets 25 tri1 80 tri1 nets 25 triand 21 trior 21 trireg 81 trireg nets 22, 224 wire 21 wired AND 21 wired logic 78 wired nets 21 wired OR 21 U UDPs definition 89 edge-sensitive UDPs 93 level-sensitive dominance 99, 100 level-sensitive sequential UDPs 92 mixing level- and edge-sensitive descriptions 98 ports 89 reducing pessimism 99 state table 89 summary of symbols in state table 100 unary operators 287 • Index ! 38 << 41 >> 41 unconnected port 158 underline character 8 unknown logic value and numbers 8 effect in different bases 8 in state table 89, 90, 93 symbolic representation 15 unspecified transitions 93 user-defined primitives definition 89 edge-sensitive 93 level-sensitive dominance 100 level-sensitive sequential 92 mixing level- and edge-sensitive descriptions 98 ports 89 reducing pessimism 99 state table 89 summary of symbols in state table 100 V value change dump file 256 value set (0, 1, x, z) 15 values of combined signals 79 Vcc 25 VCD value change dump file 256 Vdd 25 vectors 18 and vector net expansion 19 Vss 25 W wait statement as level-sensitive event control 126 syntax 126 to advance simulation time 123 weak0 59 weak1 59 while loop 119 white space 6 wired logic nets wand 78 wired-AND configurations 21 wired-OR configurations 21 wor 78 wires 21 word of array 25 writing formatted output to files 258 Verilog HDL LRM X x as display format for unknown logic value 222 in state table 89, 90 unknown logic value 15 X as display format for unknown logic value 223 Z z as display format for high impedance state 222 high impedance state 15 Z as display format for high impedance state 223 288 • Index Verilog HDL LRM