Appendix: NED Reference¶
Syntax¶
NED File Name Extension¶
NED files have the .ned file name suffix. This is mandatory, and
cannot be overridden.
NED File Encoding¶
NED files are ASCII, but non-ASCII characters are permitted in comments and string literals. This allows for using encodings that are a superset of ASCII, for example ISO 8859-1 and UTF-8.
Note
There is no standard way to specify or determine the encoding of a NED file. It is up to the user to configure the desired encoding in text editors and other tools that edit or process NED files.
String literals (e.g. in parameter values) will be passed to the C++ code
as const char * without any conversion; it is up to the simulation model
to interpret them using the desired encoding.
Line ending may be either CR or CRLF, regardless of the platform.
Reserved Words¶
The following words are reserved and cannot be used for identifiers:
Identifiers¶
Identifiers must be composed of letters of the English alphabet (a-z, A-Z), numbers (0-9), and underscore “_”. Identifiers may only begin with a letter or underscore.
The recommended way to compose identifiers from multiple words is to capitalize the beginning of each word (camel case).
Case Sensitivity¶
Keywords and identifiers in the NED language are case sensitive. For example,
TCP and Tcp are two different names.
Literals¶
String Literals¶
String literals use double quotes. The following C-style backslash escapes
are recognized: \b, \f,
\n, \r, \t,
\\, \", and
\xhh where h is a hexadecimal digit.
Numeric Constants¶
Numeric constants are accepted in the usual decimal, hexadecimal (0x prefix),
and scientific notations. Octal numbers are not accepted (numbers that start
with the 0 digit are interpreted as decimal).
nan, inf, and -inf mean the floating-point
not-a-number, positive infinity, and negative infinity values, respectively.
Quantity Constants¶
A quantity constant has the form (<numeric-constant> <unit>)+, for
example 12.5mW or 3h 15min 37.2s. Whitespace is optional in front
of a unit but must be present after a unit if it is followed by a number.
When multiple measurement units are present, they have to be convertible into each other (i.e., refer to the same physical quantity).
Section Units of Measurement lists the units recognized by OMNeT++. Other units can be used as well; the only downside being that OMNeT++ will not be able to perform conversions on them.
Null Object References¶
The keywords null and nullptr are synonymous and
denote an object reference that doesn’t refer to any valid object.
Undefined¶
The keyword undefined denotes the “missing value” value, similar
to (void)0 in C/C++. undefined has its own type and
cannot be cast to any other type.
Comments¶
Comments can be placed at the end of lines. Comments begin with a double
slash // and continue until the end of the line.
Grammar¶
The grammar of the NED language can be found in Appendix Appendix: NED Language Grammar.
Built-in Definitions¶
The NED language has the following built-in definitions, all in the ned
package: channels IdealChannel, DelayChannel, and DatarateChannel;
module interfaces IBidirectionalChannel and IUnidirectionalChannel.
The latter two are reserved for future use.
The bodies of @statistic properties have been omitted for brevity from
the following listing.
Note
One can print the full definitions by running opp_run -h neddecls.
package ned;
@namespace(omnetpp);
channel IdealChannel
{
@class(cIdealChannel);
}
channel DelayChannel
{
@class(cDelayChannel);
@signal[messageSent](type=omnetpp::cMessage);
@signal[messageDiscarded](type=omnetpp::cMessage);
@statistic[messages](title="messages sent";source=constant1(messageSent);record=count?;interpolationmode=none);
@statistic[messagesDiscarded](title="messages discarded";source=constant1(messageDiscarded);record=count?;interpolationmode=none);
bool disabled @mutable = default(false);
double delay @mutable = default(0s) @unit(s); // propagation delay
}
channel DatarateChannel
{
@class(cDatarateChannel);
@signal[channelBusy](type=long);
@signal[messageSent](type=omnetpp::cMessage);
@signal[messageDiscarded](type=omnetpp::cMessage);
@statistic[busy](title="channel busy state";source=channelBusy;record=vector?;interpolationmode=sample-hold);
@statistic[averageUtilization](title="average channel utilization";source=timeavg(channelBusy);record=last?);
@statistic[packets](title="packets sent";source=constant1(messageSent);record=count?;interpolationmode=none);
@statistic[packetBytes](title="packet bytes sent";source=packetBytes(messageSent);record=sum?;unit=B;interpolationmode=none);
@statistic[packetsDiscarded](title="packets discarded";source=constant1(messageDiscarded);record=count?;interpolationmode=none);
@statistic[averageThroughput](title="average throughput";source=sumPerDuration(packetBits(messageSent));record=last?;unit=bps);
bool disabled @mutable = default(false);
double delay @mutable = default(0s) @unit(s); // propagation delay
double datarate @mutable = default(0bps) @unit(bps); // bits per second; 0=infinite
double ber @mutable = default(0); // bit error rate (BER)
double per @mutable = default(0); // packet error rate (PER)
}
moduleinterface IBidirectionalChannel
{
gates:
inout a;
inout b;
}
moduleinterface IUnidirectionalChannel
{
gates:
input i;
output o;
}
Packages¶
NED supports hierarchical namespaces called packages. The model is similar to Java packages, with minor changes.
Package Declaration¶
A NED file may contain a package declaration. The package declaration
uses the package keyword and specifies the package for the
definitions in the NED file. If there is no package declaration, the file’s
contents are in the default package.
Component type names must be unique within their package.
Directory Structure, package.ned¶
Like in Java, the directory of a NED file must match the package
declaration. However, it is possible to omit directories at the top which do
not contain any NED files (like the typical /org/``<projectname>``
directories in Java).
The top of a directory tree containing NED files is named a NED source folder.
Note
The OMNeT++ runtime recognizes a NEDPATH environment variable, which
contains a list of NED source folders and is similar to the Java CLASSPATH
variable. NEDPATH also has a command-line option equivalent.
The package.ned file at the top level of a NED source folder plays a
special role.
If there is no toplevel package.ned or it contains no package declaration,
the declared package of a NED file in the folder ``<srcfolder>``/x/y/z
must be x.y.z.
If there is a toplevel package.ned and it declares the package as
a.b, then any NED file in the folder ``<srcfolder>``/x/y/z
must have the declared package a.b.x.y.z.
Note
package.ned files are allowed in other folders as well.
They may contain properties and/or documentation for their package,
but cannot be used to define the package they are in.
Components¶
Simple modules, compound modules, networks, channels, module interfaces and channel interfaces are called components.
Simple Modules¶
Simple module types are declared using the simple keyword;
see the NED Grammar (Appendix Appendix: NED Language Grammar) for the
syntax.
Simple modules may have properties (Properties), parameters (Parameters), and gates (Gates).
A simple module type may not have inner types (Inner Types).
A simple module type may extend another simple module type, and may implement one or more module interfaces (Module Interfaces). Inheritance rules are described in section Inheritance, and interface implementation rules in section Implementing an Interface.
Every simple module type has an associated C++ class, which must be a subclass of cSimpleModule. The way of associating the NED type with the C++ class is described in section Resolving the C++ Implementation Class.
Compound Modules¶
Compound module types are declared using the module keyword;
see the NED Grammar (Appendix Appendix: NED Language Grammar) for the
syntax.
A compound module may have properties (Properties), parameters (Parameters), and gates (Gates); its internal structure is defined by its submodules (Submodules) and connections (Connections); and it may also have inner types (Inner Types) that can be used for its submodules and connections.
A compound module type may extend another compound module type, and may implement one or more module interfaces (Module Interfaces). Inheritance rules are described in section Inheritance, and interface implementation rules in section Implementing an Interface.
Networks¶
The network Keyword¶
A network declared with the network keyword is equivalent to a compound
module (module keyword) with the @isNetwork(true) property.
Note
A simple module can only be designated as a network by specifying the
@isNetwork property; the network keyword may not
be used for that purpose.
The @isNetwork Property¶
The @isNetwork property is only recognized for simple modules and
compound modules. The value may be empty, true, or false:
@isNetwork;
@isNetwork();
@isNetwork(true);
@isNetwork(false);
The empty value corresponds to @isNetwork(true).
The @isNetwork property is not inherited; that is, a subclass
of a module with @isNetwork set does not automatically become a network.
The @isNetwork property needs to be explicitly added to the subclass
to make it a network.
Subclassing may introduce changes to a module that make it unfit to be used as a network.
Channels¶
Channel types are declared using the channel keyword;
see the NED Grammar (Appendix Appendix: NED Language Grammar) for the
syntax.
Channel types may have properties (Properties) and parameters (Parameters).
A channel type may not have inner types (Inner Types).
A channel type may extend another channel type, and may implement one or more channel interfaces (Channel Interfaces). Inheritance rules are described in section Inheritance, and interface implementation rules in section Implementing an Interface.
Every channel type has an associated C++ class, which must be a subclass of cChannel. The way of associating the NED type with the C++ class is described in section Resolving the C++ Implementation Class.
The @defaultname property of a channel type determines the default name
of the channel object when used in a connection.
Module Interfaces¶
Module interface types are declared using the moduleinterface keyword;
see the NED Grammar (Appendix Appendix: NED Language Grammar) for the
syntax.
Module interfaces may have properties (Properties), parameters (Parameters), and gates (Gates). However, parameters are not allowed to have a value assigned, not even a default value.
A module interface type may not have inner types (Inner Types).
A module interface type may extend one or more other module interface types. Inheritance rules are described in section Inheritance.
Channel Interfaces¶
Channel interface types are declared using the channelinterface keyword;
see the NED Grammar (Appendix Appendix: NED Language Grammar) for the
syntax.
Channel interfaces may have properties (Properties) and parameters (Parameters). However, parameters are not allowed to have a value assigned, not even a default value.
A channel interface type may not have inner types (Inner Types).
A channel interface type may extend one or more other channel interface types. Inheritance rules are described in section Inheritance.
Resolving the C++ Implementation Class¶
The procedure for determining the C++ implementation class for simple modules and channels, collectively referred to as components), is identical. It is as follows:
If the component extends another component and has no @class
property, the C++ implementation class is inherited from the base type.
If the component contains a @class property, the C++ class name
will be composed of the current namespace (see below) and the
value of the @class property. The @class property should
contain a single value.
Note
The @class property itself may contain a namespace declaration (i.e.
may contain “::”).
If the component contains no @class property and has no base class,
the C++ class name will be composed of the current namespace and the
unqualified name of the component.
Important
Subclassing in NED does not imply subclassing the C++ implementation. If one
intends to subclass a simple module or channel in NED as well as in C++, the
@class property needs to be explicitly specified in the derived type,
otherwise it will continue to use the C++ class from its super type.
Compound modules will be instantiated with the built-in cModule class,
unless the module contains the @class property. When @class is present,
the resolution rules are the same as with simple modules.
Current Namespace¶
The current namespace is the value of the first @namespace
property found while searching in the following order:
the current NED file
the
package.nedfile in the current package or the first ancestor package searching upwards
Note
Note that namespaces coming from multiple @namespace properties
in different scopes do not nest; rather, the nearest one wins.
The @namespace property should contain a single value.
Properties¶
Properties are a means of adding metadata annotations to NED files, component types, parameters, gates, submodules, and connections.
Identifying a Property¶
Properties are identified by name. It is possible to have several properties on the same object with the same name, as long as they have unique indices. An index is an identifier in square brackets after the property name.
The following example shows a property without an index, one with the index index1,
and a third with the index index2.
@prop();
@prop[index1]();
@prop[index2]();
Property Value¶
The value of the property is specified inside parentheses. The property value consists of key=valuelist pairs, separated by semicolons; valuelist elements are separated with commas. Example:
@prop(key1=value11,value12,value13;key2=value21,value22)
Keys must be unique.
If the key+equal sign part (key=) is missing, the valuelist belongs
to the default key. Examples:
@prop1(value1,value2)
@prop2(value1,value2;key1=value11,value12,value13)
Most properties use the default key with one value. Examples:
@namespace(inet);
@class(Foo);
@unit(s);
Property values have a liberal syntax (see Appendix Appendix: NED Language Grammar). Values that do not fit the grammar (notably, those containing a comma or a semicolon) need to be surrounded with double quotes.
When interpreting a property value, one layer of quotes is removed
automatically, that is, foo and "foo" are the same.
Within quotes, escaping works in the same way as within string literals
(see Literals).
Example:
@prop(marks=the ! mark, "the , mark", "the ; mark", other marks); // 4 items
Placement¶
Properties may be added to NED files, component types, parameters, gates, submodules, and connections. For the exact syntax, see Appendix Appendix: NED Language Grammar.
When a component type extends another component type(s), properties are merged. This is described in section Inheritance.
Property Declarations¶
The property keyword is reserved for future use. It is
envisioned that accepted property names and property keys would need
to be pre-declared, so that the NED infrastructure can warn the user
about mistyped or unrecognized names.
Parameters¶
Parameters can be defined and assigned in the parameters section
of component types. In addition, parameters can also be assigned in the
parameters sections of submodule bodies and connection bodies,
but those places do not allow adding new parameters.
The parameters keyword is optional and can be omitted
without changing the meaning.
The parameters section may also hold pattern assignments
(Pattern Assignments) and properties
(Properties).
A parameter is identified by a name and has a data type. A parameter may have a value or default value and may also have properties (see Properties).
Accepted parameter data types are double, int,
string, bool, xml, and object.
Any of the above types can be declared volatile as well
(volatile int, volatile string, etc.)
The presence of a data type keyword determines whether the given line defines a new parameter or refers to an existing parameter. One can assign a value or default value to an existing parameter, and/or modify its properties or add new properties.
Examples:
int a; // defines new parameter
int b @foo; // new parameter with property
int c = default(5); // new parameter with default value
int d = 5; // new parameter with value assigned
int e @foo = 5; // new parameter with property and value
f = 10; // assignment to existing (e.g.inherited) parameter
g = default(10); // overrides default value of existing parameter
h; // legal, but does nothing
i @foo(1); // adds a property to existing parameter
j @foo(1) = 10; // adds a property and value to existing parameter
Parameter values are NED expressions. Expressions are described in section Expressions.
For volatile parameters, the value expression is evaluated every
time the parameter value is accessed. Non-volatile parameters
are evaluated only once.
Note
The const keyword is reserved for future use within expressions
to define constant subexpressions, i.e. to denote a part within
an expression that should only be evaluated once. Constant subexpressions
are not currently supported.
The following properties are recognized for parameters: @unit,
@prompt, @mutable, @enum, @class.
The @prompt Property¶
The @prompt property defines a prompt string for the parameter. The
prompt string is used when/if a simulation runtime user interface
interactively prompts the user for the parameter’s value.
The @prompt property is expected to contain one string value for the
default key.
The @unit Property¶
A parameter may have a @unit property to associate it with a measurement
unit. The @unit property should contain one string value for the default
key. Examples:
@unit(s)
@unit(second)
When present, values assigned to the parameter must be in the same or in a compatible (that is, convertible) unit. Examples:
double a @unit(s) = 5s; // OK
double a @unit(s) = 10ms; // OK; will be converted to seconds
double a @unit(s) = 5; // error: should be 5s
double a @unit(s) = 5kg; // error: incompatible unit
@unit behavior for non-numeric parameters (boolean, string, XML)
is unspecified (may be ignored or may be an error).
The @unit property of a parameter may not be modified via inheritance.
Example:
simple A {
double p @unit(s);
}
simple B extends A {
p @unit(mW); // illegal: cannot override @unit
}
The @mutable Property¶
When a parameter is annotated with @mutable, the parameter’s value is
allowed to be changed at runtime, i.e. after its module has been set up.
Parameters without the @mutable property cannot be changed at runtime.
The @enum Property¶
The @enum property is only recognized for string parameters.
It defines a list of accepted values for the parameter. The values are specified
as a comma-separated list.
string protocol @enum("udp","tcp");
At runtime, the simulation kernel will raise an error if the parameter is assigned a value not in the list.
The @class Property on Parameters¶
The @class property on an object parameter specifies the
expected C++ class of the parameter’s value. When set, the simulation kernel
verifies that objects assigned to the parameter are instances of the given
class (or a subclass thereof).
object route @class(inet::L3Address);
Note
This use of @class is unrelated to the component-level @class
property that specifies the C++ implementation class of a module or channel
(see Resolving the C++ Implementation Class).
Pattern Assignments¶
Pattern assignments allow one to set more than one parameter using
wildcards, and to assign parameters deeper down in a submodule tree.
Pattern assignments may occur in the parameters
section of component types, submodules and connections.
The syntax of a pattern assignment is <pattern> = <value>.
A pattern consists of two or more pattern elements, separated by dots.
The pattern element syntax is defined so that it can accommodate names of
parameters, submodules (optionally with index), gates (optionally with the
$i/$o suffix and/or index) and connections, and their
wildcard forms. (The default name of connection channel objects is
channel.)
Wildcard forms may use:
Asterisks: They match zero or more characters except dots.
Numeric ranges,
{<start>..<end>}e.g.{5..120}or{..10}. They match numbers embedded in identifiers, that is, a sequence of decimal digit characters interpreted as a nonnegative integer that is within the specified start..end range (both limits are inclusive). Both start and end are optional.Numeric index ranges,
[<start>..<end>]. e.g.[5..120]or[..10]. They are intended for selecting submodule and gate index ranges. They match a nonnegative integer enclosed in square brackets that is within the specified start..end range (both limits are inclusive). Both start and end are optional.Double asterisks: They match zero or more characters (including dots), and can be used to match more than one parameter path elements.
See the NED language grammar (Appendix Appendix: NED Language Grammar) for a more formal definition of the pattern syntax.
Examples:
host1.tcp.mss = 512B;
host*.tcp.mss = 512B; // matches host, host1, host2, hostileHost, ...
host{9..11}.tcp.mss = 512B; // matches host9/host10/host11, but nothing else
host[9..11].tcp.mss = 512B; // matches host[9]/host[10]/host[11], but nothing else
**.mss = 512B; // matches foo.mss, host[1].transport.tcp[0].mss, ...
Gates¶
Gates can be defined in the gates section of component types.
The size of a gate vector (see below) may be specified at the place of
defining the gate, via inheritance in a derived type, and also in the
gates block of a submodule body. A submodule body does not allow
defining new gates.
A gate is identified by a name, and is characterized by a type
(input, output, inout) and optionally a
vector size. Gates may also have properties (see
Properties).
Gates may be scalar or vector. The vector size is specified with a numeric expression inside square brackets. The vector size may also be left unspecified by writing an empty pair of square brackets.
An already specified gate vector size may not be overridden in subclasses or in a submodule.
The presence of a gate type keyword determines whether the given line defines a new gate or refers to an existing gate. One can specify the gate vector size for an existing gate vector, and/or modify its properties, or add new properties.
Examples:
gates:
input a; // defines new gate
input b @foo; // new gate with property
input c[]; // new gate vector with unspecified size
input d[8]; // new gate vector with size=8
e[10]; // set gate size for existing (e.g.inherited) gate vector
f @foo(bar); // add property to existing gate
g[10] @foo(bar); // set gate size and add property to existing gate
Gate vector sizes are NED expressions. Expressions are described in section Expressions.
See the Connections section (Connections) for more information on gates.
Recognized Gate Properties¶
The following properties are recognized for gates: @directIn
and @loose. They have the same effect: When either of them is
present on a gate, the gate is not required to be connected in the
connections section of a compound module (see Connections).
@directIn should be used when the gate is an input gate that is
intended for being used as a target for the sendDirect() method;
@loose should be used in any other case when the gate is not
required to be connected for some reason.
Note
The reason @directIn gates are not required to remain
unconnected is that it is often useful to wrap such modules in a compound
module, where the compound module also has a @directIn input gate
that is internally connected to the submodule’s corresponding gate.
Example:
gates:
input radioIn @directIn;
Submodules¶
Submodules are defined in the submodules section of the compound
module.
The type of the submodule may be specified statically or parametrically.
Submodules may be scalar or vector. The size of submodule vectors must be specified as a numeric expression inside square brackets.
Submodules may also be conditional.
A submodule definition may or may not have a body (a curly brace delimited block). An empty submodule body is equivalent to a missing one.
Syntax examples:
submodules:
ip : IP; // scalar submodule without body
tcp : TCP {} // scalar submodule with empty body
app[10] : App; // submodule vector
Submodule Type¶
The simple or compound module type (Simple Modules, Compound Modules) that will be instantiated as the submodule may be specified either statically (with a concrete module type name) or parametrically.
Static Submodule Type¶
Submodules with a statically defined type are those that contain a concrete NED module type name. Example:
tcp : TCP;
See section Type Name Resolution for the type resolution rules.
Parametric Submodule Type¶
Parametric submodule type means that the NED type name is given in a string expression. The string expression may be specified locally in the submodule declaration, or elsewhere using typename patterns (see later).
Parametric submodule types are syntactically denoted by the presence of an
expression in a pair of angle brackets and the like keyword
followed by a module interface type Module Interfaces
that a module type must implement in order to be eligible to be chosen.
The angle brackets may be empty, contain a string expression, or contain a
default string expression (default(...) syntax).
Examples:
tcp : <tcpType> like ITCP; // type comes from parent module parameter
tcp : <"TCP_"+suffix> like ITCP; // expression using parent module parameter
tcp : <> like ITCP; // type must be specified elsewhere
tcp : <default("TCP")> like ITCP; // type may be specified elsewhere;
// if not, the default is "TCP"
tcp : <default("TCP_"+suffix)> like ITCP;
// type may be specified elsewhere;
// if not, the default is an expression
See the NED Grammar (Appendix Appendix: NED Language Grammar) for the formal syntax, and section Resolution of Parametric Types for the type resolution rules.
The @dynamic Property¶
The @dynamic property is only recognized for submodules. The value may
be empty, true or false; @dynamic is equivalent to @dynamic(true).
When a submodule is marked as dynamic inside a compound module, the submodule will not be instantiated when the compound module is created; rather, it is expected that it will be instantiated at runtime, using dynamic module creation. A module created this way will pick up parameter values from the submodule declaration in the NED file as well as from the ini file. Dynamic submodules may be displayed in the graphical NED editor as semi-transparent, allowing them to be edited and configured like other submodules.
The @omittedTypename Property¶
The @omittedTypename property is recognized on module interfaces,
channel interfaces, parametric submodules (like), and parametric
connections. It simplifies the construction of highly configurable compound
modules where many submodules are optional, by reducing the need for complex
conditional connections.
When a parametric submodule’s type name is configured as an empty string
(""), the network builder would normally raise an error. If the submodule
has an @omittedTypename property (which typically comes from the
interface), the specified type is instantiated instead. By convention, this type
is a lightweight self-destructing module (e.g. OmittedTcp) that
shortcuts its input and output gates during initialization and then removes
itself from the compound module. This way, the surrounding connections remain
valid even though the submodule is effectively absent, without the compound
module needing complicated conditional connection logic.
@omittedTypename is typically specified on the module interface, so that
all submodules using that interface inherit the behavior:
moduleinterface ITCP {
@omittedTypename(OmittedTcp);
}
It may also be specified directly on a submodule or connection, which takes
precedence over the interface. If @omittedTypename is present but its
value is empty, the submodule will simply not be created (equivalent to being
conditionally omitted). For connections with parametric channel types, an empty
value means no channel object will be created for the connection.
Conditional Submodules¶
Submodules may be made conditional using the if keyword. The
condition expression must evaluate to a boolean; if the result is
false, the submodule is not created, and trying to connect its gates
or reference its parameters will be an error.
An example:
submodules:
tcp : TCP if withTCP { ... }
Parameters, Gates¶
A submodule body may contain parameters (Parameters) and gates (Module Interfaces).
A submodule body cannot define new parameters or gates. It is only allowed to assign existing parameters, and to set the vector size of existing gate vectors.
It is also allowed to add or modify submodule properties and parameter/gate properties.
Connections¶
Connections are defined in the connections section of the compound module.
Connections may not span multiple hierarchy levels, that is, a connection may be created between two submodules, a submodule and the compound module, or between two gates of the compound module.
Normally, all gates must be connected, including submodule gates and the gates
of the compound module. When the allowunconnected modifier is present
after connections, gates will be allowed to be left unconnected.
Note
The @directIn and @loose gate properties are alternatives to the
connections allowunconnected syntax; see Gates.
Connections may be conditional, and may be created using loops (see Conditional and Loop Connections, Connection Groups).
Connection Syntax¶
The connection syntax uses arrows (-->, <--) to connect
input and output gates, and double arrows
(<-->) to connect inout gates. The latter is
also said to be a bidirectional connection.
Arrows point from the source gate (a submodule output gate or a compound
module input gate) to the destination gate (a submodule input gate or a
compound module output gate). Connections may be written either left to right
or right to left, that is, a-->b is equivalent to b<--a.
Gates are specified as <modulespec>.<gatespec> (to connect a submodule),
or as <gatespec> (to connect the compound module). <modulespec>
is either a submodule name (for scalar submodules), or a submodule name plus
an index in square brackets (for submodule vectors). For scalar gates,
<gatespec> is the gate name; for gate vectors it is either
the gate name plus a numeric index expression in square brackets,
or <gatename>++.
The <gatename>++ notation causes the first unconnected gate index
to be used. If all gates of the given gate vector are connected, the behavior
is different for submodules and for the enclosing compound module.
For submodules, the gate vector expands by one. For the compound module,
it is an error to use ++ on a gate vector with no unconnected gates.
Syntax examples:
connections:
a.out --> b.in; // unidirectional between two submodules
c.in[2] <-- in; // parent-to-child; gate vector with index
d.g++ <--> e.g++; // bidirectional, auto-expanding gate vectors
The reason it is not supported to expand the gate vector of the compound module is that the module structure is built in top-down order: new gates would be left unconnected on the outside, as there is no way in NED to “go back” and connect them afterwards.
When the ++ operator is used with $i or $o
(e.g. g$i++ or g$o++, see later), it will actually add
a gate pair (input+output) to maintain equal gate size for the two
directions.
The syntax to associate a channel (see Channels)
with the connection is to use two arrows with a channel specification
in between (see later). The same syntax is used to add properties such as
@display to the connection.
Inout Gates¶
An inout gate is represented as a gate pair: an input gate and an output gate.
The two sub-gates may also be referenced and connected individually, by adding
the $i and $o suffix to the name of the inout gate.
A bidirectional connection (which uses a double arrow to connect two inout gates), is also a shorthand for two uni-directional connections; that is,
a.g <--> b.g;
is equivalent to
a.g$o --> b.g$i;
a.g$i <-- b.g$o;
In inout gate vectors, gates are always in pairs, that is,
sizeof(g$i)==sizeof(g$o) always holds. It is maintained even
when g$i++ or g$o++ is used: the ++ operator will
add a gate pair, not just an input or an output gate.
Specifying Channels¶
A channel specification associates a channel object with the connection. A channel object is an instance of a channel type (see Channels).
Note
As bidirectional connections are a shorthand for a pair of uni-directional connections, they will actually create two channel objects, one for each direction.
The channel type to be instantiated may be implicit, or may be specified statically or parametrically.
A connection may have a body (a curly brace delimited block) for setting properties and/or parameters of the channel.
A connection syntax allows one to specify a name for the channel object.
When not specified, the channel name will be taken from the @defaultname
property of the channel type; when there is no such property, it will be
"channel". Custom connection names can be useful for easier addressing of
channel objects when assigning parameters using patterns.
See subsequent sections for details.
Implicit Channel Type¶
If the connection syntax does not say anything about the channel type, it is implicitly determined from the set of connection parameters used.
Syntax examples for connections with implicit channel types:
a.g <--> b.g; // no parameters
a.g <--> {delay = 1ms;} <--> b.g; // assigns delay
a.g <--> {datarate = 100Mbps; delay = 50ns;} <--> b.g; // assigns delay and datarate
For such connections, the actual NED type to be used will depend on the parameters set in the connection:
When no parameters are set,
ned.IdealChannelis chosen.When only
ned.DelayChannelparameters are used (delayanddisabled),ned.DelayChannelis chosen.When only
ned.DatarateChannelparameters are used (datarate,delay,ber,per,disabled), the chosen channel type will bened.DatarateChannel.
Connections with implicit channel types may not use any other parameter.
Static Channel Type¶
Connections with a statically defined channel type are those that contain a concrete NED channel type name.
Examples:
a.g <--> FastEthernet <--> b.g;
a.g <--> FastEthernet {per = 1e-6;} <--> b.g;
See section Type Name Resolution for the type resolution rules.
Parametric Channel Type¶
Parametric channel types are similar to parametric submodule types, described in section Submodules.
Parametric channel type means that the NED type name is given in a string expression. The string expression may be specified locally in the connection declaration, or elsewhere using typename patterns (see later).
Parametric channel types are syntactically denoted by the presence of an
expression in a pair of angle brackets and the like keyword
followed by a channel interface type Channel Interfaces
that a channel type must implement in order to be eligible to be chosen.
The angle brackets may be empty, contain a string expression, or contain a
default string expression (default(...) syntax).
Examples:
a.g++ <--> <channelType> like IMyChannel <--> b.g++;
// type comes from parent module parameter
a.g++ <--> <"Ch_"+suffix> like IMyChannel <--> b.g++;
// expression using parent module parameter
a.g++ <--> <> like IMyChannel <--> b.g++;
// type must be specified elsewhere
a.g++ <--> <default("MyChannel")> like IMyChannel <--> b.g++;
// type may be specified elsewhere;
// if not, the default is "MyChannel"
a.g++ <--> <default("Ch_"+suffix)> like IMyChannel <--> b.g++;
// type may be specified elsewhere;
// if not, the default is an expression
See the NED Grammar (Appendix Appendix: NED Language Grammar) for the formal syntax, and section Resolution of Parametric Types for the type resolution rules.
Channel Parameters and Properties¶
A channel definition may or may not have a body (a curly brace
delimited block). An empty channel body ({ }) is equivalent
to a missing one.
A channel body may contain parameters (Parameters).
A channel body cannot define new parameters. It is only allowed to assign existing parameters.
It is also allowed to add or modify properties and parameter properties.
The @reconnect Property¶
The @reconnect property is recognized for connections. Normally, it is
an error for a NED connection to refer to a gate that is already connected.
When @reconnect is present on a connection, the network builder first
disconnects any existing connections on the involved gates before creating the
new connection.
a.out --> {@reconnect;} --> b.in;
The primary use of @reconnect is in combination with inheritance,
where it allows a derived compound module to modify the connections established
by the base type, e.g., to insert a new submodule in the path between two
already connected submodules.
See also Reconnecting Gates.
Conditional and Loop Connections, Connection Groups¶
The connections section may contain any number of connections and connection groups. A connection group is one or more connections grouped with curly braces.
Both connections and connection groups may be conditional (if
keyword) or may be multiple (for keyword).
Any number of for and if clauses may be added to
a connection or connection loop; they are interpreted as if they were
nested in the given order. Loop variables of a for may be
referenced from subsequent conditions and loops as well as in module and
gate index expressions in the connections.
See the NED Grammar (Appendix: NED Language Grammar) for the exact syntax.
Example connections:
a.out --> b.in;
c.out --> d.in if p>0;
e.out[i] --> f[i].in for i=0..sizeof(f)-1, if i%2==0;
Example connection groups:
if p>0 {
a.out --> b.in;
a.in <-- b.out;
}
for i=0..sizeof(c)-1, if i%2==0 {
c[i].out --> out[i];
c[i].in <-- in[i];
}
for i=0..sizeof(d)-1, for j=0..sizeof(d)-1, if i!=j {
d[i].out[j] --> d[j].in[i];
}
for i=0..sizeof(e)-1, for j=0..sizeof(e)-1 {
e[i].out[j] --> e[j].in[i] if i!=j;
}
Inner Types¶
Inner types can be defined in the types section of compound
modules, with the same syntax as toplevel (i.e. non-inner) types.
Inner types may not contain further inner types, that is, type nesting is limited to two levels.
Inner types are only visible inside the enclosing component type and its subclasses.
Name Uniqueness¶
Identifier names within a component must be unique. That is, the following items in a component are considered to be in the same name space and must not have colliding names:
parameters
gates
submodules
inner types
the above items of super type(s)
For example, a gate and a submodule cannot have the same name.
Parameter Assignment Order¶
A module or channel parameter may be assigned in parameters
blocks (see Parameters) at various places in NED: in
the module or channel type that defines it; in the type’s subclasses; in
the submodule or connection that instantiates the type. The parameter may
also be assigned using pattern assignments (see
Pattern Assignments) in any compound module that uses
the given module or channel type directly or indirectly.
Patterns are matched against the relative path of the parameter, which is
the relative path of its submodule or connection, with a dot and the
parameter name appended. The relative path is composed of a list of
submodule names (name plus index) separated by dots; a connection is
identified by the full name of its source gate plus the name of the channel
object (which is currently always channel) separated by a dot.
Note
As bidirectional connections are a shorthand for two unidirectional
connections, the source gate name is qualified with $i or
$o in the relative path.
Note that the parameters keyword itself is optional,
and is usually not written out in submodules and connections.
This section describes the module and channel parameter assignments procedure.
The general rules are the following:
A (non-default) parameter assignment may not be overridden later; that is, if there are assignments in multiple places, the assignment “closest” to the parameter declaration will be effective; others will be flagged as errors.
A default value is only used if a non-default value is not present for the given parameter. A non-default value may also come from a source external to NED, namely the simulation configuration (
omnetpp.ini).Unlike non-default values, a default value may be overridden; that is, if there are default value assignments in multiple places, the assignment “farthest” from the parameter declaration will win.
Among pattern assignments within the same
parametersblock, the first match will win. Pattern assignments with default and non-default values are considered to be two disjoint sets, only one of which are searched at a time.
This yields the following conceptual search order for non-default parameter assignments:
First, the NED type that contains the parameter declaration is checked;
Then its subclasses are checked;
Then the submodule or connection that instantiates the type is checked;
Then the compound module that contains the submodule or connection is checked for matching pattern assignments;
Then, assuming the compound module is part of a network, the search for matching pattern assignments continues up on the module tree until the root (the module that represents the network). At each level (compound module), first the specific submodule definition is checked, then the (parent) compound module. If a compound module is subclassed before instantiated, the base type is checked first.
When no (non-default) assignment is found, the same places are searched in the reverse order for default value assignments. If no default value is found, an error may be raised or the user may be interactively prompted.
To illustrate the above rules, consider the following example where we want to assign parameter p:
simple A { double p; }
simple A2 extends A {...}
module B { submodules: a2: A2 {...} }
module B2 extends B {...}
network C { submodules: b2: B2 {...} }
Here, the search order is: A, A2, a2, B, B2, b2, C. NED
conceptually searches the parameters blocks in that order for a
(non-default) value, and then in reverse order for a default value.
The full search order and the form of assignment expected on each level:
A { p = ...; }A2 { p = ...; }a2 { p = ...; }B { a2.p = ...; }B2 { a2.p = ...; }b2 { a2.p = ...; }C { b2.a2.p = ...; }C { b2.a2.p = default(...); }b2 { a2.p = default(...); }B2 { a2.p = default(...); }B { a2.p = default(...); }a2 { p = default(...); }A2 { p = default(...); }A { p = default(...); }
If only a default value is found or not even that, external configuration
has a say. The configuration may contain an assignment for C.b2.a2.p;
it may apply the default if there is one; it may ask the user interactively
to enter a value; or if there is no default, it may raise an error
“no value for parameter”.
Type Name Resolution¶
Names from other NED files can be referred to either by fully qualified
name (“inet.networklayer.ip.RoutingTable”), or by short name
(“RoutingTable”) if the name is visible.
Visible names are:
inner types of the same type or its super types;
anything from the same package;
imported names.
Imports¶
Imports have a similar syntax to Java, but they are more flexible with wildcards. All of the following are legal:
import inet.networklayer.ipv4.RoutingTable;
import inet.networklayer.ipv4.*;
import inet.networklayer.ipv4.Ro*Ta*;
import inet.*.ipv4.*;
import inet.**.RoutingTable;
One asterisk stands for any character sequence not containing dots; and a double asterisk stands for any character sequence (which may contain dots). No other wildcards are recognized.
An import not containing a wildcard must match an existing NED type. However, it is legal for an import that does contain wildcards not to match any NED type (although that might generate a warning.)
Inner types may not be referenced outside their enclosing types and their subclasses.
Base Types and Submodules¶
Fully qualified names and simple names are accepted. Simple names are looked up among the inner types of the enclosing type (compound module), then using imports, then in the same package.
Network Name in the Ini File¶
The network name in the ini file may be given as a fully qualified name or as a simple (unqualified) name.
Simple (unqualified) names are tried with the same package as the ini file is in (provided it is in a NED directory).
Resolution of Parametric Types¶
This section describes the type resolution for submodules and connections
that are defined using the like keyword.
Type resolution is done in two steps. In the first step, the type name string expression is found and evaluated. Then in the second step, the resulting type name string is resolved to an actual NED type.
Step 1. The lookup of the type name string expression is similar to that of a parameter value lookup (Parameter Assignment Order).
The expression may be specified locally (between the angle brackets), or
using typename pattern assignments in any compound module that
contains the submodule or connection directly or indirectly. A
typename pattern is a pattern that ends in .typename.
Patterns are matched against the relative path of the submodule or
connection, with .typename appended. The relative path is
composed of a list of submodule names (name plus index) separated
by dots; a connection is identified by the full name of its source
gate plus the name of the channel object (which is currently always
channel) separated by a dot.
Note
As bidirectional connections are a shorthand for two unidirectional
connections, the source gate name is qualified with $i or
$o in the relative path.
An example that uses typename pattern assignment:
module Host {
submodules:
tcp: <> like ITCP;;
...
connections:
tcp.ipOut --> <> like IMyChannel --> ip.tcpIn;
}
network Network {
parameters:
host[*].tcp.typename = "TCP_lwIP";
host[*].tcp.ipOut.channel.typename = "DebugChannel";
submodules:
host[10] : Host;
...
}
The general rules are the following:
A (non-default) parameter assignment may not be overridden later; that is, if there are assignments in multiple places, the assignment “closest” to the submodule or connection definition will be effective; others will be flagged as errors.
A default value is only used if a non-default value is not present. A non-default value may also come from a source external to NED, namely the simulation configuration (
omnetpp.ini).Unlike non-default values, a default value may be overridden; that is, if there are default value assignments in multiple places, the assignment “farthest” from the submodule or connection definition will win.
Among pattern assignments within the same
parametersblock, the first match will win. Patterns assignments with default and non-default values are considered to be two disjoint sets, only one of which are searched at a time.
This yields the following conceptual search order for typename assignments:
First, the submodule or connection definition is checked (angle brackets);
Then the compound module that contains the submodule or connection is checked for matching pattern assignments;
Then, assuming the compound module is part of a network, the search for matching pattern assignments continues up on the module tree until the root (the module that represents the network). At each level (compound module), first the specific submodule definition is checked, then the (parent) compound module. If a compound module is subclassed before instantiated, the base type is checked first.
When no (non-default) assignment is found, the same places are searched in the reverse order for default value assignments. If no default value is found, an error may be raised or the user may be interactively prompted.
To illustrate the above rules, consider the following example:
module A { submodules: h: <> like IFoo; }
module A2 extends A {...}
module B { submodules: a2: A2 {...} }
module B2 extends B {...}
network C { submodules: b2: B2 {...} }
Here, the search order is: h, A, A2, a2, B, B2, b2, C. NED
conceptually searches the parameters blocks in that order for a
(non-default) value, and then in reverse order for a default value.
The full search order and the form of assignment expected on each level:
h: <...> like IFoo;A { h.typename = ...; }A2 { h.typename = ...; }a2 { h.typename = ...; }B { a2.h.typename = ...; }B2 { a2.h.typename = ...; }b2 { a2.h.typename = ...; }C { b2.a2.h.typename = ...; }C { b2.a2.h.typename = default(...); }b2 { a2.h.typename = default(...); }B2 { a2.h.typename = default(...); }B { a2.h.typename = default(...); }a2 { h.typename = default(...); }A2 { h.typename = default(...); }A { h.typename = default(...); }h: <default(...)> like IFoo;
If only a default value is found or not even that, external configuration
has a say. The configuration may contain an assignment for
C.b2.a2.h.typename; it may apply the default value if there is one;
it may ask the user interactively to enter a value; or if there is no
default value, it may raise an error “cannot determine submodule
type”.
Step 2. The type name string is expected to hold the simple name or fully qualified name of the desired NED type. Resolving the type name string to an actual NED type differs from normal type name lookups in that it ignores the imports in the file altogether. Instead, a list of NED types that have the given simple name or fully qualified name and implement the given interface is collected. The result must be exactly one module or channel type.
Implementing an Interface¶
A module type may implement one or more module interfaces, and a channel type
may implement one or more channel interfaces, using the like
keyword.
The module or channel type is required to have at least those parameters and gates that the interface has.
Regarding component properties, parameter properties and gate properties defined in the interface: the module or channel type is required to have at least the properties of the interface, with at least the same values. The component may have additional properties, and properties may add more keys and values.
Note
Implementing an interface does not cause the properties, parameters and gates to be interited by the module or channel type; they have to be added explicitly.
Note
A module or channel type may have extra properties, parameters and gates in addition to those in the interface.
Inheritance¶
Component inheritance is governed by the following rules:
A simple module may only extend a simple module.
A compound module may only extend a compound module or a simple module.
A channel may only extend a channel.
A module interface may only extend a module interface (or several module interfaces).
A channel interface may only extend a channel interface (or several channel interfaces).
A network is a shorthand for a compound module with the @isNetwork
property set, so the same rules apply to it as to compound modules.
Inheritance may:
add new properties, parameters, gates, inner types, submodules, connections, as long as names do not conflict with inherited names
modify inherited properties, and properties of inherited parameters and gates
it may not modify inherited submodules, connections and inner types
Other inheritance rules:
for inner types: new inner types can be added, but inherited ones cannot be changed
for properties: contents will be merged (rules like for display strings: values on same key and same position will overwrite old ones)
for parameters: type cannot be redefined; value may be redefined in subclasses or at place of usage
for gates: type cannot be redefined; vector size may be specified in subclasses or at place of usage if it was unspecified
for gate/parameter properties: extra properties can be added; existing properties can be overridden/extended as for standalone properties
for submodules: new submodules may be added, but inherited ones cannot be modified
for connections: new connections may be added, but inherited ones cannot be modified
The following sections will elaborate on the above rules.
Property Inheritance¶
Generally, properties may be modified via inheritance. Inheritance may:
add new keys
add/overwrite values for existing keys
remove a value from an existing key by using hyphen as a special value
Parameter Inheritance¶
Default values for parameters may be overridden in subclasses.
Gate Inheritance¶
Gate vector size may not be overridden in subclasses.
Network Build Order¶
When a network is instantiated for simulation, the module tree is built in a top-down preorder fashion. This means that starting from an empty system module, all submodules are created, their parameters and vector sizes are assigned, and they get fully connected before proceeding to go into the submodules to build their internals.
This implies that inside a compound module definition (including in submodules and connections), one can refer to the compound module’s parameters and gate sizes, because they are already built at the time of usage.
The same rules apply to compound or simple modules created dynamically during runtime.
Expressions¶
NED language expressions have a C-like syntax, with some
variations on operator names (see ^, #, ##).
Expressions may refer to module parameters, loop variables (inside connection
for loops), gate vector and module vector sizes, and other attributes
of the model. Expressions can also use built-in and user-defined functions.
There is a JSON-like notation for defining arrays and objects (dictionary-like).
Note
New NED functions can be defined in C++; refer to section Defining New NED Functions.
Constants¶
Refer to section Literals.
Array and Object Values¶
A bracketed list of zero or more comma-separated expressions denotes an
array value. For example: [9.81, false, "Hello"].
A list of zero or more comma-separated key-value pairs enclosed in a pair of curly braces
denotes an object value. A key and a value are separated by a colon. A key may be
a name or a string literal. A value may be an arbitrary expression, including a
list or an object. The open brace may be preceded by an (optionally namespace-qualified)
class name.
Example 1: {name:"John", age: 31}.
Example 2 (includes class name): Filter {dest:"10.0.0.1", port:1200}.
Array and object values may be assigned to parameters of type object.
Note that null / nullptr are also of type object.
Array values are represented with the C++ class cValueArray, and by default, object values with the C++ class cValueMap. If the object notation includes a class name, then the named C++ class will be used instead of cValueMap, and filled in using the key-value list with the help of the class descriptor (cClassDescriptor) of the class, interpreting keys as field names.
Operators¶
The following operators are supported (in order of decreasing precedence):
Operator |
Meaning |
|---|---|
|
unary minus, negation, bitwise complement |
|
power-of |
|
multiply, divide, integer modulo |
|
add, subtract, string concatenation |
|
bitwise shift |
|
bitwise and |
|
bitwise xor |
|
bitwise or |
|
string match |
|
three-way comparison, a.k.a. “spaceship operator” |
|
greater than, greater than or equal to |
|
less than, less than or equal to |
|
equal |
|
not equal |
|
logical operator and |
|
logical operator xor |
|
logical operator or |
|
the C/C++ “inline if” |
The spaceship operator is defined as follows. The result of a <=> b is negative
if a<b, zero if a==b, and positive if a>b. If either a or b is
nan (not-a-number), the result is nan as well.
The string match operator works as follows. x =~pattern
returns true if the string x matches the string pattern, and
false otherwise. The operator performs case-sensitive full-string match.
The pattern has the following syntax:
Asterisk
*matches zero or more of any character except dotDouble asterisk
**matches zero or more characters (including dot)Curly braces containing a numeric range match an embedded whole number in that range
Square brackets containing a numeric range match a number in that range enclosed in square brackets
A numeric range has the syntax of <start>..<end>, where both <start> and <end> are integers (optional)
The interpretation of other operators is similar to that in C/C++.
Conversions¶
Values may have the same types as NED parameters: boolean, integer, double,
string, XML element, and object. An integer or double value may have an
associated measurement unit (e.g., s, mW).
Double-to-integer conversions require explicit casting using the int()
function. There is no implicit conversion.
Integer-to-double conversion is implicit. However, a runtime error will be
raised if there is precision loss during the conversion, i.e., the integer is
too large to be precisely represented in a double. To suppress this error, an
explicit cast (double()) can be used.
There is no implicit conversion between boolean and numeric types. Thus, 0
is not a synonym for false, and nonzero numbers are not a synonym for
true.
There is also no conversion between string and numeric types. For example,
"foo"+5 is illegal. However, there are functions for converting a number
to a string and vice versa.
Bitwise operators expect integer arguments.
Note
Integers are represented with 64-bit signed integers (int64_t in C++).
Unit Handling¶
Operations involving numbers with units work as follows:
Addition, subtraction, and numeric comparisons require their arguments to have the same unit or compatible units. If the units are compatible, a unit conversion is performed before the operation. Incompatible units cause an error.
Modulo, power-of, and the bitwise operations require their arguments to be dimensionless. Otherwise, the result would depend on the choice of the unit.
Note
If a floating-point modulo operator that handles units is needed, the
fmod() function can be used.
Multiplying two numbers with units is not supported.
For division, dividing two numbers with units is only supported if the two units are convertible (i.e., the result will be dimensionless). Dividing a dimensionless number with a number with a unit is not supported.
Operations involving quantities with logarithmic units (e.g., dB, dBW) are not
supported, except for comparisons. The reason is that such operations would be
easy to misinterpret. For example, it is not obvious whether 10dB+10dB
(3.16+3.16) should evaluate to 20dB (=10.0) or to 16.02dB (=2*3.16=6.32),
considering that such quantities would often be hidden behind parameter names
where the unit is not obvious.
Referencing Parameters, Gates and Loop Variables¶
Expressions may refer to parameters, gates, and other submodules using the
this or the parent qualifier, or without a qualifier.
Unqualified identifiers refer to the parameters, gates or submodules of the
(nearest) block in which they are defined: the submodule or the module/channel.
In connection for loops, if an identifier matches a previously
defined loop variable, it refers to that loop variable.
Namely: [1]
- Outside submodule and connection blocks:
Unqualified identifiers refer to parameters, gates, and submodules of the compound module being defined.
- Inside submodule and connection blocks:
Unqualified identifiers refer to items of (or within) the local submodule or channel object, not to items of the enclosing compound module. To refer to the compound module’s items from within a submodule or connection block, use the
parentqualifier. To make references to the local submodule or channel explicit, use thethisqualifier.
Example demonstrating the semantics:
network Network {
parameters:
int foo;
submodules:
node1: { ... }
node2: Node {
foo = foo; // ERROR: self-reference! Change to 'foo = parent.foo'.
bar = this.foo; // OK: refers to node2.foo
baz = node1.foo; // ERROR: refers to yet-uncreated submodule this.node1!
bax = parent.node1.foo; // OK: refers to Network.node1.foo
}
}
Expressions may also refer to parameters of submodules defined earlier in the
NED file using the parent.submoduleName.paramName or
parent.submoduleName[index].paramName syntax from within a submodule block.
Note
Referencing a submodule’s submodule from NED (i.e., the a.b or
this.a.b syntax within a submodule block) is generally wrong, because the
network is built top-down and submodules are only created after parameters have
already been set up. An exception is using such references in the values of
volatile parameters, because they are evaluated later, at access time.
The typename Operator¶
The typename operator returns the NED type name as a string. If it
occurs inside a component definition but outside a submodule or channel block,
it returns the type name of the component being defined. If it occurs inside a
submodule or channel block, it returns the type name of that submodule or
channel.
The typename operator can also occur in the if condition
of a scalar submodule or connection. In such cases, it evaluates to the
would-be type name of the submodule or condition. This allows for
conditional instantiation of parametric-type submodules, controlled from a
typename assignment. (For example, by using the condition, one allows the submodule to be omitted by configuring
typename="" for it.)
The typename operator is not allowed in a submodule vector’s
if condition. The reason is that the condition applies to the vector
as a whole while the type is per-element.
The index Operator¶
The index operator is only allowed in a vector submodule’s body and
yields the index of the submodule instance.
The exists() Operator¶
The exists() operator is only accepted in compound module definitions.
It returns true if the specified item exists, and false
otherwise.
The operator accepts various forms of arguments:
exists(submoduleName)– checks if a (typically conditional) submodule existsexists(submoduleName[index])– checks if an element in a submodule vector exists (useful with submodule vectors that may contain holes due to@omittedTypename)exists(parent.submoduleName)– explicitly refers to the parent module’s submoduleexists(this.submoduleName)– checks for a submodule within the current submodule (generally only useful involatileparameter expressions)
The sizeof() Operator¶
The sizeof() operator expects one argument and is only accepted in
compound module definitions. It returns the size of a submodule vector or gate
vector. The usual scoping rules apply to the argument (see
Referencing Parameters, Gates and Loop Variables): use the
this and parent qualifiers to disambiguate.
In particular, to refer to the size of a sibling submodule’s gate vector, use
the sizeof(parent.submoduleName.gateVectorName) or
sizeof(parent.submoduleName[index].gateVectorName) syntax from within a
submodule block.
The expr() Operator¶
The expr() operator allows a mathematical formula or other expression
to be passed to a component as an object. expr() expects an
expression as an argument and returns an object that encapsulates the expression
in a parsed form. In the intended use case, the returned expression
object is assigned to a module parameter and is later utilized by user code (a
component implementation) by binding its free variables and evaluating it.
Identifiers in the expression are not interpreted as parameter references as in
NED but as free variables.
Functions¶
The functions available in NED are listed in Appendix Appendix: NED Functions.
Selected functions are documented below.
The xmldoc() Function¶
The xmldoc() NED function can be used to assign xml parameters,
that is, point them to XML files or to specific elements inside XML files.
xmldoc() accepts a file name as well as an optional second string argument
that contains an XPath-like expression.
The XPath expression is used to select an element within the document. If the expression matches several elements, the first element (in preorder depth-first traversal) will be selected (unlike XPath, which selects all matching nodes).
The expression syntax is as follows:
An expression consists of path components (or “steps”) separated by “
/” or “//”.A path component can be an element tag name, “
*”, “.”, or “..”.“
/” means child element (just like in/usr/bin/gcc), while “//” means an element at any level under the current element.“
.”, “..”, and “*” mean the current element, the parent element, and an element with any tag name, respectively.Element tag names and “
*” can have an optional predicate in the form “[position]” or “[@attribute=’value’]”. Positions start from zero.Predicates of the form “
[@attribute=``$param``]” are also accepted, where ``$param`` can be one of the following items:$MODULE_FULLPATH,$MODULE_FULLNAME,$MODULE_NAME,$MODULE_INDEX,$MODULE_ID,$PARENTMODULE_FULLPATH,$PARENTMODULE_FULLNAME,$PARENTMODULE_NAME,$PARENTMODULE_INDEX,$PARENTMODULE_ID,$GRANDPARENTMODULE_FULLPATH,$GRANDPARENTMODULE_FULLNAME,$GRANDPARENTMODULE_NAME,$GRANDPARENTMODULE_INDEX,$GRANDPARENTMODULE_ID.
The xml() Function¶
The xml() NED function can be used to parse a string as an
XML document and assign the result to an xml parameter.
xml() accepts the string to be parsed as well as an optional
second string argument that contains an XPath-like expression.
The XPath expression is used in the same manner as with the
xmldoc() function.
Units of Measurement¶
The following measurement units are recognized in constants. Other units can be
used as well, but there are no conversions available for them (i.e.,
parsec and kiloparsec will be treated as two completely unrelated
units).
Unit |
Name |
Value |
|---|---|---|
d |
day |
86400s |
h |
hour |
3600s |
min |
minute |
60s |
s |
second |
|
ms |
millisecond |
0.001s |
us |
microsecond |
1e-6s |
ns |
nanosecond |
1e-9s |
ps |
picosecond |
1e-12s |
fs |
femtosecond |
1e-15s |
as |
attosecond |
1e-18s |
bps |
bit/sec |
|
kbps |
kilobit/sec |
1000bps |
Mbps |
megabit/sec |
1e6bps |
Gbps |
gigabit/sec |
1e9bps |
Tbps |
terabit/sec |
1e12bps |
B |
byte |
8b |
KiB |
kibibyte |
8192b |
MiB |
mebibyte |
8.38861e6b |
GiB |
gibibyte |
8.58993e9b |
TiB |
tebibyte |
8.79609e12b |
kB |
kilobyte |
8000b |
MB |
megabyte |
8e6b |
GB |
gigabyte |
8e9b |
TB |
terabyte |
8e12b |
b |
bit |
|
Kib |
kibibit |
1024b |
Mib |
mebibit |
1.04858e6b |
Gib |
gibibit |
1.07374e9b |
Tib |
tebibit |
1.09951e12b |
kb |
kilobit |
1000b |
Mb |
megabit |
1e6b |
Gb |
gigabit |
1e9b |
Tb |
terabit |
1e12b |
rad |
radian |
|
deg |
degree |
0.0174533rad |
m |
meter |
|
dm |
decimeter |
0.1m |
cm |
centimeter |
0.01m |
mm |
millimeter |
0.001m |
um |
micrometer |
1e-6m |
nm |
nanometer |
1e-9m |
km |
kilometer |
1000m |
W |
watt |
|
mW |
milliwatt |
0.001W |
uW |
microwatt |
1e-6W |
nW |
nanowatt |
1e-9W |
pW |
picowatt |
1e-12W |
fW |
femtowatt |
1e-15W |
kW |
kilowatt |
1000W |
MW |
megawatt |
1e6W |
GW |
gigawatt |
1e9W |
Hz |
hertz |
|
kHz |
kilohertz |
1000Hz |
MHz |
megahertz |
1e6Hz |
GHz |
gigahertz |
1e9Hz |
THz |
terahertz |
1e12Hz |
kg |
kilogram |
|
g |
gram |
0.001kg |
t |
tonne |
1000kg |
K |
kelvin |
|
J |
joule |
|
kJ |
kilojoule |
1000J |
MJ |
megajoule |
1e6J |
Ws |
watt-second |
1J |
Wh |
watt-hour |
3600J |
kWh |
kilowatt-hour |
3.6e6J |
MWh |
megawatt-hour |
3.6e9J |
V |
volt |
|
kV |
kilovolt |
1000V |
mV |
millivolt |
0.001V |
A |
ampere |
|
mA |
milliampere |
0.001A |
uA |
microampere |
1e-6A |
Ohm |
ohm |
|
mOhm |
milliohm |
0.001Ohm |
kOhm |
kiloohm |
1000Ohm |
MOhm |
megaohm |
1e6Ohm |
mps |
meter/sec |
|
kmps |
kilometer/sec |
1000mps |
kmph |
kilometer/hour |
(1/3.6)mps |
C |
coulomb |
1As |
As |
ampere-second |
|
mAs |
milliampere-second |
0.001As |
Ah |
ampere-hour |
3600As |
mAh |
milliampere-hour |
3.6As |
x |
times |
|
dBW |
decibel-watt |
10*log10(W) |
dBm |
decibel-milliwatt |
10*log10(mW) |
dBmW |
decibel-milliwatt |
10*log10(mW) |
dBV |
decibel-volt |
20*log10(V) |
dBmV |
decibel-millivolt |
20*log10(mV) |
dBA |
decibel-ampere |
20*log10(A) |
dBmA |
decibel-milliampere |
20*log10(mA) |
dB |
decibel |