Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / common / regdef / include / Object.h
/*
* ========== 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 ============================================
*/
#ifndef __Object_h
#define __Object_h
#include <stdlib.h>
#include <string>
#include <sstream>
#include <fstream>
#include <assert.h>
#include "List.h"
#include "Trace.h"
//using namespace std;
/** @file Object.h
* The Object class is used to represent and organize simulation objects.
*
* @sa Object_Module
*/
/** @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
* objects such as:
* - 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
* state of that Object.
* - 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
* using the Param class.
*
* 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.
*/
class Object
{
friend class ObjectIterator;
friend class ObjectArray;
public:
/** 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. */
virtual ~Object();
/** 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. */
void resetTree();
/** 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. */
void traceTree();
/** 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
* automatically closed.
*/
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
* file is open.
* @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
* are to be disabled.
* @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. */
void paramTree();
/** 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
* this Block. */
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
* stream. */
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
* buffer. */
bool paramLoad (stringbuf &sb);
/** Get a pointer to the rootObject. */
static Object *getRoot() {
#if 0
// printf("+getRoot\n");
rootObject.parent = NULL;
rootObject.baseName = "ROOT";
rootObject.fullName = "ROOT";
rootObject.traceType = 0;
rootObject.tracing = false;
// printf("-getRoot\n");
#else
// printf("+getRoot\n");
rootObject = new Object("ROOT");
// printf("-getRoot\n");
#endif
return rootObject;
}
/** 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() {
#if 0
nullObject.parent = NULL;
nullObject.baseName = "NULL";
nullObject.fullName = "NULL";
nullObject.traceType = 0;
nullObject.tracing = false;
#else
nullObject = new Object("NULL");
#endif
return nullObject;
}
protected:
Object() {}
private:
static Object *rootObject;
static Object *nullObject;
int initialized;
static bool tracing;
static ofstream traceFile;
Object *parent;
List<Object> children;
List<Parameter> param;
string baseName;
string fullName;
unsigned traceType;
};
/** ObjectIterator is used to iterate through the children of an Object. */
class ObjectIterator : public ListIterator<Object>
{
public:
/** 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.
*/
class ObjectArray
{
public:
/** 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)
{
size = n;
array = new Object*[size];
for (uint i=0; i<size; i++) {
ostringstream o;
o << i;
array[i] = new Object(s + "[" + o.str() + "]", p);
}
}
/** Destructor for ObjectArray. */
~ObjectArray()
{
for (uint i=0; i<size; i++)
delete array[i];
delete[] array;
}
/** 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]; }
private:
Object **array;
uint size;
};
/** 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
{
public:
/** 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)
{
size = n;
array = new T*[size];
for (uint i=0; i<size; i++) {
ostringstream o;
o << i;
array[i] = new T(s + "[" + o.str() + "]", p);
}
}
/** Destructor for ObjectArrayOf. */
~ObjectArrayOf()
{
for (uint i=0; i<size; i++)
delete array[i];
delete[] array;
}
/** 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]; }
private:
T **array;
uint size;
};
/** @} */
#endif