VlogAMS 2.2 Pub
VlogAMS 2.2 Pub
VlogAMS 2.2 Pub
org
Accellera
Version 2.2, November 2004 This is a stripped down version of the Verilog-AMS LRM. The material concerning VPI
(Chapters 12 and 13) and Syntax (Annex A) have been removed. The full Verilog-AMS
LRM is available for a fee from www.accellera.com.
Last updated on May 12, 2006. You can find the most recent version at www.designers-
guide.org.
Permission to make copies, either paper or electronic, of this work for personal or classroom
use is granted without fee provided that the copies are not made or distributed for profit or
commercial advantage and that the copies are complete and unmodified. To distribute other-
wise, to publish, to post on servers, or to distribute to lists, requires prior written permission.
Verilog-AMS
Language Reference Manual
Version 2.2
November 2004
Accellera
www.designers-guide.org
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 Accellera.
Additional copies of this manual may be purchased by contacting Accellera at the address shown below.
Notices
The information contained in this draft manual represents the definition of the Verilog-AMS hardware
description language as proposed by Accellera (Analog and Mixed-Signal TSC) as of November 2004. Accellera
makes no warranties whatsoever with respect to the completeness, accuracy, or applicability of the information
in this draft manual to a user’s requirements.
Accellera reserves the right to make changes to the Verilog-AMS hardware description language and this manual
at any time without notice.
Accellera does not endorse any particular simulator or other CAE tool that is based on the Verilog-AMS
hardware description language.
Suggestions for improvements to the Verilog hardware description language and/or to this manual are welcome.
They should be sent to the address below.
Information about Accellera and membership enrollment can be obtained by inquiring at the address below.
ii
www.designers-guide.org
STATEMENT OF USE OF
ACCELLERA STANDARDS
Accellera Standards documents are developed within Accellera and the Technical Committees of Accellera
Organization, Inc. Accellera develops its standards through a consensus development process, approved by its
members and board of directors, which brings together volunteers representing varied viewpoints and interests to
achieve the final product. Volunteers are not necessarily members of Accellera and serve without compensation.
While Accellera administers the process and establishes rules to promote fairness in the consensus development
process, Accellera does not independently evaluate, test, or verify the accuracy of any of the information
contained in its standards.
Use of an Accellera Standard is wholly voluntary. Accellera disclaims liability for any personal injury, property
or other damage, of any nature whatsoever, whether special, indirect, consequential, or compensatory, directly or
indirectly resulting from the publication, use of, or reliance upon this, or any other Accellera Standard document.
Accellera does not warrant or represent the accuracy or content of the material contained herein, and expressly
disclaims any express or implied warranty, including any implied warranty of merchantability or suitability for a
specific purpose, or that the use of the material contained herein is free from patent infringement. Accellera
Standards documents are supplied “AS IS.”
The existence of an Accellera Standard does not imply that there are no other ways to produce, test, measure,
purchase, market, or provide other goods and services related to the scope of an Accellera Standard.
Furthermore, the viewpoint expressed at the time a standard is approved and issued is subject to change due to
developments in the state of the art and comments received from users of the standard. Every Accellera Standard
is subjected to review periodically for revision and update. Users are cautioned to check to determine that they
have the latest edition of any Accellera Standard.
In publishing and making this document available, Accellera is not suggesting or rendering professional or other
services for, or on behalf of, any person or entity. Nor is Accellera undertaking to perform any duty owed by any
other person or entity to another. Any person utilizing this, and any other Accellera Standards document, should
rely upon the advice of a competent professional in determining the exercise of reasonable care in any given
circumstances.
Interpretations: Occasionally questions may arise regarding the meaning of portions of standards as they relate to
specific applications. When the need for interpretations is brought to the attention of Accellera, Accellera will
initiate action to prepare appropriate responses. Since Accellera Standards represent a consensus of concerned
interests, it is important to ensure that any interpretation has also received the concurrence of a balance of
interests. For this reason, Accellera and the members of its Technical Committees are not able to provide an
instant response to interpretation requests except in those cases where the matter has previously received formal
consideration.
iii
www.designers-guide.org
Comments for revision of Accellera Standards are welcome from any interested party, regardless of membership
affiliation with Accellera. Suggestions for changes in documents should be in the form of a proposed change of
text, together with appropriate supporting comments. Comments on standards and requests for interpretations
should be addressed to:
Accellera Organization
1370 Trancas Street, #163
Napa, CA 94558
USA
Note: Attention is called to the possibility that implementation of this standard may require use of subject
matter covered by patent rights. By publication of this standard, no position is taken with respect to the
existence or validity of any patent rights in connection therewith. Accellera shall not be responsible for
identifying patents for which a license may be required by an Accellera standard or for conducting inquiries
into the legal validity or scope of those patents that are brought to its attention.
Accellera is the sole entity that may authorize the use of Accellera-owned certification marks and/or trademarks
to indicate compliance with the materials set forth herein.
Authorization to photocopy portions of any individual standard for internal or personal use must be granted by
Accellera Organization, Inc., provided that permission is obtained from and any required fee is paid to Accellera.
To arrange for authorization please contact Lynn Horobin, Accellera, 1370 Trancas Street #163, Napa, CA
94558, phone (707) 251-9977, e-mail [email protected]. Permission to photocopy portions of any individual
standard for educational classroom use can also be obtained from Accellera.
The following people contributed to the creation, editing, and review of this document.
iv
www.designers-guide.org
Table of Contents
1 Verilog-AMS introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1
1.1 Overview 1
1.2 Mixed-signal language features 2
1.3 Systems 3
1.3.1 Conservative systems 4
1.3.2 Kirchhoff’s Laws 5
1.3.3 Natures, disciplines, and nets 6
1.3.4 Signal-flow systems 6
1.3.5 Mixed conservative/signal flow systems 7
1.4 Conventions used in this document 10
1.5 Contents 11
4 Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.1 Operators 53
4.1.1 Operators with real operands 54
4.1.2 Binary operator precedence 55
4.1.3 Expression evaluation order 56
4.1.4 Arithmetic operators 56
4.1.5 Relational operators 57
4.1.6 Case equality operators 58
4.1.7 Logical equality operators 58
4.1.8 Logical operators 58
4.1.9 Bit-wise operators 59
4.1.10 Shift operators 60
4.1.11 Conditional operator 60
4.1.12 Event or 60
4.1.13 Concatenations 60
4.2 Built-in mathematical functions 61
4.2.1 Standard mathematical functions 61
4.2.2 Transcendental functions 62
4.2.3 Error handling 63
4.3 Signal access functions 63
5 Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .93
5.1 Analog signals 93
5.1.1 Access functions 93
5.1.2 Probes and sources 94
5.1.3 Examples 95
5.1.4 Port branches 97
5.1.5 Switch branches 98
5.1.6 Unassigned sources 99
5.2 Signal access for vector branches 99
5.2.1 Accessing net and branch signals 101
5.2.2 Accessing attributes 102
5.3 Contribution statements 102
5.3.1 Branch contribution statements 102
5.3.2 Indirect branch assignments 105
A Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .349
A.1 Source text 349
A.2 Natures 351
A.3 Disciplines 351
A.4 Declarations 352
A.5 Module instantiation 354
A.6 Mixed signal 354
A.7 Behavioral statements 355
A.8 Analog expressions 358
A.9 Expressions 358
A.10 General 361
B Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .363
B.1 All keywords 363
B.2 Discipline/nature 365
B.3 Connect rules 365
H Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405
Section 1
Verilog-AMS introduction
1.1 Overview
This Verilog-AMS Hardware Description Language (HDL) language reference manual
defines a behavioral language for analog and mixed-signal systems. Verilog-AMS HDL
is derived from IEEE 1364-1995 Verilog HDL. This document is intended to cover the
definition and semantics of Verilog-AMS HDL as proposed by Accellera.
Figure 1-1 shows the components and architecture of Verilog-AMS HDL, which
consists of the complete IEEE 1364-1995 Verilog HDL specification (noted as
Verilog-D in the figure), an analog equivalent for describing analog systems (noted as
Verilog-A), and extensions to both for specifying the full Verilog-AMS HDL (noted as
MS Extensions).
Verilog-AMS
Verilog-D
Verilog-A
1364-1995
OVI-96
MS
Extensions
• initial, always, and analog procedural blocks can appear in the same module
• both analog and digital signal values can be accessed (read operations) from any
context (analog or digital) in the same module
• digital signal values can be set (write operations) from any context outside of an
analog procedural block
• analog potentials and flows can only receive contributions (write operations)
from inside an analog procedural block
• the semantics of the initial and always blocks remain the same as in IEEE
1364-2001 Verilog HDL; the semantics for the analog block are described in
this manual
• when hierarchical connections are of mixed type (i.e., analog signal connected to
digital port or digital signal connected to analog port), user-defined connection
modules are automatically inserted to perform signal value conversion
1.3 Systems
A system is considered to be a collection of interconnected components which are acted
upon by a stimulus and produce a response. The components themselves can also be
systems, in which case a hierarchical system is defined. If a component does not have
any subcomponents, it is considered to be a primitive component. Each primitive
component connects to zero or more nets. Each net connects to a signal which can
traverse multiple levels of the hierarchy. The behavior of each component is defined in
terms of values at each net.
A signal is a hierarchical collection of nets which, because of port connections, are
contiguous. If all the nets which make up a signal are in the discrete domain, the signal
is a digital signal. If, on the other hand, all the nets which make up a signal are in the
continuous domain, the signal is an analog signal. A signal which consists of nets from
both domains is called a mixed signal.
Similarly, a port whose connections are both analog is an analog port, a port whose
connections are both digital is a digital port, and a port whose connections are both
analog and digital is a mixed port. The components connect to nodes through ports and
nets to build a hierarchy, as shown in Figure 1-2.
Ports
Node
Module Module
Module
A B
flow
+ potential -
These laws imply a node is infinitely small; so there is negligible difference in potential
between any two points on the node and a negligible accumulation of flow.
flow1
flow3 + -
- + + - potential2
flow2
potential potential
potential1
-
potential3
-
+
potential
+
-
+ -
potential4
KFL KPL
-potential1 -potential2
flow1 + flow2 + flow3 = 0 +potential3 + potential4 = 0
Figure 1-4 Kirchhoff’s Flow Law (KFL) and Potential Law (KPL)
nature only, current contributions to that node are not legal. Flow for such a node is not
defined.
Signal flow models may be written so potentials of module outputs are purely functions
of potentials at the inputs without taking flow into account.
The following example is a level shifting voltage follower:
specified, whereas conservative ports require types for both values (the potential and
flow).
Examples:
For example, consider a differential voltage amplifier, a differential current amplifier,
and a resistor. The amplifiers are written using signal-flow ports and the resistor uses
conservative ports.
analog
V(out) <+ GAIN_V * V(in) ;
endmodule
In this case, only the voltage on the ports are declared because only voltage is used in the
body of the model.
analog
I(out) <+ GAIN_I * I(in) ;
endmodule
Here, only current is used in the body of the model, so only current need be declared at
the ports.
analog
V(a,b) <+ R * I(a,b) ;
endmodule
The description of the resistor relates both the voltage and current on the ports. Both are
defined in the conservative discipline electrical.
In summary, only those signals types declared on the ports are accessible in the body of
the model. Conversely, only those signals types used in the body need be declared.
This approach provides all of the power of the conservative formulation for both signal-
flow and conservative ports, without forcing types to be declared for unused signals on
signal-flow nets and ports. In this way, the first benefit of the traditional signal-flow
formulation is provided without the restrictions.
The second benefit, that of a smaller, more efficient set of equations to solve, is provided
in a manner which is hidden from the user. The simulator begins by treating all ports as
being conservative, which allows the connection of signal-flow and conservative ports.
This results in additional unnecessary equations for those nodes which only have signal-
flow ports. This situation can be recognized by the simulator and those equations
eliminated.
Thus, this approach to allowing mixed conservative/signal-flow descriptions provides
the following benefits:
• Conservative components and signal-flow components can be freely mixed. In
addition, signal-flow components can be converted to conservative components,
and vice versa, by modifying only the component behavioral description.
• Many of the capabilities of conservative ports, such as the ability to access flow
and the ability to access floating potentials, are available with signal-flow ports.
• Natures only have to be given for potentials and flows if they are accessed in a
behavioral description.
• If nets and ports are used only in a structural description (only in instance
statements), then no natures need be specified.
1. Lower case words, some containing embedded underscores, are used to denote
syntactic categories. For example:
module_declaration
2. Bold face words are used to denote reserved keywords, operators and
punctuation marks as required part of the syntax. For example:
module = ;
5. Braces enclose a repeated item unless the braces appear in bold face, in which
case it stands for itself. The item can appear zero or more times; the repetitions
occur from left to right as with an equivalent left-recursive rule. Thus, the
following two rules are equivalent:
list_of_port_def ::=
port_def { , port_def }
list_of_port_def ::=
port_def
| list_of_port_def , port_def
6. If the name of any category starts with an italicized part, it is equivalent to the
category name without the italicized part. The italicized part is intended to
convey some semantic information. For example, msb_constant_expression
and lsb_constant_expression are equivalent to constant_expression, and
node_identifier is an identifier which is used to identify (declare or
reference) a node.
The main text uses italicized font when a term is being defined, and constant-width font
for examples, file names, and while referring to constants.
1.5 Contents
This document contains the following sections and annexes:
1. Verilog-AMS introduction
This section gives the overview of analog modeling, defines basic concepts, and
describes Kirchhoff’s Potential and Flow Laws.
2. Lexical conventions
This section defines the lexical tokens used in Verilog-AMS HDL.
3. Data types
This section describes the data types: integer, real, parameter, nature, discipline,
and net, used in Verilog-AMS HDL.
4. Expressions
This section describes expressions, mathematical functions, and time domain
functions used in Verilog-AMS HDL.
5. Signals
This section describes signals and branches, access to signals and branches, and
various transformation functions.
6. Analog behavior
This section describes the basic analog block and procedural language constructs
available in Verilog-AMS HDL for behavioral modeling.
7. Hierarchical structures
This section describes how to build hierarchical descriptions using Verilog-AMS
HDL.
8. Mixed signal
This section describes the mixed-signal aspects of the Verilog-AMS HDL
language.
9. Scheduling semantics
This section describes the basic simulation cycle as applicable to Verilog-AMS
HDL.
A. Syntax
This annex describes formal syntax for all Verilog-AMS HDL constructs in
Backus-Naur Form (BNF).
B. Keywords
This annex lists all the words which are recognized in Verilog-AMS HDL as
keywords.
C. Analog language subset
This annex describes the analog subset of Verilog-AMS HDL.
D. Standard definitions
This annex provides the definitions of several natures, disciplines, and constants
which are useful for writing models in Verilog-AMS HDL.
E. SPICE compatibility
This annex describes the SPICE compatibility with Verilog-AMS HDL.
F. Discipline resolution methods
This annex provides the semantics for two methods of resolving the discipline of
undeclared interconnect.
G. Open issues
This annex lists unresolved issues.
H. Glossary
This annex describes various terms used in this document.
Section 2
Lexical conventions
This section describes the lexical tokens used in Verilog-AMS HDL source text and their
conventions. This section is based on Section 2, Lexical conventions, of IEEE 1364-
1995 Verilog HDL. The changes specific to Verilog-AMS HDL can be found in
Section 2.5.3, Section 2.7.2, and Section 2.8.1.
• comment
• operator
• number
• string
• identifier
• keyword
2.3 Comments
Verilog-AMS HDL has two forms to introduce comments, as shown in Syntax 2-1. A
one-line comment starts with the two characters // and ends with a newline. Block
comments start with /* and ends with */. Block comments can not be nested. The
one-line comment token // does not have any special meaning in a block comment.
comment ::=
short_comment
| long_comment
short_comment ::=
// { any_ASCII_characters_except_end_of_line } \n
long_comment ::=
/* { any_ASCII_characters } */
comment_text ::=
{ Any_ASCII_character }
2.4 Operators
Operators are single, double, or triple character sequences and are used in expressions.
Section 4 discusses the use of operators in expressions.
Unary operators appear to the left of their operand. Binary operators appear between
their operands. A conditional operator has two operator characters which separate three
operands.
2.5 Numbers
Constant numbers can be specified as integer constants or real constants. The syntax for
constants is shown in Syntax 2-2.
number ::=
decimal_number
| digital_octal_number
| digital_binary_number
| digital_hex_number
| real_number
decimal_number ::=
[ sign ] unsigned_num
sign ::=
+|-
unsigned_num ::=
decimal_digit { _ | decimal_digit }
decimal_digit ::=
0|1|2|3|4|5|6|7|8|9
digital_number ::=
number
real_number ::=
[ sign ] unsigned_num . unsigned_num
| [ sign ] unsigned_num [ . unsigned_num ] e [ sign ] unsigned_num
| [ sign ] unsigned_num [ . unsigned_num ] E [ sign ] unsigned_num
| [ sign ] unsigned_num [ . unsigned_num ] scale_factor
scale_factor ::=
T|G|M|K|k|m|u|n|p|f|a
Syntax 2-2—Syntax for integer and real constants
expressed with a decimal point shall have at least one digit on each side of the decimal
point. The underscore character is legal anywhere in a real constant except as the first
character of the constant or the first character after the decimal point. The underscore
character is ignored.
Examples:
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 forms of real numbers because they do not have at least one
digit on each side of the decimal point:
.12
9.
4.E3
.2e-7
Largest Smallest
T = 1012 m = 10-3
G = 109 u = 10-6
M = 106 n = 10-9
K = 103; k = 103 p = 10-12
f = 10-15
a = 10-18
No space is permitted between the number and the symbol. Scale factors are not allowed
to be used in defining digital delays (e.g., #5u).
This form of floating-point number specification is provided in Verilog-AMS HDL in
addition to the two methods for writing floating-point numbers described in
Section 2.5.2.
Example:
2.6 Strings
A string is a sequence of characters enclosed by double quotes (") and contained on a
single line. Strings used as operands in expressions and assignments shall be treated as
unsigned integer constants represented by a sequence of 8-bit ASCII values, with one 8-
bit ASCII value representing one character. String parameters are treated differently and
are described in Section 3.2.6.
Example:
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
Note: When a variable is larger than required to hold a value being assigned, the contents on the left are
padded with zeros (0) after the assignment. This is consistent with the padding which occurs during
assignment of nonstring values. If a string is larger than the destination string variable, the string is
truncated to the left and the leftmost characters are lost.
\t Tab character
\\ \ character
Examples:
shiftreg_a
busa_index
error_condition
merge_ab
_bus3
n$657
2.7.2 Keywords
Keywords are predefined non-escaped identifiers which are used to define the language
constructs. Preceding a keyword with an escape character (\) causes it to be interpreted
as an escaped identifier.
All keywords are defined in lowercase only. Annex B lists all defined Verilog-AMS
HDL keywords (including those from IEEE 1364-1995 Verilog HDL).
system_task_or_function ::=
$system_task_identifier [ ( list_of_arguments ) ] ;
| $system_function_identifier [ ( list_of_arguments ) ] ;
list_of_arguments ::=
argument { , [ argument ] }
argument ::=
expression
Syntax 2-3—Syntax for system tasks and functions
Section 10 lists the standard system tasks and functions for Verilog-AMS HDL.
Any valid identifier, including keywords already in use in contexts other than this
construct can be used as a system task or function name.
Examples:
$display ("display a message");
$finish;
2.8 Attributes
Attributes are provided by IEEE 1364-2001 Verilog HDL as a mechanism for specifying
properties about objects, statements and groups of statements in the HDL source that
may be used by various tools, including simulators, to control the operation or behavior
of the tool. IEEE 1364-2001 Verilog HDL specifies only the syntactic mechanism that
shall be used for specifying attributes, without standardizing on any particular attributes.
The syntax is found in Syntax 2-4.
attribute_instance ::=
(* attr_spec {, attr_spec } *)
attr_spec ::=
attr_name = constant_expression
| attr_name
attr_name ::=
identifier
Syntax 2-4—Syntax for attributes
Section 3
Data types
Verilog-AMS HDL supports integer, real, and parameter data types as found in
IEEE 1364-2001 Verilog HDL. It also modifies the parameter data types and introduces
array of real as an extension of the real data type. Plus, it extends the net data types to
support a new type called wreal to model real value nets.
Verilog-AMS HDL introduces a new data type, called net_discipline, for representing
analog nets and declaring disciplines of all nets and regs. The disciplines define the
domain and the natures of potential and flow and their associated attributes for
continuous domains. A new data type called genvar is also introduced for use with
behavioral loops.
integer_declaration ::=
integer list_of_identifiers ;
real_declaration ::=
real list_of_identifiers ;
list_of_identifiers ::=
var_name { , var_name }
var_name ::=
variable_identifier
| array_identifier array_range
array_range ::=
[ upper_limit_constant_expression : lower_limit_constant_expression ]
An integer declaration declares one or more variables of type integer. These variables
can hold values ranging from -231 to 231-1. Arrays of integers can be declared using a
range which defines the upper and lower indices of the array. Both indices shall be
constant expressions and shall evaluate to a positive integer, a negative integer, or zero
(0).
Arithmetic operations performed on integer variables produce 2’s complement results.
A real declaration declares one or more variables of type real. The real variables are
stored as 64-bit quantities, as described by IEEE STD-754-1985, an IEEE standard for
double precision floating point numbers.
Arrays of real can be declared using a range which defines the upper and lower indices
of the array. Both indices shall be constant expressions and shall evaluate to a positive
integer, a negative integer, or zero (0).
Integers are initialized at the start of a simulation depending on how they are used.
Integer variables whose values are assigned in an analog context default to an initial
value of zero (0). Integer variables whose values are assigned in a digital context default
to an initial value of x. Real variables are initialized to zero (0) at the start of a simulation.
Examples:
integer a[1:64]; // an array of 64 integer values
real float ; // a variable to store real value
real gain_factor[1:30] ;// array of 30 gain multipliers
// with floating point values
3.2 Parameters
The syntax for parameter declarations is shown in Syntax 3-2.
The list of parameter assignments shall be a comma-separated list of assignments, where
the right hand side of the assignment shall be a constant expression, that is, an expression
containing only constant numbers and previously defined parameters.
For parameters defined as arrays, the initializer shall be a constant_param_arrayinit
expression which is a list of constant expressions containing only constant numbers and
previously defined parameters within { and } delimiters.
Parameters represent constants, hence it is illegal to modify their value at runtime.
However, parameters can be modified at compilation time to have values which are
different from those specified in the declaration assignment. This allows customization
of module instances. A parameter can be modified with the defparam statement or in the
module_instance statement. It is not legal to use hierarchical name referencing (from
within the analog block) to access external analog variables or parameters.
parameter_declaration ::=
parameter [opt_type] list_of_param_assignments ;
local_parameter_declaration ::=
localparam [opt_type] list_of_param_assignments ;
opt_type ::=
real
| integer
list_of_param_assignments ::=
declarator_init {, declarator_init}
declarator_init ::=
parameter_identifier = constant_expression { opt_value_range }
| parameter_array_identifier range = constant_param_arrayinit { opt_value_range }
opt_value_range ::=
from value_range_specifier
| exclude value_range_specifier
| exclude value_constant_expression
value_range_specifier ::=
start_paren expression1 : expression2 end_paren
start_paren ::=
[|(
end_paren ::=
]|)
expression1 ::=
constant_expression | -inf
expression2 ::=
constant_expression | inf
constant_param_arrayinit ::=
{ param_arrayinit_element_list }
param_arrayinit_element_list ::=
param_arrayinit_element {, param_arrayinit_element }
param_arrayinit_element ::=
constant_expression
| { replicator_constant_expression {constant_expression} }
string_parameter_declaration ::=
parameter string parameter_identifier = string_constant_expression [ string_list ] ;
local_string_parameter_declaration ::=
localparam string parameter_identifier = string_constant_expression [ string_list ] ;
string_list ::=
[ from { string {, string}} ][ exclude { string {, string}} ]
aliasparam_declaration ::=
aliasparam alias_identifier = parameter_identifier ;
• A range of permissible values can be defined for each parameter. In IEEE 1364-
1995 Verilog HDL, this check had to be done in user’s model or was left as an
implementation specific detail.
• Parameter arrays of basic integer and real data types can be specified.
The use of brackets, [ and ], indicate inclusion of the end points in the valid range. The
use of parenthesis, ( and ), indicate exclusion of the end points from the valid range. It is
possible to include one end point and not the other using [ ) and ( ]. The first expression
in the range shall be numerically smaller than the second expression in the range.
Examples:
parameter real neg_rail = -15 from [-50:0) ;
parameter integer pos_rail = 15 from (0:50) ;
parameter real gain = 1 from [1:1000] ;
Here, the default value for neg_rail is -15 and it is only allowed to acquire values
within the range of -50 <= neg_rail < 0. Similarly, the default value for parameter
pos_rail is 15 and it is only allowed to acquire values within the range of
0 < pos_rail < 50. And, the default value for gain is 1 and it is allowed to acquire
values within the range of 1<= gain <= 1000.
The keyword inf can be used to indicate infinity. If preceded by a negative sign, it
indicates negative infinity.
Example:
parameter real val3=0 from [0:inf) exclude (10:20) exclude (30:40];
A single value can be excluded from the possible valid values for a parameter.
Example:
parameter real res = 1.0 exclude 0 ;
Here, the value of a parameter is checked against the specified range. Range checking
applies to the value of the parameter for the instance and not against the default values
specified in the device. It shall be an error only if the value of the parameter is out of
range during simulation.
Valid values of string parameters are indicated differently. The from keyword may be
used with a list of valid string values, or the exclude keyword may be used with a list of
invalid string values. In either case, the list is enclosed in braces, { and }, and the items
are separated by commas.
Examples:
parameter string type = "NMOS" from { "NMOS", "PMOS" };
parameter string filename = "output.dat" exclude { "" };
The units and descriptions are only for documentation of the module; in particular, no
dimensional analysis is performed on the units. However, it is often important for the
user to know the units of a parameter, such as an angle that could be specified in radians
or degrees. It should be noted that the ‘timescale directive of IEEE 1364-1995 Verilog
HDL also affects units throughout the module, which can be confusing to the user.
The units and descriptions are of particular value for compact models, where the number
of parameters is large and the description is not always clear from the parameter name.
Simulators can use this information when generating help messages for a module; many
SPICE-like simulators can generate help messages with this information for built-in
primitives.
Units and descriptions specified for block-level parameters shall be ignored by the
simulator, but can be used for documentation purposes.
• An array assigned to an instance of a module shall be of the exact size of the array
bounds of that instance.
• If the array size is changed via a parameter assignment, the parameter array shall
be assigned an array of the new size from the same module as the parameter
assignment that changed the parameter array size.
Example:
parameter real poles[0:3] = { 1.0, 3.198, 4.554, 2.00 };
Operator Semantics
== Equality. Checks if the two strings are equal. Result is 1 if they are equal and 0
if they are not. Both operands can be string parameters, or one can be a string
parameter and the other a constant string.
Example:
module ebersmoll (c,b,e);
inout c, b, e;
electrical c, b, e;
parameter string type = "NPN" from { "NPN", "PNP" };
parameter real alphaf = 0.99 from (0:inf);
parameter real alphar = 0.5 from (0:inf);
parameter real ies = 1.0e-17 from (0:inf);
parameter real ics = 1.0e-17 from (0:inf);
real sign, ifor, irev;
analog begin
sign = ((type == "NPN")) ? 1.0 : -1.0;
ifor = ies * (limexp(sign*V(b,e)/$vt)-1);
irev = ics * (limexp(sign*V(b,c)/$vt)-1);
I(b,e) <+ sign*(ifor - alphar * irev);
I(b,c) <+ sign*(irev - alphaf * ifor);
end
endmodule
Note how the string parameter type associates the string “PNP” with a negative one (-
1) value for the variable sign. It is common in compact modeling of transistors for the
equations to be formulated for NPN or NMOS devices, and behavior of a PNP or PMOS
can be described by multiplying all the voltages and currents by -1, even though the “p”
denotes positively-charged carriers in the channel of the PMOS.
• The alias_identifier shall not occur anywhere else in the module; in particular, it
shall not conflict with a different parameter_identifier, and the equations in the
module shall reference the parameter by its original name, not the alias.
Example:
Suppose a module named nmos has the following declarations in the module:
parameter real dtemp = 0 from [-‘P_CELSIUS0:inf);
aliasparam trise = dtemp;
Then the following two instantiations of the module are valid:
nmos #(.trise(5)) m1(.d(d), .g(g), .s(s), .b(b));
nmos #(.dtemp(5)) m2(.d(d), .g(g), .s(s), .b(b));
and the value of the parameter dtemp, as used in the module equations for both instances,
is 5. This last instantiation is an error:
nmos #(.trise(5), .dtemp(5)) m3(.d(d), .g(g), .s(s), .b(b)); //error
because an override is specified for the parameter dtemp and its alias, even though the
values are equal.
3.3 Genvars
Genvars are integer-valued variables which compose static expressions for instantiating
structure behaviorally such as accessing analog signals within behavioral looping
constructs. The syntax for declaring genvar variables is shown in Syntax 3-3.
genvar_declaration ::=
genvar list_of_genvar_identifiers ;
list_of_genvar_identifiers ::=
genvar_identifier { , genvar_identifier }
The static nature of genvar variables is derived from the limitations upon the contexts in
which their values can be assigned.
Examples:
genvar i;
analog begin
...
for (i = 0; i < 8; i = i + 1) begin
V(out[i]) <+ transition(value[i], td, tr);
end
...
end
The genvar variable i can only be assigned within the for-loop control. Assignments to
the genvar variable i can consist only of expressions of static values, e.g., parameters,
literals, and other genvar variables.
3.4 Net_discipline
In addition to the data types supported by IEEE 1364-1995 Verilog HDL, an additional
data type, net_discipline, is introduced in Verilog-AMS HDL for continuous time and
mixed-signal simulation. net_discipline is used to declare analog nets, as well as
declaring the domains of digital nets and regs.
A signal can be digital, analog, or mixed, and is a hierarchical collection of nets which
are contiguous (because of port connections). For analog and mixed signals, a single
node is associated with all continuous nets segments of the signal. The fundamental
characteristic of analog and mixed signals is the values of the associated node are
determined by the simultaneous solution of equations defined by the instances connected
to the node using Kirchhoff’s conservation laws. In general, a node represents a point of
physical connections between nets of continuous-time description and it obeys
conservation-law semantics.
A net is characterized by the discipline it follows. For example, all low-voltage nets have
certain common characteristics, all mechanical nets have certain common
characteristics, etc. Therefore, a net is always declared as a type of discipline. In this
sense, a discipline is a user-defined type for declaring a net.
A discipline is characterized by the domain and the attributes defined in the natures for
potential and flow.
3.4.1 Natures
A nature is a collection of attributes. In Verilog-AMS HDL, there are several pre-defined
attributes. In addition, user-defined attributes can be declared and assigned constant
values in a nature.
The nature declarations are at the same level as discipline and module declarations in the
source text. That is, natures are declared at the top level and nature declarations do not
nest inside other nature declarations, discipline declarations, or module declarations.
The syntax for defining a nature is shown in Syntax 3-4.
nature_declaration ::=
nature nature_name
[ nature_descriptions ]
endnature
nature_name ::=
nature_identifier
| nature_identifier : parent_identifier
parent_identifier ::=
nature_identifier
| discipline_identifier.flow
| discipline_identifier.potential
nature_descriptions ::=
nature_description { nature_description }
nature_description ::=
attribute = constant_expression ;
attribute ::=
abstol
| access
| ddt_nature
| idt_nature
| units
| attribute_identifier
A nature shall be defined between the keywords nature and endnature. Each nature
definition shall have a unique identifier as the name of the nature and shall include all
the required attributes specified in 3.4.1.2.
Examples:
nature current
units = "A" ;
access = I ;
idt_nature = charge ;
abstol = 1u ;
endnature
nature voltage
units = "V" ;
access = V;
abstol = 1u ;
endnature
3.4.1.2 Attributes
Attributes define the value of certain quantities which characterize the nature. There are
five predefined attributes — abstol, access, idt_nature, ddt_nature, and units. In addition,
user-defined attributes can be defined in a nature (see Section 3.4.1.3). Attribute
declaration assigns a constant expression to the attribute name, as shown in the example
in Section 3.4.1.1.
abstol
The abstol attribute provides a tolerance measure (metric) for convergence of potential or
flow calculations. It specifies the maximum negligible for signals associated with the
nature.
This attribute is required for all base natures. It is legal for a derived nature to change
abstol, but if left unspecified it shall inherit the abstol from its parent nature. The
constant expression assigned to it shall evaluate to a real value.
access
The access attribute identifies the name for the access function. When the nature is used
to bind a potential, the name is used as an access function for the potential; when the
nature is used to bind a flow, the name is used as an access function for the flow. The
usage of access functions is described further in Section 4.3.
This attribute is required for all base natures. It is illegal for a derived nature to change
the access attribute; the derived nature always inherits the access attribute of its parent
nature. If specified, the constant expression assigned to it shall be an identifier (by name,
not as a string).
idt_nature
The idt_nature attribute provides a relationship between a nature and the nature
representing its time integral.
idt_naturecan be used to reduce the need to specified tolerances on the idt() operator. If
this operator is applied directly on nets, the tolerance can be taken from the node, which
eliminates the need to give a tolerance with the operator.
If specified, the constant expression assigned to idt_nature shall be the name (not a
string) of a nature which is defined elsewhere. It is possible for a nature to be self-
referencing with respect to its idt_nature attribute. In other words, the value of
idt_nature can be the nature that the attribute itself is associated with.
The idt_nature attribute is optional; the default value is the nature itself. While it is
possible to override the parent’s value of idt_nature using a derived nature, the nature
thus specified shall be related (share the same base nature) to the nature the parent uses
for its idt_nature.
ddt_nature
The ddt_nature attribute provides a relationship between a nature and the nature
representing its time derivative.
ddt_nature can be used to reduce the need to specified tolerances on the ddt() operator. If
this operator is applied directly on nets, the tolerance can be taken from the node,
eliminating the need to give a tolerance with the operator.
If specified, the constant expression assigned to ddt_nature shall be the name (not a
string) of a nature which is defined elsewhere. It is possible for a nature to be self-
referencing with respect to its ddt_nature attribute. In other words, the value of
ddt_nature can be the nature that the attribute itself is associated with.
The ddt_nature attribute is optional; the default value is the nature itself. While it is
possible to override the parent’s value of ddt_nature using a derived nature, the nature
thus specified shall be related (share the same base nature) to the nature the parent uses
for its ddt_nature.
units
The units attribute provides a binding between the value of the access function and the
units for that value. The units field is provided so simulators can annotate the continuous
signals with their units and is also used in the net compatibility rule check.
This attribute is required for all base natures. It is illegal for a derived nature to define or
change the units; the derived nature always inherits its parent nature units. If specified,
the constant expression assigned to it shall be a string.
3.4.2 Disciplines
A discipline description consists of specifying a domain type and binding any natures to
potential or flow.
The syntax for declaring a discipline is shown in Syntax 3-5.
discipline_declaration ::=
discipline discipline_identifier
[ discipline_descriptions ]
enddiscipline
discipline_descriptions ::=
discipline_description { discipline_description }
discipline_description ::=
nature_binding
| domain_binding
| attr_override
| attribute_identifier = constant_expression;
nature_binding ::=
pot_or_flow nature_identifier ;
pot_or_flow ::=
potential
| flow
domain_binding ::=
domain continuous ;
| domain discrete ;
attr_override ::=
pot_or_flow . attribute_identifier = constant_expression ;
A discipline shall be defined between the keywords discipline and enddiscipline. Each
discipline shall have a unique identifier as the name of the discipline.
The discipline declarations are at the same level as nature and module declarations in the
source text. That is, disciplines are declared at the top level and discipline declarations
do not nest inside other discipline declarations, nature declarations, or module
declarations. Analog behavioral nets (nodes) must have a discipline defined for them but
interconnect and digital nets do not. It is possible to set the discipline of interconnect and
digital nets through discipline declaration with hierarchical references to these nets. It
shall be an error to hierarchically override the discipline of a net that was explicitly
declared unless it is a compatible discipline.
The access function defined in the nature bound to potential is used in the model to
describe the signal-flow which obeys Kirchhoff’s Potential Law (KPL). This access
function is called the potential access function.
The access function defined in the nature bound to flow is used in the model to describe
a quantity which obeys Kirchhoff’s Flow Law (KFL). This access function is called the
flow access function.
Disciplines with two natures are called conservative disciplines and the nets associated
with conservative disciplines are called conservative nets. Conservative disciplines shall
not have the same nature specified for both the potential and the flow. Disciplines
with a single potential nature are called signal-flow disciplines and the nets with signal-
flow disciplines are called signal-flow nets. Only a potential nature is allowed to be
specified for a signal-flow discipline, as shown in the following examples.
Examples:
Conservative discipline
discipline electrical
potential Voltage ;
flow Current ;
enddiscipline
Signal-flow disciplines
discipline voltage
potential Voltage ;
enddiscipline
discipline current
potential Current;
enddiscipline
Multi-disciplinary example
Disciplines in Verilog-AMS HDL allow designs of multi-disciplinaries to be easily
defined and simulated. Disciplines can be used to allow unique tolerances based on the
size of the signals and outputs displayed in the actual units of the discipline. This
example shows how an application spanning multiple disciplines can be modeled in
Verilog-AMS HDL. It models a DC-motor driven by a voltage source.
module motorckt;
parameter real freq=100;
ground gnd;
electrical drive;
rotational shaft;
endmodule
Such disciplines may have a domain binding or they may be domain-less, thus allowing
the domain to be determined by the connectivity of the net (see Section 8.4).
Example:
discipline interconnect
domain continuous;
enddiscipline
discipline ttl
potential ttl_volt ;
flow ttl_curr ;
flow.abstol = 10u ;
enddiscipline
net_discipline_declaration ::=
discipline_identifier [ range ] list_of_nets ;
range ::=
[ constant_expression : constant_expression ]
list_of_nets ::=
net_type {, net_type}
net_type ::=
net_identifier [range] [= constant_expression | constant_array_expression]
If a range is specified for a net, the net is called a vector net; otherwise it is called a scalar
net. A vector net is also called an bus.
Examples:
electrical [MSB:LSB] n1 ; // MSB and LSB are parameters
voltage [5:0] n2, n3 ;
magnetic inductor ;
logic [10:1] connector1 ;
Nets represent the abstraction of information about signals. As with ports, nets represent
component interconnections. Nets declared in the module interface define the ports to the
module (see Section 7.4.4).
A net used for modeling a conservative system shall have a discipline with both access
functions (potential and flow) defined. When modeling a signal-flow system, the
discipline of a net can have only potential access functions. When modeling a discrete
system, the discipline of a net can only have a domain of discrete defined.
Nets declared with an empty discipline do not have declared natures, so such nets can
not be used in analog behavioral descriptions (because the access functions are not
known). However, such nets can be used in structural descriptions, where they inherit the
natures from the ports of the instances of modules that connect to them.
ground_declaration ::=
ground [ range ] list_of_nets;
Examples:
module loadedsrc(in, out);
input in;
output out;
electrical in, out;
electrical gnd;
ground gnd;
parameter real srcval = 5.0;
digital_net_declaration ::=
digital_net_declaration
| wreal [range] list_of_identifiers ;
Examples:
module foo(in, out);
input in;
output out;
wreal in;
electrical out;
analog begin
V(out) <+ in;
end
endmodule
module top();
real stim;
electrical load;
wreal wrstim;
assign wrstim = stim;
foo f1(wrstim, load);
always begin
#1 stim = stim + 0.1;
end
endmodule
For analog primitives, the discipline will be defined by the attribute port_discipline on
that instance. If no attribute is found then it will acquire the discipline of other
compatible continuous disciplines connected to that net segment. If no disciplines are
connected to that net, then the default discipline is set to electrical. This is further
described in section E.3.3.
• The discipline name can be used in a declaration which makes an out of context
reference to the net from another module.
1. A declaration from a module other than the module to which the net belongs
using an out of module reference, e.g.,
module example1;
electrical example2.net;
endmodule
2. The local declaration of the net in the module to which it belongs, e.g.,
module example2;
electrical net;
endmodule
Examples:
The following compatibility observations can be made from the above example:
• Voltage and highvoltage are compatible natures because they both exists and
are derived from the same base natures.
• electrical and highvolt are compatible disciplines because the natures for
both potential and flow exist and are derived from the same base natures.
• electrical and sig_flow_v are compatible disciplines because the nature for
potential is same for both disciplines and the nature for flow does not exist in
sig_flow_v.
• electrical and sig_flow_x are incompatible disciplines because the nature for
both potentials are not derived from the same base nature.
• An empty discipline is compatible with all other disciplines of the same domain
(determined independently) because it does not have a potential or a flow nature.
Without natures, there can be no conflicting natures.
• electrical and logic are incompatible disciplines because the domains are
different. A connect statement must be used to connect nets or ports of these
disciplines together.
3.9 Branches
A branch is a path between two nets. If both nets are conservative, then the branch is a
conservative branch and it defines a branch potential and a branch flow. If one net is a
signal-flow net, then the branch is a signal-flow branch and it defines either a branch
potential or a branch flow, but not both.
Each branch declaration is associated with two nets from which it derives a discipline.
These nets are referred to as the branch terminals. Only one net need be specified, in
which case the second net defaults to ground and the discipline for the branch is derived
from the specified net. The disciplines for the specified nets shall be compatible (see
Section 3.8).
The syntax for declaring branches is shown in Syntax 3-9.
branch_declaration ::=
branch list_of_branches ;
list_of_branches ::=
terminals list_of_branch_identifiers
terminals ::=
( net_or_port_scalar_expression )
| ( net_or_port_scalar_expression , net_or_port_scalar_expression )
list_of_branch_identifiers ::=
branch_identifier [ range ]
| branch_identifier [ range ] , list_of_branch_identifiers
If one of the terminals of a branch is a vector net, then the other terminal shall either be
a scalar net or a vector net of the same size. In the latter case, the branch is referred to as
a vector branch. When both terminals are vectors, the scalar branches that make up the
vector branch connect to the corresponding scalar nets of the vector terminals, as shown
in Figure 3-1.
Vector Branch
Vector Branch
3.10 Namespace
The following subsections define the namespace.
3.10.3 Net
The scope rules for net identifiers are the same as the scope rules for any other identifier
declarations, except nets can not be declared anywhere other than in the port of a module
or in the module itself. A net can only be declared inside a module block; a net can not
be declared local to a block.
Access functions are uniquely defined for each net based on the discipline of the net.
Each access function is used with the name of the net as its argument and a net can only
be accessed through its access functions.
The hierarchical reference character (.) can be used to reference a net across the module
boundary according to the rules specified in IEEE 1364-1995 Verilog HDL.
3.10.4 Branch
The scope rules for branch identifiers are the same as the scope rules for net identifiers.
A branch can only be declared inside a module block; there is no local declaration for a
branch.
Access functions are uniquely defined for each branch based on the discipline of the
branch. The access function is used with the name of the branch as its argument and a
branch can only be accessed through its access functions.
The hierarchical reference character (.) can be used to reference a net across the module
boundary according to the rules specified in IEEE 1364-1995 Verilog HDL.
Section 4
Expressions
This section describes the operators and operands available in the Verilog-AMS HDL,
and how to use them to form expressions.
An expression is a construct which combines operands with operators to produce a
result which is a function of the values of the operands and the semantic meaning of the
operator. Any legal operand, such as an integer or an indexed element from an array of
reals, without a operator is also considered an expression. Wherever a value is needed in
a Verilog-AMS HDL statement, an expression can be used.
Some statement constructs require an expression to be a constant expression. The
operands of a constant expression consists of constant numbers and parameter names,
but they can use any of the operators defined in Table 4-1, Table 4-17, and Table 4-18.
4.1 Operators
The symbols for the Verilog-AMS HDL operators are similar to those in the C
programming language. Table 4-1 lists these operators.
Table 4-1—Operators
+ - * / Arithmetic
% Modulus
!= == Logical equality
! Logical negation
|| Logical or
~ Bit-wise negation
^ Bit-wise exclusive or
^~ ~^ Bit-wise equivalence
?: Conditional
or Event or
+ - * / Arithmetic
% Modulus
== != Logical equality
! && || Logical
?: Conditional
or Event or
The result of using logical or relational operators on real numbers is an integer value 0
(false) or 1 (true).
Table 4-2 lists those operators which shall not be used to operate on real numbers.
Table 4-3—Operators not allowed for real expressions
Examples:
// The real numbers 35.7 and 35.5 both become 36 when
// converted to an integer and 35.2 becomes 35.
// Converting -1.5 to integer yields -2, converting 1.5 to
// integer yields 2.
* / %
+ - (binary)
<< >>
== != === !==
& ~&
^ ^~ ~^
| ~|
&&
||
Operators shown on the same row in Table 4-4 have the same precedence. Rows are
arranged in order of decreasing precedence for the operators. 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 conditional operator which
associates right to left. Associativity refers to the order in which the operators having the
same precedence are evaluated.
Example:
In the following example B is added to A and then C is subtracted from the result of A+B.
A + B - C
When operators differ in precedence, the operators with higher precedence associate
first.
Examples:
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
a+b a plus b
a–b a minus b
a*b a multiply by b
a/b a divide by b
a%b a modulo b
-m Unary minus m
The modulus operator, for example y % z, gives the remainder when the first operand is
divided by the second, and thus is zero (0) when z divides y exactly. The result of a
modulus operation takes the sign of the first operand.
For the case of the modulus operator where either argument is real, the operation
performed is
a % b = a - floor(a/b)*b;
Table 4-7 gives examples of modulus operations.
Table 4-7—Examples of modulus operations
An expression using these relational operators yields the value zero (0) if the specified
relation is false or the value one (1) if it is true.
All the relational operators have the same precedence. Relational operators have lower
precedence than arithmetic operators.
Examples:
The following examples illustrate the implications of this precedence rule:
a < foo - 1 // this expression is the same as
a < (foo - 1)// this expression, but . . .
foo - (1 < a)// this one is not the same as
foo - 1 < a // this expression
When foo - (1 < a) is evaluated, the relational expression is evaluated first and then
either zero (0) or one (1) is subtracted from foo. When foo - 1 < a is evaluated, the
value of foo operand is reduced by one (1) and then compared with a.
a == b a equal to b
a != b a not equal to b
Both equality operators have the same precedence. These operators compare the value
of the operands. As with the relational operators, the result shall be zero (0) if
comparison fails, one (1) if it succeeds.
A third logical operator is the unary logical negation operator (!). The negation operator
converts a non-zero or true operand into zero (0) and a zero or false operand into one (1).
Examples:
The following expression performs a logical and of three sub-expressions without
needing any parentheses:
a < param1 && b != c && index != lastone
However, parentheses can be used to clearly show the precedence intended, as in the
following rewrite of the above example:
(a < param1) && (b != c) && (index != lastone)
Table 4-14—Bit-wise
binary exclusive or
Table 4-10—Bit-wise Table 4-12—Bit-wise
operator
binary and operator binary nand operator
^ 0 1
& 0 1 ~& 0 1
0 0 1
0 0 0 0 1 1
1 1 0
1 0 1 1 1 0
Table 4-15—Bit-wise
Table 4-11—Bit-wise Table 4-13—Bit-wise
binary exclusive nor
binary or operator binary nor operator
operator
| 0 1 ~| 0 1
^~
0 1
~^
0 0 1 0 1 0
0 1 0
1 1 1 1 0 0
1 0 1
0 1
1 0
conditional_expression ::=
expression1 ? expression2 : expression3
4.1.12 Event or
The event or operator performs an or of events. See Section 6.7.2 for events and
triggering of events.
4.1.13 Concatenations
A concatenation is used for joining scalar elements into compound elements (buses or
arrays) for the built-in types integer or real, or for elements declared of type
net_discipline. The concatenation shall be expressed using the brace characters ({ }),
with commas separating the expressions within.
Examples:
module x;
parameter real p1[0:2] = { 1.0, 2.0, 3.0 };
...
endmodule
module y;
parameter real pole1 = 0, pole2 = 0, pole3 = 0;
x #(.p1({pole1, pole2, pole3}) x1;
...
endmodule
Module x defines a real-array parameter p1. Module y instantiates x and overrides the
array value of the parameter p1 of module x via the concatenation of the scalar
parameters pole1, pole2, and pole3.
Concatenations can be expressed using a replication multiplier.
Example:
{c, {2{a, b}}} // equivalent to: {c, a, b, a, b}
The replication multiplier shall be a constant expression.
The min(), max(), and abs() functions have discontinuous derivatives; it is necessary to
define the behavior of the derivative of these functions at the point of the discontinuity.
In this context, these functions are defined so:
min(x,y) is equivalent to (x < y) ? x : y
max(x,y) is equivalent to (x > y) ? x : y
abs(x) is equivalent to (x > 0) x : –x
asin(x) Arc-sine -1 ≤ x ≤ 1
acos(x) Arc-cosine -1 ≤ x ≤ 1
Example Comments
I(n1) Accesses the current flowing in the unnamed branch from n1 to ground.
I(n1, n2) Accesses the current flowing in the unnamed branch between n1 and n2.
I(<p1>) Accesses the current flow into the module through port p1.
The argument expression list for signal access functions shall be a branch identifier, or
a list of one or two nets or port expressions. If two net expressions are given as arguments
to a flow access function, they shall not evaluate to the same signal. The net identifiers
shall be scalar or resolve to a constant net of a composite net type (array or bus) accessed
by a genvar expression.
The operands of an expression shall be unique to define a valid branch. The access
function name shall match the discipline declaration for the nets, ports, or branch given
in the argument expression list. In this case, V and I are used as examples of access
functions for electrical potential and flow.
For port access functions, the expression list is a single port of the module. The port
identifier shall be scalar or resolve to a constant net of a bus port accessed by a genvar
expression. The access function name shall match the discipline declaration for the port
identifier.
• Analog operators are not allowed in the repeat and while looping statements.
• Analog operators can only be used inside an analog block; they can not be used
inside an initial or always block, or inside a user-defined function.
• It is illegal to specify a null argument in the argument list of an analog operator,
except as specified elsewhere in this document.
These restrictions help prevent usage which could cause the internal state to be corrupted
or become out-of-date, which results in anomalous behavior.
• const_array_expression
constant_array_expression ::=
{ constant_arrayinit_element { , constant_arrayinit_element } }
constant_arrayinit_element ::=
constant_expression
| integer_constant_expression { constant_expression }
Operator Comments
d
ddt(expr) Returns x (t ) , the time-derivative of x, where x is expr.
dt
ddt(expr, abstol) Same as above, except absolute tolerance is specified explicitly.
In DC analysis, ddt() returns zero (0). The optional parameter abstol is used as an
absolute tolerance if needed. Whether an absolute tolerance is needed depends on the
context where ddt() is used. See Section 4.4.3 for more information on the application of
tolerances to equations. The absolute tolerance, abstol or derived from nature, applies to
the output of the ddt operator and is the largest signal level that is considered negligible.
Operator Comments
∫
t
idt(expr) Returns
0
x(τ) dτ , the time-integral of x from 0 to t with the initial condition
being computed in the DC analysis. Where x is expr.
∫
t
idt(expr,ic) Returns x(τ) dτ + ic , the time-integral of x from 0 to t with the initial
0
condition ic. In DC analysis, ic is returned. Where x is expr.
∫
t
idt(expr,ic,assert) Returns
t0
x(τ) dτ + ic , the time-integral of x from t0 to t with initial condition
ic. assert is a integer-valued expression. idt returns ic when assert is non-zero. t0 is
the time when assert last became 0. Where x is expr.
When specified with initial conditions, idt() returns the value of the initial condition in
DC and IC analyses whenever assert is given and is non-zero. Without initial conditions,
idt() multiplies its argument by infinity in DC analysis. Hence, without initial conditions,
it can only be used in a system with feedback which forces its argument to zero (0).
The optional parameter abstol or nature is used to derive an absolute tolerance if needed.
Whether an absolute tolerance is needed depends on the context where idt() is used. (See
Section 4.4.3 for more information.) The absolute tolerance applies to the input of the idt
operator and is the largest signal level that is considered negligible.
Operator Comments
∫
t
idtmod(expr) Returns
0
x(τ) dτ , the time-integral of x from 0 to t with the initial
condition being computed in the DC analysis. Where x is expr.
∫
t
idtmod(expr,ic) Returns
0
x(τ) dτ + ic , the time-integral of x from 0 to t with the
initial condition ic. In DC analysis, ic is returned. Where x is expr.
∫
t
0
x ( τ ) dτ + ic = n × modulus + k , n = ... -3,-2,-1,0,1,2,3....
Where x is expr.
∫
t
0
x ( τ ) dτ + ic = n × modulus + k Where x is expr.
The initial condition is optional. If the initial condition is not specified, it defaults to zero
(0). Regardless, the initial condition shall force the DC solution to the system.
If idtmod() is used in a system with feedback configuration which forces expr to zero (0),
the initial condition can be omitted without any unexpected behavior during simulation.
For example, an operational amplifier alone needs an initial condition, but the same
amplifier with the right external feedback circuitry does not need a forced DC solution.
The output of the idtmod() function shall remain in the range
offset <= idtmod < offset+modulus
The modulus shall be an expression which evaluates to a positive value. If the modulus
is not specified, then idtmod() shall behave like idt() and not limit the output of the
integrator.
The default for offset shall be zero (0).
The following relationship between idt() and idtmod() shall hold at all times.
Examples:
If
y = idt(expr, ic) ;
z = idtmod(expr, ic, modulus, offset) ;
then
y = n * modulus + z ;// n is an integer
where
offset ≤ z < modulus + offset
In this example, the circular integrator is useful in cases where the integral can get very
large, such as a VCO. In a VCO we are only interested in the output values in the range
[0,2π], e.g.,
phase = idtmod(fc + gain∗V(in), 0, 1, 0);
V(OUT) <+ sin(2∗‘M_PI∗phase);
Here, the circular integrator returns a value in the range [0,1].
ddx_call ::=
ddx ( expression, potential_access_identifier ( net_or_port_scalar_expression ) )
| ddx ( expression, flow_access_identifier ( branch_identifier ) )
The operator returns the partial derivative of its first argument with respect to the
unknown indicated by the second argument, holding all other unknowns fixed and
evaluated at the current operating point. The second argument shall be the potential of a
scalar net or port or the flow through a branch, because these are the unknown variables
in the system of equations for the analog solver. For the modified nodal analysis used in
most SPICE-like simulators, these unknowns are the node voltages and certain branch
currents.
If the expression does not depend explicitly on the unknown, then ddx() returns zero (0).
Care must be taken when using implicit equations or indirect assignments, for which the
simulator may create internal unknowns; derivatives with respect to these internal
unknowns cannot be accessed with ddx().
Unlike the ddt() operator, no tolerance is required because the partial derivative is
computed symbolically and evaluated at the current operating point.
Examples:
This first example uses ddx() to obtain the conductance of the diode. The variable gdio
is declared as an output variable (see Section 3.1.1) so that its value is available for
inspection by the designer.
module diode(a,c);
electrical a, c;
inout a, c;
parameter real IS = 1.0e-14;
real idio;
(*desc="small-signal conductance"*)
real gdio;
analog begin
idio = IS * (limexp(V(a,c)/$vt) - 1);
gdio = ddx(idio, V(a));
I(a,c) <+ idio;
end
endmodule
The next example adds a series resistance to the diode using an implicit equation. Note
that gdio does not represent the total conductance because the flow access I(a,c) requires
introduction of another unknown in the system of equations. The conductance of the
diode is properly reported as geff, which includes the effects of RS and the nonlinear
equation.
module diode(a,c);
electrical a, c;
inout a, c;
parameter real IS = 1.0e-14;
parameter real RS = 0.0;
real idio, gdio;
(*desc="effective conductance"*)
real geff;
analog begin
idio = IS * (limexp((V(a,c)-RS*I(a,c))/$vt) - 1);
gdio = ddx(idio, V(a));
geff = gdio / (RS * gdio + 1.0);
I(a,c) <+ idio;
end
endmodule
The final example implements a voltage-controlled dependent current source and is used
to illustrate the computations of partial derivatives.
module vccs(pout,nout,pin,nin);
electrical pout, nout, pin, nin;
inout pout, nout, pin, nin;
parameter real k = 1.0;
real vin, one, minusone, zero;
analog begin
vin = V(pin,nin);
one = ddx(vin, V(pin));
minusone = ddx(vin, V(nin));
zero = ddx(vin, V(pout));
I(pout,nout) <+ k * vin;
end
endmodule
The names of the variables indicate the values of the partial derivatives: +1, -1, or 0. A
SPICE-like simulator would use these values (scaled by the parameter k) in the Newton-
Raphson solution method.
td is evaluated as a constant at a particular time for any small signal analysis. In time-
domain analyses, absdelay() introduces a transport delay equal to the instantaneous value
of td based on the following formula.
The transport delay td can be either constant (typical case) or vary as a function of time
(when maxdelay is defined). A time-dependent transport delay is shown in Figure 4-1,
with a ramp input to the absdelay operator for both positive and negative changes in the
transport delay td and a maxdelay of 5.
Input
3
td (s)
Output 2
2 4 6
input_expression(t) output_expression(t)
d
tr tf
t0 t0
4.4.9.1 Syntax
The general form is
transition( expr [ , td [ , rise_time [ , fall_time [ , time_tol ] ] ] ] )
transition() takes the following arguments (all real-valued expressions):
• the input expression
to avoid causing the simulator to take very small time steps, which would result in poor
performance.
In DC analysis, transition() passes the value of the expr directly to its output. The transition
filter is designed to smooth out piecewise constant waveforms. When applied to
waveforms which vary smoothly, the simulation results are generally unsatisfactory. In
addition, applying the transition function to a continuously varying waveform can cause
the simulator to run slowly. Use transition() for discrete signals and slew() (see
Section 4.4.10) for continuous signals.
If interrupted on a rising transition, transition() tries to complete the transition in the
specified time.
• If the new final value level is below the value level at the point of the interruption
(the current value), transition() uses the old destination as the origin.
• If the new destination is above the current level, the first origin is retained.
output_expression(t)
New destination
tr
tf
Interruption
Because the transition function is intended to handle discrete-valued signals, the small
signals present in AC analysis rarely reach transition functions. As a result, the
approximation used is generally sufficient.
4.4.9.2 Examples
Example 1 - QAM modulator
In this example, the transition function is used to control the rate of change of the
modulation signal in a QAM modulator.
module qam16(out, in) ;
parameter freq=1.0, ampl=1.0, dly=0, ttime=1.0/freq ;
input [0:4] in ;
output out ;
electrical [0:4] in;
electrical out ;
real x, y, thresh;
integer row, col ;
analog begin
row = 2*(V(in[3]) > thresh) + (V(in[2]) > thresh) ;
col = 2*(V(in[1]) > thresh) + (V(in[0]) > thresh) ;
x = transition(row - 1.5, dly, ttime) ;
y = transition(col - 1.5, dly, ttime) ;
V(out) <+ ampl*x*cos(2*‘M_PI*freq*$abstime)
+ ampl*y*sin(2*‘M_PI*freq*$abstime) ;
$bound_step(0.1/freq) ;
end
endmodule
Example 2 - A/D converter
In this example, an analog behavioral N-bit analog to digital converter, demonstrates the
ability of the transition function to handle vectors.
module adc(in, clk, out) ;
parameter bits = 8, fullscale = 1.0, dly = 0, ttime = 10n ;
input in, clk ;
output [0:bits-1] out ;
electrical in, clk;
electrical [0:bits-1] out;
real sample, thresh ;
integer result[0:bits-1];
genvar i;
analog begin
@(cross(V(clk)-2.5, +1)) begin
sample = V(in);
thresh = fullscale/2.0;
for (i = bits - 1; i >= 0; i = i - 1) begin
if (sample > thresh)
begin
result[i] = 1.0;
sample = sample - thresh ;
end else begin
result[i] = 0.0;
end
sample = 2.0*sample;
end
end
for (i = 0; i < bits; i = i + 1) begin
V(out[i]) <+ transition(result[i], dly, ttime);
end
end
endmodule
When applied, slew() forces all transitions of expression faster than max_pos_slew_rate
to change at max_pos_slew_rate rate for positive transitions and limits negative
transitions to max_neg_slew_rate rate as shown in Figure 4-5.
output_expression(t) ∆y ∆y
------ ≤ rate pmax
∆t
∆t
In DC analysis, slew() simply passes the value of the destination to its output. In AC
small-signal analyses, the slew() function has unity transfer function except when
slewing, in which case it has zero transmission through the function.
4.4.12.1 laplace_zp
laplace_zp() implements the zero-pole form of the Laplace transform filter. The general
form is
laplace_zp( expr , ζ , ρ [ , ε ] )
where ζ (zeta) is a vector of M pairs of real numbers. Each pair represents a zero, the first
number in the pair is the real part of the zero and the second is the imaginary part.
Similarly, ρ (rho) is the vector of N real pairs, one for each pole. The poles are given in
the same manner as the zeros. The transfer function is
M–1
∏ 1 – ζ-------------------
-
s
r + jζ i
k k
H ( s ) = ---------------------------------------------
k=0
N–1
-
∏ 1 – ρ--------------------
s
r + jρ i
k=0 k k
r r
where ζ k and ζ ki are the real and imaginary parts of the k th zero (0), while ρ k and ρ ki
are the real and imaginary parts of the k th pole. If a root (a pole or zero) is real, the
imaginary part shall be specified as zero (0). If a root is complex, its conjugate shall also
be present. If a root is zero, then the term associated with it is implemented as s, rather
than ( 1 – s ⁄ r ) (where r is the root).
4.4.12.2 laplace_zd
laplace_zd()
implements the zero-denominator form of the Laplace transform filter. The
general form is
laplace_zd( expr , ζ , d [ , ε ] )
where ζ (zeta) is a vector of M pairs of real numbers. Each pair represents a zero, the first
number in the pair is the real part of the zero and the second is the imaginary part.
M–1
∏ 1 – ζ-------------------
-
s
r + jζ i
k k
H ( s ) = ---------------------------------------------
k=0
N–1
-
∑ dks
k
k=0
r
where ζ k and ζ ki are the real and imaginary parts of the k th zero, while d k is the
coefficient of the k th power of s in the denominator. If a zero is real, the imaginary part
shall be specified as zero (0). If a zero is complex, its conjugate shall also be present. If
a zero is zero (0), then the term associated with it is implemented as s, rather than
(1 – s ⁄ ζ) .
4.4.12.3 laplace_np
laplace_np()
implements the numerator-pole form of the Laplace transform filter. The
general form is
laplace_np( expr , n , ρ [ , ε ] )
where n is a vector of M real numbers containing the coefficients of the numerator.
Similarly, ρ (rho) is a vector of N pairs of real numbers. Each pair represents a pole, the
first number in the pair is the real part of the pole and the second is the imaginary part.
The transfer function is
M–1
∑
k
nk s
H ( s ) = ---------------------------------------------
N–1
k=0
-
∏ 1 – ρ--------------------
s
r + jρ i
k=0 k k
r
where n k is the coefficient of the k th power of s in the numerator, while ρ k and ρ ki are
the real and imaginary parts of the k th pole. If a pole is real, the imaginary part shall be
specified as zero (0). If a pole is complex, its conjugate shall also be present. If a pole is
zero (0), then the term associated with it is implemented as s, rather than ( 1 – s ⁄ ρ ) .
4.4.12.4 laplace_nd
laplace_nd() implements the numerator-denominator form of the Laplace transform filter.
laplace_nd( expr , n , d [ , ε ] )
where n is an vector of M real numbers containing the coefficients of the numerator and
d is a vector of N real numbers containing the coefficients of the denominator. The
transfer function is
M
∑ nk s
k
H ( s ) = --------------------
k=0
N
-
∑ dk sk
k=0
4.4.12.5 Examples
V(out) <+ laplace_zp(V(in), {-1,0}, {-1,-1,-1,1});
implements
1+s
H ( s ) = -----------------------------------------------------
1 + -----------s
1 + -----------
s
1+ j 1 – j
and
V(out) <+ laplace_nd(V(in), {0,1}, {-1,0,1});
implements
s
H ( s ) = -------------
2
s –1
This example
V(out) <+ laplace_zp(white_noise(k), , {1,0,1,0,-1,0,-1,0});
implements a band-limited white noise source as
2 k
v out = ------------------
-
s –12
2
no delay. The zeros argument may be represented as a null argument. The null argument
is characterized by two adjacent commas (,,) in the argument list.
All Z-transform filters share three common arguments: T, τ, and t0. T specifies the period
of the filter, is mandatory, and shall be positive. τ specifies the transition time, is
optional, and shall be nonnegative.
If the transition time is specified and is non-zero, the timestep is controlled to accurately
resolve both the leading and trailing corner of the transition. If it is not specified, the
transition time is taken to be one (1) unit of time (as defined by the `default_transition
compiler directive) and the timestep is not controlled to resolve the trailing corner of the
transition. If the transition time is specified as zero (0), then the output is abruptly
discontinuous. A Z-filter with zero (0) transition time shall not be directly assigned to a
branch.
Finally t0 specifies the time of the first transition, and is also optional. If not given, the
first transition occurs at t=0.
4.4.13.1 zi_zp
zi_zp() implements the zero-pole form of the Z-transform filter. The general form is
zi_zp( expr , ζ , ρ , T [ , τ [ , t0 ] ] )
where ζ (zeta) is a vector of M pairs of real numbers. Each pair represents a zero, the first
number in the pair is the real part of the zero (0) and the second is the imaginary part.
Similarly, ρ (rho) is the vector of N real pairs, one for each pole. The poles are given in
the same manner as the zeros. The transfer function is
M–1
∏ 1–z
–1
( ζ kr + jζ ki )
H ( z ) = ----------------------------------------------------
k=0
N–1
-
∏ 1–z
–1
( ρ kr + jρ ki )
k=0
r r
where ζ k and ζ ki are the real and imaginary parts of the k th zero, while ρ k and ρ ki are
the real and imaginary parts of the k th pole. If a root (a pole or zero) is real, the imaginary
part shall be specified as zero. If a root is complex, its conjugate shall also be present. If
a root is zero (0), then the term associated with it is implemented as z, rather than
( 1 – z ⁄ r ) (where r is the root).
4.4.13.2 zi_zd
zi_zd() implements the zero-denominator form of the Z-transform filter.
The form is
M–1
∏ 1–z
–1
( ζ kr + jζ ki )
H ( z ) = ----------------------------------------------------
k=0
N–1
-
∑ dkz
–k
k=0
r
where ζ k and ζ ki are the real and imaginary parts of the k th zero, while d k is the
coefficient of the k th power of s in the denominator. If a zero is real, the imaginary part
shall be specified as zero (0). If a zero is complex, its conjugate shall also be present. If
a zero is zero (0), then the term associated with it is implemented as z, rather than
(1 – z ⁄ ζ) .
4.4.13.3 zi_np
zi_np() implements the numerator-pole form of the Z-transform filter. The general form is
M–1
∑
–k
nk z
H ( z ) = ----------------------------------------------------
N–1
k=0
-
∏ 1–z
–1
( ρ kr + jρ ki )
k=0
r
where n k is the coefficient of the k th power of s in the numerator, while ρ k and ρ ki are
the real and imaginary parts of the k th pole. If a pole is real, the imaginary part shall be
specified as zero (0). If a pole is complex, its conjugate shall also be present. If a pole is
zero (0), then the term associated with it is implemented as z, rather than ( 1 – z ⁄ ρ ) .
4.4.13.4 zi_nd
zi_nd() implements the numerator-denominator form of the Z-transform filter. The
general form is
∑
–k
nk z
H ( z ) = -----------------------
k=0
N–1
-
∑ d k z –k
k=0
limexp expr
4.5.1 Analysis
The analysis() function takes one or more string arguments and returns one (1) if any
argument matches the current analysis type. Otherwise it returns zero (0). The general
form is
analysis( analysis_list )
There is no fixed set of analysis types. Each simulator can support its own set. However,
simulators shall use the names listed in Table 4-24 to represent analyses which are
similar to those provided by SPICE .
Table 4-24—Analysis types
"static" Any equilibrium point calculation, including a DC analysis as well as those that precede
another analysis, such as the DC analysis which precedes an AC or noise analysis, or the
IC analysis which precedes a transient analysis.
"nodeset" The phase during an equilibrium point calculation where nodesets are forced.
DC "dc" 1 1 1 1 0 0 0 0 0 0
Transient "tran" 0 0 0 0 1 1 0 0 0 0
Small-signal "ac" 0 0 0 0 0 0 1 1 0 0
Noise "noise" 0 0 0 0 0 0 0 0 1 1
Using the analysis() function, it is possible to have a module behave differently depending
on which analysis is being run.
Examples:
To implement nodesets or initial conditions using the analysis function and switch
branches, use the following.
if (analysis("ic"))
V(cap) <+ initial_value;
else
I(cap) <+ ddt(C*V(cap));
4.5.2 DC analysis
Verilog-AMS supports a single-point dc analysis and also a multipoint dc sweep analysis
in which multiple dc points are computed over a sweep of parameter values. An
operating point analysis is done for each dc point in the sweep. A single-point dc analysis
is the same as an operating point analysis. The analysis("dc") and analysis("static")
function calls shall return true for a single-point dc analysis and also for every dc point
in a sweep analysis. The analysis("nodeset") function call shall return true only during the
phase of an operating point analysis in which nodeset values are enforced; that phase
may occur in a single-point dc analysis or the first point of a multipoint dc sweep
analysis, but does not occur for subsequent points of a dc sweep.
During a dc sweep analysis, the values of variables at the conclusion of the operating
point analysis for one dc point shall be used as the starting values for those variables for
the next dc point. However, variable values shall not be carried over between two
independent dc sweep analyses (from the last dc point of one analysis to the first dc point
of the next analysis). Variables shall be re-initialized to zero (or x, for integers whose
values are assigned in a digital context) at the start of each new analysis.
4.5.3 AC stimulus
A small-signal analysis computes the steady-state response of a system which has been
linearized about its operating point and is driven by a small sinusoid. The sinusoidal
stimulus is provided using the ac_stim() function. The general form is
ac_stim( [analysis_name [ , mag [ , phase ] ] ] )
The AC stimulus function returns zero (0) during large-signal analyses (such as DC and
transient) as well as on all small-signal analyses using names which do not match
analysis_name. The name of a small-signal analysis is implementation dependent,
although the expected name (of the equivalent of a SPICE AC analysis) is “ac”, which is
the default value of analysis_name. When the name of the small-signal analysis matches
analysis_name, the source becomes active and models a source with magnitude mag and
phase phase. The default magnitude is one (1) and the default phase is zero (0). phase is
given in radians.
4.5.4 Noise
Several functions are provided to support noise modeling during small-signal analyses.
To model large-signal noise during transient analyses, use the $random() system task. The
noise functions are often referred to as noise sources. There are three noise functions, one
models white noise processes, another models 1/f or flicker noise processes, and the last
interpolates a vector to model a process where the spectral density of the noise varies as
a piecewise linear function of frequency. The noise functions are only active in small-
signal noise analyses and return zero (0) otherwise.
4.5.4.1 white_noise
White noise processes are those whose current value is completely uncorrelated with any
previous or future values. This implies their spectral density does not depend on
frequency. They are modeled using
white_noise( pwr [ , name ] )
which generates white noise with a power of pwr.
Examples:
The thermal noise of a resistor could be modelled using
I(a,b) <+ V(a,b)/R +
white_noise(4 * ‘P_K * $temperature/R, "thermal");
The optional name argument acts as a label for the noise source used when the simulator
outputs the individual contribution of each noise source to the total output noise. The
contributions of noise sources with the same name from the same instance of a module
are combined in the noise contribution summary.
4.5.4.2 flicker_noise
The flicker_noise() function models flicker noise. The general form is
flicker_noise( pwr , exp [ , name ] )
which generates pink noise with a power of pwr at 1Hz which varies in proportion to
1/f exp.
The optional name argument acts as a label for the noise source used when the simulator
outputs the individual contribution of each noise source to the total output noise. The
contributions of noise sources with the same name from the same instance of a module
are combined in the noise contribution summary.
4.5.4.3 noise_table
The noise_table() function interpolates a vector to model a process where the spectral
density of the noise varies as a piecewise linear function of frequency. The general form
is
noise_table( vector [ , name ] )
where vector contains pairs of real numbers: the first number in each pair is the
frequency in Hertz and the second is the power. Noise pairs are specified in the order of
ascending frequencies. noise_table() performs piecewise linear interpolation to compute
the power spectral density generated by the function at each frequency.
The optional name argument acts as a label for the noise source used when the simulator
outputs the individual contribution of each noise source to the total output noise. The
contributions of noise sources with the same name from the same instance of a module
are combined in the noise contribution summary.
analog_function_declaration ::=
analog function [ type ] function_identifier ;
function_item_declaration { function_item_declaration }
statement
endfunction
type ::=
integer
| real
function_item_declaration ::=
input_declaration
| inout_declaration
| output_declaration
| block_item_declaration
block_item_declaration ::=
parameter_declaration
| integer_declaration
| real_declaration
An analog function declaration shall begin with the keywords analog function, optionally
followed by the type of the return value from the function, then the name of the function
and a semicolon, and ending with the keyword endfunction.
type specifies the return value of the function; its use is optional. type can be a real or
an integer; if unspecified, the default is real.
An analog function:
• can use any statements available for conditional execution (see Section 6.1);
• shall have at least one input declared; the block item declaration shall declare the
type of the inputs as well as local variables used in the function; if any outputs or
inouts are declared, the block item declaration shall also declare their types;
Examples:
The following example defines an analog function called maxValue, which returns the
potential of whichever signal is larger.
analog function real maxValue;
input n1, n2 ;
real n1, n2 ;
begin
// code to compare potential of two signal
maxValue = (n1 > n2) ? n1 : n2 ;
end
endfunction
The next example defines an analog function called geomcalc, which returns both the
area and perimeter of a rectangle.
analog function real geomcalc;
input l, w ;
output area, perim ;
real l, w, area, perim ;
begin
area = l * w ;
perim = 2 * ( l + w );
end
endfunction
can be read and assigned within the flow; its last assigned value is passed back on the
return call. An analog user-defined function shall always return a scalar value.
Example:
The following line (from the first example in Section 4.6.1) illustrates this concept:
maxValue = (n1 > n2) ? n1 : n2 ;
If the internal variable is not assigned, the function shall return zero (0). Because
geomcalc is not assigned in the second example in Section 4.6.1, its return value is zero.
If a function computes more than one value, output or inout arguments can be used to
pass these values back to the calling context. These variables can be read and assigned
within the flow; the last value assigned during function evaluation is then assigned to the
corresponding expression in the argument list for the function, which shall be an integer
or real identifier or an element of an integer or real array.
Example:
The following lines (from the second example in Section 4.6.1) illustrate this concept:
area = l * w ;
perim = 2 * ( l + w );
analog_function_call ::=
function_identifier ( expression { , expression } )
The order of evaluation of the arguments to an analog function call is undefined. The
argument expressions are assigned to the declared inputs, outputs, and inouts in the order
of their declaration.
An analog function:
• shall not call itself directly or indirectly, i.e., recursive functions are not
permitted;
Examples:
The following example uses the maxValue function defined in Section 4.6.1.
Section 5
Signals
• Unnamed branches are accessed in a similar manner, except the access functions
are applied to net names or port names rather than branch names.
Example 2
If n1 and n2 are electrical nets or ports, then V(n1, n2) creates an unnamed branch from
n1 to n2 (if it does not already exist) and then accesses the branch potential (or the
potential difference between n1 to n2), and V(n1) does the same from n1 to the global
reference node (ground).
• In other words, accessing the potential from a net or port to a net or port defines
an unnamed branch. Accessing the potential on a single net or port defines an
unnamed branch from that net or port to the global reference node (ground).
There can only be one unnamed branch between any two nets.
Example 3
I(n1, n2) creates an unnamed branch from n1 to n2 (if it does not already exist) and
then accesses the branch flow, and I(n1) does the same from n1 to the global reference
node (ground).
• Thus, accessing the flow from a net or port to a net or port defines an unnamed
branch. Accessing the potential on a single net or port defines an unnamed branch
from that net or port to the global reference node (ground).
• It is also possible to access the flow passing through a port into a module. The
name of the access function is derived from the flow nature of the discipline of
the port. In this case, (<>) is used to delimit the port name rather than ().
Example 4
I(<p1>) is used to access the current flow into the module through the electrical port p1.
This capability is discussed further in Section 5.1.4.
5.1.2.1 Probes
If no value is specified for either the potential or the flow, the branch is a probe. If the
flow of the branch is used in an expression anywhere in the module, the branch is a flow
probe, otherwise the branch is a potential probe. Using both the potential and the flow
of a probe branch is illegal. The models for probe branches are shown in Figure 5-1.
p f
5.1.2.2 Sources
A branch, either named or unnamed, is a source branch if either the potential or the flow
of that branch is assigned a value by a contribution statement (see Section 5.3) anywhere
in the module. It is a potential source if the branch potential is specified and is a flow
source if the branch flow is specified. A branch cannot simultaneously be both a
potential and a flow source, although it can switch between them (a switch branch).
Both the potential and the flow of a source branch are accessible in expressions
anywhere in the module. The models for potential and flow sources are shown in
Figure 5-2.
f f
p p
f is a probe which measures the flow through the branch and p is a probe which
measures the potential across the branch.
5.1.3 Examples
The following examples demonstrate how to formulate models and the correspondence
between the behavioral description and the equivalent probe/source model.
module my_conductor(p,n);
parameter real G=1;
electrical p,n;
branch (p,n) cond;
v G
analog begin
Gv
I(cond) <+ G * V(cond);
end
endmodule
module my_resistor(p,n);
parameter real R=1;
electrical p,n; i
branch (p,n) res;
R
analog begin
V(res) <+ R * I(res);
Ri
end
endmodule
d 1 t
v(t) = Ri(t) + L i(t) + ---- ∫ i(τ) dτ
dt C –∞
v(t) d 1 t
i(t) = -------- + C v(t) + --- ∫ v(τ) dτ
R dt L –∞
analog begin
I(i_diode) <+ is*(limexp(V(i_diode)/$vt) – 1);
I(junc_cap) <+
ddt(tf*I(i_diode) - 2*cjo*sqrt(phi*(phi*V(junc_cap))));
if (I(<a>) > imax)
$strobe( "Warning: diode is melting!" );
end
endmodule
The expression V(<a>) is invalid for ports and nets, where V is a potential access
function. The port branch I(<a>) can not be used on the left side of a contribution
operator <+.
//
// N-bit DAC example.
//
real aout;
genvar i;
analog begin
@(cross(V(clk) - vth, +1)) begin
aout = 0;
for (i = width - 1; i >= 0; i = i - 1) begin
if (V(in[i]) > vth) begin
aout = aout + fullscale/pow(2, width - i);
end
end
end
V(out) <+ transition(aout, td, tt);
end
endmodule
//
// 8-bit fixed-width DAC example.
//
real aout;
analog begin
@(cross(V(clk) - 2.5, +1)) begin
aout = 0;
aout = aout + ((V(in[7]) > vth) ? fullscale/2.0 : 0.0);
aout = aout + ((V(in[6]) > vth) ? fullscale/4.0 : 0.0);
aout = aout + ((V(in[5]) > vth) ? fullscale/8.0 : 0.0);
aout = aout + ((V(in[4]) > vth) ? fullscale/16.0 : 0.0);
endmodule
The syntax for analog signal access is shown in Syntax 5-1.
access_function_reference ::=
bvalue
| pvalue
bvalue ::=
access_identifier ( analog_signal_list )
analog_signal_list ::=
branch_identifier
| array_branch_identifier [ genvar_expression ]
| net_or_port_scalar_expression
| net_or_port_scalar_expression , net_or_port_scalar_expression
net_or_port_scalar_expression ::=
net_or_port_identifier
| array_net_or_port_identifier [ genvar_expression ]
| vector_net_or_port_identifier [ genvar_expression ]
pvalue ::=
flow_access_identifier (< port_scalar_expression >)
port_scalar_expression ::=
port_identifier
| array_port_identifier [ genvar_expression ]
| vector_port_identifier [ genvar_expression ]
electrical p, n;
branch (p,n) res;
parameter real R = 50;
analog
V(res) <+ R*I(res);
attribute_reference ::=
net_identifier . pot_or_flow . attribute_identifier
or
I(n1, n2) <+ expression ;
where (n1,n2) represents an unnamed source branch and V(n1,n2) refers to the
potential on the branch, while I(n1,n2) refers to the flow through the branch. The
expression can be linear, nonlinear, or dynamic in nature. The left-hand side can not use
a port access function.
Examples:
The following modules model a resistor and a capacitor.
module resistor(p, n);
electrical p, n;
parameter real r = 0;
analog
V(p,n) <+ r*I(p, n);
endmodule
module capacitor(p, n);
electrical p, n;
parameter real c = 0;
analog
I(p,n) <+ c*ddt(V(p, n));
endmodule
5.3.1.1 Relations
Branch contribution statements implicitly define source branch relations. The branch is
directed from the first net of the access function to the second net. If the second net is not
specified, the global reference node (ground) is used as the reference net.
A branch relation is a path of the flow between two nets in a module. Each net has two
quantities associated with it—the potential of the net and the flow out of the net. In
electrical circuits, the potential of a net is its voltage, whereas the flow out of the net is
its current. Similarly, each branch has two quantities associated with it—the potential
across the branch and the flow through the branch.
Examples:
The following module models a simple single-ended amplifier.
module amp(out, in);
input in;
output out;
electrical out, in;
parameter real Gain = 1;
analog
V(out) <+ Gain*V(in);
endmodule
5.3.1.2 Evaluation
A statement is evaluated as follows for source branch contributions:
3. At the end of the simulation cycle, the simulator assigns the retained value to the
source branch.
Parasitics are added to the amplifier shown in Section 5.3.1.1 by simply adding
additional contribution statements to model the input admittance and output impedance.
Examples:
module amp(out, in);
inout out, in;
electrical out, in;
parameter real Gain = 1, Rin = 1, Cin = 1, Rout = 1, Lout = 1;
analog begin
// gain of amplifier
V(out) <+ Gain*V(in);
// model input admittance
I(in) <+ V(in)/Rin;
I(in) <+ Cin*ddt(V(in));
// model output impedance
V(out) <+ Rout*I(out);
V(out) <+ Lout*ddt(I(out));
end
endmodule
analog begin
// stop to resolve threshold crossings
@(cross(V(cp,cn) - thresh, 0));
analog_branch_contribution ::=
bvalue <+ analog_expression ;
Examples:
A complete description of an ideal opamp is:
module opamp(out, pin, nin);
electrical out, pin, nin;
analog
V(out):V(pin,nin) == 0;
endmodule
Syntax 5-4 shows the syntax for an indirect assignment statement.
analog_indirect_branch_assignment ::=
bvalue : nexpr == analog_expression ;
nexpr ::=
bvalue
| pvalue
| ddt ( bvalue | pvalue )
| idt ( bvalue | pvalue )
dx
= f ( x, y, z )
dt
dy
= g ( x , y, z )
dt
dz
= h ( x, y, z )
dt
can be written as
V(x): ddt(V(x)) == f(V(x), V(y), V(z));
V(y): ddt(V(y)) == g(V(x), V(y), V(z));
V(z): ddt(V(z)) == h(V(x), V(y), V(z));
or
V(y): ddt(V(x)) == f(V(x), V(y), V(z));
V(z): ddt(V(y)) == g(V(x), V(y), V(z));
V(x): ddt(V(z)) == h(V(x), V(y), V(z));
or
V(z): ddt(V(x)) == f(V(x), V(y), V(z));
V(x): ddt(V(y)) == g(V(x), V(y), V(z));
V(y): ddt(V(z)) == h(V(x), V(y), V(z));
without affecting the results.
Section 6
Analog behavior
analog_block ::=
analog analog_statement ;
analog_statement ::=
analog_seq_block
| analog_branch_contribution
| analog_indirect_branch_assignment
| analog_procedural_assignment
| analog_conditional_statement
| analog_for_statement
| analog_case_statement
| analog_event_controlled_statement
| system_task_enable
| statement
statement ::=
| seq_block
| procedural_assignment
| conditional_statement
| loop_statement
| case_statement
The statements within the analog block are used to define the continuous-time behavior
of the module. The behavioral description is a mathematical mapping of input signals to
output signals. The mapping is done with contribution statements using the form
signal <+ analog_expression ;
or by an indirect branch assignment. The analog_expression can be any combination of
linear, nonlinear, or differential expressions of module signals, constants, and
parameters (see Section 5).
All analog blocks contained in various modules in a design are considered to be
executing concurrent with respect to each other.
seq_block ::=
begin [ : block_identifier { block_item_declaration } ]
{ statement }
end
analog_seq_block ::=
begin [ : block_identifier { block_item_declaration } ]
{ analog_statement }
end
block_item_declaration ::=
parameter_declaration
| integer_declaration
| real_declaration
procedural_assignment ::=
lexpr = expression ;
analog_procedural_assignment ::=
lexpr = analog_expression ;
lexpr ::=
integer_identifier
| real_identifier
| array_element
array_element ::=
integer_identifier [ expression ]
| real_identifier [ expression ]
conditional_statement ::=
if ( expression ) true_statement_or_null
[ else false_statement_or_null ]
If the expression evaluates to True (that is, has a non-zero value), the true_statement
shall be executed. If it evaluates to False (has a zero value (0)), the true_statement shall
not be executed. If there is an else false_statement and expression is False, the
false_statement shall be executed.
Since the numeric value of the if expression is tested for being zero (0), certain shortcuts
are possible (see Section 4.1).
6.4.1 Examples
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() which lacks an else.
In the example below, the else goes with the inner if(), as shown by indentation.
if(index > 0)
if (i > j)
result = i;
else // else applies to preceding if
result = j;
If that association is not desired, a begin-end shall be used to force the proper association,
as shown below.
if (index > 0) begin
if (i > j)
result = i;
end
else result = j;
Nesting of if statements (known as an if-else-if construct) is the most general way of
writing a multi-way decision. The expressions are evaluated in order; if any expression
is True, the statement associated with it shall be executed and this action shall terminate
the whole chain. Each statement is either a single statement or a sequential block of
statements.
analog_conditional_statement ::=
if ( genvar_expression ) true_analog_statement_or_null
[ else false_analog_statement_or_null ]
case_statement ::=
case ( expression ) case_item { case_item } endcase
| casex ( expression ) case_item { case_item } endcase
| casez ( expression ) case_item { case_item } endcase
case_item ::=
expression { , expression } : statement_or_null
| default [ : ] statement_or_null
analog_case_statement ::=
case ( genvar_expression ) analog_case_item { analog_case_item } endcase
| casex ( genvar_expression ) analog_case_item { analog_case_item } endcase
| casez ( genvar_expression ) analog_case_item { analog_case_item } endcase
analog_case_item ::=
genvar_expression { , genvar_expression } : analog_statement_or_null
| default [ : ] analog_statement_or_null
The casex and the casez versions of the case statement are described in Section 8.3.2 and
IEEE 1364-1995 Verilog HDL.
case (1)
encode[2] : $display("Select Line 2") ;
encode[1] : $display("Select Line 1") ;
encode[0] : $display("Select Line 0") ;
default $strobe("Error: One of the bits expected ON");
endcase
The case expression here is a constant expression (1). The case_items are expressions
(array elements) and are compared against the constant expression for a match.
repeat_statement ::=
repeat ( expression ) statement
while_statement ::=
while ( expression ) statement
Syntax 6-9 shows the syntax for the two forms of the for() statements.
for_statement ::=
for ( procedural_assignment ; expression ;
procedural_assignment ) statement
analog_for_statement ::=
for ( genvar_assignment ; genvar_expression ;
genvar_assignment ) analog_statement
Examples:
module genvarexp(out, dt);
parameter integer width = 1;
output out;
input dt[1:width];
electrical out;
electrical dt[1:width];
genvar k;
real tmp;
analog begin
tmp = 0.0;
for (k = 1; k <= width; k = k + 1) begin
tmp = tmp + V(dt[k]);
V(out) <+ ddt(V(dt[k]));
end
end
endmodule
See the discussion in Section 4.4.1 regarding other restrictions on the usage of analog
operators.
6.7 Events
The analog behavior of a component can be controlled using events. events have the
following characteristics:
• events have no time duration
• events can be triggered and detected in different parts of the behavioral model
There are two types of analog events, global events (Section 6.7.4) and monitored events
(Section 6.7.5). Null arguments are not allowed in analog events.
event_control_statement ::=
event_control statement_or_null
event_control ::=
@ event_identifier
| @ ( event_expression )
analog_event_expression ::=
global_event
| event_function
| digital_expression
| event_identifier
| posedge digital_expression
| negedge digital_expression
| event_expression or event_expression
digital_event_expression ::=
digital_expression
| event_identifier
| posedge digital_expression
| negedge digital_expression
| event_function
| digital_event_expression or digital_event_expression
The procedural statement following the event expression is executed whenever the event
described by the expression changes. The analog event detection is non-blocking,
meaning the execution of the procedural statement is skipped unless the analog event has
occurred. The event expression consists of one or more signal names, global events, or
monitored events separated by the or operator.
The parenthesis around the event expression are required.
global_event ::=
initial_step [ ( analysis_list ) ]
| final_step [ ( analysis_list ) ]
analysis_list ::=
analysis_name { , analysis_name }
analysis_name ::=
" analysis_identifier "
initial_step and final_step generate global events on the first and the last point in an analysis
respectively. They are useful when performing actions which should only occur at the
beginning or the end of an analysis. Both global events can take an optional argument,
consisting of an analysis list for the active global event.
Examples:
For example,
@(initial_step("ac", "dc")) // active for dc and ac only
@(initial_step("tran")) // active for transient only
Table 6-1 describes the return value of initial_step and final_step for standard
analysis types. Each column shows the return-on-event status. One (1) represents Yes
and zero (0) represents No. A Verilog-AMS HDL simulator can use any or all of these
typical analysis types. Additional analysis names can also be used as necessary for
specific implementations. (See Section 4.5.1 for further details.)
Table 6-1—Return Values for initial_step and final_step
initial_step 1 1 0 0 1 0 0 1 0 0 1 0 0
initial_step("ac") 0 0 0 0 0 0 0 1 0 0 0 0 0
initial_step("noise") 0 0 0 0 0 0 0 0 0 0 1 0 0
initial_step("tran") 0 0 0 0 1 0 0 0 0 0 0 0 0
initial_step("dc") 1 1 0 0 0 0 0 0 0 0 0 0 0
initial_step(unknown) 0 0 0 0 0 0 0 0 0 0 0 0 0
final_step 1 0 0 1 0 0 1 0 0 1 0 0 1
final_step("ac") 0 0 0 0 0 0 0 0 0 1 0 0 0
final_step("noise") 0 0 0 0 0 0 0 0 0 0 0 0 1
final_step("tran") 0 0 0 1 0 0 1 0 0 0 0 0 0
final_step("dc") 1 0 0 1 0 0 0 0 0 0 0 0 0
final_step(unknown) 0 0 0 0 0 0 0 0 0 0 0 0 0
Examples:
The following example measures the bit-error rate of a signal and prints the result at the
end of the simulation.
module bitErrorRate (in, ref) ;
input in, ref ;
electrical in, ref ;
parameter real period=1, thresh=0.5 ;
integer bits, errors ;
analog begin
@(initial_step) begin
bits = 0 ;
errors = 0 ;
end
event_function ::=
cross_function
| above_function
| timer_function
The direction indicator can only evaluate to +1, -1, or 0. If it is set to 0 or is not specified,
the event and timestep control occur on both positive and negative crossings of the
signal. If dir is +1 (or -1), the event and timestep control only occur on rising edge
(falling edge) transitions of the signal. For any other transitions of the signal, the cross()
function does not generate an event.
expr_tol and time_tol are defined as shown in Figure 6-1. They represent the maximum
allowable error between the estimated crossing point and the true crossing point.
Solution
Points
expression_tol
time_tol
Section 7
Hierarchical structures
7.1 Modules
A module definition is enclosed between the keywords module and endmodule, as shown
in Syntax 7-1. The identifier following the keyword module is the name of the module
being defined. The optional list of ports specify an ordered list of the module’s ports. The
order used can be significant when instantiating the module (see Section 7.1.2). The
identifiers in this list shall be declared in input, output, or inout declaration statements
within the module definition. The module items define what constitutes a module and
include many different types of declarations and definitions. A module definition can
have at most one analog block.
A module can have a description attribute, which shall be used by the simulator when
generating help messages for the module.
The keyword macromodule can be used interchangeably with the keyword module to
define a module. An implementation can choose to treat module definitions beginning
with the macromodule keyword differently.
module_declaration ::=
{attribute_instance} module_keyword module_identifier [ digital_list_of_ports ] ;
[ module_items ]
endmodule
module_keyword ::=
module
| macromodule
list_of_ports ::=
( port { , port } )
port ::=
port_expression
| . port_identifier ( [ port_expression ] )
port_expression ::=
port_identifier
| port_identifier [ constant_expression ]
| port_identifier [ constant_range ]
constant_range ::=
msb_constant_expression : lsb_constant_expression
module_items ::=
{ module_item }
| analog_block
module_item ::=
module_item_declaration
| parameter_override
| module_instantiation
| digital_continuous_assignment
| digital_gate_instantiation
| digital_udp_instantiation
| digital_specify_block
| digital_initial_construct
| digital_always_construct
module_item_declaration ::=
{attribute_instance} parameter_declaration
| {attribute_instance} local_parameter_declaration
| {attribute_instance} string_parameter_declaration
| {attribute_instance} local_string_parameter_declaration
| aliasparam_declaration
| {attribute_instance} digital_input_declaration
| {attribute_instance} digital_output_declaration
| {attribute_instance} digital_inout_declaration
| ground declaration
| {attribute_instance} integer_declaration
| {attribute_instance} real_declaration
| {attribute_instance} net_discipline_declaration
| genvar_declaration
| branch_declaration
| analog_function_declaration
| digital_function_declaration
| digital_net_declaration
| digital_reg_declaration
| digital_time_declaration
| digital_realtime_declaration
| digital_event_declaration
| digital_task_declaration
parameter_override ::=
defparam list_of_param_assignments ;
module_instantiation ::=
module_or_paramset_identifier [ parameter_value_assignment ] instance_list
parameter_value_assignment ::=
# ( ordered_param_override_list )
| # ( named_param_override_list )
ordered_param_override_list ::=
expression { , expression }
named_param_override_list ::=
named_param_override { , named_param_override }
named_param_override ::=
.parameter_identifier ( constant_expression )
| .$system_parameter_identifier ( constant_expression )
instance_list ::=
module_instance { , module_instance } ;
module_instance ::=
name_of_instance ( [ list_of_module_connections ] )
name_of_instance ::=
module_instance_identifier [ range ]
list_of_module_connections ::=
ordered_port_connection { , ordered_port_connection }
| named_port_connection { , named_port_connection }
ordered_port_connection ::=
[ expression ]
named_port_connection ::=
. port_identifier ( [ expression ] )
range ::=
[ constant_expression : constant_expression ]
• The list of module connections can be provided only for modules defined with
ports. The parentheses, however, are always required. When a list of module
connections is given, the first element in the list connects to the first port, the
second element to the second port, and so on. See Section 7.4 for a more detailed
discussion of ports and port connection rules.
Examples:
The example below illustrates a comparator and an integrator (lower-level modules)
which are instantiated in sigma-delta A/D converter module (the higher-level module).
module comparator(cout, inp, inm);
output cout;
input inp, inm;
ground gnd;
electrical cout, inp, inm;
parameter real td = 1n, tr = 1n, tf = 1n;
real vcout;
analog begin
@(cross(V(inp) - V(inm), 0))
vcout = ((V(inp) > V(inm)) ? 1 : 0);
V(vcout) <+ transition(vcout, td, tr, tf);
end
endmodule
module integrator(out, in);
output out;
input in;
electrical in, out;
parameter real gain = 1.0;
parameter real ic = 0.0;
analog begin
V(out) <+ gain*idt(V(in), ic);
end
endmodule
module sigmadelta(out, ref, in);
output out;
input ref, in;
endmodule
The comparator instance C1 and the integrator instance I1 in Figure 7-1 use named port
connections, whereas the comparator instance C2 and the d2a (not described here)
instance D1 use ordered port connections. Note the integrator instance I1 overrides gain
parameter positionally, whereas the d2a instance D1 overrides width parameter by named
association.
ground
aa2
D1
ref
parameter_override ::=
defparam list_of_defparam_assignments ;
list_of_defparam_assignments ::=
defparam_assign
| list_of_defparam_assignments , defparam_assign
defparam_assign ::=
parameter_identifier = constant_expression
| $system_parameter_identifier = constant_expression
| parameter_array_identifier [ range ] = constant_param_arrayinit
constant_param_arrayinit ::=
{ param_arrayinit_element_list }
param_arrayinit_element_list ::=
param_arrayinit_element
| param_arrayinit_element_list , param_arrayinit_element
param_arrayinit_element ::=
constant_expression
| { replicator_constant_expression {constant_expression} }
Examples:
module tgate;
electrical io1,io2,control,control_bar;
mosn m1 (io1, io2, control);
mosp m2 (io1, io2, control_bar);
endmodule
module mosp (source,drain,gate);
inout source, drain, gate;
electrical source, drain, gate;
parameter gate_length = 0.3e-6,
gate_width = 4.0e-6;
spice_pmos #(.l(gate_length),.w(gate_width)) p(gate,source,drain);
endmodule
module mosn (source,drain,gate);
inout source, drain, gate;
electrical source, drain, gate;
parameter gate_length = 0.3e-6,
gate_width = 4.0e-6;
spice_nmos #(.l(gate_length),.w(gate_width)) n(gate,source,drain);
endmodule
module annotate;
defparam
tgate.m1.gate_width = 5e-6,
tgate.m2.gate_width = 10e-6;
endmodule
Example:
In the following example of instantiating a voltage-controlled oscillator, the parameters
are specified on a named-association basis much as they are for ports.
module n(lo_out, rf_in):
electrical lo_out, rf_in;
//create an instance and set parameters
vco #(.centerFreq(5000), .convGain(1000)) vco1(lo_out, rf_in);
endmodule
Here, the name of the instantiated vco module is vco1. The centerFreq parameter is
passed a value of 5000 and the convGain parameter is passed a value of 1000. The
positional assignment mechanism for ports assigns lo_out as the first port and rf_in as
the second port of vco1.
value assignment by name, or a paramset; in all three methods, the system parameter
identifier is prefixed by a period (.), just as for explicitly-declared parameters.
If an instance of a module has a non-unity value of $mfactor, then the following rules are
applied automatically by the simulator:
• All contributions to a branch flow quantity in the analog block shall be multiplied
by $mfactor
• The value returned by any branch flow probe in the analog block, including those
used in indirect assignments, shall be divided by $mfactor
• Contributions to a branch flow quantity using the noise functions of Section 4.5.4
(white_noise, flicker_noise, and noise_table) shall have the noise power multiplied by
$mfactor
Application of these rules guarantees that the behavior of the module in the design is
identical to the behavior of a quantity $mfactor of identical modules with the same
connections; however, the simulator only has to evaluate the module once.
Verilog-AMS does not provide a method to disable the automatic $mfactor scaling. The
simulator shall issue a warning if it detects a misuse of the $mfactor in a manner that
would result in double-scaling.
Examples:
The two resistor modules below show ways that the $mfactor might be used in a module.
The first example, badres, misuses the $mfactor such that the contributed current would
be multiplied by $mfactor twice, once by the explicit multiplication and once by the
automatic scaling rule. The simulator will generate an error for this module.
module badres(a,b);
inout a, b;
electrical a, b;
parameter real r = 1.0 from (0:inf);
analog begin
I(a,b) <+ V(a,b) / r * $mfactor; // ERROR
end
endmodule
In this second example, parares, $mfactor is used only in the conditional expression and
does not scale the output. No error will be generated for this module. In cases where the
effective resistance r/$mfactor would be too small, the resistance is simply shorted out,
and the simulator may collapse the node to reduce the size of the system of equations.
module parares(a,b);
inout a, b;
electrical a, b;
parameter real r = 1.0 from (0:inf);
analog begin
if (r / $mfactor < 1.0e-3)
V(a,b) <+ 0.0;
else
I(a,b) <+ V(a,b) / r;
end
endmodule
The values of the five geometrical system parameters, $xposition, $yposition, $angle, $hflip,
and $vflip, do not have any automatic effect on the simulation. The paramset or module
may use these values to compute geometric layout-dependent effects, as shown in the
following example.
Example:
In this example, it is assumed that a top-level module named processinfo contains
values for the properties of polysilicon resistors in the manufacturing process, including
the nominal value processinfo.rho and the gradients processinfo.drho_dx and
processinfo.drho_dy, in the x and y direction respectively.
module polyres(a,b);
inout a, b;
electrical a, b;
parameter real length = 1u from (0:inf);
parameter real width = 1u from (0:inf);
real rho, reff;
analog begin
rho = processinfo.rho
+ $xposition * processinfo.drho_dx
+ $yposition * processinfo.drho_dy;
reff = rho * length / width;
I(a,b) <+ V(a,b) / reff;
end
endmodule
The resistor just defined could be instantiated in the following manner so as to cancel out
the process gradients:
module matchedres(a,b);
inout a, b;
electrical a, b;
parameter real length = 1u from (0:inf);
parameter real width = 1u from (0:inf);
polyres #(.width(width/4.0), .length(length),
.$xposition(-1u), .$yposition(-1u)) R1(a,b);
7.3 Paramsets
A paramset definition is enclosed between the keywords paramset and endparamset, as
shown in Syntax 7-5. The first identifier following the keyword paramset is the name of
the paramset being defined. The second identifier will usually be the name of a module
with which the paramset is associated. The second identifier may instead be the name of
a second paramset; a chain of paramsets may be defined in this way, but the last paramset
in the chain shall reference a module.
paramset_declaration ::=
{attribute_instance} paramset paramset_identifier module_or_paramset_identifier ;
paramset_item_declaration {paramset_item_declaration}
paramset_statement { paramset_statement }
endparamset
paramset_item_declaration ::=
{attribute_instance} parameter_declaration
| {attribute_instance} local_parameter_declaration
| {attribute_instance} string_parameter_declaration
| {attribute_instance} local_string_parameter_declaration
| aliasparam_declaration
| {attribute_instance} integer_declaration
| {attribute_instance} real_declaration
paramset_statement ::=
.module_parameter_identifier = constant_expression ;
.$system_parameter_identifier = constant_expression ;
| statement
The paramset itself contains no behavioral code; all of the behavior is determined by the
associated module. The restrictions on statements in the paramset are described in
Section 7.3.1.
The paramset provides a convenient way to collect parameter values for a particular
module, such that an instance need only provide overrides for a smaller number of
parameters. A simulator can use this information to optimize data storage for the
instances: multiple instances may share a paramset, and the simulator can share storage
of parameters of the underlying module. The shared storage of paramsets makes them
similar to the SPICE model card. Also like the SPICE model card, paramsets may be
overloaded, as described in Section 7.3.2.
A paramset can have a description attribute, which shall be used by the simulator when
generating help messages for the paramset.
Example:
The following example shows how one might convert a SPICE model card into a Verilog-
AMS paramset. Suppose one has the following lines in a SPICE netlist:
m1 d1 g 0 0 nch l=1u w=10u
m2 d2 g 0 0 nch l=1u w=5u
.model nch nmos (level=3 kp=5e-5 tox=3e-8 u0=650 nsub=1.3e17
+ vmax=0 tpg=1 nfs=0.8e12)
These lines could be written in Verilog-AMS as follows, assuming that nmos is a
behavioral module that contains the same equations as the SPICE primitive.
nch #(.l(1u), .w(10u)) m1(.d(d1), .g(g), .s(0), .b(0));
nch #(.l(1u), .w(5u)) m2(.d(d2), .g(g), .s(0), .b(0));
paramset nch nmos; // default paramset
parameter real l=1u from [0.25u:inf);
parameter real w=1u from [0.2u:inf);
.l=l; .w=w; .ad=w*0.5u; .as=w*0.5u;
.level=3; .kp=5e-5; .tox=3e-8; .u0=650; .nsub=1.3e17;
.vmax=0; .tpg=1; .nfs=0.8e12;
endparamset
Note that the paramset has only two parameters, l and w; an instance of the paramset that
attempts to override any of the other parameters of the underlying module nmos would
generate an error. Analog simulators are expected to optimize the storage of paramset
values in a manner similar to the way SPICE optimizes model parameter storage.
• The parameters of the paramset, with overrides and defaults, shall be all within
the allowed ranges specified in the paramset parameter declaration.
• The local parameters of the paramset, computed from parameters, shall be within
the allowed ranges specified in the paramset.
The rules above may not be sufficient for the simulator to pick a unique paramset, in
which case the following rules shall be applied in order until a unique paramset has been
selected:
• The paramset with the fewest number of un-overridden parameters shall be
selected.
• The paramset with the greatest number of local parameters with specified ranges
shall be selected.
It shall be an error if there are still more than one applicable paramset for an instance
after application of these rules.
If a paramset assigns a value to a module parameter and this value is outside the range
specified for that module parameter, it shall be an error. The simulator shall consider
only the ranges of the paramset’s own parameters when choosing a paramset.
Example:
The following example illustrates some of the rules for paramset selection. Consider a
design that includes the two paramsets defined previously (in the examples of
Section 7.3 and Section 7.3.1) as well as the following paramsets:
paramset nch nmos; // short-channel paramset
parameter real l=0.25u from [0.25u:1u);
parameter real w=1u from [0.2u:inf);
parameter real ad=0.5*w from (0:inf);
parameter real as=0.5*w from (0:inf);
.l=l; .w=w; .ad=ad; .as=as;
.level=3; .kp=5e-5; .tox=3e-8; .u0=650; .nsub=1.3e17;
.vmax=0; .tpg=1; .nfs=0.8e12;
endparamset
• A paramset output variable’s value may be computed from values of any output
parameters of the module by using the special syntax
.module_output_variable_identifier
Example:
The following example declares an output variable ft for instances of the paramset
smnpn.The module is assumed to have output variables named gm, cpi, and cmu. If the
module npn had an output variable named ft, the paramset’s output variable would
replace it.
paramset smnpn npn; // small npn paramset
(*desc="cut-off frequency"*) real ft;
.is=2.0e-17; .bf=120.0; .br=10; rb=145; .rc=75; .re=12;
.cje=2.0e-14; .vje=0.9; .mje=0.4;
.cjc=3.0e-14; .vjc=0.6; .mjc=0.3; .xcjc=0.2;
ft = .gm/(‘M_TWO_PI*(.cpi + .cmu));
endparamset
7.4 Ports
Ports provide a means of interconnecting instances of modules. For example, if a module
A instantiates module B, the ports of module B are associated with either the ports or the
internal nets of module A.
port ::=
port_expression
| . port_identifier ( [ port_expression ] )
port_expression ::=
port_identifier
| port_identifier [ constant_expression ]
| port_identifier [ constant_range ]
constant_range ::=
msb_constant_expression : lsb_constant_expression
The port expression in the port definition can be one of the following:
• a simple net identifier
The two types of module port definitions cannot be mixed; the ports of a particular
module definition shall all be defined by order or by name. The port expression is
optional because ports can be defined which do not connect to anything internal to the
module.
net_discipline_declaration ::=
discipline_identifier [ range ] list_net_identifiers;
list_net_identifiers ::=
net_identifier { , net_identifier }
input_declaration ::=
input [ range ] list_of_port_identifiers ;
output_declaration ::=
output [ range ] list_of_port_identifiers ;
inout_declaration ::=
inout [ range ] list_of_port_identifiers ;
A port can be declared in both a port type declaration and a port direction declaration. If
a port is declared as a vector, the range specification between the two declarations of a
port shall be identical.
Note: Implementations can limit the maximum number of ports in a module definition, but this shall be
a minimum of 256 ports per implementation.
• The port expression shall be the name used by the instantiating module and can
be one of the following:
• The two types of module port connections can not be mixed; connections to the
ports of a particular module instance shall be all by order or all by name.
Examples:
module adc4 (out, rem, in);
input in;
output [3:0] out; output rem;
electrical [3:0] out;
electrical in, rem, rem_chain;
Each net in the hierarchical name tree is treated as a separate scope with respect to
identifiers. A particular identifier can be declared only once in any scope.
Any named object can be referenced uniquely in its full form by concatenating the names
of the module instance or named blocks that contain it. The period character (.) is used
to separate 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
name in a path name can also be the top of a hierarchy which starts at the level where the
path is being used.
Examples:
module samplehold (in, cntrl, out );
input in, cntrl ;
output out ;
electrical in, cntrl, out ;
electrical store, sample ;
parameter real vthresh = 0.0 ;
parameter real cap = 10e-9 ;
amp op1 (in, sample, sample);
amp op2 (store, out, out) ;
analog begin
I(store) <+ cap * ddt(V(store)) ;
if (V(cntrl) > vthresh)
V(store, sample) <+ 0 ;
else
I(store, sample) <+ 0 ;
end
endmodule
samplehold
op1 op2
• tasks
• named blocks
• functions
• analog functions
An identifier can be used to declare only one item within a scope. This means it is illegal
to declare two or more variables which have the same name or to give an instance the
same name as the name of the net connected to its output.
If an identifier is referenced directly (without a hierarchical path) within a named block,
it shall be declared either locally within the named block, within a module, or within a
named block which is higher in the same branch of the name tree containing the named
block. If it is declared locally, the local item shall be used; if not, the search shall
continue upward until an item by that name is found or until a module boundary is
encountered. The search can cross named block boundaries, but not module boundaries.
Note: Because of the upward searching process, path names which are not strictly on a downward path
can be used.
Section 8
Mixed signal
8.1 Introduction
With the mixed use of digital and analog simulators, a common terminology is needed.
This section provides the core terminology used in this LRM and highlights the behavior
of the mixed-signal capabilities of Verilog-AMS HDL.
Verilog-AMS HDL provides the ability to accurately model analog, digital, and
mixed-signal blocks. Mixed-signal blocks provide the ability to access data and be
controlled by events from the other domain. In addition to providing mixed-signal
interaction directly through behavioral descriptions, Verilog-AMS HDL also provides a
mechanism for the mixed-signal interaction between modules.
Verilog-AMS HDL is a hierarchical language which enables top-down design of
mixed-signal systems. Connect modules are used in the language to resolve the
mixed-signal interaction between modules. These modules can be manually inserted (by
the user) or automatically inserted (by the simulator) based on rules provided by the user.
Connect rules and the discipline of the mixed signals can be used to control
auto-insertion throughout the hierarchy. Prior to insertion, all net segments of a mixed
signal shall first be assigned a discipline. This is commonly needed for interconnect,
which often does not have a discipline declared for it. Once a discipline has been
assigned (usually through use of a discipline resolution algorithm), connect modules
shall be inserted based on the specified connect rules. Connect rules control which
connect modules are used and where are they inserted.
Connect modules are a special form of a mixed-signal module which provide significant
power in accurately modeling the interfaces between analog and digital blocks. They
help ensure the drivers and receivers of a connect module are correctly handled so the
simulation results are not impacted.
This section also details a feature which allows analog to accurately model the effects
the digital receivers for mixed signals containing both drivers and receivers. In addition,
special functions provide access to driver values so a more accurate connect module can
be created.
The following subsections define these capabilities in more detail.
8.2 Fundamentals
The most important feature of Verilog-AMS HDL is it puts capabilities of both analog
and digital modeling into a single language. This section describes how the continuous
(analog) and discrete (digital) domains interact together, as well as the
mixed-signal-specific features of the language.
8.2.1 Domains
The domain of a value refers to characteristics of the computational method used to
calculate it. In Verilog-AMS HDL, a variable is calculated either in the continuous
(analog) domain or the discrete (digital) domain every time. The potentials and flows
described in natures are calculated in the continuous domain, while register contents and
the states of gate primitives are calculated in the discrete domain. The values of real and
integer variables can be calculated in either the continuous or discrete domain depending
on how their values are assigned.
Values calculated in the discrete domain change value instantaneously and only at
integer multiples of a minimum resolvable time. For this reason, the derivative with
respect to time of a digital value is always zero (0). Values calculated in the continuous
domain, on the other hand, are continuously varying.
8.2.2 Contexts
Statements in a Verilog-AMS HDL module description can appear in the body of an
analog block, in the body of an initial or always block, or outside of any block (in the body
of the module itself). Those statements which appear in the body of an analog block are
said to be in the continuous (analog) context; all others are said to be in the discrete
(digital) context. A given variable can be assigned values only in one context or the other,
but not in both. The domain of a variable is that of the context from which its value is
assigned.
connections to a port are frequently referred to as the formal and actual connections
respectively.
A net can be declared with either a discrete or analog discipline or no discipline (neutral
interconnect). Within the Verilog-AMS language, only digital blocks and primitives can
drive a discrete net (drivers), and only analog blocks can contribute to an analog net
(contributions). A signal is a hierarchical collection of nets which, because of port
connections, are contiguous. If all the nets that make up a signal are in the discrete
domain, the signal is a digital signal. If all the nets that make up a signal are in the
continuous domain, the signal is an analog signal. A signal that consists of nets from
both domains is called a mixed signal.
Similarly, a port whose connections are both analog is an analog port, a port whose
connections are both digital is a digital port, and a port whose connections are analog
and digital is a mixed port.
Since it is physically one wire in the design, Kirchoff’s current law applies to the whole
signal, and it forms one node in analog simulation (see Section 3.4). Drivers in the digital
domain are converted to contributions in analog domain using auto-inserted
digital-to-analog connection modules (D2As), and the signal value is calculated in the
analog domain. Instead of determining the final digital receiver value of the signal by
resolving all the digital drivers, the resolved analog signal is converted back to a digital
value. A digital behavioral block that reads the value of a signal is a receiver, but since
Verilog-AMS has no syntax that identifies multiple receivers within a module as distinct,
the associated net can be viewed as a single receiver for the purposes of analog to digital
conversion. Drivers are created by declaring a reg, instantiating a digital primitive or
using a continuous assign statement. Since it is only possible to insert connect modules
at port boundaries, when multiple continuous assign statements exist in a module, they
are handled by a single connect module.
The drivers and receivers of a mixed signal are associated with their locally-declared net;
the discipline of that net is used to determined which connection modules to use. The
discipline of the whole signal is found by discipline resolution, as described in
Section 8.4, and is used to determine the attributes of the node in simulation.
The specific time when an event from one domain is detected in the other domain is
subject to the synchronization algorithm described in Section 8.3.6 and Section 9. This
algorithm also determines when changes in nets and variables of one domain are
accessible in the other domain.
primary ::=
number
| identifier
| identifier [ expression ]
| identifier [ msb_constant_expression : lsb_constant_expression ]
| concatenation
| analog_function_call
| string
| access_function
Examples:
The following example accesses the discrete primary in from a continuous context.
module onebit_dac (in, out);
input in;
inout out;
wire in;
electrical out;
real x;
analog begin
if (in == 0)
x = 0.0;
else
x = 3.0;
V(out) <+ x;
end
endmodule
• binary, octal and hexadecimal numeric constants which can contain X and Z as
digits.
The case equality and case inequality operators have the same precedence as the equality
operator.
Example:
module a2d(dnet, anet);
input dnet;
wire dnet;
logic dnet;
output anet;
electrical out;
analog begin
case (dnet)
1’b1:var = 5;
1’bx:var = var;// hold value
1’b0:var = 0;
1’bz:var = 2.5; // high impedance - float value
endcase
V(anet) <+ var;
end
endmodule
Note: A case statement may be replaced with an if-else-if statement using the case
equality operators to perform the 4-state logic value comparisons.
Accessing digital net and digital binary constant operands are supported within analog
context expressions. It is an error if these operands return ’x’ or ’z’ bit values when
solved. It will be an error if the value of the digital variable being accessed in the analog
context goes either to ’x’ or ’z’.
Example:
module converter(dnet,anet);
reg dnet;
electrical anet;
integer var1;
real var2;
initial begin
dnet = 1’b1;
#50 dnet = 1’bz;
$finish;
end
analog begin
var1 = 1’bx;// error
var2 = 1’bz;// error
var1 = 1 + dnet;// error after #50
The syntax for the features that support X and Z comparisons in a continuous context is
defined in Section 2.5 and Section 6.5. Support for X and Z is limited in the analog blocks
as defined above.
Note: Consult IEEE 1364-1995 Verilog HDL for a description of the semantics of these operators.
digital_primary ::=
digital_number
| identifier
| identifier [ digital_expression ]
| identifier [ digital_msb_constant_expression : digital_lsb_constant_expression ]
| digital_concatenation
| digital_multiple_concatenation
| digital_function_call
| ( digital_mintypmax_expression )
| access_function_reference
Examples:
The following example accesses the continuous net V(in) from the discrete context is.
endmodule
Continuous variables can be accessed for reading from any discrete context in the same
module where these variables are declared. Because the discrete domain can fully
represent all continuous types, a continuous variable is fully visible when it is read in a
discrete context.
event_control_statement ::=
event_control statement_or_null
event_control ::=
@ event_identifier
| @ ( event_expression )
event_expression ::=
global_event
| event_function
| digital_expression
| event_identifier
| posedge digital_expression
| negedge digital_expression
| event_expression or event_expression
Examples:
The following example shows a discrete event being detected in an analog block.
analog begin
@(posedge clk1 or cross(V(clk2), 1))
vout = V(in);
V(out) <+ vout;
end
endmodule
digital_event_expression ::=
digital_expression
| event_identifier
| posedge digital_expression
| negedge digital_expression
| event_function
| digital_event_expression or digital_event_expression
Examples:
The following example detects a continuous event in an always block.
module sampler2 (in, clk, out);
input in, clk;
output out;
wire in;
reg out;
electrical clk;
endmodule
8.3.6 Concurrency
Verilog-AMS HDL provides synchronization between the continuous and discrete
domains. Simulation in the discrete domain proceeds in integer multiples of the digital
tick. This is the smallest value of the second argument of the `timescale directive (see
Section 16.7 in IEEE 1364-1995 Verilog HDL). Thus, values calculated in the digital
domain shall be constant between digital ticks and can only change at digital ticks.
Simulation in the continuous domain appears to proceed continuously. Thus, there is no
time granularity below which continuous values can be guaranteed to be constant.
The rest of this section describes synchronization semantics for each of the four types of
mixed-signal behavioral interaction. Any synchronization method can be employed,
provided the semantics preserved. A typical synchronization algorithm is described in
Section 9.2.
Examples:
always begin
@(cross(V(x) - 5.5,1))
n = 1;
end
When it is determined the event has occurred in the analog domain, the statements under
the event control shall be scheduled in the digital domain at the largest digital time tick
smaller than or equal to the time of the analog event. This event shall not be schedule in
the digital domain earlier than the current digital event (see Section 9.2.3).
which is assigned to the undeclared net. If all the nets are of the same discipline, no rule
is needed; that discipline becomes the resolved discipline of the net.
Example:
In the example shown in Figure 8-2, NetA and NetB are undeclared interconnects. NetB
has cmos3 and cmos4 at the lower connection ports, while it is an upper connection.
cmos3
cmos1
NetA
module blk (out);
module blk (out);
NetB
cmos4
cmos2
NetD
module top;
Note: The specified resolveto connect statements are ignored in this mode unless coercion (see
Section 8.8.1) is used.
NetD
module top;
module digital_blk (out); module twoblks (out); module mix (out);
NetC
cmos3
cmos1
NetA cmos2
module blk3 (out);
module blk1 (out);
NetB module blk2 (out);
cmos4
cmos2 electrical
module blk4 (out);
module blk2 (out); module ablk (out);
disciplines of the ports of the connect modules and their directions are used to determine
the circumstances in which the module can be automatically inserted.
The connect module is a special form of a module; its definition is shown in Syntax 8-5.
connectmodule_declaration ::=
connectmodule module_identifier ( connectmod_port , connectmod_port ) ;
[ module_items ]
endmodule
connectmod_port ::=
connectmod_port_identifier
continuous discrete
input output
output input
inout inout
Examples:
Example 1
connectmodule d2a(in, out);
input in;
output out;
logic in;
electrical out;
// insert connect module behavioral here
endmodule
can bridge a mixed input port whose upper connection is compatible with discipline
logic and whose lower connection is compatible with electrical, or a mixed output
port whose upper connection is compatible with discipline electrical and whose lower
connection is compatible with logic.
Example 2
connectmodule a2d(out, in);
output out;
input in;
logic out;
electrical in;
// insert connect module behavioral here
endmodule
can bridge a mixed output port whose upper connection is compatible with discipline
logic and whose lower connection is compatible with electrical, or a mixed input
port whose upper connection is compatible with discipline electrical and whose lower
connection is compatible with logic.
Example 3
connectmodule bidir(out, in);
inout out;
inout in;
logic out;
electrical in;
// insert connect module behavioral here
endmodule
can bridge any mixed port whose one connection is compatible with discipline logic
and whose connection is compatible with electrical.
• overrides for the connect module default disciplines and port directions
connect_specification ::=
connectrules connectrule_identifier;
{connect_spec_item }
endconnectrules
connect_spec_item ::=
connect_insertion
| connect_resolution
The two forms of the connect specification statements and their syntaxes are detailed in
the following subsections.
connect_insertion ::=
connect connect_module_identifier connect_attributes
[ [ direction ] discipline_identifier , [ direction ] discipline_identifier ] ;
connect_attributes ::=
[ connect_mode] [ #( attribute_list ) ]
connect_mode ::=
merged
| split
attribute_list ::=
attribute
| attribute_list , attribute
attribute ::=
.parameter_identifier ( expression )
direction ::=
input
| output
| inout
discipline_list ::=
discipline_identifier
| discipline_list , discipline_identifier
Connect modules can be reused for different, but compatible disciplines by specifying
different discipline combinations in which the connect module can be used. The form is
connect connect_module_identifier connect_attributes discipline_identifier , discipline_identifier ;
where the specified disciplines shall be compatible for both the continuous and discrete
disciplines of the given connect module.
It is also possible to override the port directions of the connect module, which allows a
module to be used both as a unidirectional and bidirectional connect module. This
override also aids library based designs by allowing the user to specify the connect rules,
rather than having to search the entire library. The form is
connect connect_module_identifier connect_attributes direction discipline_identifier ,
direction discipline_identifier ;
where the specified disciplines shall be compatible for both the continuous and discrete
disciplines of the given connect module and the specified directions are used to define
the type of connect module.
connect_resolution ::=
connect discipline_list resolveto discipline_identifier ;
discipline_list ::=
discipline_identifier
| discipline_list , discipline_identifier
Example 2:
connect x,y,a resolveto y;
connect x,y,a resolveto a;
connect x,y,b resolveto b;
For the above set of connect rule specifications,
disciplines x,y would resolve to discipline y with a warning.
disciplines x,y,a would resolve to discipline y with a warning.
disciplines y,b would resolve to b.
8.7.4 connect_mode
This can be used to specify additional segregation of connect modules at each level of
the hierarchy. Setting connect_mode to split or merged defines whether all ports of a
common discrete discipline and port direction share an connect module or have
individual connect modules.
Examples:
connect a2d_035u split #(.tt(3.5n), .vcc(3.3));
Here each digital port has a separate connect module.
endmodule
connectmodule logic_to_elect(cm,el);
input cm;
output el;
logic cm;
electrical el;
analog
V(el) <+ transition((cm == 1) ? 5.0 : 0.0);
endmodule
connectrules mixedsignal;
connect elect_to_logic;
connect logic_to_elect;
endconnectrules
Here two modules, elect_to_logic and logic_to_elect, are specified as the connect
modules to be automatically inserted whenever a signal and a module port of disciplines
electrical and logic are connected.
Module elect_to_logic converts signals on port out of instance a3 to port in of
instance d1. Module logic_to_elect converts the signal on port out of instance d2 to
port in of instance a3.
NetD
module top;
LOGIC
connect instance
Analog
LOGIC
Analog LOGIC
in
LOGIC
out
Analog
out
LOGIC
in
Analog LOGIC
in
two LOGIC segments
(one for inputs, one for outputs)
LOGIC
Analog
LOGIC
Analog LOGIC
8.8.3.1 merged
This instructs the simulator to try to group all ports (whether they are input, output, or
inout) and to use just one connector module, provided the module is the same.
Example:
Figure 8-8 illustrates the effect of the merged attribute.
Connection of the electrical signal to the ttl inout ports and ttl input ports results
in a single connector module, bidir, being inserted between the ports and the
electrical signal. The ttl output ports are merged, but with a different connect
module; i.e., there is one connector module inserted between the electrical signal and all
of the ttl output ports.
TTL
bidir
electrical
inputs
outputs
d2a
inouts
TTL
inputs
outputs
inouts
connectrules example;
connect d2a merged input ttl, output electrical ;
connect bidir merged output electrical, input ttl ;
connect bidir merged inout ttl, inout electrical ;
endconnectrules
8.8.3.2 split
If more than one input port is connected at a net of a signal, using split forces there to
be one connect module for each port which converts between the net discipline and the
port discipline. In this way, the net connecting to the ports is segmented by the insertion
of one connect module for each port.
Examples:
Example 1
connect elect_to_logic split;
This connect statement specifies the module elect_to_logic shall be split across the
discrete module ports:
• if an input port has logic discipline and the signal connecting to the port has
electrical discipline, or
• if an output port has electrical discipline and the signal connecting to the port has
logic discipline.
Example 2
In Figure 8-9, the connections of an electrical signal to ttl output ports results in a
distinct instance of the d2a connect module being inserted for each output port. This is
mandated by the split parameter.
Connection of the electrical signal to ttl input ports results in a single instance of
the a2d connect module being inserted between the electrical signal and all the ttl
input ports. This is mandated by merged parameter. This behavior is also seen for the
ttl inout ports where the merged parameter is used.
TTL
a2d
electrical
inputs
d2a
outputs
d2a
inouts
TTL
inputs
d2a
outputs
d2a
inouts
bidir
connectrules example;
connect d2a split input ttl, output electrical;
connect a2d merged output electrical, input ttl ;
connect bidir merged inout electrical, inout ttl ;
endconnectrules
If there are many output ports where this rule applies, by definition there is no
segmentation of the signal between these ports, since the ports have discipline
electrical (an analog discipline).
Example 4
This last example:
connect cmosA2d merged #(.r(15k) input electrical, output cmos04u;
does three things:
8.8.4 Rules for driver-receiver segregation and connect module selection and insertion
Driver-receiver segregation and connect module insertion is a post elaboration
operation. It depends on a complete hierarchical examination of each signal in the
design, i.e., an examination of the signal in all the contexts through which it passes. If
the complete hierarchy of a signal is digital, i.e., the signal has a digital discipline in all
contexts through which is passes, it is a digital signal rather than a mixed signal.
Similarly, if the complete hierarchy of a signal is analog, it is an analog signal rather than
a mixed signal. Rules for driver-receiver segregation and connect module insertion apply
only to mixed signals, i.e., signals which have an analog discipline in one or more of the
contexts through which they pass and a digital discipline in one or more of the contexts.
In this case, context refers to the appearance of a signal in a particular module instance.
For a particular signal, a module instance has a digital context if the signal has a digital
discipline in that module or an analog context if the signal has an analog discipline. The
appearance of a signal in a particular context is referred to as a segment of the signal. In
general, a signal in a fully elaborated design consists of various segments, some of which
can be analog and some of which can be digital.
A port represents a connection between two net segments of a signal. The context of one
of the net segments is an instantiated module and the context of the other is the module
which instantiates it. The segment in the instantiated module is called the lower or formal
connection and the segment in the instantiating module is the upper or actual connection.
A connection element is selected for each port where one connection is analog and the
other digital.
The following rules govern driver-receiver segregation and connect module selection.
These rules apply only to mixed signals.
3. A connection shall be selected for a port only if one of the connections to the port
is digital and the other is analog. In this case, the port shall match one (and only
one) connect statement. The module named in the connect statement is the one
which shall be selected for the port.
Once connect modules have been selected, they are inserted according to the
connect_mode parameter in the pertinent connect statements. These rules apply to
connect module insertion:
1. The connect mode of a port for which a connect module has been selected shall
be determined by the value of the connect_mode parameter of the connect
statement which was used to select the connect module.
2. The connect module for a port shall be instantiated in the context of the ports
upper connection.
3. All ports connecting to the same signal (upper connection), sharing the same
connect module, and having merged parameter shall share a single instance of the
selected connect module.
4. All other ports shall have an instance of the selected connect module, i.e., one
connect module instance per port.
1. merged
In the merged case, one or more ports have a given discipline at their bottom
connection, call it BottomDiscipline, and a common signal, call it SigName, of
another discipline at their top connection. A single connect module, call it
ModuleName, is placed between the top signal and the bottom signals. In this case,
the instance name of the connect module is derived from the signal name, module
name, and the bottom discipline:
SigName__ModuleName__BottomDiscipline
2. split
In the split case, one or more ports have a given discipline at their bottom
connection and a common signal of another discipline, call it TopDiscipline, at
their top connection. One module instance is instantiated for each such port. In
this case, the instance name of the connect module is
SigName__InstName__PortName
where InstName and PortName are the local instance name of the port and its
instance respectively.
Note: The __ between the elements of these generated instance names is a double underscore.
The following naming conventions shall be used when generating connect module
instance names that are connected to built-in digital primitives.
1. For N-input gates (and, nand, nor, or, xnor, xor) the output will be named out,
and the inputs reading from left to right will be in1, in2, in3, and so forth.
2. For N-output gates (buf, not) The input will be named in, and the outputs reading
from left to right will be named out1, out2, out3, and so forth.
3. For 3 port MOS switches (nmos, pmos, rnmos, rpmos) the ports reading from left
to right will be named source, drain, gate.
4. For 4 port MOS switches (cmos, rcmos) the ports reading from left to right will
be named source, drain, ngate, pgate.
5. For bidirectional pass switches (tran, tranif1, tranif0, rtran, rtranif1, rtranif) the
ports reading from left to right will be named source, drain, gate.
6. For single port primitives (pullup, pulldown) the port will be named out.
In the digital domain, signals can have drivers and receivers. A driver makes a
contribution to the state of the signal. A receiver accesses, or reads, the state of the signal.
In a pure digital net, i.e., one without an analog segment, the simulation kernel resolves
the values of the drivers of a signal and it propagates the new value to the receivers by
means of an event when there is a change in state.
In the case of a mixed net, i.e., one with digital segments and an analog segment, it can
be useful to propagate the change to the analog simulation kernel, which can then detect
a threshold crossing, and then propagate the change in state back to the digital kernel.
This, among other things, allows the simulation to account for rise and fall times caused
by analog parasitics.
Within digital segments of a mixed-signal net, drivers and receivers of ordinary modules
shall be segregated, so transitions are not propagated directly from drivers to receivers,
but propagate through the analog domain instead. In this case, the drivers and receivers
of connect modules shall be oppositely segregated; i.e., the connect module drivers shall
be grouped with the ordinary module receivers and the ordinary module drivers shall be
grouped with the connect module receivers.
Thus, digital transitions are propagated from drivers to receivers by way of analog
(through using connect module instances). Figure 8-10 and Figure 8-11 show
driver-receiver segregation in modules having bidirectional and unidirectional ports,
respectively.
analog analog
digital
digital
inout port
drivers
digital connection
drivers driver
connection
receivers receiver
receivers
input
inout port port output
port
drivers
drivers
digital
receivers
connection receivers
receiver
inout port connection
driver
analog
analog
analog
digital digital
output port
receivers
receivers
drivers connection
digital driver
drivers
receivers
analog
8.10.1 $driver_count
$driver_count returns an integer representing the number of drivers associated with the
signal in question. The syntax is shown in Syntax 8-9.
driver_count_function ::=
$driver_count ( signal_name )
The drivers are arbitrarily numbered from 0 to N-1, where N is the total number of
ordinary drivers contributing to the signal value. For example, if this function returns a
value 5 then the signal has five drivers numbered from 0 to 4.
8.10.2 $driver_state
driver_state
returns the current value contribution of a specific driver to the state of the
signal. The syntax is shown in Syntax 8-10.
driver_state_function ::=
$driver_state ( signal_name , driver_index )
driver_index is an integer value between 0 and N-1, where N is the total number of drivers
contributing to the signal value. The state value is returned as 0, 1, x, or z.
8.10.3 $driver_strength
driver_strength returns the current strength contribution of a specific driver to the strength
of the signal. The syntax is shown in Syntax 8-11.
driver_strength_function ::=
$driver_strength ( signal_name , driver_index )
driver_index is an integer value between 0 and N-1, where N is the total number of drivers
contributing to the signal value. The strength value is returned as two strengths, Bits 5-
3 for strength0 and Bits 2-0 for strength1 (see IEEE 1364-1995 Verilog HDL,
sections 7.10 and 7.11).
If the value returned is 0 or 1, strength0 returns the high-end of the strength range and
strength1 returns the low-end of the strength range. Otherwise, the strengths of both
strength0 and strength1 is defined as shown in Figure 8-12 below.
strength0 strength1
Bits
7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 Bits
Su0 St0 Pu0 La0 We0 Me0 Sm0 HiZ0 HiZ1 Sm1 Me1 We1 La1 Pu1 St1 Su1
B5 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 B2
B4 1 1 0 0 1 1 0 0 0 0 1 1 0 0 1 1 B1
B3 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 B0
8.10.4 driver_update
The status of drivers for a given signal can be monitored with the event detection
keyword driver_update. It can be used in conjunction with the event detection operator @
to detect updates to any of the drivers of the signal.
Examples:
always @(driver_update clock)
statement;
causes the statement to execute any time a driver of the signal clock is updated. Here,
an update is defined as the addition of a new pending value to the driver. This is true
whether or not there is a change in the resolved value of the signal.
d3 d2
n1
d1 c2e
c1
reg out;
ground gnd;
branch (rail,a)pull_up;
branch (a,gnd)pull_down;
branch (rail,gnd)power;
parameter real impedence0 = 120.0;
parameter real impedence1 = 100.0;
parameter real impedenceOff = 1e6;
parameter real vt_hi = 3.5;
parameter real vt_lo = 1.5;
parameter real supply = 5.0;
integer i, num_ones, num_zeros;
assign d=out;
initial begin
num_ones = 0;
num_zeros = 0;
end
always @(driver_update(d)) begin
num_ones = 0;
num_zeros = 0;
for ( i = 0; i < $driver_count(d); i=i+1)
if ( $driver_state(d,i) == 1 )
num_ones = num_ones + 1;
else
num_zeros = num_zeros + 1;
end
always @(cross(V(a) - vt_hi, -1) or cross(V(a) - vt_lo, +1))
out = 1‘bx;
always @(cross(V(a) - vt_hi, +1))
out = 1‘b1;
always @(cross(V(a) - vt_lo, -1))
out = 1‘b0;
analog begin
// Approximately one impedence1 resistor to rail per high output
// connected to the digital net
V(pull_up) <+ 1/((1/impedence1)*num_ones+(1/impedenceOff)) *
I(pull_up);
// Approximately one impedence0 resistor to ground per low output
// connected to the digital net
V(pull_down) <+ 1/((1/impedence0)*num_zeros+(1/impedenceOff)) *
I(pull_down);
V(power) <+ supply;
end
endmodule
Note: Because the scheduled digital events can be scheduled with an insufficient delay or cancelled
before they mature, be careful when using these functions.
8.11.1 $driver_delay
$driver_delay returns the delay, from current simulation time, after which the pending
state or strength becomes active. If there is no pending value on a signal, it returns the
value minus one (-1.0). The syntax is shown in Syntax 8-12.
driver_delay_function ::=
$driver_delay ( signal_name , driver_index )
driver_index is an integer value between 0 and N-1, where N is the total number of drivers
contributing to the signal value. The returned delay value is a real number, which is
defined by the `timescale for that module where the call has been made. The fractional part
arises from the possibility of a driver being updated by an A2D event off the digital
timeticks.
8.11.2 $driver_next_state
$driver_next_state returns the pending state of the driver, if there is one. If there is no
pending state, it returns the current state. The syntax is shown in Syntax 8-13.
driver_next_state_function ::=
$driver_next_state ( signal_name , driver_index )
driver_index is an integer value between 0 and N-1, where N is the total number of drivers
contributing to the signal value. The pending state value is returned as 1’b0, 1’b1, 1’bx,
or 1’bz.
8.11.3 $driver_next_strength
$driver_next_strength returns the strength associated with the pending state of the driver,
if there is one. If there is no pending state, it returns the current strength. The syntax is
shown in Syntax 8-14.
driver_next_strength_function ::=
$driver_next_strength ( signal_name , driver_index )
driver_index is an integer value between 0 and N-1, where N is the total number of drivers
contributing to the signal value. The pending strength value is returned as an integer
between 0 and 7.
8.11.4 $driver_type
$driver_type returns an integer value with its bits set according to the system header file
“driver_access.vams” (refer to Annex D for the header file) for the driver specified by
the signal_name and the driver_index. Connect modules for digital to analog conversion
can use the returned information to help minimize the difference between the digital
event time and the analog crossover when the user swaps between coding styles and
performs backannotation1. A simulator that cannot provide proper information for a
given driver type should return 0 (‘DRIVER_UNKNOWN). All drivers on wor and
wand nets will have a bit set indicating such, and any extra drivers added by the kernel
for pull-up or pull-down will be marked as belonging to the kernel. The syntax is shown
in Syntax 8-15.
driver_type_function ::=
$driver_type( signal_name , driver_index )
Digital primitives (like nand and nor gates) should always provide data about their
scheduled output changes; i.e., a gate with a 5ns delay should provide 5ns of look-ahead.
Behavioral code with blocking assigns cannot provide look-ahead, but non-blocking
assigns with delays can. However, since the capability is implementation- and
configuration-dependent, this function is provided so that the connect module can adapt
for a particular instance.
Section 9
Scheduling semantics
This section details the simulation cycles for analog simulation and mixed A/D
simulations.
9.1 Introduction
A mixed-signal simulator shall contain an analog solver that complies with the analog
simulation cycle described in Section 9.2. This component of the mixed-signal simulator
is termed the analog engine. A mixed signal simulator shall also contain a discrete event
simulator that complies with the scheduling semantics described in Section 9.4. This
component is termed the digital engine.
In a mixed-signal circuit, an “analog macro-process” is a set of continuous nodes that
must be solved together because they are joined by analog blocks or analog primitives.
A mixed-signal circuit can comprise one or more analog macro-process separated by
digital processes.
dq ( v, t )
f ( v, t ) = ------------------- + i ( v, t ) = 0
dt
v ( 0 ) = v0
Start Analysis
Initialization
t <- 0
v(0) <- v0
$Display
Yes
Done? (T = t )
End
No
Update time
t <- t + ∆t
Update values
v <- v + ∆v
Evaluate equations
f(v,t) = residue
Converged?
No
residue < e
∆v < ∆
Yes
Yes
Accept the No
time step?
9.2.3 Convergence
In the analog kernel, the behavioral description is evaluated iteratively until the NR
method converges. On the first iteration, the signal values used in expressions are
approximate and do not satisfy Kirchhoff’s Laws.
In fact, the initial values might not be reasonable, so models need to be written so they
do something reasonable even when given unreasonable signal values.
For example, the log or square root of a signal value is being computed, some signal
values cause the arguments to these functions to become negative, even though a real-
world system never exhibits negative values.
As the iteration progresses, the signal values approach the solution. Iteration continues
until two convergence criteria are satisfied. The first criterion is the proposed solution on
this iteration, v(j)(t), shall be close to the proposed solution on the previous iteration, v(j-
1)
(t), and
| vn(j) - vn(j-1) | < reltol (max(| vn(j)| , |vn(j-1)|)) + abstol
where reltol is the relative tolerance and abstol is the absolute tolerance.
reltol is set as a simulator option and typically has a value of 0.001. There can be many
absolute tolerances, which one is used depends on the quantity the signal represents
(volts, amps, etc.). The absolute tolerance is important when vn is converging to zero (0).
Without abstol, the iteration never converges.
The second criterion ensures Kirchhoff's Flow Law is satisfied:
9.3.2.1 Concurrency
Most (current) simulators are single-threaded in execution, meaning that although the
semantics of Verilog-AMS imply processes are active concurrently, the reality is that
they are not. If an implementation is genuinely multi-threaded, it should not evaluate
processes that directly share memory concurrently, as there are no data locking
semantics in Verilog-AMS.
it’s wake-up for the next analog event or acceptance. Events to external processes
generated from analog events are not communicated until the global simulation time
reaches the time of the analog event.
If the time to acceptance is infinite then no wake-up event needs to be scheduled1.
Analog processes are sensitive to changes in all variables and digital signals read by the
process unless that access is only in statements ‘guarded’ by event expressions. For
example the following code implements a simple digital to analog convertor:
module d2a(val,vo); // 16 bit D->A
parameter Vgain = 1.0/65536;
input val;
wire [15:0] val;
electrical vo;
analog begin
V(vo) <+ Vgain * val;
end
endmodule
The output voltage V(vo) is reevaluated when any bit in val changes, which is not a
problem if all the bits change simultaneously and no ‘X’ values occur. A practical design
would require that the digital value is latched to avoid bad bit sequences, as in the
following version:
module d2aC(clk,val,vo); // Clocked 16 bit D2A
parameter Vgain = 1.0/65536;
input clk;
input val;
wire [15:0] val;
electrical vo;
real v_clkd;
analog begin
@(posedge clk) v_clkd = Vgain * val;
V(vo) <+ v_clkd;
end
endmodule
Since val is now guarded by the @(posedge clock) expression the analog block is not
sensitive to changes in val and only reevaluates when clk changes.
1. The case when all derivatives are zero - the circuit is stable.
Macro processes can be evaluated separately but may be evaluated together1, in which
case, the wake up event for one process will cause the re-evaluation of all or some of the
processes. Users should bear this in mind when writing mixed-signal code, as it will
mean that the code should be able to handle re-evaluation at any time (not just at its own
event times).
A B
Connection modules
1. This is implementation-dependent.
output o;
reg o;
electrical i;
always begin @(cross(V(i) - vdd/2,+1)o = 1; end
always begin @(cross(V(i) - vdd/2,-1)o = 0; end
endmodule
connectmodule d2a(i, o);
parameter vdd = 1.0;
parameter slewrate = 2.0/1e9; // V/s
input i;
output o;
electrical o;
reg qd_val, // queued value
nw_val;
real et; // delay to event
real start_delay; // .. to ramp start
always @(driver_update i) begin
nw_val = $driver_next_state(i,0); // assume one driver
if (nw_val == qd_val) begin
// no change (assume delay constant)
end else begin
et = $driver_delay(i,0) * 1e-9; // real delay
qd_val = nw_val;
end
end
analog begin
@(qd_val) start_delay = et - (vdd/2)/slewrate;
V(o) <+ vdd * transition(qd_val,start_delay,vdd/slewrate);
end
endmodule
Example:
If A detects a positive crossing as a result of a transient solution at time 5.2e-9, the
digital kernel shall report a rising edge at A at time 5.0e-9 and falling edge at B at time
5.0e-9, but the analog kernel shall see the transition at B begin at time 5.2e-9, as shown
in Figure 9-3. D2As fed with zero delay events cannot be preemptive, so the crossover
on the return is delayed from the digital event; zero-delay inverters are not physically
realizable devices.
analog
signal
digital reported
A
digital real-time
4 ns 5 ns 6 ns
signal
analog
B
digital reported
digital real-time
analog
signal
digital reported
A
digital real-time
signal 4 ns 5 ns 6 ns
analog
B
digital reported
digital real-time
Any events queued ahead of the current global event time may be cancelled. For
instance, if the sequence above is interrupted by a change on the primary input before
digital assignment takes place as shown in Figure 9-5.
Time Event Queue
4.9ns Evaluating the first analog inverter
Evaluate acceptance at 5.4ns, but schedule wake-up
for 5.2 for crossing.
5.2ns Evaluate crossing event
The A2D logic sets the digital signal A, which triggers
the evaluation of the non-blocking assign to B, which
schedules the actual assignment for 6ns (rounded 1ns
delay).
D2A notices queued event and changes value using
transition filter.
Schedule wake-up at 5.4ns (as previously calculated).
5.3ns Analog event disturbs the solution
Accept at 5.3ns.
Cancel 5.4ns wake-up.
New acceptance is 5.45ns, but schedule wake-up for
crossing at 5.4ns.
5.4ns Evaluate crossing event
analog
signal
digital reported
A
digital real-time
signal 4 ns 5 ns 6 ns
analog
B
digital reported
digital real-time
14
A2D
1 6 10 etc.
ANALOG
15
11 13
2 7 9 16 18
DIGITAL
3 4 8 12 17
D2A
T1 T2 T3 T4 T5 T6
1. The Analog engine begins transient analysis and sends state information (that it
is good up to T2) to the Digital engine (1, 2).
2. The Digital engine begins to run using its own time steps (3); however, if there
is no D2A event, the Analog engine is not notified and the digital engine
continues to simulate until it can not advance its time without surpassing the time
of the analog solution (4). Control of the simulation is then returned to the analog
engine (5), which accepts at T2. This process is repeated (7, 8, 9, 10, and 11).
3. If the Digital engine produces a D2A event (12), control of the simulation is
returned to the Analog engine (13). The analog engine accepts at the time of the
D2A event (14, which may involve recalculating from T3). The Analog engine
then calculates the next time step (15).
4. If the Analog engine produces an A2D event, it returns control to the Digital
engine (16), which simulates up to the time of the A2D event, and then surrenders
control (17 and 18).
1b. Explicit D2A events that occur at the current simulation time shall be processed
after all the active events are processed.
2. Events that occur at the current simulation time, but that shall be processed after
all the active and explicit D2A events are processed. These are the inactive
events.
3. Events that have been evaluated during some previous simulation time, but that
shall be assigned at this simulation time after all the active, explicit D2A and
inactive events are processed. These are the non blocking assign update events.
3b. Analog macro-process events shall be processed after all active, explicit D2A
events, inactive events and non blocking assign update events are processed.
4. Events that shall be processed after all the active, explicit D2A, inactive, non
blocking assign update events and analog macro-process events are processed.
These are the monitor events.
5. Events that occur at some future simulation time. These are the future events.
Future events are divided into future inactive events and future non blocking
assignment update events.
expression changes, it causes an active update event to be added to the event queue, using
current values to determine the target.
can process tran at any time. It can process a subset of tran-connected events at a
particular time, intermingled with the execution of other active events. Further
refinement is required when some transistors have gate value x. A conceptually simple
technique is to solve the network repeatedly with these transistors set to all possible
combinations of fully conducting and nonconducting transistors. Any node that has a
unique logic level in all cases has steady-state response equal to this level. All other
nodes have steady-state response.
Section 10
System tasks and functions
This section describes system tasks and functions available in Verilog-AMS HDL.
environment_parameter_functions ::=
$temperature
| $abstime
| $realtime [ ( real_number ) ]
| $vt [ ( temperature_expression ) ]
| $simparam (string [, expression] )
These functions return information about the current environment parameters as a real
value.
$temperaturedoes not take any input arguments and returns the circuit’s ambient
temperature in Kelvin units.
$abstime returns the absolute time, that is a real value number representing time in
seconds.
$realtime can have an optional argument which scales the time. If no argument is given,
$realtime’s return value is scaled to the `time_unit of the module which invoked it. If an
argument is given, $realtime shall divide the absolute time by the value of the argument
(i.e., scale to the value specified in the argument). The argument for $realtime follows
the semantics of the `time_unit, that is it shall consist of an integer followed by a scale
factor. Valid integers are: 1, 10, and 100; valid scale factors are: s (seconds), ms
(milliseconds), us (microseconds), ns (nanoseconds), ps (picoseconds), and fs
(femtoseconds).
Note: Previous Verilog-A modules using $realtime may not produce the same results as in the past as
$realtime used to return time scaled to one (1) second. If the time_unit of the `timescale directive is
set to 1s, the behavior shall be the same. For analog blocks, the $abstime function should typically be
used, as it returns time in seconds.
$vt can optionally have temperature (in Kelvin units) as an input argument and returns
the thermal voltage (kT/q) at the given temperature. $vt without the optional input
temperature argument returns the thermal voltage using $temperature.
$simparam() queries the simulator for a simulation parameter named string. If string is
known, its value is returned. If string is not known, and the optional expression is not
supplied, then an error is generated. If the optional expression is supplied, its value is
returned if string is not known and no error is generated. $simparam() shall always return
a real value; simulation parameters that have integer values shall be coerced to real.
There is no fixed list of simulation parameters. However, simulators shall accept the
strings in Table 10-1 to access commonly-known simulation parameters, if they support
the parameter. Simulators can also accept other strings to access the same parameters.
Table 10-1—Simulation parameter names
imax Amps Branch current threshold above which the constitutive relation of a
nonlinear branch should be linearized.
tnom degrees Default value of temperature at which model parameters were extracted.
Celsius
In this second example, the variable sourcescale is set to the simulator’s parameter
named gmin, if it exists, otherwise, the value 1.0 is returned.
sourcescale = $simparam("sourceScaleFactor", 1.0);
random_function ::=
$random [ ( seed [, type_string] ) ] ;
seed ::=
integer_variable_identifier
| reg_variable_identifier
| time_variable_identifier
| integer_parameter_identifier
| decimal_number
type_string ::=
"global"
| "instance"
The system function $random provides a mechanism for generating random numbers.
The random number returned is a 32-bit signed integer; it can be positive or negative.
The seed argument may take one of several forms. It may be omitted, in which case the
simulator picks a seed. It may be a reg, integer, or time variable, in which case it is an
inout argument; that is, a value is passed to the function and a different value is returned.
The variable should be initialized by the user prior to calling $random and only updated
by the system function. If the seed is a variable or is omitted, the function returns a new
32-bit random number each time it is called.
The system function $random shall always return the same stream of values given the
same initial seed. This facilitates debugging by making the operation of the system
repeatable.
The seed argument may also be a parameter or a constant, in which case the system
function does not update the value. This makes the system function useable for
parameter initialization. In order to get different random values when the seed argument
is a parameter, the user can override the parameter using a method in Section 7.2.
The type_string provides support for Monte-Carlo analysis. If the type_string is
“global,” then one value is generated for each Monte-Carlo trial. If the type_string is
“instance,” then one value is generated for each instance that references this value, and
a new set of values for these instances is generated for each Monte-Carlo trial.
Examples:
Where b > 0, the expression ($random % b) gives a number in the following range:
[(-b+1) : (b-1)].
The following code fragment shows an example of random number generation between
-59 and 59:
integer rand;
rand = $random % 60;
distribution_functions ::=
$digital_dist_functions ( args ) ;
| $rdist_uniform ( seed, start_expression, end_expression [, type_string] ) ;
| $rdist_normal ( seed, mean_expression, standard_deviation_expression [, type_string] ) ;
| $rdist_exponential ( seed, mean_expression [, type_string] ) ;
| $rdist_poisson ( seed, mean_expression [, type_string] ) ;
| $rdist_chi_square ( seed, degree_of_freedom_expression [, type_string] ) ;
| $rdist_t ( seed, degree_of_freedom_expression [, type_string] ) ;
| $rdist_erlang ( seed, k_stage_expression, mean_expression [, type_string] ) ;
seed ::=
integer_variable_identifier
| integer_parameter_identifier
| decimal_number
type_string ::=
"global"
| "instance"
• For each system function, the seed argument shall be an integer. If it is an integer
variable, then it is an inout argument; that is, a value is passed to the function
and a different value is returned. The variable is initialized by the user and only
updated by the system function. This ensures the desired distribution is achieved
upon successive calls to the system function. If the seed argument is a parameter
or constant, then the system function does not update the value. This makes the
system function useable for parameter initialization.
• The system functions shall always return the same value given the same seed.
This facilitates debugging by making the operation of the system repeatable. In
order to get different random values when the seed argument is a parameter, the
user can override the parameter.
• In $rdist_uniform, the start and end arguments are real inputs which bound the
values returned. The start value shall be smaller than the end value.
10.4.1 $finish
The syntax for this task is shown in Syntax 10-4.
finish_task ::=
$finish [ ( n ) ] ;
$finish simply makes the simulator exit. If an expression is supplied to this task, its value
determines which diagnostic messages are printed before the prompt is issued, as shown
in Table 10-2. One (1) is the default if no argument is supplied.
Table 10-2—Diagnostic messages
Parameter Message
0 Prints nothing
2 Prints simulation time, location, and statistics about the memory and CPU time used in simulation
10.4.2 $stop
The syntax for this task is shown in Syntax 10-5.
stop_task ::=
$stop [ ( n ) ] ;
10.5.1 $fopen
The syntax for this task is shown in Syntax 10-6.
file_open_task ::=
integer multi_channel_descriptor = $fopen ( " file_name " ) ;
$fopen opens the file specified as an argument and returns a 32-bit multichannel
descriptor which is uniquely associated with the file. It returns 0 if the file could not be
opened for writing.
The multichannel descriptor can 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. The standard output is also called
channel 0. The other bits refer to channels which have been opened by $fopen.
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 return values of 8, 16, 32, and so on, up to
a maximum of 32 open channels. Thus, a channel number corresponds to an individual
bit in a multichannel descriptor.
10.5.2 $fclose
The syntax for this task is shown in Syntax 10-7.
file_close_task ::=
$fclose ( multi_channel_descriptor_identifier ) ;
$fclosecloses the channels specified in the multichannel descriptor and does not allow
any further output to the closed channels. $fopen reuses channels which have been closed.
display_tasks ::=
$strobe ( list_of_arguments ) ;
| $display ( list_of_arguments ) ;
| $monitor ( list_of_arguments ) ;
| $write ( list_of_arguments ) ;
| $debug ( list_of_arguments ) ;
— $strobe displays its arguments in the same order they appear in the argument list.
Each argument can be a quoted string, an expression which returns a value, or a
null argument.
— The contents of string arguments 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:
• The special character \ indicates the character to follow is a literal or non-
printable character (see Table 10-3).
• The special character string %% indicates the display of the percent sign character
(%) (see Table 10-3).
— Any null argument produces a single space character in the display. (A null
argument is characterized by two adjacent commas (,,) in the argument list.)
— When $strobe is invoked without arguments, it simply prints a newline character.
The $display task provides the same capabilities as $strobe. The $write task provides the
same capabilities as $strobe, but with no newline. The $monitor task provides the same
capabilities as $strobe, but outputs only when an argument changes. The $debug task
provides the capability to display simulation data while the analog simulator is solving
the equations; it displays its arguments for each iteration of the analog solver.
\\ The \ character
%% The % character
%s or %S Display as a string
Note: Because discontinuous behavior can cause convergence problems, discontinuity shall be avoided
whenever possible.
The filter functions (transition(), slew(), laplace(), etc.) can be used to smooth discontinuous
behavior. However, in some cases it is not possible to implement the desired
functionality using these filters. In those cases, the $discontinuity function shall be
executed when the signal behavior changes abruptly.
Note: Discontinuity created by switch branches and built-in system functions, such as transition() and
slew(), does not need to be announced.
A special form of the $discontinuity function, $discontinuity(-1), is used with the
$limit() function. See Section 10.9 for an explanation.
Examples:
Example 1
The following example uses the discontinuity function to model a relay.
limit_call ::=
$limit ( access_function_reference )
| $limit ( access_function_reference, string, arg_list )
| $limit ( access_function_reference, analog_function_identifier, arg_list )
When the simulator has converged, the return value of the $limit() function is the value
of the access function reference, within appropriate tolerances. For some analysis types
or solution methods, such as damped Newton-Raphson, the return value of the $limit()
function may depend on the value of the access function and internal state of the
function. In all cases, the simulator is responsible for determining if limiting should be
applied and what the return value is on a given iteration.
When more than one argument is supplied to the $limit() function, the second argument
recommends a function to use to compute the return value. When the second argument
is a string, it refers to a built-in function of the simulator. The two most common such
functions are pnjlim and fetlim, which are found in SPICE and many SPICE-like
simulators. Simulators may support other built-in functions and need not support pnjlim
or fetlim. If the string refers to an unknown or unsupported function, the simulator is
responsible for determining the appropriate limiting algorithm, just as if no string had
been supplied.
pnjlim is intended for limiting arguments to exponentials, and the limexp() function of
Section 4.4.14 may be implemented through a function derived from pnjlim. Two
additional arguments to the $limit() function are required when the second argument to
the limit function is the string “pnjlim”: the third argument to $limit() indicates a step size
vte and the fourth argument is a critical voltage vcrit. The step size vte is usually the
product of the thermal voltage $vt and the emission coefficient of the junction. The
critical voltage is generally obtained from the formula V crit = vte ⋅ ln ( vte ⁄ ( 2 ⋅ I s ) ) ,
where I s is the saturation current of the junction.
fetlim is intended for limiting the potential across the oxide of a MOS transistor. One
additional argument to the $limit() function is required when the second argument to the
limit function is the string “fetlim”: the third argument to $limit() is generally the
threshold voltage of the MOS transistor.
In the case that none of the built-in functions of the simulator is appropriate for limiting
the potential (or flow) used in a nonlinear equation, the second argument of the $limit()
function may be an identifier referring to a user-defined analog function. User-defined
functions are described in Section 4.6. In this case, if the simulator determines that
limiting is needed to improve convergence, it will pass the following quantities as
arguments to the user-defined function:
• The first argument of the user-defined function shall be the value of the access
function reference for the current iteration.
• The second argument shall be the appropriate internal state; generally, this is the
value that was returned by the $limit() function on the previous iteration.
• If more than two arguments are given to the $limit() function, then the third and
subsequent arguments are passed as the third and subsequent arguments of the
user-defined function.
In order to prevent convergence when the output of the $limit() function is not sufficiently
close to the value of the access function reference, the user-defined function shall call
$discontinuity(-1) (see Section 10.7) when its return value is not sufficiently close to the
value of its first argument.
Example:
The module below defines a diode and includes an analog function that mimics the
behavior of pnjlim in SPICE. Though limexp() could have been used for the exponential in
the current, using $limit() allows the same voltage to be used in the charge calculation.
module diode(a,c);
electrical a, c;
inout a, c;
parameter real IS = 1.0e-14;
parameter real CJO = 0.0;
analog function real spicepnjlim;
input vnew, vold, vt, vcrit;
real vnew, vold, vt, vcrit, arg;
begin
if ((vnew > vcrit) && (abs(vnew-vold) > (vt+vt))) begin
if (vold > 0) begin
arg = 1 + (vnew-vold) / vt;
if (arg > 0)
vnew = vold + vt * ln(arg);
else
vnew = vcrit;
end else
vnew = vt * ln(vnew/vt);
end
$discontinuity(-1);
end
spicepnjlim = vnew;
end
endfunction
real vdio, idio, qdio;
analog begin
vdio = $limit(V(a,c), spicepnjlim, $vt, vcrit);
idio = IS * (exp(vdio/$vt) - 1);
I(a,c) <+ idio;
if (vdio < 0.5) begin
qdio = 0.5 * CJO * (1-sqrt(1-Vd));
end else begin
qdio = cjo * (2.0*(1.0-sqrt(0.5))
+ sqrt(2.0)/2.0*(vdio*vdio+vdio-3.0/4.0));
end
I(a,c) <+ ddt(qdio);
end
endmodule
hierarchical_system_parameter_functions ::=
$mfactor
| $xposition
| $yposition
| $angle
| $hflip
| $vflip
For example, when a module makes a call to $mfactor, the simulator computes the
product of the multiplicity factor specified for the instance (or 1.0, if no override was
specified) times the value for the parent module that instantiated the module, times the
parent’s parent’s value, and so on, until the top level is reached.
Note that $angle is specified and returned in degrees, but the trigonometric functions of
Section 4.2.2 operate in radians.
genvar_system_function ::=
$param_given ( module_parameter_identifier )
| $port_connected ( port_scalar_expression )
Note that the return values of these functions shall be constant during a simulation; the
value is fixed during elaboration. As such, these functions can be used in genvar
expressions controlling conditional or looping behavior of the analog operators of
Section 4.4.
The $param_given() function can be used to determine whether a parameter value was
obtained from the default value in its declaration statement or if that value was
overridden. The $param_given() function takes a single argument, which must be a
parameter identifier. The return value shall be one (1) if the parameter was overridden,
either by a defparam statement or by a module instance parameter value assignment, and
zero (0) otherwise.
Example:
The following example sets the variable temp to represent the device temperature. Note
that $temperature is not a constant_expression, so it cannot be used as the default value
of the parameter tdevice. It is important to be able to distinguish the case where
tdevice has its default value (say, 27) from the declaration statement from the case
where the value 27 was in fact specified as an override, if the simulation is performed at
a different temperature.
if ($param_given(tdevice))
temp = tdevice + ‘P_CELSIUS0;
else
temp = $temperature;
Module ports need not be connected when the module is instantiated. The
$port_connected() function can be used to determine whether a connection was specified
for a port. The $port_connected() function takes one argument, which must be a port
identifier. The return value shall be one (1) if the port was connected to a net (by order
or by name) when the module was instantiated, and zero (0) otherwise. Note that the port
may be connected to a net that has no other connections, but $port_connected() shall still
return one.
Example:
In the following example, $port_connected() is used to skip the transition filter for
unconnected nodes. In module twoclk, the instances of myclk only have connections for
their vout_q ports, and thus the filter for vout_qbar is not implemented for either
instance. In module top, the vout_q2 port is not connected, so that the vout_q port of
topclk1.clk2 is not ultimately used in the circuit; however, the filter for vout_q of
clk2 is implemented, because it vout_q is connected on clk2’s instantiation line.
module myclk(vout_q, vout_qbar);
output vout_q, vout_qbar;
electrical vout_q, vout_qbar;
parameter real tdel = 3u from [0:inf);
parameter real trise = 1u from (0:inf);
parameter real tfall = 1u from (0:inf);
parameter real period = 20u from (0:inf);
integer q;
analog begin
@ (timer(0, period))
q = 0;
@ (timer(period/2, period))
q = 1;
if ($port_connected(vout_q))
V(vout_q) <+ transition( q, tdel, trise, tfall);
else
V(vout_q) <+ 0.0;
if ($port_connected(vout_qbar))
V(vout_qbar) <+ transition( !q, tdel, trise, tfall);
else
V(vout_qbar) <+ 0.0;
end
endmodule
table_model_function ::=
$table_model ( table_inputs, table_data_source, table_control_string )
table_inputs ::=
expression [, 2nd_dim_expression [, 3rd_dim_expression]]
table_data_source ::=
filename_string | table_model_array
table_model_array ::=
1st_dim_array_identifier [, 2nd_dim_array_identifier [, 3rd_dim_array_identifier]],
output_array_identifier
table_control_string ::=
"[1st_dim_table_ctrl_substr] [, 2nd_dim_table_ctrl_substr [, 3rd_dim_table_ctrl_substr]]]"
table_ctrl_substr ::=
[table_extrap_char [higher_table_extrap_char]]
table_extrap_char ::=
L|E
The sample points may be stored in the file in any order. The following shows a sample
data file:
# example.tbl
# 2-D table model sample example
#
# x y f(x,y)
-10 -10 0
-10 -8 -0.4
-10 -6 -0.8
-9 -10 0.2
-9 -8 -0.2
-9 -6 -0.6
-9 -4 -1
-8 -10 0.4
-8 -9 0.2
-8 -7 -0.2
-8 -5 -0.6
-8 -3 -1
-7 -10 0.6
-7 -9 0.4
-7 -8 0.2
-7 -7 0
-7 -6 -0.2
-7 -5 -0.4
If the user chooses the array source, a set of one-dimensional arrays that contain the data
points shall be passed to the $table_model function. The size of these arrays is the number
of sample points in the table, M. The data will be stored in the arrays such that for the kth
dimension of the ith sample point, kth_dim_array_identifier[i] = Xik and such that
for the ith sample point output_array_identifier[i] = Yi .
An example using the array source is given in Section 10.12.4.
When one extrapolation method character is given, the specified extrapolation method
will be used for both ends. When two extrapolation method characters are given, the first
character specifies the extrapolation method used for the end with the lower coordinate
value, and the second character is used for the end with the higher coordinate value.
10.12.4 Examples
The following examples are for the same 2-D table model but using the different types
of data source.
Example 1: $table_model with file data source
Note the contents of example.tbl are those given earlier in this section.
module measured_resistance (a, b);
electrical a, b;
inout a, b;
analog begin
I(a, b) <+ $table_model (V(a), V(b), "example.tbl", "L,L");
end
endmodule
Section 11
Compiler directives
All Verilog-AMS HDL 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.
This section describes the following compiler directives:
`default_discipline
`default_transition
`define
`else
`endif
`ifdef
`include
`resetall
`undef
Those compiler directives defined in IEEE 1364-1995 Verilog HDL are also supported.
11.1 `default_discipline
The scope of this directive is similar to the scope of the `define compiler directive,
although it can be used only outside of module definitions. The default discipline is
applied to all discrete signals without a discipline declaration that appear in the text
stream following the use of the ‘default_discipline directive, until either the end of
the text stream or another ‘default_discipline directive with the qualifier (if
applicable) is found in the subsequent text, even across source file boundaries.
Therefore, more than one ‘default_discipline directive can be in force
simultaneously, provided each differs in qualifier
In addition to ‘reset_all, if this directive is used without a discipline name, it turns off
all currently active default disciplines without setting a new default discipline.
Subsequent discrete signals without a discipline shall be associated with the empty
discipline. Syntax 11-1 shows the syntax for this directive.
default_discipline_directive ::=
`default_discipline [discipline_identifier [ qualifier ] ]
qualifier ::=
integer | real | reg | wreal
wire | tri | wand | triand | wor | trior | trireg |
tri0 | tri1 | supply0 | supply1
Example:
`default_discipline logic
module behavnand(in1, in2, out);
input in1, in2;
output out;
reg out;
always begin
out = ~(in1 && in2);
end
endmodule
This example illustrates the usage of the ‘default_discipline directive. The nets in1,
in2, and out all have discipline logic by default.
There is a precedence of compiler directives; the more specific directives have higher
precedence over general directives.
11.2 `default_transition
The scope of this directive is similar to the scope of the `define compiler directive
although it can be used only outside of module definitions. This directive specifies the
default value for rise and fall time for the transition filter (see Section 4.4.9). There are
no scope restrictions for this directive. The syntax for this directive is shown in
Syntax 11-2.
default_transition_compiler_directive ::=
`default_transition transition_time
transition_time ::=
constant_expression
For all transition filters which follow this directive and do not have rise time and fall time
arguments specified, transition_time is used as the default rise and fall time values. If
another `default_transition directive is encountered in the subsequent source description,
the transition filters following the newly encountered directive derive their default rise
and fall times from the transition time value of the newly encountered directive. In other
words, the default rise and fall times for a transition filter are derived from the
transition_time value of the directive which immediately precedes the transition filter.
If a `default_transition directive is not used in the description, transition_time is controlled
by the simulator.
11.3.1 `define
`definecreates a macro for text substitution. This directive 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
substitutes the text of the macro for the string `text_macro_name. All compiler
directives are considered pre-defined macro names; it is illegal to re-define a compiler
directive as a macro name.
A text macro can be defined with arguments. This allows the macro to be customized for
each use individually.
The syntax for text macro definitions is shown in Syntax 11-3.
text_macro_definition ::=
`define text_macro_name macro_text
text_macro_name ::=
text_macro_identifier [ ( list_of_formal_arguments ) ]
list_of_formal_arguments ::=
formal_argument_identifier { , formal_argument_identifier }
The macro text can be any arbitrary text specified on the same line as the text macro
name, but shall not begin with __VAMS_ to avoid conflicts with predefined macros in
Section 11.7. If more than one line is necessary to specify the text, the newline shall be
preceded by a backslash (\). The first newline not preceded by a backslash shall end the
macro text. The newline preceded by a backslash is replaced in the expanded macro with
a newline (but without the preceding backslash character).
When formal arguments are used to define a text macro, the scope of the formal
arguments extend up to the end of the macro text. A formal argument can be used in the
macro text in the same manner as an identifier.
If a one-line comment (i.e., a comment specified with the characters //) is included in
the text, the comment does not become part of the text substituted. The 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 shown in Syntax 11-4.
text_macro_usage ::=
`text_macro_identifier [ ( list_of_actual_arguments ) ]
list_of_actual_arguments ::=
actual_argument { , actual_argument }
actual_argument ::=
expression
For a macro without an argument, the text is substituted “as is” for every occurrence of
`text_macro. However, a text macro with one or more arguments shall be expanded by
substituting each formal argument with the expression used as the actual argument in the
macro usage.
Once a text macro name has been defined, it can be used anywhere in a source
description; i.e., there are no scope restrictions.
The text specified for macro text can not be split across the following lexical tokens:
• comments
• numbers
• strings
• identifiers
• keywords
• operators
Examples:
`define M_PI 3.14159265358979323846
`define size 8
electrical [1:` size] vout;
Note 1: Text macro names can not be the same as compiler directive keywords.
Note 2: Text macro names can re-use names being used as ordinary identifiers. For example,
signal_name and `signal_name are different.
Note 3: 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.
11.3.2 `undef
`undef undefines a previously defined text macro. An attempt to undefine a text macro
which was not previously defined by a `define compiler directive can result in a warning.
The syntax for `undef is shown in Syntax 11-5.
undefine_compiler_directive ::=
`undef text_macro_identifier
conditional_compilation_directive ::=
`ifdef text_macro_name
first_group_of_lines
[ `else
second_group_of_lines
`endif ]
Note 1: Any group of lines the compiler ignores still needs to follow the Verilog-AMS HDL lexical
conventions for white space, comments, numbers, strings, identifiers, keywords, and operators.
11.5 `include
This 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 compiler directive. `include can be used to include global or
commonly used definitions and tasks without encapsulating repeated code within
module boundaries.
This directive can be useful in the following situations:
• providing an integral part of configuration management;
include_compiler_directive ::=
`include "filename"
The compiler directive `include can be specified anywhere within the Verilog-AMS 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.
Only white space or a comment can appear on the same line as the `include compiler
directive.
A file included in the source using `include can contain other `include compiler directives.
The number of nesting levels for included files are finite.
Examples:
`include "parts/count.v"
`include "fileA"
`include "fileB" // including fileB
Note: Implementations can limit the maximum number of levels to which include files can be nested,
but this limit shall be a minimum of 15 levels.
11.6 `resetall
When the `resetall compiler directive is encountered during compilation, all compiler
directives are set to their default values. This is useful for ensuring only those directives
which are desired in compiling a particular source file are active.
To do so, place `resetall at the beginning of each source text file, followed immediately
by the directives desired in the file.
Verilog-AMS simulators shall also provide a predefined macro so that the module can
conditionally include (or exclude) portions of the source text specific to a particular
simulator. This macro shall be documented in the Verilog-AMS section of the simulator
manual.
Annex B
Keywords
This annex contains the list of all keywords used in Verilog-AMS HDL.
B.2 Discipline/nature
Discipline and nature keywords are predefined nonescaped identifiers which define and
are only applicable to Verilog-AMS HDL discipline and nature constructs. All discipline
and nature keywords are used between the Verilog-AMS HDL keywords discipline and
enddiscipline and between the keywords nature and endnature. An escaped identifier shall
not be treated as a discipline or nature keyword.
abstol
access
continuous
ddt_nature
discrete
domain
idt_nature
units
Annex C
Analog language subset
Prior to the release of Verilog-AMS HDL, the OVI board approved an analog-only
specification called Verilog-A v1.0. With the release of Verilog-AMS HDL, the
“official” Verilog–A LRM is no longer supported as it is included as part of the
Verilog-AMS HDL specification. This annex defines a working subset of Verilog-AMS
HDL for analog-only products.
• From Section 2.6, Strings: support for regs is limited to the digital context only.
• From Section 3.4.2.2, Domain binding: the domain binding type discrete shall
be an error in Verilog-A.
• From Section 3.5, Real net declarations: the wreal data type is not supported in
Verilog-A.
Note: This feature allows the use of digital modules in Verilog-AMS HDL without editing them to add
a discipline.
C.4 Expressions
The expressions defined in Section 4 are applicable to both Verilog-AMS HDL and
Verilog-A with the following exception:
The case equality operators (===, !==) are not supported in Verilog-A.
C.5 Signals
The signals defined in Section 5 are applicable to both Verilog-AMS HDL and
Verilog-A.
C.14 Syntax
This annex (Annex A) defines the differences between Verilog-AMS HDL and
Verilog-A. Annex A defines the BNF for Verilog-AMS HDL.
C.15 Keywords
The keywords in this annex (Annex B) are the complete set of Verilog-AMS HDL
keywords, including those from IEEE 1364-2001 Verilog HDL. The following keywords
as defined in this LRM are not used by Verilog-A:
• From Annex B.1, All keywords:
connectmodule
connectrules
driver_update
endconnectrules
net_resolution
wreal
Note: All keywords of Verilog-AMS HDL are reserved words for Verilog-A.
Empty discipline predefined as type wire type not defined default definition
Array setting aa[0:1] = {2.1 = (1), 4.5 = (2) aa[0:1] = {2.1,4.5} syntax
Time tolerance on timer func- N/A supports additional time toler- Extension
tions ance argument for timer()
2 Not to use “max” and use “maxval” instead since max is a keyword Section 3.4.1.1, Section 3.4.2.6
3 Support of user-defined attributes to disciplines similar to natures has been Section 3.4.2, Section 3.4.2.7
added. This would be a useful way to pass information to other tools reading
the Verilog-AMS netlist
4 LRM specifies TRI and WIRE as aliases. The existing AMS LRM forces nets Section 3.4.2.4, Section 3.5
with wiretypes other than wire or tri to become digital, but in many cases
these are really interconnect also. If they are tied to behavioral code they will
become digital but if they are interconnected, we should not force them until
after discipline resolution. This is needed if you have configs where the
blocks connected to the net can change between analog and digital. If we
force these nets to be digital we force unneeded CMs when blocks are
switched to analog.
5 Setting an initial value on net as part of the net declaration. Section 3.4.3 Syntax 3-6, Section 3.4.3.2
6 Initial value of wreal to be set to 0.0 if the value has not been determined at t Section 3.5
= 0.
8 Reference to derived disciplines to be removed as current BNF does not Section 3.8
support the syntax
9 Reworked discipline and nature compatibility rules for better clarity. Section 3.8
10 Removed the reference to neutral discipline since wire can be used in the Section 3.8
same context.
12 Array declaration wrongly specified before the variable identifier. For Section 6.5.2 (Example)
variables, array specification is written after the name of the variable.
13 @(final_step) without arguments should not have parenthesis Section 6.7.4, Table 6-1
16 Examples to be fixed to use assign for wreal and use wreal in instantiation, Section 7.4.3, Section 3.5
and also add a top level block for example in 7.3.3, and the testbench use
wreal.
17 Clarification on the port bound semantics in explaining the hierarchical Section 8.2.3
structure for a port with respect to vpiLoConn and vpiHiConn and
clarification on driver and receiver segregation
19 Mixed-signal module examples to use case syntax with X & Z instead of “==” Section 8.2.3
for value comparison
20 Clarification on accessing discrete nets and variables and X & Z bits in the Section 8.2.3
analog context.
21 Adding Support for ‘NaN & X’ into Verilog-AMS. Contribution of these Section 8.2.3, Section 8.3.2.1
values to a branch would be an error; however, analog variables should be
able to propagate this value. Added a section regarding NaN
22 The diagram corresponding to the bidir model has been reworked, and the Section 8.6
example module shown for bidir will match the corresponding figure.
25 Support for digital primitive instantiation in an analog block. Port names are Section 8.8.5.1
created for the ports of the digital primitives, and these digital port names
cannot be used in child instantiations.
27 Corrections to the connect module example using the driver access function. Section 8.10.6
The errors in the example have been corrected to make it syntactically and
semantically correct
28 The constraints for supplementary drivers and delays ar clearly stated. Section 8.11
29 Driver Type function: There should be a driver access function for finding Section 8.11.4, Annex D
type of driver.
driver_type_function ::= $driver_type(signal_name, signal_index)
31 Truncation versus Rounding mechanism for converting from analog to digital Section 9.3.2.3
times.
33 Units for charge, angle and other definitions in disciplines.vams have been Annex D
changed to adhere to SI standards.
34 Values specified in constants file for charge, light, Boltzmann constant, and so Annex D
forth have been changed to adhere to the standard definitions.
C.19.1 Forever
This statement is no longer supported.
C.19.2 NULL
This statement is no longer supported. Certain functions such as case, conditionals and
the event statement do allow null statements as defined by the syntax.
C.19.3 Generate
The generate statement is a looping construct which is unrolled at elaboration time. It is
the only looping statement that can contain analog operators. The syntax of generate
statement is shown in Figure C.1.
generate_statement ::=
generate indexr_identifier ( start_expr , end_expr [ , incr_expr ] )
statement
start_expr ::=
constant_expression
end_expr ::=
constant_expression
incr_expr ::=
constant_expression
analog begin
thresh = fullscale/2.0;
generate i (bits-1,0) begin
V(out[i]) <+ transition(sample > thresh, dly, ttime);
if (sample > thresh) sample = sample - thresh;
sample = 2.0*sample;
end
end
endmodule
Annex D
Standard definitions
// Potential in volts
nature Voltage
units = "V";
access = V;
idt_nature = Flux;
`ifdef VOLTAGE_ABSTOL
abstol = `VOLTAGE_ABSTOL;
`else
abstol = 1e-6;
`endif
endnature
// Flux in Webers
nature Flux
units = "Wb";
access = Phi;
ddt_nature = Voltage;
`ifdef FLUX_ABSTOL
abstol = `FLUX_ABSTOL;
`else
abstol = 1e-9;
`endif
endnature
// Conservative discipline
discipline electrical
potential Voltage;
flow Current;
enddiscipline
// Signal flow disciplines
discipline voltage
potential Voltage;
enddiscipline
discipline current
potential Current;
enddiscipline
// Magnetic
// Magnetomotive force in Ampere-Turns.
nature Magneto_Motive_Force
units = "A*turn";
access = MMF;
`ifdef MAGNETO_MOTIVE_FORCE_ABSTOL
abstol = `MAGNETO_MOTIVE_FORCE_ABSTOL;
`else
abstol = 1e-12;
`endif
endnature
// Conservative discipline
discipline magnetic
potential Magneto_Motive_Force;
flow Flux;
enddiscipline
// Thermal
// Temperature in Kelvin
nature Temperature
units = "K";
access = Temp;
`ifdef TEMPERATURE_ABSTOL
abstol = `TEMPERATURE_ABSTOL;
`else
abstol = 1e-4;
`endif
endnature
// Power in Watts
nature Power
units = "W";
access = Pwr;
`ifdef POWER_ABSTOL
abstol = `POWER_ABSTOL;
`else
abstol = 1e-9;
`endif
endnature
// Conservative discipline
discipline thermal
potential Temperature;
flow Power;
enddiscipline
// Kinematic
// Position in meters
nature Position
units = "m";
access = Pos;
ddt_nature = Velocity;
`ifdef POSITION_ABSTOL
abstol = `POSITION_ABSTOL;
`else
abstol = 1e-6;
`endif
endnature
discipline kinematic_v
potential Velocity;
flow Force;
enddiscipline
// Rotational
// Angle in radians
nature Angle
units = "rads";
access = Theta;
ddt_nature = Angular_Velocity;
`ifdef ANGLE_ABSTOL
abstol = `ANGLE_ABSTOL;
`else
abstol = 1e-6;
`endif
endnature
// Angular Velocity in radians per second
nature Angular_Velocity
units = "rads/s";
access = Omega;
ddt_nature = Angular_Acceleration;
idt_nature = Angle;
`ifdef ANGULAR_VELOCITY_ABSTOL
abstol = `ANGULAR_VELOCITY_ABSTOL;
`else
abstol = 1e-6;
`endif
endnature
// Angular acceleration in radians per second squared
nature Angular_Acceleration
units = "rads/s^2";
access = Alpha;
idt_nature = Angular_Velocity;
`ifdef ANGULAR_ACCELERATION_ABSTOL
abstol = `ANGULAR_ACCELERATION_ABSTOL;
`else
abstol = 1e-6;
`endif
endnature
// Torque in Newtons
nature Angular_Force
units = "N*m";
access = Tau;
`ifdef ANGULAR_FORCE_ABSTOL
abstol = `ANGULAR_FORCE_ABSTOL;
`else
abstol = 1e-6;
`endif
endnature
// Conservative disciplines
discipline rotational
potential Angle;
flow Angular_Force;
enddiscipline
discipline rotational_omega
potential Angular_Velocity;
flow Angular_Force;
enddiscipline
`endif
1. For optimization
Annex E
SPICE compatibility
E.1 Introduction
Analog simulation has long been performed with SPICE and SPICE-like simulators. As
such, there is a huge legacy of SPICE netlists. In addition, SPICE provides a rich set of
predefined models and it is considered neither practical nor desirable to convert these
models into a Verilog-AMS HDL behavioral description. In order for Verilog-AMS
HDL to be embraced by the analog design community, it is important Verilog-AMS
HDL provide an appropriate degree of SPICE compatibility. This annex describes the
degree of compatibility which Verilog-AMS HDL provides and the approach taken to
provide that compatibility.
1. The version of the SPICE language accepted by various simulators is different and
to some degree proprietary. This issue is not addressed by Verilog-AMS HDL.
So whether a particular Verilog-AMS simulator is SPICE compatible, and with
which particular variant of SPICE it is compatible, is solely determined by the
authors of the simulator.
2. Not all SPICE simulators support the same set of component primitives. Thus, a
particular SPICE netlist can reference a primitive which is unsupported. Verilog-
AMS HDL offers no alternative in this case other than the possibility that if the
model equations are known, the primitive can be rewritten as a module.
3. The names of the built-in SPICE primitives, their parameters, or their ports can
differ from simulator to simulator. This is particularly true because many
primitives, parameters, and ports are unnamed in SPICE. When instantiating
SPICE primitives in Verilog-AMS HDL, the primitives shall, and parameters and
ports can, be named. Since there are no established standard names, there is a
high likelihood of incompatibility cropping up in these names.
To reduce this, a list of what names shall be used for the more common
components is shown in Annex E.3. However, it is not possible to anticipate all
SPICE primitives and parameters which could be supported; so different
implementations can end up using different names. This level of incompatibility
can be overcome by using wrapper modules to map names.
4. The mathematical description of the built-in primitives can differ. As with the
netlist syntax, incompatible enhancements of the models have crept in through
the years. Again, Verilog-AMS HDL offers no solution in this case other than the
possibility that if the model equations are known, the primitive can be rewritten
as a module.
However, if no exact match is found, the mixed-case name shall match the same name
defined within SPICE regardless of the case.
E.2.2 Examples
This subsection shows some examples.
c1 c2
b1 b2
endmodule
Unlike with SPICE, the first letter of the instance name, in this case Q1 and Q2, is not
constrained by the primitive type. For example, they can just as easily be T1 and T2.
The ports and parameters of the BJT are determined by the BJT primitive itself and not
by the model statement for the BJT. See Annex E.3 for more details. The BJT has 3
mandatory ports (collector, base, and emitter) and one optional port (the substrate). In
the instantiation of Q1, the ports are passed by order. With Q2, the ports are passed by
name. In both cases, the optional substrate port is defaulted by simply not giving it.
Note: In Verilog-AMS HDL the name of the subcircuit instance is not constrained to start with X as it
is in SPICE.
parameters shall be given in the order listed. The default discipline of the ports for these
primitives shall be electrical and their descriptions shall be inout.
Attributes are defined in the IEEE 1364-2001 LRM and will not be described in this
document.
pnjlim vte, vcrit voltage across diodes and pn junctions in other devices
Annex F
Discipline resolution methods
For example, electrical sig; makes all instances of sig electrical, unless they have
been overridden by an out-of-context declaration.
3. Apply all out-of-context node and signal declarations.
More than one conflicting in-context discipline declaration or more than one conflicting
out-of-context discipline declaration for the same hierarchical segment of a signal is an
error. In this case, conflicting simply means an attempt to declare more than one
discipline regardless of whether the disciplines are compatible or not.
4. Traverse each signal hierarchically (depth-first) when a net is encountered which
still has not been assigned a discipline:
A. It shall be determined whether the net is analog or digital. Any net whose port
connections (i.e., connections to the upper part of a port) are all digital shall be
considered digital (discrete domain), any others shall be considered analog
(continuous domain).
B. Apply any `default_discipline directives to any net segments which do not yet have
a discipline, provided their domain is the same as the domain of the default
discipline. This is done according to the rules of precedence for `default_discipline
(see Section 3.7).
C. If the segment has not yet been assigned a discipline, examine all ports to which
the segment forms the upper connection and construct a list of all disciplines at
the lower connections of these ports whose domains match the domain of the
segment:
• If there is only a single discipline in the list, the signal is of that discipline
• If there is more than one discipline in the list and the contents of the list match
the discipline list of a resolution connect statement, the net is of the resolved
discipline given by the statement.
• Otherwise the discipline is unknown. This is legal provided the net segment has
no mixed-port connections (i.e., it does not connect through a port to a segment
of a different domain). Otherwise this is an error.
At this point, connection module selection and insertion can be performed. Insert
converters applying the rules and semantics of the connect statement (Section 8.7) and
auto-insertion sections (Section 8.8).
After this step, every port in the design has both its upper (actual) connection and its
lower (formal) connection defined.
2. Apply all in-context node and signal declarations
For example, electrical sig; makes all instances of sig electrical, unless they have
been overridden by an out-of-context declaration.
3. Apply all out-of-context node and signal declarations.
A. It shall be determined whether the net is analog or digital. Any net whose port
connections (i.e., connections to the upper part of a port) are all digital shall be
considered digital. If any of the connections are analog, the net shall be
considered analog. Any others shall still be considered unknown.
B. Apply any `default_discipline directives to any net segments which do not yet have
a discipline, provided their domain is the same as the domain of the default
discipline. This is done according to the rules of precedence for `default_discipline
(see Section 3.7).
C. If the segment has not yet been assigned a discipline, examine all ports to which
the segment forms the upper or lower connection. and construct a list of all
disciplines at the other connections of these ports whose domains match the
domain of the segment:
• If there is only a single discipline in the list, the signal is of that discipline
• If there is more than one discipline in the list and the contents of the list match
the discipline list of a resolution connect statement, the net is of the resolved
discipline given by the statement.
5. Traverse each net hierarchically (top-down) when a net is encountered which still
has not been assigned a discipline:
A. It shall be determined whether the net is analog or digital. Any net whose port
(i.e., connection to the lower part of a port) is digital shall be considered digital.
Any others shall be considered analog.
B. Apply any `default_discipline directives which to any net segments which do not
yet have a discipline, provided their domain is the same as the domain of the
default discipline. This is done according to the rules of precedence for
`default_discipline (see Section 3.7).
C. If the segment has not yet been assigned a discipline, examine all ports to which
the segment forms the lower connection and construct a list of all disciplines at
the upper connections of these ports whose domains match the domain of the
segment:
• If there is only a single discipline in the list, the signal is of that discipline
• If there is more than one discipline in the list and the contents of the list match
the discipline list of a resolution connect statement, the net is of the resolved
discipline given by the statement.
• Otherwise the discipline is unknown. This is legal provided the net segment has
no mixed-port connections (i.e., it does not connect through a port to a segment
of a different domain). Otherwise this is an error.
At this point, connection module selection and insertion can be performed. Insert
converters applying the rules and semantics of the connect statement (Section 8.7) and
auto-insertion sections (Section 8.8).
Annex G
Open issues
Annex G identifies issues in this LRM version that require additional investigation, and
which will be addressed in the next revision. The following table describes the issues and
categorizes them as follows:
• Ambiguity
Indicates something that is unclear in the current version of the LRM
• BNF
Indicates that the Verilog-AMS syntax grammar requires modification
• Enhancement
Indicates something that is not addressed in the current language but will be
addressed in future revisions
Table G.1—Open issues in LRM 2.1
3 Discipline Resolution Issues: Algorithm is based on net types rather than driver that appears on Ambiguity
mixed net.
Related Issues:
• Driver-Receiver segregation
• placement of A/D converter
• empty disciplines, undeclared nets
• how to deal with leaf level wires
• no clear definition on OOMR
• What is the discipline of an expression when an expression is specified as an actual in a port
connection? A driver might have to be created as an unnamed implicit function.
5 System tasks and function. Issue with $random. The syntax is defined in both digital (1364-2001) BNF
as well as analog (LRM 2.1) BNF. The syntax should be in sync.
6 Issue with genvar. Currently genvar is defined both in Verilog-D 1364-2001 std as well as LRM 2.1, BNF
and they are used in different contexts. Digital genvar is used more in structural context and analog
genvar is used in a behavioural (analog_for) context.
7 • External module definition to support direct import of SPICE netlists in Annex E. Currently this Enhancement
is not clearly stated in the LRM.
• Augment “external module” and “macromodule” definitions within a “simulator class”. Extend the
“external module” syntax with parameters indicating the language used. Also, case sensitivity of
SPICE simulators should be accounted for in the language. Should there be filters for support of
foreign language? Implement something similar to “shell” which is used in digital simulators.
9 Ambiguities with if-else-if BNF syntax, when nested if statements are used, when the if-condition is BNF
statically evaluatable.
11 LRM does not specify DC Sweep behavior for mixed-signal simulations. Ambiguity
13 SPICE versus Verilog name conflict. There is an issue while instantiating two modules with the Enhancement
same name defined in different abstractions (SPICE versus Verilog). Currently, the LRM does not
have any name scoping mechanisms. Look at the possibility of issuing an error when a name conflict
occurs, or use the standard library methodology to pick the first match from the library.
14 Switch branch syntax not defined in BNF, though it is explained in an example. Also, should indirect BNF
branch assignment be made illegal in conditional? This is not clearly defined in the LRM (direct
contribution statements are allowed in if statements to model switch behavior).
18 ‘include does not support both <> and "" to include header files. This syntax could be used to Enhancement
differentiate system-defined header files and user-defined header files.
20 Should flow and potential etc. be part of global keyword list? Should there be a single global Enhancement
keyword list?
21 Coercion of string to real does not make sense and is not defined, but it is currently allowed. The BNF
LRM should not allow coercing of a string to real. This should be treated as an error in the analog
context.
22 The concept of associating variables based on which context they are assigned is apparently felt to Enhancement
be ambiguous. Can there be a better approach to identifying the domain of a variable in a mixed-
signal context?
23 Can “,,” (comma-comma) syntax be used for null arguments instead of “{}”? This can be useful for Enhancement
defining NULL numerator/denominator arguments in Laplace/Zi. Can this be explicitly allowed for
these operators?
24 How will we handle parameter override values specified in defparam versus instantiation Enhancement
precedence? If the module is pre-compiled, the compiler would not know about the last override
value. (Apparently there was a discussion on Verilog-D not to support defparam.)
25 Light Weight Conversions: connectmodule only addresses automatic conversion of signals passed Enhancement
through ports (structural). What about OOMRs where behavioral code asks for values not passed
through ports? These are just probes, which do not need resolution. There should be a mechanism in
the LRM for treating these light weight conversions.
26 VPI issue: Nature and disciplines should not use param_assign, instead there should be a new object Ambiguity
called attr_assign
28 Indexing of Named vector branches: What should be the index of a vector branch declared between BNF
two vector nodes:
electrical [1:2] a;
electrical [0:1] b;
branch (a,b) br1 [1:2];
branch (a,b) br2; //??
30 Currently, the digital syntax does not allow register declaration in named blocks mentioned in an Enhancement
@(initial) or @(always) block. Register and net declarations should be allowed as part of these
named blocks
32 Events inside loop statements: Events are used inside loops in references through examples (Section Ambiguity
5.2, dac), though this is disallowed as per the grammar.
33 Accessing discipline attributes (both digital and analog) to be supported in the language. Enhancement
34 Discipline name “logic” in disciplines.vams conflicts with keyword in SystemVerilog for BNF
a variable type logic.
35 The LRM should conform to IEEE Standard Style Guide for usage of "may," "shall," and "can." BNF
Annex H
Glossary
Glossary of Terms
AMS
See also, Verilog-AMS.
behavioral description
A level within the behavioral description of a module, delimited by begin and end.
branch
A relationship between two nodes and their attached quantities within the behavioral
description of a module. Each branch has two quantities, a value and a flow, with a
reference direction for each.
compact model
component
The essential relationships (expressions and statements) between the outputs of a module
and its inputs and parameters, which define the nature of the module. These relationships
constitute a behavioral description.
control flow
The conditional and iterative statements controlling the behavior of a module. These
statements evaluate arbitrary variables (counters, flags, and tokens) to control the
operation of different sections of a behavioral description.
child module
flow
One of the two fundamental quantities used to simulate the behavior of a system. In
electrical systems, the flow is the current.
instance
Any named occurrence of an component created from a module definition. One module
can occur in multiple instances.
instantiation
The process of creating an instance from a module definition or simulator primitive and
defining the connectivity and parameters of that instance. (Placing the instance in the
circuit or system.)
Kirchhoff’s Laws
The physical laws defining the interconnection relationships of nodes, branches, values,
and flows. They specify a conservation of flow in and out of a node and a conservation
of value around a loop of branches.
level
model
A named instance with a unique group of parameters specifying the behavior of one
particular version of a module. Models can be used to instantiate elements with
parametric specifications different from those in the original module definition.
module
nesting level
A connection point in the system, with access functions for potential and/or flow through
an underlying discipline.
node declaration
The statement in a module definition identifying the names of the nets associated with
the module ports or local to the module. A net declaration also identifies the discipline
of the net, which in turn identifies the access functions.
NR method
parameter
The statement in a module definition which defines the parameters of that module.
port
One of the two fundamental quantities used to simulate the behavior of a system. In
electrical systems, the potential is the voltage.
primitive
A basic component defined entirely in terms of behavior, without reference to any other
primitives. A primitive is the smallest and simplest portion of a simulated circuit or
system.
probe
A branch in a circuit (or system), which does not alter its behavior, but lets the simulator
read out the potential or flow at that point.
reference direction
A convention for determining whether the value of a node, the flow through a branch,
the value across a branch, or the flow in or out of a terminal, is positive or negative.
reference node
The global node (which equals zero (0)) against whose potentials all node values are
measured. Nets declared as ground shall be bound to the reference node.
run time binding
The conditional introduction and removal of value and flow sources during a simulation.
A value source can replace a flow source and vice-versa. Binding a source to a specific
node or branch prevents it from going into an unknown state.
scope
The current nesting level of a block statement, which includes all lines of code within
one set of braces in a module definition.
structural definitions
Instantiating modules inside other modules through the use of module definitions and
declarations to create a hierarchical structure in the module’s behavioral description.
terminal
Verilog-A
A subset of Verilog-AMS detailing the analog version of Verilog HDL (see Annex C).
This is a language for the behavioral description of continuous-time systems, which uses
a syntax similar to the IEEE 1364-2001 Verilog HDL specification.
Verilog-AMS