|Home > Iris overview > Interfaces and communication|
The following diagram provides an overview of the Iris interfaces:
An Iris system consists of the following:
The simulator executable can be implemented using C or C++, SystemC, Gem5, or Fast Models. It can be a standalone executable or a DSO.
The term Iris instance, or just instance, refers to an entity that can send and receive Iris function calls. This includes all components, plug-ins, clients, for example debuggers, and framework entities, for example the global instance. All Iris instances can send and receive Iris function calls to and from all other instances. In Figure 1-1 Iris architecture, Iris instances are shown by boxes with a bold outline.
This is the central routing instance between all Iris instances. The global instance registry records all Iris instances in the system. All Iris instances must register and unregister themselves in the instance registry, and they can use it to query a list of all other instances.
TCP server that is provided by IrisSupportLib and runs as part of the simulator executable. It listens for connections from TCP clients, typically an
IrisTcpClient. It transparently forwards function calls and responses. It does not explicitly support Iris functions, so extending the Iris interface, for example by adding functions or arguments, or adding new data structures, does not require any changes to the
IrisInterface communication trivially
maps onto a TCP socket because it is inherently
split between request and response, and because
function calls and responses are data only. This
data is transmitted almost unchanged over TCP
between clients and servers.
A proprietary binary variant of
JSON, which is JSON-compatible. It is based on
and is optimized for speed, not size. It removes
the runtime overhead of JSON parsing and data
conversion. It is used in-process and is one of
many options for out-of-process, or IPC
An in-process, generic mechanism
that transports Iris function calls, including
callbacks and responses. In-process function calls
and responses are made according to the JSON RPC
2.0 specification and are encoded in U64JSON.
Instance implementations usually use a helper
IrisInstance, which hides the internals
Implements all necessary boilerplate code to provide debuggers and components with easy access to Iris functions. IrisSupportLib provides implementations for C++ and Python. For example, it provides:
TCP client that is provided by IrisSupportLib. As with the
IrisTcpServer, extending the Iris interface does not require any changes to the
IrisTcpClient. Using the
IrisTcpClient to connect to the
IrisTcpServer is not mandatory, but is convenient. A client application, for example a debugger, typically uses an
IrisInstance connected to an
IrisTcpClient to connect to an Iris server running in the model process.
The protocol that is used over TCP and the format and semantics of all Iris functions are defined and public. In Figure 1-1 Iris architecture, they are shown by dashed lines.
A C++ client application that uses IrisSupportLib, built from source. It can call Iris functions directly from C++ and can update the IrisSupportLib source at any time. An update is not mandatory after the simulator executable has updated any part of the system. Clients and simulators can update at different times. There are no shared header files, but both sides must follow the Iris specification to be compatible.
The same as
written in Python.
These plug-ins use
communicate with the rest of the system. There is
no difference between a plug-in and a client that
is connected using IPC in how they call and are
called by Iris functions, except for the plug-in
loading mechanism and speed considerations.
Components written in C++, LISA, or SystemC, that model hardware or perform other simulation functionality. They use
IrisInstance to avoid being exposed to the internals of the function call mechanism, and to use infrastructure that is common to a lot of components, for example meta information for registers and memory spaces. Internally in the
IrisInstance, they send and receive U64JSON-encoded Iris function calls through the low-level
IrisC API. They might buffer these function calls in an event queue. Later on, and typically from another thread, they send the response back to the
IrisInterface of the global instance.
Iris function calls are transported using the following mechanisms:
In-process. The transport is the
IrisC interface on DSO boundaries and the C++
IrisInterface inside DSOs. The Iris interface is bi-directional so it can send function calls and responses in both directions.
IrisInterface only supports U64JSON directly, but adapters exist to enable function calls from C++ and Python directly, or to use other formats, for example JSON. The in-process mechanism is used whenever possible, typically by:
IrisTcpServerto communicate with component instances and with the global instance.
Inter Process Communication (IPC). The transport is a TCP socket. Usually the simulation contains a TCP server which listens for inbound connections. Iris calls and their responses are sent in both directions across the same TCP socket. The TCP connection is persistent.
Various formats can be used across the TCP connection, including U64JSON and JSON. IPC is used only if necessary, typically by IPC clients, for example debuggers, shells, and IPC plug-ins, to communicate with component instances, the global instance, plug-ins, or even other clients.