summaryrefslogtreecommitdiff
path: root/ext/systemc/src/sysc/kernel/sc_object.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ext/systemc/src/sysc/kernel/sc_object.cpp')
-rw-r--r--ext/systemc/src/sysc/kernel/sc_object.cpp568
1 files changed, 568 insertions, 0 deletions
diff --git a/ext/systemc/src/sysc/kernel/sc_object.cpp b/ext/systemc/src/sysc/kernel/sc_object.cpp
new file mode 100644
index 000000000..e624d12b5
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_object.cpp
@@ -0,0 +1,568 @@
+/*****************************************************************************
+
+ Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
+ more contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright ownership.
+ Accellera licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with the
+ License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ sc_object.cpp -- Abstract base class of all SystemC objects.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include <cstdlib>
+#include <cassert>
+#include <stddef.h>
+#include <cstdio>
+#include <string.h>
+#include <ctype.h>
+
+#include "sysc/kernel/sc_externs.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_object.h"
+#include "sysc/kernel/sc_object_manager.h"
+#include "sysc/kernel/sc_phase_callback_registry.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_event.h"
+#include "sysc/utils/sc_hash.h"
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/utils/sc_list.h"
+#include "sysc/utils/sc_utils_ids.h"
+#include "sysc/utils/sc_mempool.h"
+
+namespace sc_core {
+
+typedef int (*STRCMP)(const void*, const void*);
+
+const char SC_HIERARCHY_CHAR = '.';
+
+/* This will be gotten rid after multiple-processes
+ are implemented. This is to fix some regression
+ problems. */
+bool sc_enable_name_checking = true;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_object
+//
+// Abstract base class of all SystemC `simulation' objects.
+// ----------------------------------------------------------------------------
+
+void
+sc_object::add_child_event( sc_event* event_p )
+{
+ // no check if event_p is already in the set
+ m_child_events.push_back( event_p );
+}
+
+void
+sc_object::add_child_object( sc_object* object_ )
+{
+ // no check if object_ is already in the set
+ m_child_objects.push_back( object_ );
+}
+
+const char*
+sc_object::basename() const
+{
+ size_t pos; // position of last SC_HIERARCHY_CHAR.
+ pos = m_name.rfind( (char)SC_HIERARCHY_CHAR );
+ return ( pos == m_name.npos ) ? m_name.c_str() : &(m_name.c_str()[pos+1]);
+}
+
+void
+sc_object::print(::std::ostream& os) const
+{
+ os << name();
+}
+
+void
+sc_object::dump(::std::ostream& os) const
+{
+ os << "name = " << name() << "\n";
+ os << "kind = " << kind() << "\n";
+}
+
+static int sc_object_num = 0;
+
+static std::string
+sc_object_newname()
+{
+ char buffer[64];
+ std::string result;
+
+ std::sprintf(buffer, "{%d}", sc_object_num);
+ sc_object_num++;
+ result = buffer;
+
+ return result;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object::remove_child_event"
+// |
+// | This virtual method removes the supplied event from the list of child
+// | events if it is present.
+// |
+// | Arguments:
+// | event_p -> event to be removed.
+// | Returns true if the event was present, false if not.
+// +----------------------------------------------------------------------------
+bool
+sc_object::remove_child_event( sc_event* event_p )
+{
+ int size = m_child_events.size();
+ for( int i = 0; i < size; ++ i ) {
+ if( event_p == m_child_events[i] ) {
+ m_child_events[i] = m_child_events[size - 1];
+ m_child_events.pop_back();
+ return true;
+ }
+ }
+ return false;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object::remove_child_object"
+// |
+// | This virtual method removes the supplied object from the list of child
+// | objects if it is present.
+// |
+// | Arguments:
+// | object_p -> object to be removed.
+// | Returns true if the object was present, false if not.
+// +----------------------------------------------------------------------------
+bool
+sc_object::remove_child_object( sc_object* object_p )
+{
+ int size = m_child_objects.size();
+ for( int i = 0; i < size; ++ i ) {
+ if( object_p == m_child_objects[i] ) {
+ m_child_objects[i] = m_child_objects[size - 1];
+ m_child_objects.pop_back();
+ object_p->m_parent = NULL;
+ return true;
+ }
+ }
+ return false;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object::sc_object_init"
+// |
+// | This method initializes this object instance and places it in to the
+// | object hierarchy if the supplied name is not NULL.
+// |
+// | Arguments:
+// | nm = leaf name for the object.
+// +----------------------------------------------------------------------------
+void
+sc_object::sc_object_init(const char* nm)
+{
+ // SET UP POINTERS TO OBJECT MANAGER, PARENT, AND SIMULATION CONTEXT:
+ //
+ // Make the current simcontext the simcontext for this object
+
+ m_simc = sc_get_curr_simcontext();
+ m_attr_cltn_p = 0;
+ sc_object_manager* object_manager = m_simc->get_object_manager();
+ m_parent = m_simc->active_object();
+
+ // CONSTRUCT PATHNAME TO OBJECT BEING CREATED:
+ //
+ // If there is not a leaf name generate one.
+
+ m_name = object_manager->create_name(nm ? nm : sc_object_newname().c_str());
+
+
+ // PLACE THE OBJECT INTO THE HIERARCHY
+
+ object_manager->insert_object(m_name, this);
+ if ( m_parent )
+ m_parent->add_child_object( this );
+ else
+ m_simc->add_child_object( this );
+}
+
+sc_object::sc_object() :
+ m_attr_cltn_p(0), m_child_events(), m_child_objects(), m_name(),
+ m_parent(0), m_simc(0)
+{
+ sc_object_init( sc_gen_unique_name("object") );
+}
+
+sc_object::sc_object( const sc_object& that ) :
+ m_attr_cltn_p(0), m_child_events(), m_child_objects(), m_name(),
+ m_parent(0), m_simc(0)
+{
+ sc_object_init( sc_gen_unique_name( that.basename() ) );
+}
+
+
+static bool
+object_name_illegal_char(char ch)
+{
+ return (ch == SC_HIERARCHY_CHAR) || isspace(ch);
+}
+
+sc_object::sc_object(const char* nm) :
+ m_attr_cltn_p(0), m_child_events(), m_child_objects(), m_name(),
+ m_parent(0), m_simc(0)
+{
+ int namebuf_alloc = 0;
+ char* namebuf = 0;
+ const char* p;
+
+ // null name or "" uses machine generated name.
+
+ if ( !nm || !*nm )
+ nm = sc_gen_unique_name("object");
+ p = nm;
+
+ if (nm && sc_enable_name_checking) {
+ namebuf_alloc = 1 + strlen(nm);
+ namebuf = (char*) sc_mempool::allocate(namebuf_alloc);
+ char* q = namebuf;
+ const char* r = nm;
+ bool has_illegal_char = false;
+ while (*r) {
+ if (object_name_illegal_char(*r)) {
+ has_illegal_char = true;
+ *q = '_';
+ } else {
+ *q = *r;
+ }
+ r++;
+ q++;
+ }
+ *q = '\0';
+ p = namebuf;
+ if (has_illegal_char)
+ {
+ std::string message = nm;
+ message += " substituted by ";
+ message += namebuf;
+ SC_REPORT_WARNING( SC_ID_ILLEGAL_CHARACTERS_, message.c_str());
+ }
+ }
+ sc_object_init(p);
+ sc_mempool::release( namebuf, namebuf_alloc );
+}
+
+sc_object::~sc_object()
+{
+#if SC_HAS_PHASE_CALLBACKS_
+ unregister_simulation_phase_callback( SC_STATUS_ANY );
+#endif
+ detach();
+ delete m_attr_cltn_p;
+}
+
+//------------------------------------------------------------------------------
+//"sc_object::detach"
+//
+// This method detaches this object instance from the object hierarchy.
+// It is called in two places: ~sc_object() and sc_process_b::kill_process().
+//------------------------------------------------------------------------------
+void sc_object::detach()
+{
+ if (m_simc) {
+
+ // REMOVE OBJECT FROM THE OBJECT MANAGER:
+
+ sc_object_manager* object_manager = m_simc->get_object_manager();
+ object_manager->remove_object(m_name);
+
+ // REMOVE OBJECT FROM PARENT'S LIST OF OBJECTS:
+
+ if ( m_parent )
+ m_parent->remove_child_object( this );
+ else
+ m_simc->remove_child_object( this );
+
+ // ORPHAN THIS OBJECT'S CHILDREN:
+
+#if 0 // ####
+ ::std::<sc_object*> children_p = &get_child_objects();
+ int child_n = children_p->size();
+ sc_object* parent_p;
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ (*children_p)[child_i]->m_parent = 0;
+ }
+#endif
+
+ }
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object::orphan_child_events"
+// |
+// | This method moves the children of this object instance to be children
+// | of the simulator.
+// +----------------------------------------------------------------------------
+void sc_object::orphan_child_events()
+{
+ std::vector< sc_event* > const & events = get_child_events();
+
+ std::vector< sc_event* >::const_iterator
+ it = events.begin(), end = events.end();
+
+ for( ; it != end; ++it )
+ {
+ (*it)->m_parent_p = NULL;
+ simcontext()->add_child_event(*it);
+ }
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object::orphan_child_objects"
+// |
+// | This method moves the children of this object instance to be children
+// | of the simulator.
+// +----------------------------------------------------------------------------
+void sc_object::orphan_child_objects()
+{
+ std::vector< sc_object* > const & children = get_child_objects();
+
+ std::vector< sc_object* >::const_iterator
+ it = children.begin(), end = children.end();
+
+ for( ; it != end; ++it )
+ {
+ (*it)->m_parent = NULL;
+ simcontext()->add_child_object(*it);
+ }
+}
+
+void
+sc_object::trace( sc_trace_file * /* unused */) const
+{
+ /* This space is intentionally left blank */
+}
+
+
+// add attribute
+
+bool
+sc_object::add_attribute( sc_attr_base& attribute_ )
+{
+ if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
+ return ( m_attr_cltn_p->push_back( &attribute_ ) );
+}
+
+
+// get attribute by name
+
+sc_attr_base*
+sc_object::get_attribute( const std::string& name_ )
+{
+ if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
+ return ( (*m_attr_cltn_p)[name_] );
+}
+
+const sc_attr_base*
+sc_object::get_attribute( const std::string& name_ ) const
+{
+ if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
+ return ( (*m_attr_cltn_p)[name_] );
+}
+
+
+// remove attribute by name
+
+sc_attr_base*
+sc_object::remove_attribute( const std::string& name_ )
+{
+ if ( m_attr_cltn_p )
+ return ( m_attr_cltn_p->remove( name_ ) );
+ else
+ return 0;
+}
+
+
+// remove all attributes
+
+void
+sc_object::remove_all_attributes()
+{
+ if ( m_attr_cltn_p )
+ m_attr_cltn_p->remove_all();
+}
+
+
+// get the number of attributes
+
+int
+sc_object::num_attributes() const
+{
+ if ( m_attr_cltn_p )
+ return ( m_attr_cltn_p->size() );
+ else
+ return 0;
+}
+
+
+// get the attribute collection
+
+sc_attr_cltn&
+sc_object::attr_cltn()
+{
+ if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
+ return *m_attr_cltn_p;
+}
+
+const sc_attr_cltn&
+sc_object::attr_cltn() const
+{
+ if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
+ return *m_attr_cltn_p;
+}
+
+sc_object*
+sc_object::get_parent() const
+{
+ static bool warn_sc_get_parent_deprecated=true;
+ if ( warn_sc_get_parent_deprecated )
+ {
+ warn_sc_get_parent_deprecated=false;
+ SC_REPORT_INFO(sc_core::SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_object::get_parent() is deprecated, "
+ "use get_parent_object() instead");
+ }
+ return get_parent_object();
+}
+
+// ----------------------------------------------------------------------------
+// simulation phase callbacks
+
+
+sc_object::phase_cb_mask
+sc_object::register_simulation_phase_callback( phase_cb_mask mask )
+{
+ mask = simcontext()->m_phase_cb_registry
+ ->register_callback(*this, mask);
+ return mask;
+}
+
+
+sc_object::phase_cb_mask
+sc_object::unregister_simulation_phase_callback( phase_cb_mask mask )
+{
+ mask = simcontext()->m_phase_cb_registry
+ ->unregister_callback(*this, mask);
+ return mask;
+}
+
+
+void
+sc_object::simulation_phase_callback()
+{
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_NOT_IMPLEMENTED_, name() );
+}
+
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+ Description of Modification: if module name hierarchy is empty, sc_object
+ ctor assumes the currently executing process
+ as the parent object to support dynamic process
+ creation similar to other sc_objects
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems
+ 5 September 2003
+ Description of Modification: - Made creation of attributes structure
+ conditional on its being used. This eliminates
+ 100 bytes of storage for each normal sc_object.
+
+ *****************************************************************************/
+
+
+// $Log: sc_object.cpp,v $
+// Revision 1.16 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.15 2011/08/26 20:46:10 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+// Revision 1.14 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.13 2011/04/01 21:24:57 acg
+// Andy Goodrich: removed unused code.
+//
+// Revision 1.12 2011/03/06 15:55:11 acg
+// Andy Goodrich: Changes for named events.
+//
+// Revision 1.11 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.10 2011/03/05 04:45:16 acg
+// Andy Goodrich: moved active process calculation to the sc_simcontext class.
+//
+// Revision 1.9 2011/03/05 01:39:21 acg
+// Andy Goodrich: changes for named events.
+//
+// Revision 1.8 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.7 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.6 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.5 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.4 2010/08/03 17:02:39 acg
+// Andy Goodrich: formatting changes.
+//
+// Revision 1.3 2009/02/28 00:26:58 acg
+// Andy Goodrich: changed boost name space to sc_boost to allow use with
+// full boost library applications.
+//
+// Revision 1.2 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.5 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.4 2006/03/21 00:00:34 acg
+// Andy Goodrich: changed name of sc_get_current_process_base() to be
+// sc_get_current_process_b() since its returning an sc_process_b instance.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//