The topology of any module contains two parts:
Example:
DEFINE_DEVICE_INSTANCES:
processor_A = MC6830
processor_B = MC6830
END_DEFINE_DEVICE_INSTANCES.
DEFINE_TOPOLOGY:
/* src-proc / port to dest-proc / port dir q-lngth rate ovrhd */
processor_A ioprt processor_B ioprt hdplx 1 20.0 10.0
END_DEFINE_TOPOLOGY.
DEFINE_DEVICE_INSTANCES:
proc1 = iWARP
proc2 = iWARP
controller = MC6830
END_DEFINE_DEVICE_INSTANCES.
The connection list consists of 8 columns. The first four columns on each line contain a processor and port connection pair (ie. processor_1 port_x to processor_2 port_y). The processor names given must match those instantiated in the instantiation section (2).
The port names may be arbitrarily chosen, but become defined here for later reference by the behavior code in section (3).
All connections are point-to-point and must be unique. A common bus structure may be defined as a special device with multiple ports in which any incoming message is distributed to all ports.
The fifth column must contain either the keyword "smplx", "hdplx", or "fdplx", depending on whether the links are simplex, half-duplex, or full-duplex. In simplex mode, messages may travel in only one direction, namely only from the first to second device. In half-duplex mode, messages may travel in either direction, but only in one direction at a time. In full-duplex mode, messages may flow in both directions simultaneously, and the ports are treated as two separate simplex ports that run in opposite directions. In other words, simplex links are "uni"-directional, while half- duplex and full-duplex links are two types of bi-directional links.
The sixth column indicates the maximum queue length of the communications link. The queue length must be an integer greater than or equal to 1. It signifies the maximum number messages which may be queued up on a port before further send operations are blocked. A queue depth of "1" indicates that a sending device will be blocked if tries to write a new message to a port on which the previous message has not yet been read by the receiving device. If blocked, operation will resume whenever the message is read. A queue length of "2" allows two messages to be enqueued before blocking, etc. If you never want blocking in your model, then use a very huge number. The queue length is critical in issues of processor synchronization and memory buffer space.
The seventh column specifies the link data rate in terms of message length units per time unit. Each message has a length which is specified in each SEND operation. For instance, if the time units are defined to be uSec, the message length units are bytes, and the data rate of the link being modeled is 10-MB/s, the rate entry in the topology table would be 10e6 B/s * 1e-6 s/us = 10.0 B/us.
The eighth column is the fixed communication overhead time delay that a message should experience in transitting the link. This time delay is added to all message transfers regardless of message size.
The topological section is closed by the keyword "END_DEFINE_TOPOLOGY.".
The "*" serves as a wild-card or infinite speed attribute. In the first case above, consider a module with a link having a "*" attribute that connects to a link on another hierarchical module which has a finite literal value. The link attribute will then resolve to the finite value. It will not be considered a mismatch. In the second case above, any link attribute that does not resolve to a non-"*" value, will take on:
An example of a simple topology is shown below:
DEFINE_TOPOLOGY:
/* src-proc/port to dest-proc/port dir q-lngth rate fixd-ovrhd */
proc1 port_x proc3 port_z smplx 1 20.0 10.0
shmem d5 p10 y_data fdplx 3 10.0 5.0
sensor i1 shmem d0 hdplx 10 10.0 5.0
END_DEFINE_TOPOLOGY.
Note: This topological specification style makes it easy to build an automatic
topology generator for regular topologies such as meshes, grids, etc.,
that can later be manually modified as needed.
Hierarchical topologies may be specified by defining the interconnection of modules. Modules may consist of devices and other modules. Each module definition contains a miniature "DEFINE_DEVICE_INSTANCES" section and a "DEFINE_TOPOLOGY" section, just like in the overall description. However, these sections are both enclosed by a common "DEFINE_MODULE" / "END_DEFINE_MODULE" keyword block. In the outer levels, the module names are used just like device names.
Example module definition:
DEFINE_MODULE: Double_node
DEFINE_DEVICE_INSTANCES:
proc1 = Pentium
proc2 = RS6000
xbar = Crossbar
END_DEFINE_DEVICE_INSTANCES.
DEFINE_TOPOLOGY:
proc1 io_port xbar p1 hdplx 1 20.0 1.0
proc2 io_port xbar p2 hdplx 1 20.0 1.0
xbar p3 Double_node Ext_IO_prt * * * *
END_DEFINE_TOPOLOGY.
END_DEFINE_MODULE.
DEFINE_MODULE: top_level
DEFINE_DEVICE_INSTANCES:
Dual1 = Double_node
Dual2 = Double_node
END_DEFINE_DEVICE_INSTANCES.
DEFINE_TOPOLOGY:
Dual1 Ext_IO_prt Dual2 Ext_IO_prt fdplx 1 20 1.0
END_DEFINE_TOPOLOGY.
END_DEFINE_MODULE.
Figure A1 below, shows the diagram of the example topology corresponding to the text above.
The device naming during simulation takes on a hierarchical "module/module/ device" syntax so that all devices in the system are uniquely identified. For example: /Dual1/proc1.
All ports that are not interconnected to other devices within the module being defined are considered to be external ports, and are thus connected to the module boundary itself. The direction, queue-length, rate, and overhead attributes of inter-module links are ignored. However, these attributes must match accordingly when resolved down to their ultimate device-device connections.
Modules must be instantiated at the outer level in order to be instantiated in the simulation. Otherwise, everything within them does not exist. Modules must be defined before they are referenced. A module cannot reference (contain) itself. These rules avoid infinite recursion.
Ports which are not connected to anything can be explicitly connected to "DEV_NULL" to avoid warning messages about unconnected ports during preprocessing. The default device "DEV_NULL" has two port types: "NC" and "null". "NC" stands for not connected, and will give a runtime error if a device tries to write or read from such a port. "null" is essentially a "bit bucket", and it will absorb anything written to it during the simulation. Reads will simply never return.

(Questions, Comments, & Suggestions: chein@atl.lmco.com)