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:
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.
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.
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.
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.
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.
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.