Previous - Up - Next

6.4   Components

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.

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.

6.4.1   Component Definitions

All machines are based on a top-level component. The top-level component is the root of the component hierarchy and is often a motherboard, backplane, or system chassis.

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.

A standalone component is a component that can be instantiated without being connected to a component hierarchy. A typical example is a hotplug device, such as a PC Card (PCMCIA) or an Ethernet link.

6.4.2   Importing Component Commands
Components in Simics are grouped by machine architecture, or by type, into several collections. Before a component can be used in Simics, the corresponding component collection has to be imported. What the import actually does, is to add CLI commands for creating components in the collection. The most common collections, that are not architecture specific, are memory, pci, std and timing. To import all collections that are used by the Ebony machine for example, issue the following commands:
simics> import-pci-components
simics> import-std-components
simics> import-memory-components
simics> import-ppc440gp-components
6.4.3   Creating Components

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 'ebony-board' component representing an Ebony Reference Board, called 'board'

simics> (create-ebony-board board cpu_frequency = 100
.......                           mac_address0 = "00:04:ac:00:50:00"
.......                           mac_address1 = "00:04:ac:00:50:01"
.......                           rtc_time = "2003-09-03 11:17:00 UTC")
The parentheses are needed to allow multi-line input. The command arguments set the processor frequency, the MAC addresses of the on-board network adapters, and the time and date of the real-time clock.

In multi machine configurations it is often useful to separate objects from the different machines by name. The command set-component-prefix str causes all following create- commands to prefix all created object names—including the names of the components themselves—with the string str.

6.4.4   Connectors

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. A typical example of a hotplug multi connector is the Ethernet link.

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:

Information about board [class ebony-board]

Implementing objects:

                     ddr-slot0 : mem-bus              down
                     ddr-slot1 : mem-bus              down
                         emac0 : ethernet-link        down  hotplug
                         emac1 : ethernet-link        down  hotplug
                     pci-slot0 : pci-bus              down
                     pci-slot1 : pci-bus              down
                     pci-slot2 : pci-bus              down
                     pci-slot3 : pci-bus              down
                         uart0 : serial               down  hotplug
                         uart1 : serial               down  hotplug
Since the component in the example isn't instantiated yet, the list of implementing objects is empty. The ebony-board has two slots for DDR SDRAM modules, four PCI slots, two serial ports and two Ethernet ports. The memory slot is not listed as hotplug since DDR modules have to be inserted when the machine is configured initially, while serial and Ethernet ports support connect and disconnect in run-time. As the ebony-board is a top-level component, there are no up connectors.

To enable input and output for the simulated machine, the following commands create a serial text console and connects it to the uart0 connector of the Ebony board. Since the text console only has a single connector, it does not have to be specified in the connect command.

simics> board.connect uart0 (create-std-text-console)
Created non-instantiated 'std-text-console' component 'text_console_cmp0'.
Since no name is given the console component, a unique name will be assigned to it by the configuration system. The create- command returns the name of the newly created component, allowing it to be used as in the example above.

If the board only had a single serial connector, the uart0 connector name could have been left out as well.

Since the machine needs some memory to run, we also add a DDR memory module to our example. A CLI variable is used to hold the name of the memory component.

simics> $ddr = (create-ddr-memory-module rank_density = 128 module_data_width = 64)
Created non-instantiated 'ddr-memory-module' component 'ddr_memory_module_cmp0'.
simics> board.connect ddr-slot0 $ddr
6.4.5   Instantiation
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 Ebony board is now properly configured, but since no software is loaded, it will not show any output on the console if the machine is started.

6.4.6   Inspecting Component Configurations

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 name-space command provides static information about a component, such as the implementing objects and a list of connectors.

The status name-space command provides dynamic information about a component, such as attribute values and a list of all current connections. The output from status in the Ebony example:

simics> board.status 
Status of board [class ebony-board]

                      rtc_time : 2003-09-03 11:17:00 UTC
                 cpu_frequency : 100
                  mac_address0 : 00:04:ac:00:50:00
                  mac_address1 : 00:04:ac:00:50:01

                         uart0 : text_console_cmp0
                     ddr-slot0 : ddr_memory_module_cmp0

The Eclipse-based User Interface includes a Configuration Browser where the configuration can be browsed visually.

6.4.7   Accessing Objects from Components
When doing more advanced configuration of a machine, it may be necessary to access configuration objects and their attributes directly. Since the objects are created by the component system automatically during instantiation, the names of the implementing objects are not known in advance. For this reason it is possible to query a component about what configuration objects are used to implement it, using get-component-object. The argument is a name for the object that is the same for all components of the same class. A list of such names, and their mapping to actual configuration object names, is available in the output from the info command. The next example prints the pc attribute from the cpu object.
simics> p -x (board.get-component-object cpu)->pc
The get-component-object is mainly useful in scripts, when running interactively it is easy to find object names using the info command, or list-objects.

The get-component-object command does not work for non-instantiated components since they do not have any associated configuration objects. But it is possible to access the pre_conf_objects of the non-instantiated component from Python using the get_component_object() function. This functions works for both instantiated and non-instantiated components, and Python code as in the following example works in both cases:

@print "0x%x" % get_component_object(conf.board, 'cpu').pc

6.4.8   Available Components
The Simics Target Guide for each architecture lists and describes all components that are available.

Previous - Up - Next