[Prev] [Next] [TOC] [Chapters]

19 Appendix A: NED Reference

19.1 Syntax

19.1.1 NED File Name Extension

NED files have the .ned file name suffix. This is mandatory, and cannot be overridden.

19.1.2 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.

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.

19.1.3 Reserved Words

NED file authors have to take care that no reserved words are used as identifiers. The reserved words of the NED language are:

allowunconnected bool channel channelinterface connections const default double extends false for gates if import index inf inout input int like module moduleinterface nan network output package parameters property simple sizeof string submodules this true typename types volatile xml xmldoc

19.1.4 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).

19.1.5 Case Sensitivity

Keywords and identifiers in the NED language are case sensitive. For example, TCP and Tcp are two different names.

19.1.6 Literals

19.1.6.1 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.

19.1.6.2 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.

19.1.6.3 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 [19.5.9] 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.

19.1.7 Comments

Comments can be placed at the end of lines. Comments begin with a double slash //, and continue until the end of the line.

19.1.8 Grammar

The grammar of the NED language can be found in Appendix [20].

19.2 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.

package ned;
@namespace("");

channel IdealChannel
{
    @class(cIdealChannel);
}

channel DelayChannel
{
    @class(cDelayChannel);
    @signal[messageSent](type=cMessage);
    @signal[messageDiscarded](type=cMessage);
    @statistic[messages](...);
    @statistic[messagesDiscarded](...);
    bool disabled = default(false);
    double delay = default(0s) @unit(s); // propagation delay
}

channel DatarateChannel
{
    @class(cDatarateChannel);
    @signal[channelBusy](type=long);
    @signal[messageSent](type=cMessage);
    @signal[messageDiscarded](type=cMessage);
    @statistic[busy](...);
    @statistic[utilization](...);
    @statistic[packets](...);
    @statistic[packetBytes](...);
    @statistic[packetsDiscarded](...);
    @statistic[throughput](...);
    bool disabled = default(false);
    double delay = default(0s) @unit(s); // propagation delay
    double datarate = default(0bps) @unit(bps); // bits per second; 0=infinite
    double ber = default(0); // bit error rate (BER)
    double per = default(0); // packet error rate (PER)
}

moduleinterface IBidirectionalChannel
{
    gates:
        inout a;
        inout b;
}

moduleinterface IUnidirectionalChannel
{
    gates:
        input i;
        output o;
}

19.3 Packages

NED supports hierarchical namespaces called packages. The model is similar to Java packages, with minor changes.

19.3.1 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.

19.3.2 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.

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.

19.4 Components

Simple modules, compound modules, networks, channels, module interfaces and channel interfaces are called components.

19.4.1 Simple Modules

Simple module types are declared with the simple keyword; see the NED Grammar (Appendix [20]) for the syntax.

Simple modules may have properties ([19.4.8]), parameters ([19.4.9]) and gates ([19.4.11]).

A simple module type may not have inner types ([19.4.15]).

A simple module type may extend another simple module type, and may implement one or more module interfaces ([19.4.5]). Inheritance rules are described in section [19.4.21], and interface implementation rules in section [19.4.20].

Every simple module type has an associated C++ class, which must be subclassed from cSimpleModule. The way of associating the NED type with the C++ class is described in section [19.4.7].

19.4.2 Compound Modules

Compound module types are declared with the module keyword; see the NED Grammar (Appendix [20]) for the syntax.

A compound module may have properties ([19.4.8]), parameters ([19.4.9]), and gates ([19.4.11]); its internal structure is defined by its submodules ([19.4.12]) and connections ([19.4.13]); and it may also have inner types ([19.4.15]) 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 ([19.4.5]). Inheritance rules are described in section [19.4.21], and interface implementation rules in section [19.4.20].

19.4.3 Networks

19.4.3.1 The network Keyword

A network declared with the network keyword is equivalent to a compound module (module keyword) with the @isNetwork(true) property.

19.4.3.2 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.

19.4.4 Channels

Channel types are declared with the channel keyword; see the NED Grammar (Appendix [20]) for the syntax.

Channel types may have properties ([19.4.8]) and parameters ([19.4.9]).

A channel type may not have inner types ([19.4.15]).

A channel type may extend another channel type, and may implement one or more channel interfaces ([19.4.6]). Inheritance rules are described in section [19.4.21], and interface implementation rules in section [19.4.20].

Every channel type has an associated C++ class, which must be subclassed from cChannel. The way of associating the NED type with the C++ class is described in section [19.4.7].

The @defaultname property of a channel type determines the default name of the channel object when used in a connection.

19.4.5 Module Interfaces

Module interface types are declared with the moduleinterface keyword; see the NED Grammar (Appendix [20]) for the syntax.

Module interfaces may have properties ([19.4.8]), parameters ([19.4.9]), and gates ([19.4.11]). However, parameters are not allowed to have a value assigned, not even a default value.

A module interface type may not have inner types ([19.4.15]).

A module interface type may extend one or more other module interface types. Inheritance rules are described in section [19.4.21].

19.4.6 Channel Interfaces

Channel interface types are declared with the channelinterface keyword; see the NED Grammar (Appendix [20]) for the syntax.

Channel interfaces may have properties ([19.4.8]) and parameters ([19.4.9]). However, parameters are not allowed to have a value assigned, not even a default value.

A channel interface type may not have inner types ([19.4.15]).

A channel interface type may extend one or more other channel interface types. Inheritance rules are described in section [19.4.21].

19.4.7 Resolving the C++ Implementation Class

The procedure for determining the C++ implementation class for simple modules and for channels are identical. It goes as follows (we are going to say component instead of “simple module or channel”):

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.

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.

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.

19.4.7.1 Current Namespace

The current namespace is the value of the first @namespace property found while searching the following order:

  1. the current NED file
  2. the package.ned file in the current package or the first ancestor package searching upwards

The @namespace property should contain a single value.

19.4.8 Properties

Properties are a means of adding metadata annotations to NED files, component types, parameters, gates, submodules, and connections.

19.4.8.1 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 index, one with the index index1, and a third with the index index2.

@prop1();
@prop2[index1]();
@prop3[index2]();

19.4.8.2 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 of the properties use the default key with one value. Examples:

@namespace(inet);
@class(Foo);
@unit(s);

Property values have a liberal syntax (see Appendix [20]). 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 [19.1.6]).

Example:

@prop(marks=the ! mark, "the , mark", "the ; mark", other marks); // 4 items

19.4.8.3 Placement

Properties may be added to NED files, component types, parameters, gates, submodules and connections. For the exact syntax, see Appendix [20].

When a component type extends another component type(s), properties are merged. This is described in section [19.4.21].

19.4.8.4 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.

19.4.9 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 change in the meaning.

The parameters section may also hold pattern assignments ([19.4.10]) and properties ([19.4.8]).

A parameter is identified by a name, and has a data type. A parameter may have value or default value, and may also have properties (see [19.4.8]).

Accepted parameter data types are double, int, string, bool, and xml. 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 [19.5].

For volatile parameters, the value expression is evaluated every time the parameter value is accessed. Non-volatile parameters are evaluated only once.

The following properties are recognized for parameters: @unit, @prompt.

19.4.9.1 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.

19.4.9.2 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
}

19.4.10 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 accomodate 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:

  1. Asterisks: They match zero or more characters except dots.
  2. 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.
  3. 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.
  4. 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 [20]) 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, ...

19.4.11 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 [19.4.8]).

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 [19.5].

See the Connections section ([19.4.13]) for more information on gates.

19.4.11.1 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 [19.4.13]).

@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.

Example:

gates:
    input radioIn @directIn;

19.4.12 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

19.4.12.1 Submodule Type

The simple or compound module type ([19.4.1], [19.4.2]) that will be instantiated as the submodule may be specified either statically (with a concrete module type name) or parametrically.

19.4.12.2 Static Submodule Type

Submodules with a statically defined type are those that contain a concrete NED module type name. Example:

tcp : TCP;

See section [19.4.18] for the type resolution rules.

19.4.12.3 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 [19.4.5] 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 [20]) for the formal syntax, and section [19.4.19] for the type resolution rules.

19.4.12.4 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 { ... }

19.4.12.5 Parameters, Gates

A submodule body may contain parameters ([19.4.9]) and gates ([19.4.5]).

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.

19.4.13 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.

Connections may be conditional, and may be created using loops (see [19.4.14]).

19.4.13.1 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

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 [19.4.4]) 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.

19.4.13.2 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.go --> b.gi;
a.gi <-- b.go;

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.

19.4.13.3 Specifying Channels

A channel specification associates a channel object with the connection. A channel object is an instance of a channel type (see [19.4.4]).

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.

19.4.13.4 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:

  1. When no parameters are set, ned.IdealChannel is chosen.
  2. When only ned.DelayChannel parameters are used (delay and disabled), ned.DelayChannel is chosen.
  3. When only ned.DatarateChannel parameters are used (datarate, delay, ber, per, disabled), the chosen channel type will be ned.DatarateChannel.

Connections with implicit channel types may not use any other parameter.

19.4.13.5 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 [19.4.18] for the type resolution rules.

19.4.13.6 Parametric Channel Type

Parametric channel types are similar to parametric submodule types, described in section [19.4.12].

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 [19.4.6] 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 [20]) for the formal syntax, and section [19.4.19] for the type resolution rules.

19.4.13.7 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 ([19.4.9]).

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.

19.4.14 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 ([20]) 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;
}

19.4.15 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.

19.4.16 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:

For example, a gate and a submodule cannot have the same name.

19.4.17 Parameter Assignment Order

A module or channel parameter may be assigned in parameters blocks (see [19.4.9]) 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 [19.4.10]) 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 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:

  1. 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.
  2. 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).
  3. 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.
  4. Among pattern assignments within the same parameters block, 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:

  1. First, the NED type that contains the parameter declaration is checked;
  2. Then its subclasses are checked;
  3. Then the submodule or connection that instantiates the type is checked;
  4. Then the compound module that contains the submodule or connection is checked for matching pattern assignments;
  5. 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:

  1. A { p = ...; }
  2. A2 { p = ...; }
  3. a2 { p = ...; }
  4. B { a2.p = ...; }
  5. B2 { a2.p = ...; }
  6. b2 { a2.p = ...; }
  7. C { b2.a2.p = ...; }
  8. C { b2.a2.p = default(...); }
  9. b2 { a2.p = default(...); }
  10. B2 { a2.p = default(...); }
  11. B { a2.p = default(...); }
  12. a2 { p = default(...); }
  13. A2 { p = default(...); }
  14. 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”.

19.4.18 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:

19.4.18.1 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.

19.4.18.2 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.

19.4.18.3 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).

19.4.19 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 ([19.4.17]).

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.

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:

  1. 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.
  2. 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).
  3. 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.
  4. Among pattern assignments within the same parameters block, 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:

  1. First, the submodule or connection definition is checked (angle brackets);
  2. Then the compound module that contains the submodule or connection is checked for matching pattern assignments;
  3. 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:

  1. h: <...> like IFoo;
  2. A { h.typename = ...; }
  3. A2 { h.typename = ...; }
  4. a2 { h.typename = ...; }
  5. B { a2.h.typename = ...; }
  6. B2 { a2.h.typename = ...; }
  7. b2 { a2.h.typename = ...; }
  8. C { b2.a2.h.typename = ...; }
  9. C { b2.a2.h.typename = default(...); }
  10. b2 { a2.h.typename = default(...); }
  11. B2 { a2.h.typename = default(...); }
  12. B { a2.h.typename = default(...); }
  13. a2 { h.typename = default(...); }
  14. A2 { h.typename = default(...); }
  15. A { h.typename = default(...); }
  16. 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.

19.4.20 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.

19.4.21 Inheritance

Component inheritance is governed by the following rules:

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:

Other inheritance rules:

The following sections will elaborate on the above rules.

19.4.21.1 Property Inheritance

Generally, properties may be modified via inheritance. Inheritance may:

19.4.21.2 Parameter Inheritance

Default values for parameters may be overridden in subclasses.

19.4.21.3 Gate Inheritance

Gate vector size may not be overridden in subclasses.

19.4.22 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.

19.5 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 use built-in and user-defined functions as well.

19.5.1 Constants

See section [19.1.6].

19.5.2 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, or, xor
== equal
!= not equal
>, >= greater than, greater than or equal to
<, <= less than, less than or equal to
&&, ||, ## logical operators and, or, xor
?: the C/C++ “inline if”

19.5.2.1 Conversions

Values may have the same types as NED parameters: boolean, integer, double, string, or XML element. An integer or double value may have an associated measurement unit (s, mW, etc.)

Double-to-integer conversions require explicit cast using the int() function, there is no implicit conversion.

Integer-to-double converson is implicit. However, a runtime error will be raised if there is precision loss during the conversion, i.e. the integer is so large that it cannot be precisely represented in a double. That error can be suppressed by using an explicit cast (double().

There is no implicit conversion between boolean and numeric types, so 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, so e.g. "foo"+5 is illegal. There are functions for converting a number to string and vice versa.

Bitwise operators expect integer arguments.

19.5.2.2 Unit Handling

Operations involving numbers with units work in the following way:

Addition, subtraction, and numeric comparisons require their arguments to have the same unit or compatible units; in the latter case 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.

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 unit is not supported.

Operations involving quantities with logarithmic units (dB, dBW, etc.) 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.)

19.5.3 Referencing Parameters and Loop Variables

Identifiers in expressions occurring anywhere in component definitions are interpreted as referring to parameters of the given component. For example, identifiers inside submodule bodies refer to the parameters of the compound module.

Expressions may also refer to parameters of submodules defined earlier in the NED file, using the submoduleName.paramName or the submoduleName[index].paramName syntax. To refer to parameters of the local submodule inside a submodule body, use the this qualifier: this.destAddress.

Exception: if an identifier occurs in a connection for loop and names a previously defined loop variable, then it is understood as referring to the loop variable.

19.5.4 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 may 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 if typename!="" condition, one allows the submodule to be omitted by configuring typename="" for it.

typename is not allowed in a submodule vector's if condition. The reason is that the condition applies to the vector as a whole, while type is per-element.

19.5.5 The index Operator

The index operator is only allowed in a vector submodule's body, and yields the index of the submodule instance.

19.5.6 The exists() Operator

The exists() operator takes one identifier as argument, and it is only accepted in compound module definitions. The identifier must name a previously defined submodule, which will typically be a conditional submodule. The operator returns true if given submodule exists (has been created), and false otherwise.

19.5.7 The sizeof() Operator

The sizeof() operator expects one argument, and it is only accepted in compound module definitions.

The sizeof(identifier) syntax occurring anywhere in a compound module yields the size of the named submodule or gate vector of the compound module.

Inside submodule bodies, the size of a gate vector of the same submodule can be referred to with the this qualifier: sizeof(this.out).

To refer to the size of a submodule's gate vector defined earlier in the NED file, use the sizeof(submoduleName.gateVectorName) or sizeof(submoduleName[index].gateVectorName) syntax.

19.5.8 Functions

The functions available in NED are listed in Appendix [22].

Selected functions are documented below.

19.5.8.1 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. (This is unlike XPath, which selects all matching nodes.)

The expression syntax is the following:

19.5.8.2 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.

19.5.9 Units of Measurement

The following measurements 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
s second
d day 86400s
h hour 3600s
min minute 60s
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 1024B
MiB mebibyte 1.04858e6B
GiB gibibyte 1.07374e9B
TiB tebibyte 1.09951e12B
kB kilobyte 1000B
MB megabyte 1e6B
GB gigabyte 1e9B
TB terabyte 1e12B
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
mm millimeter 0.001m
cm centimeter 0.01m
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
K kelvin
J joule
kJ kilojoule 1000J
MJ megajoule 1e6J
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
As ampere-second 1C
mAs milliampere-second 0.001C
Ah ampere-hour 3600C
mAh milliampere-hour 3.6C
ratio ratio
pct percent 0.01ratio
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 20*log10(ratio)



[Prev] [Next] [TOC] [Chapters]