Joachim Schlosser: Development and Verification of fast C/C++ Simulation Models for the Star12 Microcontroller
For an application it is essential to understand accurately what model information a model manager is providing. Only with detailed information the application can correctly utilize the model manager and so accomplish its task. In the OMI information is realized as a set of objects manipulated through the programming interface, thus forming the basis for the communication between model manager and application. The precise definition of all objects is specified in the OMI information model. This information model does not only describe the type and meaning of information, but also the kinds of routines available for accessing this information.
Some important terms for the information model must be clarified, they are briefly explained here and more detailed later when they are used
The basic three terms for model boundary classes are:
Then there are other terms that are used extensively to specify information:
Two kinds of primitive types are distinguished: built-in primitive types and enumeration primitive types. The following primitive types are valid for the OMI information model:
Integer | : primitive type |
String | : primitive type |
DataValue | : primitive type |
|
|
Boolean | : primitive enumeration type |
IODirection | : primitive enumeration type |
StorageType | : primitive enumeration type |
ClockValueRelationship | : primitive enumeration type |
There is a corresponding C type for each primitive type in this list, specified in the programming interface. To get the name of the C type, add a prefix omi and a suffix T to the name.
The notation used for the OMI information model is based on a system of class definitions, object definitions, relationships and properties. It aids to formally relate the kinds of OMI objects to the interface routines operating upon them.
An object meets the common definition it has in the object-oriented programming paradigm, which says information, comprised in an object, should never be accessed directly, but read and written using interface functions. This allows implementing the internal representation in different ways.
A class or object can have zero or more parent classes, which means the object definition or class inherits all properties and relationships of its parent classes. This concept meets the multiple inheritance concept of some object-oriented programming languages.
The definitions of classes and objects appear in the information model in the following form:
class ClassName
parent classes
list of parent classes |
list of properties |
list of relationships |
object ObjectName
parent classes
list of parent classes |
list of properties |
list of relationships |
Properties are primitive values, as defined above, that do not allow access to other objects. In contrast to attributes they provide required information, while attributes represent optional information. A relationship defines access to other objects. There is a difference between a singular relationship, which defines access to just one single object, and a multiple relationship that yields any number of objects, unordered in a set or ordered in a list.
Each information item has a type and an unique name within the class or object. Relationships and properties share one name space, so a property cannot have the same name as a relationship within the same object. Named items inherited from more than one source occur only once in the current class or object.
The names of objects are given by the Name property, which is an example of an OMI name. An OMI name has the following constraints:
In order to solve the problem of possible name clashes in the overall system, the concept of scopes is invented, including the name space technique. A scope is a set of objects, all having distinct values for their Name properties, so within the name space there is a set of uniquely names. An overview of the objects and their scope-defining relationships will be presented later.
There are some basic objects, which have to be explained, in order to be able to use them later for classifying a concrete model manager. The definitions are taken from [IEE99], chapter 7.
Starting point for accessing the information known to a model manager is a single root object. The root object contains includes relationships for Models, which represent a set of stand-alone-models known to the model manager; these are models that are not contained in a library. It also contains the Libraries known to the model manager. The Attributes relationship may represent the characteristics of the model manager.
object Root
relationships
Models | : set of Model |
Libraries | : set of Library |
Attributes | : set of Attribute |
Models can be collected in libraries. A library bears a property, Name, with which libraries are distinguished. The unordered set of models contained in the library is represented by the Models property. Like in the root object, the Attributes relationship is used for additional characteristics. Certain attributes are predefined by the OMI.
object Library
properties
Name | : String |
Models | : set of Model |
Libraries | : set of Library |
Attributes | : set of Attribute |
A model object contains information on its model boundary, which is the set of parameters, ports, viewports and timing definitions, as well as other information regarding functionality and timing characteristics.
object Model
properties
Name | : String |
SupportsSaveRestore | : Boolean |
SupportsResetTimeZero | : Boolean |
ParameterDefinitions | : list of ParameterDefinition |
PortDefinitions | : list of PortDefinition |
ViewportDefinitions | : set of ViewportDefinition |
DefaultTimingDelays | : set of TimingDefinition |
DefaultTimingChecks | : set of TimingDefinition |
ClockingSpecifications | : set of ClockingSpecification |
EnclosingLibrary | : Library |
Attributes | : set of Attribute |
Most of the properties and relationships should be self-explanatory due to their names. The types of objects, not introduced before, will be explained within the subsequent sections.
When a model is instantiated, it is tailored to follow specific needs of the application. The instantiation forms a new object named ModelInstance object.
object ModelInstance
relationships
Definition | : Model |
Parameters | : list of Parameter |
Ports | : list of DefinedPort |
Viewports | : set of Viewport |
TimingDelays | : set of TimingDefinition |
TimingChecks | : set of TimingDefinition |
All default relationships are again specified here, but now with the actual values.
A data object epitomizes a modeling element having a value and is so capable of storing state information.
class DataObject
properties
Value | : DataValue |
ObjectType | : CompletelyCharacterizedType |
Definition | : DataObjectDefinition |
The Value property may not be available without an initialization of the object, and additionally it may change during simulation. The second information in a data object is its completely characterized data type.
A data object may have a Definition relationship; in this case it is derived from a data object definition object, which has the following definition:
class DataObjectDefinition
properties
Name | : String |
ObjectType | : DataType |
Attributes | : set of Attribute |
The value of the Name property of course has to be unique in the related scope. An application may have certain expectations for data objects and their names, but it must not assume all expectations to be fulfilled, rather the application has to verify, that the model has these characteristics using the OMI interfaces.
Parameters A parameter is an instrument by which characteristics of a model can be customized at creation time, so it has a constant value. Usually a parameter is derived from a parameter definition.
object DataObjectDefinition
parent classes
DataObjectDefinition |
DefaultValue | : DataValue |
The default value shall always be available, so not depend on the instantiation of the model.
An actual parameter object is a data object with a relationship to the parameter definition it is derived from:
object DataObjectDefinition
parent classes
DataObject |
Definition | : ParameterDefinition |
Ports Ports are the dynamic communication channels of a model. A port is usually attached to an object in the application to allow the application and the model to interact during simulation. Like a parameter, a port is derived from a definition, too.
object PortDefinition
parent classes
DataObjectDefinition |
Direction | : IODirection |
IsAtomic | : Boolean |
The Direction property defines the direction in which the information flows, may it be from or to the model, or both. A port can be manipulated as a single atomic unit or as a collection of separate elements. These possibilities are named atomic and non-atomic and indicated by the IsAtomic property.
The actual port object represents a port associated with a model instance. Like all other data objects, a port may be of a scalar type or a composite type, thus leading to scalar port and composite port objects. A port of a model is related to the port definition of the corresponding model in such a way that for each port definition, a corresponding port, called defined port, exists on the instance. A port definition, which is configured to instantiate non-atomic ports, leads to a port-per-scalar element, called port element. All ports are either defined ports or port elements.
class Port
parent classes
DataObject |
NumElements | : Integer |
For a composite non-atomic port, a NumElements property with a value greater than 0 indicates the number of port elements. It is 0 only if the port is an atomic port.
The defined port is one of the two kinds of ports as mentioned above; it is not part of another port but one immediately associated with a model.
class DefinedPort
parent classes
Port |
Elements | : list of PortElement |
Definition | : PortDefinition |
If it is an atomic port, the list of the Elements relationship is empty; otherwise the list contains the elements’ objects.
class PortElement
parent classes
Port |
Name | : String |
Parent | : DefinedPort |
A port element bears a name and of course a relationship to its parent port.
Viewports Ports are usually visible to the application as they are the normal way of interaction. For special purposes, such as debugging exploration or action, a model contains access ways to the hidden internal data objects. The means for access to these data objects is the viewport concept, which is a way to provide access to certain internal objects without disclosing the whole internal structure and information. Again, the actual viewport is derived from a viewport definition.
object ViewportDefinition
parent classes
DataObjectDefinition |
CanModify | : Boolean |
The CanModify property of a viewport definition distinguishes between read-only and read-writable viewports.
object Viewport
parent classes
DataObject |
Definition | : ViewportDefinition |
Internally a viewport may represent a signal, a variable or a constant. Again the application is responsible to determine the correct type and must not rely on a specific realization.
A composite viewport contains viewport elements.
object ViewportElement
parent classes
DataObject |
Name | : String |
Parent | : Viewport |
A viewport element object bears a name and a relationship to its parent viewport.
Data types are not only used within object and class definitions; they themselves are members of a class. A data type generally is used to specify either the values, that a data object can adopt or the structure of a complex data type, like an array or a record.
class DataType
properties
Name | : String |
StorageType | : StorageType |
Attributes | : set of Attribute |
Array Types There are two other classes within the data type context. The array type defines a sequence of homogeneous elements that are referenced by an index.
class ArrayType
parent classes
DataType |
ElementType | : CompletelyCharacterizedType |
There are some predefined array types, e. g. omiStringT for character arrays. The array is stored left-to-right with the left bound element having the index 0.
Completely Characterized Data Types In some of the former definitions I mentioned the completely characterized data type, which is one, whose characteristics have been fully established. This is mandatory for data objects, and optional for parameter, port and viewport definitions. The least ones may also be defined using incompletely characterized data types.
class CompletelyCharacterizedType
parent classes
DataType |
StorageSize | : Integer |
The StorageSize property is quite self-explanatory, specifying the size (in bytes), required to store a value of the data type within its omiDataValueT form.
The introduced class is a super class for a whole set of data types. The complete definitions are omitted, a list of the types is sufficient:
Incompletely Characterized Data Types If not all characteristics of a data type have been fully established; it is an incomplete characterized one.
class CompletelyCharacterizedType
parent classes
DataType |
All incompletely characterized data types are array types.
First, there are the Unconstrained Array Type Objects. As the name indicates, this type does not have a fixed index range associated with it. For such a parameter or port definition the bounds for the index range come from the application.
object UnconstrainedArrayData
parent classes
IncompletelyCharacterizedType |
ArrayType |
Due to its unclear size it cannot be the element type of an array type, as this would interfere with the fixed element size of an array.
Second, there are the Parameterized Array Type Objects. If the bound of an array type cannot be specified at definition time but are fixed by model parameter values, this is called a parameterized array type. For this there has to be some link to the parameter type.
class ArrayBound
object FixedArrayBound
parent classes
ArrayBound |
FixedBound | : Integer |
object ParameterizedArrayBound
parent classes
ArrayBound |
ParameterizedBound | : ParameterDefinition |
object ParameterizedArrayData
parent classes
IncompletelyCharacterizedType |
ArrayType |
LeftBoundParameter | : ArrayBound |
RightBoundParameter | : ArrayBound |
The class ArrayBound has no own information, it serves as a super class to the two objects representing the two cases of array bounds: fixed values or parameter values. Note that although it is possible to define a parameterized array type with two fixed bounds, in this case the fixed array type should be used. With the parameterized array type it is possible to create e. g. generic wrapper models.
Private Data Types It is possible in OMI to use also data types that are not defined by the OMI. These are private data types, whose representation are implementation specific and may be proprietary to a particular model vendor.
object PrivateData
parent classes
CompletelyCharacterizedType |
For usage it is necessary that the application utilizes the information provided by the model vendor about the nature of the private type.
A timing object represents a piece of timing information associated with a model.
object TimingDefinition
properties
TimingSpecification | : String |
Attributes | : set of Attribute |
The TimingSpecification property is a string in the SDF (Standard Delay Format) syntax. There are two kinds of timing definitions: timing checks, defined by an SDF tc_spec rule, and timing delays, defined by an SDF del_def rule. The Standard Delay Format is subject to become IEEE Std 1497, it was developed by a group named Open Verilog International, which is now part of the Accellera group. Referring to the specification [Hor95], a SDF file “stores the timing data generated by EDA tools for use at any stage in the design process.” This can include delays, timing checks, timing constraints, timing environments, incremental and absolute delays, conditional and unconditional module path delays, design- or instance-specific data, type- or library-specific data and scaling, environmental and technology parameters.
Additional to the SDF specification there are some other constraints for the TimingSpecification string, such as containing some extra formatting restrictions and naming conventions.
For cycle-based simulation, as described in section 2.2.1 on page 68, there were invented clock ports, which are described by clocking specifications. A clock port is required in cycle-based simulation to allow efficient communication between application and model instead of the application assuming worst-case characteristics. Therefore a model for cycle-base simulation should provide clocking specifications.
A clock port is an input-only port with a MVL2LogicData object type.
class ClockingSpecification
relationships
Attributes | : set of Attribute |
A clock appears in a certain waveform, described by the ClockWaveform object.
object ClockWaveform
parent classes
ClockingSpecification |
ClockPeriod | : DataValue |
RisingPhaseLength | : DataValue |
FallingPhaseLength | : DataValue |
RisingPhaseIsFirst | : Boolean |
Clock | : PortDefinition |
As ports can depend on a particular clock a clock domain object is needed. Such objects should exist either for none or all clock ports, so that the simulator can easily determine if there are any dependencies between ports and clocks.
object ClockDomain
parent classes
ClockingSpecification |
Clock | : PortDefinition |
Dependents | : set of PortDefinition |
Two clocks can be related, too, using the ClockRelationship object.
object ClockRelationship
parent classes
ClockingSpecification |
Relationship | : ClockValueRelationship |
LeftClock | : PortDefinition |
RightClock | : PortDefinition |
Many of the objects introduced are decorated with attributes. There are some OMI predefined attributes.
object Attribute
parent classes
DataObject |
name | : String |
Attributes | : set of Attribute |
Each attribute is unique within its scope, which usually is the current object, by its name. Attributes may be nested.
A small set of routines is used to provide access to the information described in OMI information models.
There are access routines for all basic types, shown in Table 2.1 on page 100.
|
A handle is used to denote an object. Any number of handles may point to a single object. A handle remains valid until it is explicitly released. After releasing a handle it is erroneous to use it. So a handle is the same as a pointer in various programming languages. Therefore a handle is implementation dependent, so handles, obtained through different model managers, will be incompatible in practice.