* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: Object.h
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
* The above named program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
* ========== Copyright Header End ============================================
* The Object class is used to represent and organize simulation objects.
/** @defgroup Object_Module The Object Module
* All objects are held in the Object tree. This is rooted at a special
* pre-defined Object, the rootObject. The rootObject is called "ROOT",
* which is both the basename and the fullname of that Object. When
* a new Object is constructed it is given a basename, and is associated
* with a parent Object (which must already exist). The fullname of an
* Object is formed by walking the tree from the rootObject down to that
* Object and concatenating the basename of each node in the tree
* (including "ROOT" and the basename of that Object) separated by a period.
* The Object class provides basic simulation infrastructure to
* - naming and hierarchy (as described above)
* - printing: dumping of Object internal state for debug purposes.
* - reset: the "resetThis" method of an Object is called to reset the
* - signing: the "signThis" method of an Object is called to create
* a Signature for each item that can in a trace.
* - tracing: the output of trace data for analysis purposes.
* - parameterization: parameters are associated with objects in the Object
* tree. Mechanisms are provided to get, set, save and load parameters
* Simulation objects derive from the Object class and over-ride its
* virtual methods (printThis, resetThis, signThis, traceThis,
* paramThis) as required. In fact, the Block class derives from Object,
* and provides additional mechanism and infrastructure that is appropriate
* for system-level performance modelling. Most blocks that model system
* hardware will derive from Block instead of from Object. However, if a
* a new class of simulation objects is required that does not benefit
* from Block, then this can derive directly from Object.
class Parameter
; // cross-reference to Parameter from Param.h
/** The Object class provides infrastructure and mechanism for the
* modelling of simulation objects.
friend class ObjectIterator
;
friend class ObjectArray
;
/** Constructor for Object.
* @param s - the basename of the Object.
* @param p - the parent of the Object. If this is omitted or if it is
* specified as NULL, then the parent will be the rootObject.
* Initially, the Object will have no children and be associated with no
* parameters. Child objects and parameters are automatically added to their
* parent Object when they are created.
Object(string s
, Object
*p
=NULL
);
/** Destructor for Object. This is virtual so that the appropriate
* destructor for any derived class is used. */
/** Get the basename of this Object. */
string
getBaseName() { return baseName
; }
/** Get the fullname of this Object. */
string
getFullName() { return fullName
; }
/** Print information about the Object tree rooted at this Object. */
void printTree(ostream
&os
);
/** Print information about this Object to the specified output stream.
* The implementation of Object::printThis simply prints the fullname
* of this Object. It is a virtual method so that additional functionality
* can be provided by a sub-class of Object. */
virtual void printThis(ostream
&os
);
/** Reset the Object tree rooted at this Object. */
/** The resetThis method is called to place this Object into its
* reset state. The implementation of Object::resetThis is empty,
* but is a virtual method so that this functionality can be
* provided by a sub-class of Object. */
virtual void resetThis() {}
/** Produce signature information about the Object tree rooted
* at this Object to the specified output file stream. This mechanism
* is used to produce the header information for a trace file. */
void signTree(ofstream
&ofs
);
/** The signThis method is called to produce signature information
* for this Object to the specified output file stream. The
* implementation of Object::signThis is empty, but is a virtual
* method so that this functionality can be provided by a
* sub-class of Object. */
virtual void signThis(ofstream
&ofs
) {}
/** Produce trace data for the Object tree rooted at this Object. */
/** Produce trace data for this Object. The implementation of
* Object::traceThis is empty, but is a virtual method so that
* this functionality can be provided by a sub-class of Object. */
virtual void traceThis() {}
/** This static method opens a trace file.
* @param filename the name of the trace file to be opened. If not
* specified, the default filename is "default.trc".
* Note that only one trace file can be open at a time. If a trace
* file is open when traceOpen is called, the old one will be
static void traceOpen(const char *filename
= "default.trc");
/** This static method closes the currently open trace file. */
static void traceClose();
/** This static method enters a time-stamp record into the trace file.
* Usually there is no need to enter explicit time-stamps because
* trace file entries will themselves indicate the current time.
* However, if there is no trace file activity for extended periods
* (e.g. because no values are changing) it can be useful to insert
* an explicit time-stamp. A specific example is when a trace file
* is closed - in this case, an automatic time-stamp is produced
* to ensure that the final time-stamp is captured. */
static void traceStamp();
/** This status method returns the output file stream by reference. */
static ofstream
&getTraceFile() { return traceFile
; }
/** This static method returns a boolean indicating whether a trace
* @return True if a trace file is open, otherwise false.
static bool getTracing() { return tracing
; }
/** The traceMode method is used to set or clear the trace mode for
* objects using the Object tree. There is a trace mode variable
* maintained for each Object, and this is a bitwise OR of values
* from the Trace enumeration. Trace of a particular kind is enabled
* for an Object if the trace mode for that kind is set for that Object,
* otherwise it is disabled. This method sets or clears bits in the
* trace mode, and the change is applied to this Object and to all
* objects in the tree rooted at this Object. This provides a powerful
* mechanism to set up trace filters.
* @param b If true the parameter "t" specifies the kinds of trace
* which are to be enabled, otherwise the kinds of trace that
* @param t Indicates the kinds of trace for which the trace mode
* is to be changed. This defaults to all known kinds of Trace.
void traceMode(bool b
, unsigned t
=Trace::DEFAULT
);
/** Returns a boolean indicating whether tracing is enabled for this Object.
* @return True if a trace file is open and any kind of trace is enabled
* for this Object, otherwise false.
bool isTracing() { return tracing
&& (traceType
!= 0); }
/** Returns a boolean indicating whether the specified kind of tracing is
* enabled for this Object.
* @param t the kind of trace to test for. This parameter is a bitwise
* OR of values from the Trace enumeration.
* @return True if a trace file is open and any kind of the specified
* kinds of trace are enabled for this Object, otherwise false.
bool isTracing(unsigned t
) { return tracing
&& ((traceType
& t
) != 0); }
/** Propagate the value of all parameters associated with objects in the
* Object tree rooted at this Object. This mechanism is invoked when
* a parameter file is loaded so that anything dependent on or derived
* from a parameter value can be re-evaluated. */
/** Evaluate the value of all parameters associated with this Object.
* The implementation of Object::signThis is empty, but is a virtual
* method so that this functionality can be provided by a sub-class
* of Object. This mechanism is invoked when a parameter file is
* loaded so that anything dependent on or derived from a parameter
* value can be re-evaluated. */
virtual void paramThis() {}
/** Add the specified parameter to the list of parameters associated with
void addParameter (Parameter
*param
);
/** Print the parameters associated with this Object and with each Object
* in the Object tree rooted at this Object to the specified output stream.
void paramPrint (ostream
&os
);
/** This static method saves all parameters to a parameter file.
* @param filename the name of the parameter file to save to. If not
* specified, the default filename is "default.prm".
static void paramSave (const char *filename
= "default.prm");
/** Save the parameters associated with this Object and with each Object
* in the Object tree rooted at this Object to the specified output file
void paramSave (ofstream
&ofs
);
/** This static method loads parameters from a parameter file.
* @param filename the name of the parameter file to load from. If not
* specified, the default filename is "default.prm".
* Each parameter that appears in the parameter file will be set to
* the specified value. Other parameters will be unchanged.
static void paramLoad (const char *filename
= "default.prm");
/** Load the parameters associated with this Object and with each Object
* in the Object tree rooted at this Object from the specified string
bool paramLoad (stringbuf
&sb
);
/** Get a pointer to the rootObject. */
static Object
*getRoot() {
rootObject
.parent
= NULL
;
rootObject
.baseName
= "ROOT";
rootObject
.fullName
= "ROOT";
rootObject
.traceType
= 0;
rootObject
.tracing
= false;
rootObject
= new Object("ROOT");
/** Get a pointer to the nullObject. This is a useful place to hang objects
* outside of the root tree. Such objects will not be visited in walks
* over the Object tree, and are therefore hidden from the Object tree
* print, reset, sign and trace mechanisms. */
static Object
*getNull() {
nullObject
.parent
= NULL
;
nullObject
.baseName
= "NULL";
nullObject
.fullName
= "NULL";
nullObject
.traceType
= 0;
nullObject
.tracing
= false;
nullObject
= new Object("NULL");
static Object
*rootObject
;
static Object
*nullObject
;
static ofstream traceFile
;
/** ObjectIterator is used to iterate through the children of an Object. */
class ObjectIterator
: public ListIterator
<Object
>
/** Constructor for ObjectIterator.
* @param o a pointer to the Object to be iterated over.
* All other methods are inherited, see ListIterator for details.
ObjectIterator(Object
*o
) : ListIterator
<Object
>(&o
->children
) {}
/** ObjectArray is used to constructs arrays of Objects, and index into
* the array to a Object element.
/** Constructor for ObjectArray.
* @param n the number of Objects in the array.
* @param s the basename for this ObjectArray. The basename of an Object
* in the array will be this basename appended by "[i]" where
* i is the index of that Object in the array.
* @param p the parent Object of this ObjectArray.
ObjectArray(uint n
, string s
, Object
*p
=NULL
)
array
= new Object
*[size
];
for (uint i
=0; i
<size
; i
++) {
array
[i
] = new Object(s
+ "[" + o
.str() + "]", p
);
/** Destructor for ObjectArray. */
for (uint i
=0; i
<size
; i
++)
/** Index operator for ObjectArray. This indexes into the ObjectArray
* and returns the Object instance at the specified index. */
Object
&operator[](uint i
) { assert(i
< size
); return *array
[i
]; }
/** ObjectArrayOf<T,P> is used to constructs arrays of some type T which is
* presumed to be a subclass of Object, where each element in the array
* has a parent of type P. The only actual requirement on T
* is that it provides a constructor compatible with the Object constructor.
* This is useful for creating arrays of some subclass of Object without
* having to redeclare an appropriate array class. In practice, this class
* is more useful than ObjectArray since interesting Objects must extend
* Object. The problem with ObjectArray is that it is statically associated
* with the constructor for Object. The use of templates for ObjectArrayOf
* ensures that the appropriate constructor for type T is used, and that
* the type of the parent P can be passed through with a type cast.
template<class T
, class P
> class ObjectArrayOf
/** Constructor for ObjectArrayOf.
* @param n the number of Objects in the array.
* @param s the basename for this ObjectArrayOf. The basename of an Object
* in the array will be this basename appended by "[i]" where
* i is the index of that Object in the array.
* @param p the parent Object of this ObjectArrayOf.
ObjectArrayOf(uint n
, string s
, P
*p
=NULL
)
for (uint i
=0; i
<size
; i
++) {
array
[i
] = new T(s
+ "[" + o
.str() + "]", p
);
/** Destructor for ObjectArrayOf. */
for (uint i
=0; i
<size
; i
++)
/** Index operator for ObjectArrayOf. This indexes into the ObjectArrayOf
* and returns the Object instance at the specified index. */
T
&operator[](uint i
) { assert(i
< size
); return *array
[i
]; }