2.2 Basic Module Requirements 2.4 Thread Domains
API Reference Manual  /  2 Threading Model  / 

2.3 Simulation Cells

A cell is a group of configuration objects which may interact with each other through direct function calls. If a model needs to communicate with objects in other cells during the simulation, it needs to do this through links (see section 2.3.4 or the Link Library Programming Guide). A link always introduces a delay in the communication, which means that messages cannot be sent and received in the same cycle.

In a configuration, a cell is represented by a configuration object of class cell. All objects that implement the cycle interface (referred to as clocks) automatically have a cell attribute that will point to the cell they belong to. Since all Simics objects have a queue attribute pointing at a clock object, they will by extension belong to the cell of their clock object. This is illustrated in the figure below:

Figure 3. Configuration is partitioned into cells

Another example is the following configuration:
OBJECT cell0 TYPE cell {
}
OBJECT cell1 TYPE cell {
}
OBJECT cpu0 TYPE cpu {
       cell: cell0
}
OBJECT cpu1 TYPE cpu {
       cell: cell0
}
OBJECT cpu2 TYPE cpu {
       cell: cell1
}
OBJECT device0 TYPE device {
       queue = cpu0
}
OBJECT device1 TYPE device {
       queue = cpu0
}
OBJECT device2 TYPE device {
       queue = cpu2
}

In this example, device0 has cpu0 as a queue, and thus belongs to cell0, while device2 has cpu2 as a queue, and thus belongs to cell1.

2.3.1 Cells and Components

Simics provides an automatic cell partitioning based on top-level components. Each component object implements a create_cell() method that can return True or False to the question: should a simulation cell be created to contain this component and all its sub-components? By default, top-level components return True and all other components return False. By overriding this method, it is possible to automatically create cells at lower levels in the component hierarchy, or to disable cell creation altogether. In the latter case, the create_cell() should return False and the components should define cell objects themselves and assign clocks to them as appropriate, just as normal configuration objects.

The code snippets below show how to overload the create_cell() function for both old-style and hierarchical way of writing components.

class mycomp(component_object):
    ...
    def create_cell(self):
        return False

class mycomp(StandardConnectorComponent): # or StandardComponent
    ....
    class component(comp.StandardComponent.component):
        def create_cell(self):
            return False

Cells can also be created independently of components, by creating cell objects and setting the cell attribute of the clock objects which should belong to the cell.

2.3.2 Compatibility

If clock objects are created that do not point to a cell, then a default_cell object will be created, unless it exists already, to make sure these clock objects are scheduled as intended. This is a simple compatibility mechanism for use with older scripts. If you are building your configurations in several steps, but without using components, you will have to introduce your own cells and configure them.

2.3.3 Verifying the Cell Partitioning

The check-cell-partitioning command checks either a checkpoint or the currently loaded configuration for violations of the cell partitioning rules—namely, that objects belonging to one cell do not have any references to objects in another cell. Such references will be shown in the form of a chain of attributes connecting the cells.

An object is considered to belong to a cell if either it is a cell object, or if it refers to or is referred to by an object belonging to that cell. Object references are object values in (checkpointed) attributes.

False positives can be suppressed by defining the attribute outside_cell and setting it to true for objects that should not be considered part of any cell but still refer to other objects in cells. This can be necessary for objects that only use these references in safe ways, e.g., in Global Context.

2.3.4 Links

Links are the only Simics objects that should connect different cells together. In other words, link components are allowed to connect to device components belonging to different cells without breaking the cell isolation rules. This works because all communication over the links are asynchronous with a delay that is constrained by the synchronization parameters so that the information exchange never becomes indeterministic.

Note: While it is possible to perform cross-cell calls if special precautions are taken, it should be avoided since it likely prevents the simulation from being deterministic even when the simulation is running in the "serial" threading mode.

2.3.5 Synchronization domains

All cells are connected to a synchronization domain that controls the execution in the cells to ensure that they do not run too far apart in virtual time. The domain has a min_latency parameter that limits the allowed difference in time between clocks in all the cells connected to it. This works as a lower limit for the latency that link objects can use when communicating between cells.

2.2 Basic Module Requirements 2.4 Thread Domains