All machines in
[simics]\targets\
architecture use
components to create configurations. A component is typically the
smallest hardware unit that can be used when configuring a real
machine, and examples include motherboards, PCI cards, hard disks, and
backplanes. Components are usually implemented in Simics using several
configuration objects and can also contain subcomponents.
Components are intended to reduce the large configuration space provided by Simics's objects and attributes, by only allowing combinations that match real hardware. This greatly simplifies the creation of different systems by catching many misconfigurations.
Components themselves are also configuration objects in Simics. But to avoid confusion, they will always be referred to as components and the objects implementing the actual functionality will be called objects.
The component is the basic building block in the component system. When a component is created, it is in a non-instantiated state. At this stage only the component itself exists, not the configuration objects that will implement the actual functionality. Once a complete configuration has been created, all included components can be instantiated. When this happens, all objects are created and their attributes are set.
Components are connected to each other with connectors. Each connector has a connector type which tells what kind of connector it is and a direction, which can be up, down, or any. A connector is either required or optional. If it is optional it does not need to be connected to anything. Unless a connector is specified as hotpluggable it cannot be connected or disconnected after the component is instantiated. If a connection is hotpluggable it must be optional.
Connectors can be connected to each other in connections. Each connection connects an up connector with a down connector. A connection can also include an any connector. If an any connector is connected to an up connector it works exactly like a down connector and if it is connected to a down connector it works exactly like an up connector. The connections in the system must not form a cycle. You can think of the components and connections in the system as a directed acyclic graph with the components as the vertices and the connections as the edges.
Each connected subgraph in the set of components is called a component hierarchy.
A component A is said to be above a component B if it can be reached through up connectors in one or more steps from component B. Analogously, component A is said to be below a component B if B is above A.
A root is a component without any components above it. A component's roots are the roots which are above it.
A component where the top_level attribute returns true is a top-level component. It is often a motherboard, backplane or system chassis. It must be a root.
A standalone component is a component without any required connectors. A typical example is a hotplug device, such as a PC Card (PCMCIA) or an Ethernet link.
To instantiate a set of components, each component which is not standalone or top-level must have a top-level component as a root.
Components are also namespaces and can be nested in a namespace hierarchy, which is separate from the component hierarchy. The root of the hierarchy is the global namespace, and this is the only namespace which is not a component. Each configuration object (including components) lives in a namespace. The object is a child of the namespace and the namespace is the parent of the object. The other objects in the namespace are siblings of the object.
Components in Simics are grouped by machine architecture, or by type, into
several modules. Before a component can be used in Simics, the
corresponding component module has to be loaded. When the component module
is loaded, CLI commands for creating components are added to the front end. The
most common modules, that are not architecture specific, are
memory-comp
, pci-comp
, std-comp
,
console-components
. To import all modules that are used by
the QSP-Simple machine, issue the
following commands:
simics> load-module std-comp simics> load-module memory-comp simics> load-module console-components simics> load-module x58-ich10-comp simics> load-module x86-nehalem-comp
The create-<component> command is used to create non-instantiated components. There is one create command for each component class. The arguments to the create command represent attributes in the component. Standalone components can be created both non-instantiated and instantiated. To create instantiated components, there are new- commands, similar to the create- commands.
The following code creates a non-instantiated 'motherboard_x58_ich10' component , called 'motherboard0'
simics> load-module x58-ich10-comp simics> create-motherboard-x58-ich10 Created non-instantiated 'motherboard_x58_ich10' component 'motherboard0'
A connector provides a means for a component to connect to other components. Connectors have a defined direction: up, down, or any. The direction is up if it needs an existing hierarchy to connect to; for example, the PCI-bus connector in a PCI device must connect to a PCI slot. A connector has a down direction if it extends the hierarchy downwards; for example, a PCI slot is a connection downward from a board to a PCI device. There are also non-directed connectors, with direction any. You can only connect an up to a down connector or to an any connector, and similar for down connectors. Connectors with the any direction can not be connected together.
Many connectors have to be connected before the component is instantiated, while others can be empty. A standalone component, as described above, may have all connectors empty.
A hotplug connector supports connect and disconnect after instantiation. Other connectors can only be connected, or left unconnected, when the configuration is created and may not be modified after that point. A multi connector supports connections to several other connectors. Creating multi connectors should be avoided, it is often better to dynamically create non-multi connectors when new connectors are needed.
It is not possible to connect instantiated components with non-instantiated ones. The reason is that the instantiated component expects the other to have all objects already created, and need to access some of them to finish the connection.
The info command of a component lists all connectors and some information about them:
simics> motherboard0.info Information about motherboard0 [class motherboard_x58_ich10] ============================================================ Slots: dimm[0] : motherboard0.dimm[0] dimm[1] : motherboard0.dimm[1] dimm[2] : motherboard0.dimm[2] dimm[3] : motherboard0.dimm[3] nb : motherboard0.nb reset_bus : motherboard0.reset_bus sb : motherboard0.sb socket[0] : motherboard0.socket[0] socket[1] : motherboard0.socket[1] socket[2] : motherboard0.socket[2] socket[3] : motherboard0.socket[3] socket[4] : motherboard0.socket[4] socket[5] : motherboard0.socket[5] socket[6] : motherboard0.socket[6] socket[7] : motherboard0.socket[7] Connectors: dimm[0] : mem-bus down dimm[1] : mem-bus down dimm[2] : mem-bus down dimm[3] : mem-bus down reset_bus : x86-reset-bus down socket[0] : x86-apic-processor down socket[1] : x86-apic-processor down socket[2] : x86-apic-processor down socket[3] : x86-apic-processor down socket[4] : x86-apic-processor down socket[5] : x86-apic-processor down socket[6] : x86-apic-processor down socket[7] : x86-apic-processor down
The board has four slots for memory modules, one north bridge, one reset bus, one south bridge, eight sockets. All slots are not listed as hotplug since they have to be inserted when the machine is configured initially.
Since the machine need a cpu, we also add a x86QSP1 processor to our example. A CLI variable is used to hold the name of the processor component.
simics> load-module x86-nehalem-comp simics> $cpu = (create-processor-x86QSP1 freq_mhz = 2000) simics> connect motherboard0.socket[0] $cpu.socket
To enable input and output for the simulated machine, the following commands
create a serial text console and connect it to the serial[0]
connector
of the south bridge.
simics> load-module console-components simics> connect motherboard0.sb.serial[0] (create-txt-console-comp).serial
Since the machine needs some memory to run, we also add a memory module to our example. A CLI variable is used to hold the name of the memory component.
simics> load-module memory-comp simics> $dimm = (create-simple-memory-module memory_megs = 2048) simics> connect motherboard0.dimm[0] $dimm.mem_bus
When a component hierarchy has been created, it can be instantiated using the instantiate-components command. This command will look for all non-instantiated top-level components and instantiate all components below them. The instantiate-components command can also be given a specific component as argument. Then only that component will be instantiated, including its hierarchy if it is a top-level component.
simics> instantiate-components
If there are unconnected connectors left that may not be empty, the command will return with an error.
When the instantiation is ready, all object and attributes have been created and initialized. In our example, a text console window should have opened. The hardware of the simulated motherboard is now properly configured, but since no software is loaded, it will not show any output on the console if the machine is started.
The list-components command prints a list of all components in the system. All connectors are included, and information about existing connections between them.
The info namespace command provides static information about a component, such as the slots and a list of connectors.
The status namespace command provides dynamic information about a component, such as attribute values and a list of all current connections. The output from status in the example:
simics> motherboard0.status Status of motherboard0 [class motherboard_x58_ich10] ==================================================== Setup: Top component : none Instantiated : True Attributes: acpi : True bios : break_on_reboot : False mac_address : 20:20:20:20:20:20 rtc_time : 2008-06-05 23:52:01 spi_flash : system_clock : False system_clock_class : clock Connections: dimm[0] : dimm0:mem_bus socket[0] : processor0:socket
When doing more advanced configuration of a machine, it may be necessary to access configuration objects and their attributes directly. Each object in a component has a slot name that can be used for accessing the object. A list of slot names, and their mappings to actual configuration object names, is available from the output of the component's info command. The next example prints the frequency attribute from the core object.
simics> processor0.core[0][0]->frequency [20000000, 1]
Accessing objects of non-instantiated components is not possible, since
they do not have any associated configuration objects. But it is
possible to access the pre_conf_object
s of a
non-instantiated component from Python. The following
example works both for instantiated and non-instantiated components:
simics> @print(conf.processor0.core[0][0].cpuid_stepping) 8
Remember that not all configuration object attributes are available on a
pre_conf_object
. Only attributes that have been assigned by
the component during initialization exists.
The Target Guide for each architecture lists and describes all components that are available.