summaryrefslogtreecommitdiff
path: root/ext/systemc/src/sysc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'ext/systemc/src/sysc/kernel')
-rw-r--r--ext/systemc/src/sysc/kernel/sc_attribute.cpp191
-rw-r--r--ext/systemc/src/sysc/kernel/sc_attribute.h209
-rw-r--r--ext/systemc/src/sysc/kernel/sc_boost.h94
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cmnhdr.h138
-rw-r--r--ext/systemc/src/sysc/kernel/sc_constants.h82
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cor.h157
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cor_fiber.cpp224
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cor_fiber.h169
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cor_pthread.cpp313
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cor_pthread.h157
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cor_qt.cpp271
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cor_qt.h154
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cthread_process.cpp123
-rw-r--r--ext/systemc/src/sysc/kernel/sc_cthread_process.h144
-rw-r--r--ext/systemc/src/sysc/kernel/sc_dynamic_processes.h67
-rw-r--r--ext/systemc/src/sysc/kernel/sc_event.cpp759
-rw-r--r--ext/systemc/src/sysc/kernel/sc_event.h884
-rw-r--r--ext/systemc/src/sysc/kernel/sc_except.cpp142
-rw-r--r--ext/systemc/src/sysc/kernel/sc_except.h178
-rw-r--r--ext/systemc/src/sysc/kernel/sc_externs.h65
-rw-r--r--ext/systemc/src/sysc/kernel/sc_join.cpp143
-rw-r--r--ext/systemc/src/sysc/kernel/sc_join.h136
-rw-r--r--ext/systemc/src/sysc/kernel/sc_kernel_ids.h321
-rw-r--r--ext/systemc/src/sysc/kernel/sc_macros.h136
-rw-r--r--ext/systemc/src/sysc/kernel/sc_main.cpp58
-rw-r--r--ext/systemc/src/sysc/kernel/sc_main_main.cpp167
-rw-r--r--ext/systemc/src/sysc/kernel/sc_method_process.cpp1023
-rw-r--r--ext/systemc/src/sysc/kernel/sc_method_process.h467
-rw-r--r--ext/systemc/src/sysc/kernel/sc_module.cpp846
-rw-r--r--ext/systemc/src/sysc/kernel/sc_module.h583
-rw-r--r--ext/systemc/src/sysc/kernel/sc_module_name.cpp123
-rw-r--r--ext/systemc/src/sysc/kernel/sc_module_name.h140
-rw-r--r--ext/systemc/src/sysc/kernel/sc_module_registry.cpp184
-rw-r--r--ext/systemc/src/sysc/kernel/sc_module_registry.h124
-rw-r--r--ext/systemc/src/sysc/kernel/sc_name_gen.cpp109
-rw-r--r--ext/systemc/src/sysc/kernel/sc_name_gen.h93
-rw-r--r--ext/systemc/src/sysc/kernel/sc_object.cpp568
-rw-r--r--ext/systemc/src/sysc/kernel/sc_object.h244
-rw-r--r--ext/systemc/src/sysc/kernel/sc_object_int.h99
-rw-r--r--ext/systemc/src/sysc/kernel/sc_object_manager.cpp462
-rw-r--r--ext/systemc/src/sysc/kernel/sc_object_manager.h139
-rw-r--r--ext/systemc/src/sysc/kernel/sc_phase_callback_registry.cpp301
-rw-r--r--ext/systemc/src/sysc/kernel/sc_phase_callback_registry.h276
-rw-r--r--ext/systemc/src/sysc/kernel/sc_process.cpp854
-rw-r--r--ext/systemc/src/sysc/kernel/sc_process.h887
-rw-r--r--ext/systemc/src/sysc/kernel/sc_process_handle.h608
-rw-r--r--ext/systemc/src/sysc/kernel/sc_reset.cpp440
-rw-r--r--ext/systemc/src/sysc/kernel/sc_reset.h164
-rw-r--r--ext/systemc/src/sysc/kernel/sc_runnable.h144
-rw-r--r--ext/systemc/src/sysc/kernel/sc_runnable_int.h574
-rw-r--r--ext/systemc/src/sysc/kernel/sc_sensitive.cpp959
-rw-r--r--ext/systemc/src/sysc/kernel/sc_sensitive.h306
-rw-r--r--ext/systemc/src/sysc/kernel/sc_simcontext.cpp2284
-rw-r--r--ext/systemc/src/sysc/kernel/sc_simcontext.h903
-rw-r--r--ext/systemc/src/sysc/kernel/sc_simcontext_int.h365
-rw-r--r--ext/systemc/src/sysc/kernel/sc_spawn.h337
-rw-r--r--ext/systemc/src/sysc/kernel/sc_spawn_options.cpp124
-rw-r--r--ext/systemc/src/sysc/kernel/sc_spawn_options.h161
-rw-r--r--ext/systemc/src/sysc/kernel/sc_status.h83
-rw-r--r--ext/systemc/src/sysc/kernel/sc_thread_process.cpp1127
-rw-r--r--ext/systemc/src/sysc/kernel/sc_thread_process.h635
-rw-r--r--ext/systemc/src/sysc/kernel/sc_time.cpp465
-rw-r--r--ext/systemc/src/sysc/kernel/sc_time.h414
-rw-r--r--ext/systemc/src/sysc/kernel/sc_ver.cpp228
-rw-r--r--ext/systemc/src/sysc/kernel/sc_ver.h186
-rw-r--r--ext/systemc/src/sysc/kernel/sc_wait.cpp446
-rw-r--r--ext/systemc/src/sysc/kernel/sc_wait.h277
-rw-r--r--ext/systemc/src/sysc/kernel/sc_wait_cthread.cpp169
-rw-r--r--ext/systemc/src/sysc/kernel/sc_wait_cthread.h126
69 files changed, 24529 insertions, 0 deletions
diff --git a/ext/systemc/src/sysc/kernel/sc_attribute.cpp b/ext/systemc/src/sysc/kernel/sc_attribute.cpp
new file mode 100644
index 000000000..de89c6adf
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_attribute.cpp
@@ -0,0 +1,191 @@
+/*****************************************************************************
+
+ 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_attribute.cpp -- Attribute classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_attribute.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_attr_base
+//
+// Attribute base class.
+// ----------------------------------------------------------------------------
+
+// constructors
+
+sc_attr_base::sc_attr_base( const std::string& name_ )
+: m_name( name_ )
+{}
+
+sc_attr_base::sc_attr_base( const sc_attr_base& a )
+: m_name( a.m_name )
+{}
+
+
+// destructor (does nothing)
+
+sc_attr_base::~sc_attr_base()
+{}
+
+
+// get the name
+const std::string&
+sc_attr_base::name() const
+{
+ return m_name;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_attr_cltn
+//
+// Attribute collection class. Stores pointers to attributes.
+// Note: iterate over the collection by using iterators.
+// ----------------------------------------------------------------------------
+
+// constructors
+
+sc_attr_cltn::sc_attr_cltn() : m_cltn()
+{}
+
+sc_attr_cltn::sc_attr_cltn( const sc_attr_cltn& a )
+: m_cltn( a.m_cltn )
+{}
+
+
+// destructor
+sc_attr_cltn::~sc_attr_cltn()
+{
+ remove_all();
+}
+
+
+// add attribute to the collection.
+// returns 'true' if the name of the attribute is unique,
+// returns 'false' otherwise (attribute is not added).
+
+bool
+sc_attr_cltn::push_back( sc_attr_base* attribute_ )
+{
+ if( attribute_ == 0 ) {
+ return false;
+ }
+ for( int i = m_cltn.size() - 1; i >= 0; -- i ) {
+ if( attribute_->name() == m_cltn[i]->name() ) {
+ return false;
+ }
+ }
+ m_cltn.push_back( attribute_ );
+ return true;
+}
+
+
+// get attribute by name.
+// returns pointer to attribute, or 0 if name does not exist.
+
+sc_attr_base*
+sc_attr_cltn::operator [] ( const std::string& name_ )
+{
+ for( int i = m_cltn.size() - 1; i >= 0; -- i ) {
+ if( name_ == m_cltn[i]->name() ) {
+ return m_cltn[i];
+ }
+ }
+ return 0;
+}
+
+const sc_attr_base*
+sc_attr_cltn::operator [] ( const std::string& name_ ) const
+{
+ for( int i = m_cltn.size() - 1; i >= 0; -- i ) {
+ if( name_ == m_cltn[i]->name() ) {
+ return m_cltn[i];
+ }
+ }
+ return 0;
+}
+
+
+// remove attribute by name.
+// returns pointer to attribute, or 0 if name does not exist.
+
+sc_attr_base*
+sc_attr_cltn::remove( const std::string& name_ )
+{
+ for( int i = m_cltn.size() - 1; i >= 0; -- i ) {
+ if( name_ == m_cltn[i]->name() ) {
+ sc_attr_base* attribute = m_cltn[i];
+ std::swap( m_cltn[i], m_cltn.back() );
+ m_cltn.pop_back();
+ return attribute;
+ }
+ }
+ return 0;
+}
+
+
+// remove all attributes
+
+void
+sc_attr_cltn::remove_all()
+{
+ m_cltn.clear();
+}
+
+} // namespace sc_core
+
+// $Log: sc_attribute.cpp,v $
+// Revision 1.7 2011/08/26 20:46:08 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.6 2011/08/24 22:05:50 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.2 2008/05/22 17:06:24 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.4 2006/01/16 22:27:08 acg
+// Test of $Log comment.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_attribute.h b/ext/systemc/src/sysc/kernel/sc_attribute.h
new file mode 100644
index 000000000..0efa70de5
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_attribute.h
@@ -0,0 +1,209 @@
+/*****************************************************************************
+
+ 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_attribute.h -- Attribute classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_ATTRIBUTE_H
+#define SC_ATTRIBUTE_H
+
+#include <string>
+#include <vector>
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_attr_base
+//
+// Attribute base class.
+// ----------------------------------------------------------------------------
+
+class sc_attr_base
+{
+public:
+
+ // constructors
+ sc_attr_base( const std::string& name_ );
+ sc_attr_base( const sc_attr_base& );
+
+ // destructor (does nothing)
+ virtual ~sc_attr_base();
+
+ // get the name
+ const std::string& name() const;
+
+private:
+
+ std::string m_name;
+
+private:
+
+ // disabled
+ sc_attr_base();
+ sc_attr_base& operator = ( const sc_attr_base& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_attr_cltn
+//
+// Attribute collection class. Stores pointers to attributes.
+// Note: iterate over the collection by using iterators.
+// ----------------------------------------------------------------------------
+
+class sc_attr_cltn
+{
+public:
+
+ // typedefs
+ typedef sc_attr_base* elem_type;
+ typedef std::vector<elem_type>::iterator iterator;
+ typedef std::vector<elem_type>::const_iterator const_iterator;
+
+ // constructors
+ sc_attr_cltn();
+ sc_attr_cltn( const sc_attr_cltn& );
+
+ // destructor
+ ~sc_attr_cltn();
+
+ // add attribute to the collection.
+ // returns 'true' if the name of the attribute is unique,
+ // returns 'false' otherwise (attribute is not added).
+ bool push_back( sc_attr_base* );
+
+ // get attribute by name.
+ // returns pointer to attribute, or 0 if name does not exist.
+ sc_attr_base* operator [] ( const std::string& name_ );
+ const sc_attr_base* operator [] ( const std::string& name_ ) const;
+
+ // remove attribute by name.
+ // returns pointer to attribute, or 0 if name does not exist.
+ sc_attr_base* remove( const std::string& name_ );
+
+ // remove all attributes
+ void remove_all();
+
+ // get the size of the collection
+ int size() const
+ { return m_cltn.size(); }
+
+ // get the begin iterator
+ iterator begin()
+ { return m_cltn.begin(); }
+ const_iterator begin() const
+ { return m_cltn.begin(); }
+
+ // get the end iterator
+ iterator end()
+ { return m_cltn.end(); }
+ const_iterator end() const
+ { return m_cltn.end(); }
+
+private:
+ std::vector<sc_attr_base*> m_cltn;
+
+private:
+
+ // disabled
+ sc_attr_cltn& operator = ( const sc_attr_cltn& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_attribute<T>
+//
+// Attribute class.
+// Note: T must have a default constructor and copy constructor.
+// ----------------------------------------------------------------------------
+
+template <class T>
+class sc_attribute
+: public sc_attr_base
+{
+public:
+
+ // constructors
+
+ sc_attribute( const std::string& name_ )
+ : sc_attr_base( name_ ), value()
+ {}
+
+ sc_attribute( const std::string& name_, const T& value_ )
+ : sc_attr_base( name_ ), value( value_ )
+ {}
+
+ sc_attribute( const sc_attribute<T>& a )
+ : sc_attr_base( a.name() ), value( a.value )
+ {}
+
+
+ // destructor (does nothing)
+
+ virtual ~sc_attribute()
+ {}
+
+public:
+
+ // public data member; for easy access
+ T value;
+
+private:
+
+ // disabled
+ sc_attribute();
+ sc_attribute<T>& operator = ( const sc_attribute<T>& );
+};
+
+} // namespace sc_core
+
+// $Log: sc_attribute.h,v $
+// Revision 1.6 2011/08/26 20:46:08 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.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.2 2008/05/22 17:06:24 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.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_boost.h b/ext/systemc/src/sysc/kernel/sc_boost.h
new file mode 100644
index 000000000..4383c21c9
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_boost.h
@@ -0,0 +1,94 @@
+/*****************************************************************************
+
+ 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_boost.h -- Thread Semantics Provided By The Boost Library
+
+ Original Author: Stuart Swan, Cadence Design Systems, Inc
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_BOOST_H
+#define SC_BOOST_H
+
+// namespace sc_dp { This is off because of bugs with gcc 2.9x
+
+// SET THE NAME OF OBJECTS THAT THE SC_BOOST LIBRARY WILL PRODUCE AND INCLUDE IT
+
+#if defined(_MSC_VER) && !defined(__ICL) && !defined(__COMO__)
+# pragma warning(disable: 4786) // identifier truncated in debug info
+# pragma warning(disable: 4710) // function not inlined
+# pragma warning(disable: 4711) // funct. selected for auto-inline expansion
+# pragma warning(disable: 4514) // unreferenced inline removed
+#endif
+
+#include <functional>
+
+#if defined(SC_BOOST_MSVC) && (SC_BOOST_MSVC < 1300)
+# pragma warning(push, 3)
+#endif
+
+#if defined(SC_BOOST_MSVC) && (SC_BOOST_MSVC < 1300)
+# pragma warning(pop)
+#endif
+
+// } // namespace sc_dp This is off because of bugs with gcc 2.9x
+
+// macros to help avoid direct user code dependencies on boost lib
+//
+// note the use of the sc_boost namespace for the SystemC version of
+// boost. to replace the version shipped with SystemC with another boost
+// you will need to change the namespace prefix back to boost.
+
+#define sc_bind std::bind
+#define sc_ref(r) std::ref(r)
+#define sc_cref(r) std::cref(r)
+
+// $Log: sc_boost.h,v $
+// Revision 1.7 2011/08/26 20:46:09 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.6 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.5 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.4 2009/07/28 01:10:53 acg
+// Andy Goodrich: updates for 2.3 release candidate.
+//
+// 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:24 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.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif // SC_BOOST_H
diff --git a/ext/systemc/src/sysc/kernel/sc_cmnhdr.h b/ext/systemc/src/sysc/kernel/sc_cmnhdr.h
new file mode 100644
index 000000000..fcbb2f568
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cmnhdr.h
@@ -0,0 +1,138 @@
+/*****************************************************************************
+
+ 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_cmnhdr.h - Common header file containing handy pragmas, macros and
+ definitions common to all SystemC source files.
+
+ Original Author: Amit Rao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_CMNHDR_H
+#define SC_CMNHDR_H
+
+#if defined(_WIN32) || defined(_MSC_VER) || defined(__BORLANDC__) || \
+ defined(__MINGW32__)
+
+// all windows 32-bit compilers should define WIN32
+#if !defined(WIN32) && !defined(WIN64) && !defined(_WIN64)
+#define WIN32
+#endif
+
+// Windows Version Build Option
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0400
+#endif
+
+// remember to later include windows.h, if needed
+#define SC_HAS_WINDOWS_H_
+
+#endif // WIN32
+
+// ----------------------------------------------------------------------------
+
+#ifdef _MSC_VER
+
+// Disable VC++ warnings that are harmless
+
+// this : used in base member initializer list
+#pragma warning(disable: 4355)
+
+// new and delete warning when exception handling is turned on
+#pragma warning(disable: 4291)
+
+// in many places implicit conversion to bool
+// from other integral types is performed
+#pragma warning(disable: 4800)
+
+// unary minus operator applied to unsigned
+#pragma warning(disable: 4146)
+
+// multiple copy constructors
+#pragma warning(disable: 4521)
+
+// identifier was truncated to '255' characters in the browser information
+#pragma warning(disable: 4786)
+
+#endif
+
+// ----------------------------------------------------------------------------
+// helper macros to aid branch prediction on GCC (compatible) compilers
+
+#ifndef __GNUC__
+# define SC_LIKELY_( x ) !!(x)
+# define SC_UNLIKELY_( x ) !!(x)
+#else
+# define SC_LIKELY_( x ) __builtin_expect( !!(x), 1 )
+# define SC_UNLIKELY_( x ) __builtin_expect( !!(x), 0 )
+#endif
+
+// ----------------------------------------------------------------------------
+
+#include <cassert>
+#include <cstdio>
+#include <cstdlib>
+
+#endif // SC_CMNHDR_H
+
+// ----------------------------------------------------------------------------
+// only include Windows.h, if explicitly requested
+// (deliberately outside of include guards to enable later effect)
+#if defined(SC_HAS_WINDOWS_H_) && defined(SC_INCLUDE_WINDOWS_H)
+# undef SC_HAS_WINDOWS_H_
+# include <Windows.h>
+#endif
+
+// $Log: sc_cmnhdr.h,v $
+// Revision 1.8 2011/08/26 20:46:09 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.7 2011/05/09 04:07:48 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.6 2011/05/05 17:45:27 acg
+// Philip A. Hartmann: changes in WIN64 support.
+// Andy Goodrich: additional DEBUG_MSG instances to trace process handling.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.2 2008/05/22 17:06:24 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.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_constants.h b/ext/systemc/src/sysc/kernel/sc_constants.h
new file mode 100644
index 000000000..1ff20adbd
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_constants.h
@@ -0,0 +1,82 @@
+/*****************************************************************************
+
+ 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_constants.h -- Default constants whose values may need to be
+ changed depending on the application.
+
+ Original Author: Ali Dasdan, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_CONSTANTS_H
+#define SC_CONSTANTS_H
+
+namespace sc_core {
+
+// Maximum number of bits for arbitrary precision arithmetic. If
+// defined, the arithmetic becomes faster. If not defined, the
+// arithmetic becomes slower and the precision becomes infinite. It
+// is a good idea to define this constant as a multiple of
+// BITS_PER_DIGIT, which is defined in numeric_bit/sc_nbdefs.h.
+//#define SC_MAX_NBITS 510 // 17 * BITS_PER_DIGIT
+
+
+// deprecated in 1666-2005 and later, but kept for backwards compatibility
+// - can be set by defining SC_OVERRIDE_DEFAULT_STACK_SIZE
+// - defaults defined in sc_thread_process.cpp
+extern const int SC_DEFAULT_STACK_SIZE;
+
+
+#ifdef DEBUG_SYSTEMC
+const int SC_MAX_NUM_DELTA_CYCLES = 10000;
+#endif
+
+} // namespace sc_core
+
+// $Log: sc_constants.h,v $
+// Revision 1.7 2011/08/26 20:46:09 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.6 2011/02/18 20:33:26 acg
+// Philipp A. Hartmann: added default stack size for CYGWIN32.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2010/03/15 18:29:25 acg
+// Andy Goodrich: Changed the default stack size to 128K from 64K.
+//
+// Revision 1.2 2008/05/22 17:06:24 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.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_cor.h b/ext/systemc/src/sysc/kernel/sc_cor.h
new file mode 100644
index 000000000..49892ca7a
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cor.h
@@ -0,0 +1,157 @@
+/*****************************************************************************
+
+ 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_cor.h -- Coroutine abstract base classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-12-18
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_COR_H
+#define SC_COR_H
+
+
+#include <cassert>
+#include <cstdlib>
+
+namespace sc_core {
+
+class sc_simcontext;
+
+
+// ----------------------------------------------------------------------------
+// TYPEDEF : sc_cor_fn
+//
+// Function type for creating coroutines.
+// ----------------------------------------------------------------------------
+
+typedef void (sc_cor_fn)( void* );
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor
+//
+// Coroutine abstract base class.
+// ----------------------------------------------------------------------------
+
+class sc_cor
+{
+protected:
+
+ // constructor
+ sc_cor() {}
+
+public:
+
+ // destructor
+ virtual ~sc_cor() {}
+
+ // switch stack protection on/off
+ virtual void stack_protect( bool /* enable */ ) {}
+
+private:
+
+ // disabled
+ sc_cor( const sc_cor& );
+ sc_cor& operator = ( const sc_cor& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pkg
+//
+// Coroutine package abstract base class.
+// ----------------------------------------------------------------------------
+
+class sc_cor_pkg
+{
+public:
+
+ // constructor
+ sc_cor_pkg( sc_simcontext* simc )
+ : m_simc( simc ) { assert( simc != 0 ); }
+
+ // destructor
+ virtual ~sc_cor_pkg() {}
+
+ // create a new coroutine
+ virtual sc_cor* create(
+ std::size_t stack_size, sc_cor_fn* fn, void* arg ) = 0;
+
+ // yield to the next coroutine
+ virtual void yield( sc_cor* next_cor ) = 0;
+
+ // abort the current coroutine (and resume the next coroutine)
+ virtual void abort( sc_cor* next_cor ) = 0;
+
+ // get the main coroutine
+ virtual sc_cor* get_main() = 0;
+
+ // get the simulation context
+ sc_simcontext* simcontext()
+ { return m_simc; }
+
+private:
+
+ sc_simcontext* m_simc;
+
+private:
+
+ // disabled
+ sc_cor_pkg();
+ sc_cor_pkg( const sc_cor_pkg& );
+ sc_cor_pkg& operator = ( const sc_cor_pkg& );
+};
+
+} // namespace sc_core
+
+// $Log: sc_cor.h,v $
+// Revision 1.7 2011/08/26 20:46:09 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.6 2011/08/15 16:43:24 acg
+// Torsten Maehne: changes to remove unused argument warnings.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2011/01/19 23:21:49 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.2 2008/05/22 17:06:24 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.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_cor_fiber.cpp b/ext/systemc/src/sysc/kernel/sc_cor_fiber.cpp
new file mode 100644
index 000000000..77cec8227
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cor_fiber.cpp
@@ -0,0 +1,224 @@
+/*****************************************************************************
+
+ 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_cor_fiber.cpp -- Coroutine implementation with fibers.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-12-18
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#if defined(_WIN32) || defined(WIN32) || defined(WIN64)
+
+#ifndef SC_INCLUDE_WINDOWS_H
+# define SC_INCLUDE_WINDOWS_H // include Windows.h, if needed
+#endif
+
+#include "sysc/kernel/sc_cor_fiber.h"
+#include "sysc/kernel/sc_simcontext.h"
+#if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+# if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ > 2))
+# include <unwind.h>
+# else
+ extern "C" void _Unwind_SjLj_Register (struct SjLj_Function_Context *);
+ extern "C" void _Unwind_SjLj_Unregister (struct SjLj_Function_Context *);
+# endif
+#endif
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// File static variables.
+// ----------------------------------------------------------------------------
+
+// main coroutine
+
+static sc_cor_fiber main_cor;
+#if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+// current coroutine
+static sc_cor_fiber* curr_cor;
+#endif
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_fiber
+//
+// Coroutine class implemented with Windows fibers.
+// ----------------------------------------------------------------------------
+
+// destructor
+
+sc_cor_fiber::~sc_cor_fiber()
+{
+ if( m_fiber != 0 ) {
+ PVOID cur_fiber = GetCurrentFiber();
+ if (m_fiber != cur_fiber)
+ DeleteFiber( m_fiber );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pkg_fiber
+//
+// Coroutine package class implemented with QuickThreads.
+// ----------------------------------------------------------------------------
+
+int sc_cor_pkg_fiber::instance_count = 0;
+
+
+// constructor
+
+sc_cor_pkg_fiber::sc_cor_pkg_fiber( sc_simcontext* simc )
+: sc_cor_pkg( simc )
+{
+ if( ++ instance_count == 1 ) {
+ // initialize the main coroutine
+ assert( main_cor.m_fiber == 0 );
+ main_cor.m_fiber = ConvertThreadToFiber( 0 );
+
+ if( !main_cor.m_fiber && GetLastError() == ERROR_ALREADY_FIBER ) {
+ // conversion of current thread to fiber has failed, because
+ // someone else already converted the main thread to a fiber
+ // -> store current fiber
+ main_cor.m_fiber = GetCurrentFiber();
+ }
+ assert( main_cor.m_fiber != 0 );
+
+# if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+ // initialize the current coroutine
+ assert( curr_cor == 0 );
+ curr_cor = &main_cor;
+# endif
+ }
+}
+
+
+// destructor
+
+sc_cor_pkg_fiber::~sc_cor_pkg_fiber()
+{
+ if( -- instance_count == 0 ) {
+ // cleanup the main coroutine
+ main_cor.m_fiber = 0;
+# if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+ // cleanup the current coroutine
+ curr_cor = 0;
+# endif
+ }
+}
+
+
+// create a new coroutine
+
+sc_cor*
+sc_cor_pkg_fiber::create( std::size_t stack_size, sc_cor_fn* fn, void* arg )
+{
+ sc_cor_fiber* cor = new sc_cor_fiber;
+ cor->m_pkg = this;
+ cor->m_stack_size = stack_size;
+ cor->m_fiber = CreateFiberEx( cor->m_stack_size / 2, cor->m_stack_size, 0,
+ (LPFIBER_START_ROUTINE) fn, arg );
+ return cor;
+}
+
+
+// yield to the next coroutine
+
+void
+sc_cor_pkg_fiber::yield( sc_cor* next_cor )
+{
+ sc_cor_fiber* new_cor = SCAST<sc_cor_fiber*>( next_cor );
+# if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+ // Switch SJLJ exception handling function contexts
+ _Unwind_SjLj_Register(&curr_cor->m_eh);
+ _Unwind_SjLj_Unregister(&new_cor->m_eh);
+ curr_cor = new_cor;
+# endif
+ SwitchToFiber( new_cor->m_fiber );
+}
+
+
+// abort the current coroutine (and resume the next coroutine)
+
+void
+sc_cor_pkg_fiber::abort( sc_cor* next_cor )
+{
+ sc_cor_fiber* new_cor = SCAST<sc_cor_fiber*>( next_cor );
+# if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+ // Switch SJLJ exception handling function contexts
+ _Unwind_SjLj_Register(&curr_cor->m_eh);
+ _Unwind_SjLj_Unregister(&new_cor->m_eh);
+ curr_cor = new_cor;
+# endif
+ SwitchToFiber( new_cor->m_fiber );
+}
+
+
+// get the main coroutine
+
+sc_cor*
+sc_cor_pkg_fiber::get_main()
+{
+ return &main_cor;
+}
+
+} // namespace sc_core
+
+
+// $Log: sc_cor_fiber.cpp,v $
+// Revision 1.9 2011/09/08 16:12:45 acg
+// Philipp A. Hartmann: make sure we don't try to make a thread a fiber if
+// its already a fiber.
+//
+// Revision 1.8 2011/08/26 20:46:09 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.7 2011/06/25 17:08:39 acg
+// Andy Goodrich: Jerome Cornet's changes to use libtool to build the
+// library.
+//
+// Revision 1.6 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.5 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.4 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.2 2008/05/22 17:06:25 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.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_cor_fiber.h b/ext/systemc/src/sysc/kernel/sc_cor_fiber.h
new file mode 100644
index 000000000..96163f497
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cor_fiber.h
@@ -0,0 +1,169 @@
+/*****************************************************************************
+
+ 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_cor_fiber.h -- Coroutine implementation with fibers.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-12-18
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_COR_FIBER_H
+#define SC_COR_FIBER_H
+
+#if defined(_WIN32) || defined(WIN32) || defined(WIN64)
+
+#include "sysc/kernel/sc_cor.h"
+#include "sysc/kernel/sc_cmnhdr.h"
+
+#if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+ // _Unwind_SjLj_Register() & _Unwind_SjLj_Unregister() only need first field.
+ struct SjLj_Function_Context {
+ struct SjLj_Function_Context *prev;
+ };
+#endif
+
+namespace sc_core {
+
+class sc_cor_pkg_fiber;
+typedef sc_cor_pkg_fiber sc_cor_pkg_t;
+
+#if( defined(_MSC_VER) && _MSC_VER >= 1300 )
+typedef std::size_t size_t;
+#endif
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_fiber
+//
+// Coroutine class implemented with QuickThreads.
+// ----------------------------------------------------------------------------
+
+class sc_cor_fiber
+: public sc_cor
+{
+
+public:
+
+ // constructor
+ sc_cor_fiber()
+ : m_stack_size( 0 ), m_fiber( 0 ), m_pkg( 0 )
+ {
+# if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+ m_eh.prev = 0;
+# endif
+ }
+
+ // destructor
+ virtual ~sc_cor_fiber();
+
+public:
+
+ std::size_t m_stack_size; // stack size
+ void* m_fiber; // fiber
+
+ sc_cor_pkg_fiber* m_pkg; // the creating coroutine package
+#if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
+ struct SjLj_Function_Context m_eh; // the exception handling context
+#endif
+
+
+private:
+
+ // disabled
+ sc_cor_fiber( const sc_cor_fiber& );
+ sc_cor_fiber& operator = ( const sc_cor_fiber& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pkg_fiber
+//
+// Coroutine package class implemented with QuickThreads.
+// ----------------------------------------------------------------------------
+
+class sc_cor_pkg_fiber
+: public sc_cor_pkg
+{
+ public:
+
+ // constructor
+ sc_cor_pkg_fiber( sc_simcontext* simc );
+
+ // destructor
+ virtual ~sc_cor_pkg_fiber();
+
+ // create a new coroutine
+ virtual sc_cor* create( std::size_t stack_size, sc_cor_fn* fn, void* arg );
+
+ // yield to the next coroutine
+ virtual void yield( sc_cor* next_cor );
+
+ // abort the current coroutine (and resume the next coroutine)
+ virtual void abort( sc_cor* next_cor );
+
+ // get the main coroutine
+ virtual sc_cor* get_main();
+
+private:
+
+ static int instance_count;
+
+private:
+
+ // disabled
+ sc_cor_pkg_fiber();
+ sc_cor_pkg_fiber( const sc_cor_pkg_fiber& );
+ sc_cor_pkg_fiber& operator = ( const sc_cor_pkg_fiber& );
+};
+
+} // namespace sc_core
+
+#endif // WIN32
+
+// $Log: sc_cor_fiber.h,v $
+// Revision 1.6 2011/08/26 20:46:09 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.5 2011/06/25 17:08:39 acg
+// Andy Goodrich: Jerome Cornet's changes to use libtool to build the
+// library.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:25 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.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_cor_pthread.cpp b/ext/systemc/src/sysc/kernel/sc_cor_pthread.cpp
new file mode 100644
index 000000000..d95eca93b
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cor_pthread.cpp
@@ -0,0 +1,313 @@
+/*****************************************************************************
+
+ 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_cor_pthread.cpp -- Coroutine implementation with pthreads.
+
+ Original Author: Andy Goodrich, Forte Design Systems, 2002-11-10
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#if !defined(_WIN32) && !defined(WIN32) && defined(SC_USE_PTHREADS)
+
+// ORDER OF THE INCLUDES AND namespace sc_core IS IMPORTANT!!!
+
+#include "sysc/kernel/sc_cor_pthread.h"
+#include "sysc/kernel/sc_simcontext.h"
+
+using namespace std;
+
+namespace sc_core {
+
+// MAKE SURE WE HAVE A NULL THAT WILL WORK:
+
+#if defined(__hpux)
+# define PTHREAD_NULL cma_c_null
+#else // !defined(__hpux)
+# define PTHREAD_NULL NULL
+#endif // !defined(__hpux)
+
+#define DEBUGF \
+ if (0) std::cout << "sc_cor_pthread.cpp(" << __LINE__ << ") "
+
+// ----------------------------------------------------------------------------
+// File static variables.
+//
+// (1) The thread creation mutex and the creation condition are used to
+// suspend the thread creating another one until the created thread
+// reaches its invoke_module_method. This allows us to get control of
+// thread scheduling away from the pthread package.
+// ----------------------------------------------------------------------------
+
+static sc_cor_pthread* active_cor_p=0; // Active co-routine.
+static pthread_cond_t create_condition; // See note 1 above.
+static pthread_mutex_t create_mutex; // See note 1 above.
+static sc_cor_pthread main_cor; // Main coroutine.
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pthread
+//
+// Coroutine class implemented with Posix Threads.
+// ----------------------------------------------------------------------------
+
+// constructor
+
+sc_cor_pthread::sc_cor_pthread()
+ : m_cor_fn_arg( 0 ), m_pkg_p( 0 )
+{
+ DEBUGF << this << ": sc_cor_pthread::sc_cor_pthread()" << std::endl;
+ pthread_cond_init( &m_pt_condition, PTHREAD_NULL );
+ pthread_mutex_init( &m_mutex, PTHREAD_NULL );
+}
+
+
+// destructor
+
+sc_cor_pthread::~sc_cor_pthread()
+{
+ DEBUGF << this << ": sc_cor_pthread::~sc_cor_pthread()" << std::endl;
+ pthread_cond_destroy( &m_pt_condition);
+ pthread_mutex_destroy( &m_mutex );
+}
+
+
+// This static method is a Posix Threads helper callback and invokes a thread
+// for the first time. It performs some synchronization and then invokes the
+// actual sc_cor helper function.
+// context_p -> thread to invoke module method of.
+// Result is 0 and ignored.
+
+void* sc_cor_pthread::invoke_module_method(void* context_p)
+{
+ sc_cor_pthread* p = (sc_cor_pthread*)context_p;
+ DEBUGF << p << ": sc_cor_pthread::invoke_module_method()" << std::endl;
+
+
+ // SUSPEND THE THREAD SO WE CAN GAIN CONTROL FROM THE PTHREAD PACKAGE:
+ //
+ // Since pthread_create schedules each thread behind our back for its
+ // initial execution we immediately suspend a newly created thread
+ // here so we can control when its execution will occur. We also wake
+ // up the main thread which is waiting for this thread to execute to this
+ // wait point.
+
+ pthread_mutex_lock( &create_mutex );
+ DEBUGF << p << ": child signalling main thread " << endl;
+ pthread_cond_signal( &create_condition );
+ pthread_mutex_lock( &p->m_mutex );
+ pthread_mutex_unlock( &create_mutex );
+ pthread_cond_wait( &p->m_pt_condition, &p->m_mutex );
+ pthread_mutex_unlock( &p->m_mutex );
+
+
+ // CALL THE SYSTEMC CODE THAT WILL ACTUALLY START THE THREAD OFF:
+
+ active_cor_p = p;
+ DEBUGF << p << ": about to invoke real method "
+ << active_cor_p << std::endl;
+ (p->m_cor_fn)(p->m_cor_fn_arg);
+
+ return 0;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pkg_pthread
+//
+// Coroutine package class implemented with Posix Threads.
+// ----------------------------------------------------------------------------
+
+int sc_cor_pkg_pthread::instance_count = 0;
+
+
+// constructor
+
+sc_cor_pkg_pthread::sc_cor_pkg_pthread( sc_simcontext* simc )
+: sc_cor_pkg( simc )
+{
+ // initialize the current coroutine
+ if( ++ instance_count == 1 )
+ {
+ pthread_cond_init( &create_condition, PTHREAD_NULL );
+ pthread_mutex_init( &create_mutex, PTHREAD_NULL );
+ assert( active_cor_p == 0 );
+ main_cor.m_pkg_p = this;
+ DEBUGF << &main_cor << ": is main co-routine" << std::endl;
+ active_cor_p = &main_cor;
+ }
+}
+
+
+// destructor
+
+sc_cor_pkg_pthread::~sc_cor_pkg_pthread()
+{
+ if( -- instance_count == 0 ) {
+ // cleanup the main coroutine
+ }
+}
+
+
+// create a new coroutine
+
+sc_cor*
+sc_cor_pkg_pthread::create( std::size_t stack_size, sc_cor_fn* fn, void* arg )
+{
+ sc_cor_pthread* cor_p = new sc_cor_pthread;
+ DEBUGF << &main_cor << ": sc_cor_pkg_pthread::create("
+ << cor_p << ")" << std::endl;
+
+
+ // INITIALIZE OBJECT'S FIELDS FROM ARGUMENT LIST:
+
+ cor_p->m_pkg_p = this;
+ cor_p->m_cor_fn = fn;
+ cor_p->m_cor_fn_arg = arg;
+
+
+ // SET UP THREAD CREATION ATTRIBUTES:
+ //
+ // Use default values except for stack size. If stack size is non-zero
+ // set it.
+
+ pthread_attr_t attr;
+ pthread_attr_init( &attr );
+ if ( stack_size != 0 )
+ {
+ pthread_attr_setstacksize( &attr, stack_size );
+ }
+
+
+ // ALLOCATE THE POSIX THREAD TO USE AND FORCE SEQUENTIAL EXECUTION:
+ //
+ // Because pthread_create causes the created thread to be executed,
+ // we need to let it run until we can block in the invoke_module_method.
+ // So we:
+ // (1) Lock the creation mutex before creating the new thread.
+ // (2) Sleep on the creation condition, which will be signalled by
+ // the newly created thread just before it goes to sleep in
+ // invoke_module_method.
+ // This scheme results in the newly created thread being dormant before
+ // the main thread continues execution.
+
+ pthread_mutex_lock( &create_mutex );
+ DEBUGF << &main_cor << ": about to create actual thread "
+ << cor_p << std::endl;
+ if ( pthread_create( &cor_p->m_thread, &attr,
+ &sc_cor_pthread::invoke_module_method, (void*)cor_p ) )
+ {
+ std::fprintf(stderr, "ERROR - could not create thread\n");
+ }
+
+ DEBUGF << &main_cor << ": main thread waiting for signal from "
+ << cor_p << std::endl;
+ pthread_cond_wait( &create_condition, &create_mutex );
+ DEBUGF << &main_cor << ": main thread signaled by "
+ << cor_p << endl;
+ pthread_attr_destroy( &attr );
+ pthread_mutex_unlock( &create_mutex );
+ DEBUGF << &main_cor << ": exiting sc_cor_pkg_pthread::create("
+ << cor_p << ")" << std::endl;
+
+ return cor_p;
+}
+
+
+// yield to the next coroutine
+//
+// We don't do anything after the p_thread_cond_wait since it won't
+// happen until the thread wakes up again!
+
+void
+sc_cor_pkg_pthread::yield( sc_cor* next_cor_p )
+{
+ sc_cor_pthread* from_p = active_cor_p;
+ sc_cor_pthread* to_p = (sc_cor_pthread*)next_cor_p;
+
+ DEBUGF << from_p << ": switch to " << to_p << std::endl;
+ if ( to_p != from_p )
+ {
+ pthread_mutex_lock( &to_p->m_mutex );
+ pthread_cond_signal( &to_p->m_pt_condition );
+ pthread_mutex_lock( &from_p->m_mutex );
+ pthread_mutex_unlock( &to_p->m_mutex );
+ pthread_cond_wait( &from_p->m_pt_condition, &from_p->m_mutex );
+ pthread_mutex_unlock( &from_p->m_mutex );
+ }
+
+ active_cor_p = from_p; // When we come out of wait make ourselves active.
+ DEBUGF << from_p << " restarting after yield to " << to_p << std::endl;
+}
+
+
+// abort the current coroutine (and resume the next coroutine)
+
+void
+sc_cor_pkg_pthread::abort( sc_cor* next_cor_p )
+{
+ sc_cor_pthread* n_p = (sc_cor_pthread*)next_cor_p;
+
+ DEBUGF << active_cor_p << ": aborting, switching to " << n_p << std::endl;
+ pthread_mutex_lock( &n_p->m_mutex );
+ pthread_cond_signal( &n_p->m_pt_condition );
+ pthread_mutex_unlock( &n_p->m_mutex );
+}
+
+
+// get the main coroutine
+
+sc_cor*
+sc_cor_pkg_pthread::get_main()
+{
+ return &main_cor;
+}
+
+} // namespace sc_core
+
+#endif // !defined(_WIN32) && !defined(WIN32) && defined(SC_USE_PTHREADS)
+
+
+// $Log: sc_cor_pthread.cpp,v $
+// Revision 1.6 2011/08/30 21:51:04 acg
+// Jerome Cornet: auto processing of pthread configurations.
+//
+// Revision 1.5 2011/08/26 20:46:09 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.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:25 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.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_cor_pthread.h b/ext/systemc/src/sysc/kernel/sc_cor_pthread.h
new file mode 100644
index 000000000..f4d835de3
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cor_pthread.h
@@ -0,0 +1,157 @@
+/*****************************************************************************
+
+ 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_cor_pthread.h -- Coroutine implementation with pthreads.
+
+ Original Author: Andy Goodrich, Forte Design Systems, 2002-11-10
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_COR_PTHREAD_H
+#define SC_COR_PTHREAD_H
+
+
+#if defined(SC_USE_PTHREADS)
+
+#include "sysc/kernel/sc_cor.h"
+#include "sysc/kernel/sc_cmnhdr.h"
+#include <pthread.h>
+
+namespace sc_core {
+
+class sc_cor_pkg_pthread;
+typedef sc_cor_pkg_pthread sc_cor_pkg_t;
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pthread
+//
+// Coroutine class implemented with Posix Threads.
+//
+// Notes:
+// (1) The thread creation mutex and the creation condition are used to
+// suspend the thread creating another one until the created thread
+// reaches its invoke_module_method. This allows us to get control of
+// thread scheduling away from the pthread package.
+// ----------------------------------------------------------------------------
+
+class sc_cor_pthread : public sc_cor
+{
+ public:
+
+ // constructor
+ sc_cor_pthread();
+
+ // destructor
+ virtual ~sc_cor_pthread();
+
+ // module method invocator (starts thread execution)
+ static void* invoke_module_method( void* context_p );
+
+ public:
+ static sc_cor_pthread* m_active_cor_p; // Active coroutine.
+
+ public:
+ sc_cor_fn* m_cor_fn; // Core function.
+ void* m_cor_fn_arg; // Core function argument.
+ pthread_mutex_t m_mutex; // Mutex to suspend thread on.
+ sc_cor_pkg_pthread* m_pkg_p; // the creating coroutine package
+ pthread_cond_t m_pt_condition; // Condition waiting for.
+ pthread_t m_thread; // Our pthread storage.
+
+private:
+
+ // disabled
+ sc_cor_pthread( const sc_cor_pthread& );
+ sc_cor_pthread& operator = ( const sc_cor_pthread& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pkg_pthread
+//
+// Coroutine package class implemented with Posix Threads.
+// ----------------------------------------------------------------------------
+
+class sc_cor_pkg_pthread
+: public sc_cor_pkg
+{
+public:
+
+ // constructor
+ sc_cor_pkg_pthread( sc_simcontext* simc );
+
+ // destructor
+ virtual ~sc_cor_pkg_pthread();
+
+ // create a new coroutine
+ virtual sc_cor* create( std::size_t stack_size, sc_cor_fn* fn, void* arg );
+
+ // yield to the next coroutine
+ virtual void yield( sc_cor* next_cor );
+
+ // abort the current coroutine (and resume the next coroutine)
+ virtual void abort( sc_cor* next_cor );
+
+ // get the main coroutine
+ virtual sc_cor* get_main();
+
+private:
+
+ static int instance_count;
+
+private:
+
+ // disabled
+ sc_cor_pkg_pthread();
+ sc_cor_pkg_pthread( const sc_cor_pkg_pthread& );
+ sc_cor_pkg_pthread& operator = ( const sc_cor_pkg_pthread& );
+};
+
+} // namespace sc_core
+
+#endif
+
+// $Log: sc_cor_pthread.h,v $
+// Revision 1.5 2011/08/26 20:46:09 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.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:25 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.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif // defined(SC_USE_PTHREADS)
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_cor_qt.cpp b/ext/systemc/src/sysc/kernel/sc_cor_qt.cpp
new file mode 100644
index 000000000..d42298a62
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cor_qt.cpp
@@ -0,0 +1,271 @@
+/*****************************************************************************
+
+ 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_cor_qt.cpp -- Coroutine implementation with QuickThreads.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-12-18
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#if !defined(_WIN32) && !defined(WIN32) && !defined(SC_USE_PTHREADS)
+
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+
+#include "sysc/kernel/sc_cor_qt.h"
+#include "sysc/kernel/sc_simcontext.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// File static variables.
+// ----------------------------------------------------------------------------
+
+// main coroutine
+
+static sc_cor_qt main_cor;
+
+// current coroutine
+
+static sc_cor_qt* curr_cor = 0;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_qt
+//
+// Coroutine class implemented with QuickThreads.
+// ----------------------------------------------------------------------------
+
+// switch stack protection on/off
+
+void
+sc_cor_qt::stack_protect( bool enable )
+{
+ // Code needs to be tested on HP-UX and disabled if it doesn't work there
+ // Code still needs to be ported to WIN32
+
+ static std::size_t pagesize;
+
+ if( pagesize == 0 ) {
+# if defined(__ppc__)
+ pagesize = getpagesize();
+# else
+ pagesize = sysconf( _SC_PAGESIZE );
+# endif
+ }
+
+ assert( pagesize != 0 );
+ assert( m_stack_size > ( 2 * pagesize ) );
+
+#ifdef QUICKTHREADS_GROW_DOWN
+ // Stacks grow from high address down to low address
+ caddr_t redzone = caddr_t( ( ( std::size_t( m_stack ) + pagesize - 1 ) /
+ pagesize ) * pagesize );
+#else
+ // Stacks grow from low address up to high address
+ caddr_t redzone = caddr_t( ( ( std::size_t( m_stack ) +
+ m_stack_size - pagesize ) /
+ pagesize ) * pagesize );
+#endif
+
+ int ret;
+
+ // Enable the red zone at the end of the stack so that references within
+ // it will cause an interrupt.
+
+ if( enable ) {
+ ret = mprotect( redzone, pagesize - 1, PROT_NONE );
+ }
+
+ // Revert the red zone to normal memory usage. Try to make it read - write -
+ // execute. If that does not work then settle for read - write
+
+ else {
+ ret = mprotect( redzone, pagesize - 1, PROT_READ|PROT_WRITE|PROT_EXEC);
+ if ( ret != 0 )
+ ret = mprotect( redzone, pagesize - 1, PROT_READ | PROT_WRITE );
+ }
+
+ assert( ret == 0 );
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pkg_qt
+//
+// Coroutine package class implemented with QuickThreads.
+// ----------------------------------------------------------------------------
+
+int sc_cor_pkg_qt::instance_count = 0;
+
+
+// support function
+
+inline
+void*
+stack_align( void* sp, int alignment, std::size_t* stack_size )
+{
+ int round_up_mask = alignment - 1;
+ *stack_size = (*stack_size + round_up_mask) & ~round_up_mask;
+ return ( (void*)(((qt_word_t) sp + round_up_mask) & ~round_up_mask) );
+}
+
+
+// constructor
+
+sc_cor_pkg_qt::sc_cor_pkg_qt( sc_simcontext* simc )
+: sc_cor_pkg( simc )
+{
+ if( ++ instance_count == 1 ) {
+ // initialize the current coroutine
+ assert( curr_cor == 0 );
+ curr_cor = &main_cor;
+ }
+}
+
+
+// destructor
+
+sc_cor_pkg_qt::~sc_cor_pkg_qt()
+{
+ if( -- instance_count == 0 ) {
+ // cleanup the current coroutine
+ curr_cor = 0;
+ }
+}
+
+
+// create a new coroutine
+
+extern "C"
+void
+sc_cor_qt_wrapper( void* arg, void* cor, qt_userf_t* fn )
+{
+ curr_cor = RCAST<sc_cor_qt*>( cor );
+ // invoke the user function
+ (*(sc_cor_fn*) fn)( arg );
+ // not reached
+}
+
+sc_cor*
+sc_cor_pkg_qt::create( std::size_t stack_size, sc_cor_fn* fn, void* arg )
+{
+ sc_cor_qt* cor = new sc_cor_qt();
+ cor->m_pkg = this;
+ cor->m_stack_size = stack_size;
+ cor->m_stack = new char[cor->m_stack_size];
+ void* sto = stack_align( cor->m_stack, QUICKTHREADS_STKALIGN,
+ &cor->m_stack_size );
+ cor->m_sp = QUICKTHREADS_SP(sto, cor->m_stack_size - QUICKTHREADS_STKALIGN);
+ cor->m_sp = QUICKTHREADS_ARGS( cor->m_sp, arg, cor, (qt_userf_t*) fn,
+ sc_cor_qt_wrapper );
+ return cor;
+}
+
+
+// yield to the next coroutine
+
+extern "C"
+void*
+sc_cor_qt_yieldhelp( qt_t* sp, void* old_cor, void* )
+{
+ RCAST<sc_cor_qt*>( old_cor )->m_sp = sp;
+ return 0;
+}
+
+void
+sc_cor_pkg_qt::yield( sc_cor* next_cor )
+{
+ sc_cor_qt* new_cor = SCAST<sc_cor_qt*>( next_cor );
+ sc_cor_qt* old_cor = curr_cor;
+ curr_cor = new_cor;
+ QUICKTHREADS_BLOCK( sc_cor_qt_yieldhelp, old_cor, 0, new_cor->m_sp );
+}
+
+
+// abort the current coroutine (and resume the next coroutine)
+
+extern "C"
+void*
+sc_cor_qt_aborthelp( qt_t*, void*, void* )
+{
+ return 0;
+}
+
+void
+sc_cor_pkg_qt::abort( sc_cor* next_cor )
+{
+ sc_cor_qt* new_cor = SCAST<sc_cor_qt*>( next_cor );
+ sc_cor_qt* old_cor = curr_cor;
+ curr_cor = new_cor;
+ QUICKTHREADS_ABORT( sc_cor_qt_aborthelp, old_cor, 0, new_cor->m_sp );
+}
+
+
+// get the main coroutine
+
+sc_cor*
+sc_cor_pkg_qt::get_main()
+{
+ return &main_cor;
+}
+
+} // namespace sc_core
+
+#endif
+
+// $Log: sc_cor_qt.cpp,v $
+// Revision 1.9 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.8 2011/08/26 20:46:09 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.7 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.6 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.5 2010/08/03 16:52:14 acg
+// Andy Goodrich: line formatting.
+//
+// Revision 1.4 2008/11/11 14:03:07 acg
+// Andy Goodrich: added execute access to the release of red zone storage
+// per Ulli's suggestion.
+//
+// Revision 1.3 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2008/03/24 18:32:36 acg
+// Andy Goodrich: added include of sys/types.h to pick up the declaration
+// of caddr_t.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_cor_qt.h b/ext/systemc/src/sysc/kernel/sc_cor_qt.h
new file mode 100644
index 000000000..644d39c3f
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cor_qt.h
@@ -0,0 +1,154 @@
+/*****************************************************************************
+
+ 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_cor_qt.h -- Coroutine implementation with QuickThreads.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-12-18
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_COR_QT_H
+#define SC_COR_QT_H
+
+
+#if !defined(_WIN32) && !defined(WIN32) && !defined(WIN64) && !defined(SC_USE_PTHREADS)
+
+#include "sysc/kernel/sc_cor.h"
+#include "sysc/qt/qt.h"
+
+namespace sc_core {
+
+class sc_cor_pkg_qt;
+typedef sc_cor_pkg_qt sc_cor_pkg_t;
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_qt
+//
+// Coroutine class implemented with QuickThreads.
+// ----------------------------------------------------------------------------
+
+class sc_cor_qt
+: public sc_cor
+{
+public:
+
+ // constructor
+ sc_cor_qt()
+ : m_stack_size( 0 ), m_stack( 0 ), m_sp( 0 ), m_pkg( 0 )
+ {}
+
+ // destructor
+ virtual ~sc_cor_qt()
+ { delete[] (char*) m_stack; }
+
+ // switch stack protection on/off
+ virtual void stack_protect( bool enable );
+
+public:
+
+ std::size_t m_stack_size; // stack size
+ void* m_stack; // stack
+ qt_t* m_sp; // stack pointer
+
+ sc_cor_pkg_qt* m_pkg; // the creating coroutine package
+
+private:
+
+ // disabled
+ sc_cor_qt( const sc_cor_qt& );
+ sc_cor_qt& operator = ( const sc_cor_qt& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_cor_pkg_qt
+//
+// Coroutine package class implemented with QuickThreads.
+// ----------------------------------------------------------------------------
+
+class sc_cor_pkg_qt
+: public sc_cor_pkg
+{
+public:
+
+ // constructor
+ sc_cor_pkg_qt( sc_simcontext* simc );
+
+ // destructor
+ virtual ~sc_cor_pkg_qt();
+
+ // create a new coroutine
+ virtual sc_cor* create( std::size_t stack_size, sc_cor_fn* fn, void* arg );
+
+ // yield to the next coroutine
+ virtual void yield( sc_cor* next_cor );
+
+ // abort the current coroutine (and resume the next coroutine)
+ virtual void abort( sc_cor* next_cor );
+
+ // get the main coroutine
+ virtual sc_cor* get_main();
+
+private:
+
+ static int instance_count;
+
+private:
+
+ // disabled
+ sc_cor_pkg_qt();
+ sc_cor_pkg_qt( const sc_cor_pkg_qt& );
+ sc_cor_pkg_qt& operator = ( const sc_cor_pkg_qt& );
+};
+
+} // namespace sc_core
+
+#endif
+
+// $Log: sc_cor_qt.h,v $
+// Revision 1.6 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.5 2011/08/26 20:46:09 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.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:25 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.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_cthread_process.cpp b/ext/systemc/src/sysc/kernel/sc_cthread_process.cpp
new file mode 100644
index 000000000..fef5cc8d8
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cthread_process.cpp
@@ -0,0 +1,123 @@
+/*****************************************************************************
+
+ 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_cthread_process.cpp -- Clocked thread implementation.
+
+ Original Author: Andy Goodrich, Forte Design Systems, 4 August 2005
+
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_cthread_process.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+
+namespace sc_core {
+
+//------------------------------------------------------------------------------
+//"sc_cthread_process::dont_initialize"
+//
+// This virtual method sets the initialization switch for this object instance.
+//------------------------------------------------------------------------------
+void sc_cthread_process::dont_initialize( bool /* dont */ )
+{
+ SC_REPORT_WARNING( SC_ID_DONT_INITIALIZE_, 0 );
+}
+
+//------------------------------------------------------------------------------
+//"sc_cthread_process::sc_cthread_process"
+//
+// This is the object instance constructor for this class.
+//------------------------------------------------------------------------------
+sc_cthread_process::sc_cthread_process( const char* name_p,
+ bool free_host, SC_ENTRY_FUNC method_p,
+ sc_process_host* host_p, const sc_spawn_options* opt_p
+):
+ sc_thread_process(name_p, free_host, method_p, host_p, opt_p)
+{
+ m_dont_init = true;
+ m_process_kind = SC_CTHREAD_PROC_;
+}
+
+//------------------------------------------------------------------------------
+//"sc_cthread_process::~sc_cthread_process"
+//
+// This is the object instance constructor for this class.
+//------------------------------------------------------------------------------
+sc_cthread_process::~sc_cthread_process()
+{
+}
+
+} // namespace sc_core
+
+// $Log: sc_cthread_process.cpp,v $
+// Revision 1.11 2011/08/26 20:46:09 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.10 2011/08/15 16:43:24 acg
+// Torsten Maehne: changes to remove unused argument warnings.
+//
+// Revision 1.9 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.8 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.7 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.6 2011/02/01 21:00:35 acg
+// Andy Goodrich: removed throw_reset as it is now handled by parent
+// sc_thread_process::throw_reset().
+//
+// Revision 1.5 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.4 2009/07/28 01:10:53 acg
+// Andy Goodrich: updates for 2.3 release candidate.
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.2 2008/05/22 17:06:25 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.6 2006/04/20 17:08:16 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.5 2006/04/11 23:13:20 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.4 2006/01/24 20:49:04 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_cthread_process.h b/ext/systemc/src/sysc/kernel/sc_cthread_process.h
new file mode 100644
index 000000000..6d35ece0d
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_cthread_process.h
@@ -0,0 +1,144 @@
+/*****************************************************************************
+
+ 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_cthread_process.h -- Clocked thread declarations
+
+ Original Author: Andy Goodrich, Forte Design Systems, 4 August 2005
+
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#if !defined(sc_cthread_process_h_INCLUDED)
+#define sc_cthread_process_h_INCLUDED
+
+#include "sysc/kernel/sc_thread_process.h"
+
+namespace sc_core {
+
+// friend function declarations:
+
+void halt( sc_simcontext* );
+void wait( int, sc_simcontext* );
+
+
+//==============================================================================
+// sc_cthread_process -
+//
+//==============================================================================
+class sc_cthread_process : public sc_thread_process {
+
+ friend class sc_module;
+ friend class sc_process_handle;
+ friend class sc_process_table;
+ friend class sc_thread_process;
+ friend class sc_simcontext;
+
+ friend void sc_cthread_cor_fn( void* );
+
+ friend void halt( sc_simcontext* );
+ friend void wait( int, sc_simcontext* );
+
+ public:
+ sc_cthread_process( const char* name_p, bool free_host,
+ SC_ENTRY_FUNC method_p, sc_process_host* host_p,
+ const sc_spawn_options* opt_p );
+
+ virtual void dont_initialize( bool dont );
+ virtual const char* kind() const
+ { return "sc_cthread_process"; }
+
+private:
+
+ sc_cthread_process( const char* nm,
+ SC_ENTRY_FUNC fn,
+ sc_process_host* host );
+
+ // may not be deleted manually (called from sc_process_b)
+ virtual ~sc_cthread_process();
+
+ bool eval_watchlist();
+ bool eval_watchlist_curr_level();
+
+ void wait_halt();
+
+};
+
+//------------------------------------------------------------------------------
+//"sc_cthread_process::wait_halt"
+//
+//------------------------------------------------------------------------------
+inline void sc_cthread_process::wait_halt()
+{
+ m_wait_cycle_n = 0;
+ suspend_me();
+ throw sc_halt();
+}
+
+} // namespace sc_core
+
+// $Log: sc_cthread_process.h,v $
+// Revision 1.8 2011/08/26 20:46:09 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.7 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.6 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.5 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.4 2011/02/01 21:01:41 acg
+// Andy Goodrich: removed throw_reset() as it is now handled by the parent
+// method sc_thread_process::throw_reset().
+//
+// Revision 1.3 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.2 2008/05/22 17:06:25 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.6 2006/05/08 17:57:13 acg
+// Andy Goodrich: Added David Long's forward declarations for friend functions
+// to keep the Microsoft C++ compiler happy.
+//
+// Revision 1.5 2006/04/20 17:08:16 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.4 2006/04/11 23:13:20 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif // !defined(sc_cthread_process_h_INCLUDED)
diff --git a/ext/systemc/src/sysc/kernel/sc_dynamic_processes.h b/ext/systemc/src/sysc/kernel/sc_dynamic_processes.h
new file mode 100644
index 000000000..628c3300a
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_dynamic_processes.h
@@ -0,0 +1,67 @@
+/*****************************************************************************
+
+ 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_dynamic_process.h -- Dynamic Process Package Definitions
+
+ Original Author: Andy Goodrich, Forte Design Systems, 5 May 2003
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_DYNAMIC_PROCESSES_H
+#define SC_DYNAMIC_PROCESSES_H
+
+#include "sysc/kernel/sc_except.h"
+#include "sysc/kernel/sc_spawn.h"
+#include "sysc/kernel/sc_join.h"
+#include "sysc/kernel/sc_boost.h"
+
+// $Log: sc_dynamic_processes.h,v $
+// Revision 1.5 2011/08/26 20:46:09 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.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:25 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:16 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.4 2006/04/11 23:13:20 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif // SC_DYNAMIC_PROCESSES_H
diff --git a/ext/systemc/src/sysc/kernel/sc_event.cpp b/ext/systemc/src/sysc/kernel/sc_event.cpp
new file mode 100644
index 000000000..488210ee9
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_event.cpp
@@ -0,0 +1,759 @@
+/*****************************************************************************
+
+ 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_event.cpp --
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_phase_callback_registry.h"
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_object_manager.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event
+//
+// The event class.
+// ----------------------------------------------------------------------------
+
+const char*
+sc_event::basename() const
+{
+ const char* p = strrchr( m_name.c_str(), SC_HIERARCHY_CHAR );
+ return p ? (p + 1) : m_name.c_str();
+}
+
+void
+sc_event::cancel()
+{
+ // cancel a delta or timed notification
+ switch( m_notify_type ) {
+ case DELTA: {
+ // remove this event from the delta events set
+ m_simc->remove_delta_event( this );
+ m_notify_type = NONE;
+ break;
+ }
+ case TIMED: {
+ // remove this event from the timed events set
+ sc_assert( m_timed != 0 );
+ m_timed->m_event = 0;
+ m_timed = 0;
+ m_notify_type = NONE;
+ break;
+ }
+ default:
+ ;
+ }
+}
+
+
+void
+sc_event::notify()
+{
+ // immediate notification
+ if(
+ // coming from sc_prim_channel::update
+ m_simc->update_phase()
+#if SC_HAS_PHASE_CALLBACKS_
+ // coming from phase callbacks
+ || m_simc->notify_phase()
+#endif
+ )
+ {
+ SC_REPORT_ERROR( SC_ID_IMMEDIATE_NOTIFICATION_, "" );
+ return;
+ }
+ cancel();
+ trigger();
+}
+
+void
+sc_event::notify( const sc_time& t )
+{
+ if( m_notify_type == DELTA ) {
+ return;
+ }
+ if( t == SC_ZERO_TIME ) {
+# if SC_HAS_PHASE_CALLBACKS_
+ if( SC_UNLIKELY_( m_simc->get_status()
+ & (SC_END_OF_UPDATE|SC_BEFORE_TIMESTEP) ) )
+ {
+ std::stringstream msg;
+ msg << m_simc->get_status()
+ << ":\n\t delta notification of `"
+ << name() << "' ignored";
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_FORBIDDEN_
+ , msg.str().c_str() );
+ return;
+ }
+# endif
+ if( m_notify_type == TIMED ) {
+ // remove this event from the timed events set
+ sc_assert( m_timed != 0 );
+ m_timed->m_event = 0;
+ m_timed = 0;
+ }
+ // add this event to the delta events set
+ m_delta_event_index = m_simc->add_delta_event( this );
+ m_notify_type = DELTA;
+ return;
+ }
+# if SC_HAS_PHASE_CALLBACKS_
+ if( SC_UNLIKELY_( m_simc->get_status()
+ & (SC_END_OF_UPDATE|SC_BEFORE_TIMESTEP) ) )
+ {
+ std::stringstream msg;
+ msg << m_simc->get_status()
+ << ":\n\t timed notification of `"
+ << name() << "' ignored";
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_FORBIDDEN_
+ , msg.str().c_str() );
+ return;
+ }
+# endif
+ if( m_notify_type == TIMED ) {
+ sc_assert( m_timed != 0 );
+ if( m_timed->m_notify_time <= m_simc->time_stamp() + t ) {
+ return;
+ }
+ // remove this event from the timed events set
+ m_timed->m_event = 0;
+ m_timed = 0;
+ }
+ // add this event to the timed events set
+ sc_event_timed* et = new sc_event_timed( this, m_simc->time_stamp() + t );
+ m_simc->add_timed_event( et );
+ m_timed = et;
+ m_notify_type = TIMED;
+}
+
+static void sc_warn_notify_delayed()
+{
+ static bool warn_notify_delayed=true;
+ if ( warn_notify_delayed )
+ {
+ warn_notify_delayed = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "notify_delayed(...) is deprecated, use notify(sc_time) instead" );
+ }
+}
+
+void
+sc_event::notify_delayed()
+{
+ sc_warn_notify_delayed();
+ if( m_notify_type != NONE ) {
+ SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
+ }
+ // add this event to the delta events set
+ m_delta_event_index = m_simc->add_delta_event( this );
+ m_notify_type = DELTA;
+}
+
+void
+sc_event::notify_delayed( const sc_time& t )
+{
+ sc_warn_notify_delayed();
+ if( m_notify_type != NONE ) {
+ SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
+ }
+ if( t == SC_ZERO_TIME ) {
+ // add this event to the delta events set
+ m_delta_event_index = m_simc->add_delta_event( this );
+ m_notify_type = DELTA;
+ } else {
+ // add this event to the timed events set
+ sc_event_timed* et = new sc_event_timed( this,
+ m_simc->time_stamp() + t );
+ m_simc->add_timed_event( et );
+ m_timed = et;
+ m_notify_type = TIMED;
+ }
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_event::register_event"
+// |
+// | This method sets the name of this object instance and optionally adds
+// | it to the object manager's hierarchy. The object instance will be
+// | inserted into the object manager's hierarchy if one of the following is
+// | true:
+// | (a) the leaf name is non-null and does not start with
+// | SC_KERNEL_EVENT_PREFIX.
+// | (b) the event is being created before the start of simulation.
+// |
+// | Arguments:
+// | leaf_name = leaf name of the object or NULL.
+// +----------------------------------------------------------------------------
+void sc_event::register_event( const char* leaf_name )
+{
+ sc_object_manager* object_manager = m_simc->get_object_manager();
+ m_parent_p = m_simc->active_object();
+
+ // No name provided, if we are not executing then create a name:
+
+ if( !leaf_name || !leaf_name[0] )
+ {
+ if ( sc_is_running( m_simc ) ) return;
+ leaf_name = sc_gen_unique_name("event");
+ }
+
+ // Create a hierarchichal name and place it into the object manager if
+ // its not a kernel event:
+
+ object_manager->create_name( leaf_name ).swap( m_name );
+
+ if ( strncmp( leaf_name, SC_KERNEL_EVENT_PREFIX,
+ strlen(SC_KERNEL_EVENT_PREFIX) ) )
+ {
+ object_manager->insert_event(m_name, this);
+ if ( m_parent_p )
+ m_parent_p->add_child_event( this );
+ else
+ m_simc->add_child_event( this );
+ }
+}
+
+void
+sc_event::reset()
+{
+ m_notify_type = NONE;
+ m_delta_event_index = -1;
+ m_timed = 0;
+ // clear the dynamic sensitive methods
+ m_methods_dynamic.resize(0);
+ // clear the dynamic sensitive threads
+ m_threads_dynamic.resize(0);
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_event::sc_event(name)"
+// |
+// | This is the object instance constructor for named sc_event instances.
+// | If the name is non-null or the this is during elaboration add the
+// | event to the object hierarchy.
+// |
+// | Arguments:
+// | name = name of the event.
+// +----------------------------------------------------------------------------
+sc_event::sc_event( const char* name ) :
+ m_name(),
+ m_parent_p(NULL),
+ m_simc( sc_get_curr_simcontext() ),
+ m_notify_type( NONE ),
+ m_delta_event_index( -1 ),
+ m_timed( 0 ),
+ m_methods_static(),
+ m_methods_dynamic(),
+ m_threads_static(),
+ m_threads_dynamic()
+{
+ // Skip simulator's internally defined events.
+
+ register_event( name );
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_event::sc_event(name)"
+// |
+// | This is the object instance constructor for non-named sc_event instances.
+// | If this is during elaboration add create a name and add it to the object
+// | hierarchy.
+// +----------------------------------------------------------------------------
+sc_event::sc_event() :
+ m_name(),
+ m_parent_p(NULL),
+ m_simc( sc_get_curr_simcontext() ),
+ m_notify_type( NONE ),
+ m_delta_event_index( -1 ),
+ m_timed( 0 ),
+ m_methods_static(),
+ m_methods_dynamic(),
+ m_threads_static(),
+ m_threads_dynamic()
+{
+
+ register_event( NULL );
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_event::~sc_event"
+// |
+// | This is the object instance destructor for this class. It cancels any
+// | outstanding waits and removes the event from the object manager's
+// | instance table if it has a name.
+// +----------------------------------------------------------------------------
+sc_event::~sc_event()
+{
+ cancel();
+ if ( m_name.length() != 0 )
+ {
+ sc_object_manager* object_manager_p = m_simc->get_object_manager();
+ object_manager_p->remove_event( m_name );
+ }
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_event::trigger"
+// |
+// | This method "triggers" this object instance. This consists of scheduling
+// | for execution all the processes that are schedulable and waiting on this
+// | event.
+// +----------------------------------------------------------------------------
+void
+sc_event::trigger()
+{
+ int last_i; // index of last element in vector now accessing.
+ int size; // size of vector now accessing.
+
+
+ // trigger the static sensitive methods
+
+ if( ( size = m_methods_static.size() ) != 0 )
+ {
+ sc_method_handle* l_methods_static = &m_methods_static[0];
+ int i = size - 1;
+ do {
+ sc_method_handle method_h = l_methods_static[i];
+ method_h->trigger_static();
+ } while( -- i >= 0 );
+ }
+
+ // trigger the dynamic sensitive methods
+
+
+ if( ( size = m_methods_dynamic.size() ) != 0 )
+ {
+ last_i = size - 1;
+ sc_method_handle* l_methods_dynamic = &m_methods_dynamic[0];
+ for ( int i = 0; i <= last_i; i++ )
+ {
+ sc_method_handle method_h = l_methods_dynamic[i];
+ if ( method_h->trigger_dynamic( this ) )
+ {
+ l_methods_dynamic[i] = l_methods_dynamic[last_i];
+ last_i--;
+ i--;
+ }
+ }
+ m_methods_dynamic.resize(last_i+1);
+ }
+
+
+ // trigger the static sensitive threads
+
+ if( ( size = m_threads_static.size() ) != 0 )
+ {
+ sc_thread_handle* l_threads_static = &m_threads_static[0];
+ int i = size - 1;
+ do {
+ sc_thread_handle thread_h = l_threads_static[i];
+ thread_h->trigger_static();
+ } while( -- i >= 0 );
+ }
+
+ // trigger the dynamic sensitive threads
+
+ if( ( size = m_threads_dynamic.size() ) != 0 )
+ {
+ last_i = size - 1;
+ sc_thread_handle* l_threads_dynamic = &m_threads_dynamic[0];
+ for ( int i = 0; i <= last_i; i++ )
+ {
+ sc_thread_handle thread_h = l_threads_dynamic[i];
+ if ( thread_h->trigger_dynamic( this ) )
+ {
+ l_threads_dynamic[i] = l_threads_dynamic[last_i];
+ i--;
+ last_i--;
+ }
+ }
+ m_threads_dynamic.resize(last_i+1);
+ }
+
+ m_notify_type = NONE;
+ m_delta_event_index = -1;
+ m_timed = 0;
+}
+
+
+bool
+sc_event::remove_static( sc_method_handle method_h_ ) const
+{
+ int size;
+ if ( ( size = m_methods_static.size() ) != 0 ) {
+ sc_method_handle* l_methods_static = &m_methods_static[0];
+ for( int i = size - 1; i >= 0; -- i ) {
+ if( l_methods_static[i] == method_h_ ) {
+ l_methods_static[i] = l_methods_static[size - 1];
+ m_methods_static.resize(size-1);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool
+sc_event::remove_static( sc_thread_handle thread_h_ ) const
+{
+ int size;
+ if ( ( size = m_threads_static.size() ) != 0 ) {
+ sc_thread_handle* l_threads_static = &m_threads_static[0];
+ for( int i = size - 1; i >= 0; -- i ) {
+ if( l_threads_static[i] == thread_h_ ) {
+ l_threads_static[i] = l_threads_static[size - 1];
+ m_threads_static.resize(size-1);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool
+sc_event::remove_dynamic( sc_method_handle method_h_ ) const
+{
+ int size;
+ if ( ( size = m_methods_dynamic.size() ) != 0 ) {
+ sc_method_handle* l_methods_dynamic = &m_methods_dynamic[0];
+ for( int i = size - 1; i >= 0; -- i ) {
+ if( l_methods_dynamic[i] == method_h_ ) {
+ l_methods_dynamic[i] = l_methods_dynamic[size - 1];
+ m_methods_dynamic.resize(size-1);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool
+sc_event::remove_dynamic( sc_thread_handle thread_h_ ) const
+{
+ int size;
+ if ( ( size= m_threads_dynamic.size() ) != 0 ) {
+ sc_thread_handle* l_threads_dynamic = &m_threads_dynamic[0];
+ for( int i = size - 1; i >= 0; -- i ) {
+ if( l_threads_dynamic[i] == thread_h_ ) {
+ l_threads_dynamic[i] = l_threads_dynamic[size - 1];
+ m_threads_dynamic.resize(size-1);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event_timed
+//
+// Class for storing the time to notify a timed event.
+// ----------------------------------------------------------------------------
+
+// dedicated memory management; not MT-Safe
+
+union sc_event_timed_u
+{
+ sc_event_timed_u* next;
+ char dummy[sizeof( sc_event_timed )];
+};
+
+static
+sc_event_timed_u* free_list = 0;
+
+void*
+sc_event_timed::allocate()
+{
+ const int ALLOC_SIZE = 64;
+
+ if( free_list == 0 ) {
+ free_list = (sc_event_timed_u*) malloc( ALLOC_SIZE *
+ sizeof( sc_event_timed ) );
+ int i = 0;
+ for( ; i < ALLOC_SIZE - 1; ++ i ) {
+ free_list[i].next = &free_list[i + 1];
+ }
+ free_list[i].next = 0;
+ }
+
+ sc_event_timed_u* q = free_list;
+ free_list = free_list->next;
+ return q;
+}
+
+void
+sc_event_timed::deallocate( void* p )
+{
+ if( p != 0 ) {
+ sc_event_timed_u* q = RCAST<sc_event_timed_u*>( p );
+ q->next = free_list;
+ free_list = q;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event_list
+//
+// Base class for lists of events.
+// ----------------------------------------------------------------------------
+
+void
+sc_event_list::push_back( const sc_event& e )
+{
+ // make sure e is not already in the list
+ if ( m_events.size() != 0 ) {
+ const sc_event** l_events = &m_events[0];
+ for( int i = m_events.size() - 1; i >= 0; -- i ) {
+ if( &e == l_events[i] ) {
+ // event already in the list; ignore
+ return;
+ }
+ }
+ }
+ m_events.push_back( &e );
+}
+
+void
+sc_event_list::push_back( const sc_event_list& el )
+{
+ m_events.reserve( size() + el.size() );
+ for ( int i = el.m_events.size() - 1; i >= 0; --i )
+ {
+ push_back( *el.m_events[i] );
+ }
+ el.auto_delete();
+}
+
+void
+sc_event_list::add_dynamic( sc_method_handle method_h ) const
+{
+ m_busy++;
+ if ( m_events.size() != 0 ) {
+ const sc_event* const * l_events = &m_events[0];
+ for( int i = m_events.size() - 1; i >= 0; -- i ) {
+ l_events[i]->add_dynamic( method_h );
+ }
+ }
+}
+
+void
+sc_event_list::add_dynamic( sc_thread_handle thread_h ) const
+{
+ m_busy++;
+ if ( m_events.size() != 0 ) {
+ const sc_event* const* l_events = &m_events[0];
+ for( int i = m_events.size() - 1; i >= 0; -- i ) {
+ l_events[i]->add_dynamic( thread_h );
+ }
+ }
+}
+
+void
+sc_event_list::remove_dynamic( sc_method_handle method_h,
+ const sc_event* e_not ) const
+{
+ if ( m_events.size() != 0 ) {
+ const sc_event* const* l_events = &m_events[0];
+ for( int i = m_events.size() - 1; i >= 0; -- i ) {
+ const sc_event* e = l_events[i];
+ if( e != e_not ) {
+ e->remove_dynamic( method_h );
+ }
+ }
+ }
+}
+
+void
+sc_event_list::remove_dynamic( sc_thread_handle thread_h,
+ const sc_event* e_not ) const
+{
+ if ( m_events.size() != 0 ) {
+ const sc_event* const* l_events = &m_events[0];
+ for( int i = m_events.size() - 1; i >= 0; -- i ) {
+ const sc_event* e = l_events[i];
+ if( e != e_not ) {
+ e->remove_dynamic( thread_h );
+ }
+ }
+ }
+}
+
+void
+sc_event_list::report_premature_destruction() const
+{
+ // TDB: reliably detect premature destruction
+ //
+ // If an event list is used as a member of a module,
+ // its lifetime may (correctly) end, although there
+ // are processes currently waiting for it.
+ //
+ // Detecting (and ignoring) this corner-case is quite
+ // difficult for similar reasons to the sc_is_running()
+ // return value during the destruction of the module
+ // hierarchy.
+ //
+ // Ignoring the lifetime checks for now, if no process
+ // is currently running (which is only part of the story):
+
+ if( sc_get_current_process_handle().valid() ) {
+ // FIXME: improve error-handling
+ sc_assert( false && "sc_event_list prematurely destroyed" );
+ }
+
+}
+
+void
+sc_event_list::report_invalid_modification() const
+{
+ // FIXME: improve error-handling
+ sc_assert( false && "sc_event_list modfied while being waited on" );
+}
+
+// ----------------------------------------------------------------------------
+// Deprecated functional notation for notifying events.
+// ----------------------------------------------------------------------------
+
+static void sc_warn_notify()
+{
+ static bool warn_notify=true;
+ if ( warn_notify )
+ {
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "the notify() function is deprecated use sc_event::notify()" );
+ warn_notify = false;
+ }
+}
+
+void
+notify( sc_event& e )
+{
+ sc_warn_notify();
+ e.notify();
+}
+
+void
+notify( const sc_time& t, sc_event& e )
+{
+ sc_warn_notify();
+ e.notify( t );
+}
+
+void
+notify( double v, sc_time_unit tu, sc_event& e )
+{
+ sc_warn_notify();
+ e.notify( v, tu );
+}
+
+} // namespace sc_core
+
+// $Log: sc_event.cpp,v $
+// Revision 1.17 2011/08/26 20:46:09 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.16 2011/08/24 22:05:50 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.15 2011/03/12 21:07:51 acg
+// Andy Goodrich: changes to kernel generated event support.
+//
+// Revision 1.14 2011/03/06 15:55:52 acg
+// Andy Goodrich: changes for named events.
+//
+// Revision 1.13 2011/03/05 01:39:21 acg
+// Andy Goodrich: changes for named events.
+//
+// Revision 1.12 2011/02/19 08:33:25 acg
+// Andy Goodrich: remove }'s that should have been removed before.
+//
+// Revision 1.11 2011/02/19 08:30:53 acg
+// Andy Goodrich: Moved process queueing into trigger_static from
+// sc_event::notify.
+//
+// Revision 1.10 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.9 2011/02/17 19:49:51 acg
+// Andy Goodrich:
+// (1) Changed signature of trigger_dynamic() to return a bool again.
+// (2) Moved process run queue processing into trigger_dynamic().
+//
+// Revision 1.8 2011/02/16 22:37:30 acg
+// Andy Goodrich: clean up to remove need for ps_disable_pending.
+//
+// Revision 1.7 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.6 2011/02/01 21:02:28 acg
+// Andy Goodrich: new return code for trigger_dynamic() calls.
+//
+// Revision 1.5 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.4 2011/01/06 18:04:05 acg
+// Andy Goodrich: added code to leave disabled processes on the dynamic
+// method and thread queues.
+//
+// Revision 1.3 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2007/01/17 22:44:30 acg
+// Andy Goodrich: fix for Microsoft compiler.
+//
+// Revision 1.7 2006/04/11 23:13:20 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.6 2006/01/25 00:31:19 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.5 2006/01/24 20:59:11 acg
+// Andy Goodrich: fix up of CVS comments, new version roll.
+//
+// Revision 1.4 2006/01/24 20:48:14 acg
+// Andy Goodrich: added deprecation warnings for notify_delayed(). Added two
+// new implementation-dependent methods, notify_next_delta() & notify_internal()
+// to replace calls to notify_delayed() from within the simulator. These two
+// new methods are simpler than notify_delayed() and should speed up simulations
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_event.h b/ext/systemc/src/sysc/kernel/sc_event.h
new file mode 100644
index 000000000..9633752ce
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_event.h
@@ -0,0 +1,884 @@
+/*****************************************************************************
+
+ 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_event.h --
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_EVENT_H
+#define SC_EVENT_H
+
+#include "sysc/kernel/sc_cmnhdr.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/communication/sc_writer_policy.h"
+
+namespace sc_core {
+
+// forward declarations
+class sc_event;
+class sc_event_timed;
+class sc_event_list;
+class sc_event_or_list;
+class sc_event_and_list;
+class sc_object;
+
+// friend function declarations
+ int sc_notify_time_compare( const void*, const void* );
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event_expr
+//
+// The event expression class.
+// ----------------------------------------------------------------------------
+
+template< typename T >
+class sc_event_expr
+{
+ friend class sc_event;
+ friend class sc_event_and_list;
+ friend class sc_event_or_list;
+
+ typedef T type;
+
+ inline sc_event_expr()
+ : m_expr( new T(true) )
+ {}
+
+public:
+
+ inline sc_event_expr( sc_event_expr const & e) // move semantics
+ : m_expr(e.m_expr)
+ {
+ e.m_expr = 0;
+ }
+
+ T const & release() const
+ {
+ sc_assert( m_expr );
+ T* expr = m_expr;
+ m_expr=0;
+ return *expr;
+ }
+
+ void push_back( sc_event const & e) const
+ {
+ sc_assert( m_expr );
+ m_expr->push_back(e);
+ }
+
+ void push_back( type const & el) const
+ {
+ sc_assert( m_expr );
+ m_expr->push_back(el);
+ }
+ operator T const &() const
+ {
+ return release();
+ }
+
+ ~sc_event_expr()
+ {
+ delete m_expr;
+ }
+
+private:
+ mutable type * m_expr;
+
+ // disabled
+ void operator=( sc_event_expr const & );
+};
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event_list
+//
+// Base class for lists of events.
+// ----------------------------------------------------------------------------
+
+class sc_event_list
+{
+ friend class sc_process_b;
+ friend class sc_method_process;
+ friend class sc_thread_process;
+ friend void sc_thread_cor_fn( void* arg );
+
+public:
+ sc_event_list( const sc_event_list& );
+ sc_event_list& operator = ( const sc_event_list& );
+
+ int size() const;
+
+protected:
+
+ void push_back( const sc_event& );
+ void push_back( const sc_event_list& );
+
+ explicit
+ sc_event_list( bool and_list_, bool auto_delete_ = false );
+
+ sc_event_list( const sc_event&,
+ bool and_list_,
+ bool auto_delete_ = false );
+
+ ~sc_event_list();
+
+ void swap( sc_event_list& );
+ void move_from( const sc_event_list& );
+
+ bool and_list() const;
+
+ void add_dynamic( sc_method_handle ) const;
+ void add_dynamic( sc_thread_handle ) const;
+ void remove_dynamic( sc_method_handle, const sc_event* ) const;
+ void remove_dynamic( sc_thread_handle, const sc_event* ) const;
+
+ bool busy() const;
+ bool temporary() const;
+ void auto_delete() const;
+
+ void report_premature_destruction() const;
+ void report_invalid_modification() const;
+
+private:
+
+ std::vector<const sc_event*> m_events;
+ bool m_and_list;
+ bool m_auto_delete;
+ mutable unsigned m_busy;
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event_and_list
+//
+// AND list of events.
+// ----------------------------------------------------------------------------
+
+class sc_event_and_list
+: public sc_event_list
+{
+ friend class sc_event;
+ friend class sc_event_expr<sc_event_and_list>;
+ friend class sc_process_b;
+ friend class sc_method_process;
+ friend class sc_thread_process;
+
+protected:
+
+ explicit
+ sc_event_and_list( bool auto_delete_ );
+
+public:
+
+ sc_event_and_list();
+ sc_event_and_list( const sc_event& );
+
+ void swap( sc_event_and_list& );
+ sc_event_and_list& operator &= ( const sc_event& );
+ sc_event_and_list& operator &= ( const sc_event_and_list & );
+
+ sc_event_expr<sc_event_and_list> operator & ( const sc_event& );
+ sc_event_expr<sc_event_and_list> operator & ( const sc_event_and_list& );
+};
+
+typedef sc_event_expr<sc_event_and_list> sc_event_and_expr;
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event_or_list
+//
+// OR list of events.
+// ----------------------------------------------------------------------------
+
+class sc_event_or_list
+: public sc_event_list
+{
+ friend class sc_event;
+ friend class sc_event_expr<sc_event_or_list>;
+ friend class sc_process_b;
+ friend class sc_method_process;
+ friend class sc_thread_process;
+
+protected:
+
+ explicit
+ sc_event_or_list( bool auto_delete_ );
+
+public:
+ sc_event_or_list();
+ sc_event_or_list( const sc_event& );
+ void swap( sc_event_or_list& );
+ sc_event_or_list& operator |= ( const sc_event& );
+ sc_event_or_list& operator |= ( const sc_event_or_list & );
+ sc_event_expr<sc_event_or_list> operator | ( const sc_event& ) const;
+ sc_event_expr<sc_event_or_list> operator | ( const sc_event_or_list& ) const;
+};
+
+typedef sc_event_expr<sc_event_or_list> sc_event_or_expr;
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event
+//
+// The event class.
+// ----------------------------------------------------------------------------
+
+class sc_event
+{
+ friend class sc_clock;
+ friend class sc_event_list;
+ friend class sc_event_timed;
+ friend class sc_simcontext;
+ friend class sc_object;
+ friend class sc_process_b;
+ friend class sc_method_process;
+ friend class sc_thread_process;
+ template<typename IF, sc_writer_policy POL> friend class sc_signal;
+ friend void sc_thread_cor_fn( void* arg );
+
+public:
+
+ sc_event();
+ sc_event( const char* name );
+ ~sc_event();
+
+ void cancel();
+
+ const char* name() const { return m_name.c_str(); }
+ const char* basename() const;
+ sc_object* get_parent_object() const { return m_parent_p; }
+ bool in_hierarchy() const { return m_name.length() != 0; }
+
+ void notify();
+ void notify( const sc_time& );
+ void notify( double, sc_time_unit );
+
+ void notify_delayed();
+ void notify_delayed( const sc_time& );
+ void notify_delayed( double, sc_time_unit );
+
+ sc_event_or_expr operator | ( const sc_event& ) const;
+ sc_event_or_expr operator | ( const sc_event_or_list& ) const;
+ sc_event_and_expr operator & ( const sc_event& ) const;
+ sc_event_and_expr operator & ( const sc_event_and_list& ) const;
+
+
+private:
+
+ void add_static( sc_method_handle ) const;
+ void add_static( sc_thread_handle ) const;
+ void add_dynamic( sc_method_handle ) const;
+ void add_dynamic( sc_thread_handle ) const;
+
+ void notify_internal( const sc_time& );
+ void notify_next_delta();
+
+ bool remove_static( sc_method_handle ) const;
+ bool remove_static( sc_thread_handle ) const;
+ bool remove_dynamic( sc_method_handle ) const;
+ bool remove_dynamic( sc_thread_handle ) const;
+
+ void register_event( const char* name );
+ void reset();
+
+ void trigger();
+
+private:
+
+ enum notify_t { NONE, DELTA, TIMED };
+
+ std::string m_name; // name of object.
+ sc_object* m_parent_p; // parent sc_object for this event.
+ sc_simcontext* m_simc;
+ notify_t m_notify_type;
+ int m_delta_event_index;
+ sc_event_timed* m_timed;
+
+ mutable std::vector<sc_method_handle> m_methods_static;
+ mutable std::vector<sc_method_handle> m_methods_dynamic;
+ mutable std::vector<sc_thread_handle> m_threads_static;
+ mutable std::vector<sc_thread_handle> m_threads_dynamic;
+
+private:
+
+ // disabled
+ sc_event( const sc_event& );
+ sc_event& operator = ( const sc_event& );
+};
+
+#define SC_KERNEL_EVENT_PREFIX "$$$$kernel_event$$$$_"
+
+extern sc_event sc_non_event; // Event that never happens.
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_event_timed
+//
+// Class for storing the time to notify a timed event.
+// ----------------------------------------------------------------------------
+
+class sc_event_timed
+{
+ friend class sc_event;
+ friend class sc_simcontext;
+
+ friend int sc_notify_time_compare( const void*, const void* );
+
+private:
+
+ sc_event_timed( sc_event* e, const sc_time& t )
+ : m_event( e ), m_notify_time( t )
+ {}
+
+ ~sc_event_timed()
+ { if( m_event != 0 ) { m_event->m_timed = 0; } }
+
+ sc_event* event() const
+ { return m_event; }
+
+ const sc_time& notify_time() const
+ { return m_notify_time; }
+
+ static void* operator new( std::size_t )
+ { return allocate(); }
+
+ static void operator delete( void* p, std::size_t )
+ { deallocate( p ); }
+
+private:
+
+ // dedicated memory management
+ static void* allocate();
+ static void deallocate( void* );
+
+private:
+
+ sc_event* m_event;
+ sc_time m_notify_time;
+
+private:
+
+ // disabled
+ sc_event_timed();
+ sc_event_timed( const sc_event_timed& );
+ sc_event_timed& operator = ( const sc_event_timed& );
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+void
+sc_event::notify( double v, sc_time_unit tu )
+{
+ notify( sc_time( v, tu, m_simc ) );
+}
+
+
+inline
+void
+sc_event::notify_internal( const sc_time& t )
+{
+ if( t == SC_ZERO_TIME ) {
+ // add this event to the delta events set
+ m_delta_event_index = m_simc->add_delta_event( this );
+ m_notify_type = DELTA;
+ } else {
+ sc_event_timed* et =
+ new sc_event_timed( this, m_simc->time_stamp() + t );
+ m_simc->add_timed_event( et );
+ m_timed = et;
+ m_notify_type = TIMED;
+ }
+}
+
+inline
+void
+sc_event::notify_next_delta()
+{
+ if( m_notify_type != NONE ) {
+ SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
+ }
+ // add this event to the delta events set
+ m_delta_event_index = m_simc->add_delta_event( this );
+ m_notify_type = DELTA;
+}
+
+inline
+void
+sc_event::notify_delayed( double v, sc_time_unit tu )
+{
+ notify_delayed( sc_time( v, tu, m_simc ) );
+}
+
+
+inline
+void
+sc_event::add_static( sc_method_handle method_h ) const
+{
+ m_methods_static.push_back( method_h );
+}
+
+inline
+void
+sc_event::add_static( sc_thread_handle thread_h ) const
+{
+ m_threads_static.push_back( thread_h );
+}
+
+inline
+void
+sc_event::add_dynamic( sc_method_handle method_h ) const
+{
+ m_methods_dynamic.push_back( method_h );
+}
+
+inline
+void
+sc_event::add_dynamic( sc_thread_handle thread_h ) const
+{
+ m_threads_dynamic.push_back( thread_h );
+}
+
+
+// ----------------------------------------------------------------------------
+// Deprecated functional notation for notifying events.
+// ----------------------------------------------------------------------------
+
+extern void notify( sc_event& e );
+extern void notify( const sc_time& t, sc_event& e );
+extern void notify( double v, sc_time_unit tu, sc_event& e );
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+sc_event_list::sc_event_list( bool and_list_, bool auto_delete_ )
+ : m_events()
+ , m_and_list( and_list_ )
+ , m_auto_delete( auto_delete_ )
+ , m_busy( 0 )
+{
+}
+
+inline
+sc_event_list::sc_event_list( const sc_event& e,
+ bool and_list_,
+ bool auto_delete_ )
+ : m_events()
+ , m_and_list( and_list_ )
+ , m_auto_delete( auto_delete_ )
+ , m_busy(0)
+{
+ m_events.push_back( &e );
+}
+
+inline
+sc_event_list::sc_event_list( sc_event_list const & that )
+ : m_events()
+ , m_and_list( that.m_and_list )
+ , m_auto_delete( false )
+ , m_busy( 0 )
+{
+ move_from( that );
+ that.auto_delete(); // free automatic lists
+}
+
+inline
+sc_event_list&
+sc_event_list::operator=( sc_event_list const & that )
+{
+ if( m_busy )
+ report_invalid_modification();
+
+ move_from( that );
+ that.auto_delete(); // free automatic lists
+
+ return *this;
+}
+
+inline
+sc_event_list::~sc_event_list()
+{
+ if( m_busy )
+ report_premature_destruction();
+}
+
+inline
+void
+sc_event_list::swap( sc_event_list& that )
+{
+ if( busy() || that.busy() )
+ report_invalid_modification();
+ m_events.swap( that.m_events );
+}
+
+inline
+void
+sc_event_list::move_from( sc_event_list const& that )
+{
+ if( that.temporary() ) {
+ swap( const_cast<sc_event_list&>(that) ); // move from source
+ } else {
+ m_events = that.m_events; // copy from source
+ }
+}
+
+inline
+int
+sc_event_list::size() const
+{
+ return m_events.size();
+}
+
+inline
+bool
+sc_event_list::and_list() const
+{
+ return m_and_list;
+}
+
+
+inline
+bool
+sc_event_list::busy() const
+{
+ return m_busy != 0;
+}
+
+
+inline
+bool
+sc_event_list::temporary() const
+{
+ return m_auto_delete && ! m_busy;
+}
+
+inline
+void
+sc_event_list::auto_delete() const
+{
+ if( m_busy ) {
+ --m_busy;
+ }
+ if( ! m_busy && m_auto_delete ) {
+ delete this;
+ }
+}
+
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+sc_event_or_list::sc_event_or_list()
+ : sc_event_list( false )
+{}
+
+inline
+sc_event_or_list::sc_event_or_list( const sc_event& e )
+: sc_event_list( false )
+{
+ push_back( e );
+}
+
+inline
+sc_event_or_list::sc_event_or_list( bool auto_delete_ )
+: sc_event_list( false, auto_delete_ )
+{}
+
+inline
+sc_event_or_list&
+sc_event_or_list::operator |= ( const sc_event& e )
+{
+ if( busy() )
+ report_invalid_modification();
+
+ push_back( e );
+ return *this;
+}
+
+inline
+sc_event_or_list&
+sc_event_or_list::operator |= ( const sc_event_or_list& el )
+{
+ if( busy() )
+ report_invalid_modification();
+
+ push_back( el );
+ return *this;
+}
+
+inline
+sc_event_or_expr
+sc_event_or_list::operator | ( const sc_event& e2 ) const
+{
+ sc_event_or_expr expr;
+ expr.push_back( *this );
+ expr.push_back( e2 );
+ return expr;
+}
+
+inline
+sc_event_or_expr
+sc_event_or_list::operator | ( const sc_event_or_list& e2 ) const
+{
+ sc_event_or_expr expr;
+ expr.push_back( *this );
+ expr.push_back( e2 );
+ return expr;
+}
+
+
+// sc_event
+
+inline
+sc_event_or_expr
+sc_event::operator | ( const sc_event& e2 ) const
+{
+ sc_event_or_expr expr;
+ expr.push_back( *this );
+ expr.push_back( e2 );
+ return expr;
+}
+
+inline
+sc_event_or_expr
+sc_event::operator | ( const sc_event_or_list& e2 ) const
+{
+ sc_event_or_expr expr;
+ expr.push_back( *this );
+ expr.push_back( e2 );
+ return expr;
+}
+
+// sc_event_expr
+
+inline
+sc_event_or_expr
+operator | ( sc_event_or_expr expr, sc_event const & e )
+{
+ expr.push_back( e );
+ return expr;
+}
+
+inline
+sc_event_or_expr
+operator | ( sc_event_or_expr expr, sc_event_or_list const & el )
+{
+ expr.push_back( el );
+ return expr;
+}
+
+inline
+void
+sc_event_or_list::swap( sc_event_or_list & that )
+{
+ sc_event_list::swap( that );
+}
+
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+sc_event_and_list::sc_event_and_list()
+ : sc_event_list( true )
+{}
+
+inline
+sc_event_and_list::sc_event_and_list( const sc_event& e )
+: sc_event_list( true )
+{
+ push_back( e );
+}
+
+inline
+sc_event_and_list::sc_event_and_list( bool auto_delete_ )
+: sc_event_list( true, auto_delete_ )
+{}
+
+inline
+void
+sc_event_and_list::swap( sc_event_and_list & that )
+{
+ sc_event_list::swap( that );
+}
+
+
+inline
+sc_event_and_list&
+sc_event_and_list::operator &= ( const sc_event& e )
+{
+ if( busy() )
+ report_invalid_modification();
+
+ push_back( e );
+ return *this;
+}
+
+inline
+sc_event_and_list&
+sc_event_and_list::operator &= ( const sc_event_and_list& el )
+{
+ if( busy() )
+ report_invalid_modification();
+
+ push_back( el );
+ return *this;
+}
+
+inline
+sc_event_and_expr
+sc_event_and_list::operator & ( const sc_event& e )
+{
+ sc_event_and_expr expr;
+ expr.push_back( *this );
+ expr.push_back( e );
+ return expr;
+}
+
+inline
+sc_event_and_expr
+sc_event_and_list::operator & ( const sc_event_and_list& el )
+{
+ sc_event_and_expr expr;
+ expr.push_back( *this );
+ expr.push_back( el );
+ return expr;
+}
+
+// sc_event
+
+inline
+sc_event_and_expr
+sc_event::operator & ( const sc_event& e2 ) const
+{
+ sc_event_and_expr expr;
+ expr.push_back( *this );
+ expr.push_back( e2 );
+ return expr;
+}
+
+inline
+sc_event_and_expr
+sc_event::operator & ( const sc_event_and_list& e2 ) const
+{
+ sc_event_and_expr expr;
+ expr.push_back( *this );
+ expr.push_back( e2 );
+ return expr;
+}
+
+// sc_event_expr
+
+inline
+sc_event_and_expr
+operator & ( sc_event_and_expr expr, sc_event const & e )
+{
+ expr.push_back( e );
+ return expr;
+}
+
+inline
+sc_event_and_expr
+operator & ( sc_event_and_expr expr, sc_event_and_list const & el )
+{
+ expr.push_back( el );
+ return expr;
+}
+
+} // namespace sc_core
+
+// $Log: sc_event.h,v $
+// Revision 1.14 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.13 2011/08/26 20:46:09 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.12 2011/08/24 22:05:50 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.11 2011/03/12 21:07:51 acg
+// Andy Goodrich: changes to kernel generated event support.
+//
+// Revision 1.10 2011/03/06 15:55:11 acg
+// Andy Goodrich: Changes for named events.
+//
+// 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/02/01 21:03:23 acg
+// Andy Goodrich: new return codes for trigger_dynamic calls.
+//
+// Revision 1.5 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.4 2010/12/07 20:09:11 acg
+// Andy Goodrich: writer policy fix.
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.2 2008/05/22 17:06:25 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.8 2006/05/26 20:33:16 acg
+// Andy Goodrich: changes required by additional platform compilers (i.e.,
+// Microsoft VC++, Sun Forte, HP aCC).
+//
+// Revision 1.7 2006/05/08 17:57:51 acg
+// Andy Goodrich: added David Long's forward declarations for friend
+// functions, methods, and operators to keep the Microsoft compiler happy.
+//
+// Revision 1.6 2006/04/11 23:13:20 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.5 2006/01/24 20:56:00 acg
+// Andy Goodrich: fixed up CVS comment.
+//
+// Revision 1.4 2006/01/24 20:48:14 acg
+// Andy Goodrich: added deprecation warnings for notify_delayed(). Added two
+// new implementation-dependent methods, notify_next_delta() & notify_internal()
+// to replace calls to notify_delayed() from within the simulator. These two
+// new methods are simpler than notify_delayed() and should speed up simulations
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_except.cpp b/ext/systemc/src/sysc/kernel/sc_except.cpp
new file mode 100644
index 000000000..2699f8daf
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_except.cpp
@@ -0,0 +1,142 @@
+/*****************************************************************************
+
+ 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_except.cpp -- kill/reset exception handling
+
+ Original Author: Philipp A. Hartmann, OFFIS
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_cmnhdr.h"
+//
+#include "sysc/kernel/sc_except.h"
+#include "sysc/kernel/sc_process.h"
+//
+#include "sysc/utils/sc_report.h"
+
+namespace sc_core {
+
+sc_unwind_exception::sc_unwind_exception( sc_process_b* proc_p, bool is_reset )
+ : m_proc_p(proc_p), m_is_reset( is_reset )
+{
+ sc_assert( m_proc_p );
+ m_proc_p->start_unwinding();
+}
+
+bool
+sc_unwind_exception::active() const
+{
+ return m_proc_p && m_proc_p->is_unwinding();
+}
+
+void
+sc_unwind_exception::clear() const
+{
+ sc_assert( m_proc_p );
+ m_proc_p->clear_unwinding();
+}
+
+const char*
+sc_unwind_exception::what() const throw()
+{
+ return ( m_is_reset ) ? "RESET" : "KILL";
+}
+
+sc_unwind_exception::~sc_unwind_exception() throw()
+{
+ if( active() ) {
+ // can't throw an exception, since we're already throwing
+ // -> abort instead
+ SC_REPORT_FATAL( SC_ID_RETHROW_UNWINDING_, m_proc_p->name() );
+ }
+}
+
+// handle and translate uncaught exceptions here
+//
+// These exceptions can either escape from sc_main() directly,
+// indirectly from an SC_METHOD(), or are thrown from within
+// an SC_(C)THREAD()
+//
+// returns a pointer to a dynamically allocated sc_report object,
+// containing the caught message
+
+sc_report*
+sc_handle_exception()
+{
+ try {
+
+ // re-throw exception here
+ try { throw; }
+
+ catch( sc_report & ) // to be on the safe side
+ {
+ throw; // continue
+ }
+ catch( sc_unwind_exception const & )
+ {
+ sc_assert( false && "Unhandled kill/reset, should never happen" );
+ }
+ catch( std::exception const & x )
+ {
+ SC_REPORT_ERROR( SC_ID_SIMULATION_UNCAUGHT_EXCEPTION_, x.what() );
+ }
+ catch( char const * x )
+ {
+ SC_REPORT_ERROR( SC_ID_SIMULATION_UNCAUGHT_EXCEPTION_, x );
+ }
+ catch( ... )
+ {
+ SC_REPORT_ERROR( SC_ID_SIMULATION_UNCAUGHT_EXCEPTION_,
+ "UNKNOWN EXCEPTION" );
+ }
+ }
+ // everything is an sc_report now
+ catch( sc_report & rpt )
+ {
+ sc_report* rpt_p = new sc_report;
+ rpt_p->swap( rpt );
+ return rpt_p;
+ }
+ return 0;
+}
+
+} // namespace sc_core
+
+// $Log: sc_except.cpp,v $
+// Revision 1.4 2011/08/26 20:46:09 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.3 2011/05/09 04:07:48 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.2 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.1 2011/02/10 22:47:38 acg
+// Andy Goodrich: first check in of Philipp A. Hartmann's new exception
+// processing code.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_except.h b/ext/systemc/src/sysc/kernel/sc_except.h
new file mode 100644
index 000000000..e3bacbd9c
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_except.h
@@ -0,0 +1,178 @@
+/*****************************************************************************
+
+ 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_except.h - Exception classes to be handled by SystemC.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_EXCEPT_H
+#define SC_EXCEPT_H
+
+#include <exception>
+
+namespace sc_core {
+
+class sc_simcontext;
+class sc_process_b;
+class sc_method_process;
+class sc_thread_process;
+void sc_thread_cor_fn( void* arg );
+
+/*
+ * These classes are intentionally empty. Their raison d'etre is for
+ * the implementation of various SystemC throws.
+ */
+
+class sc_user
+{
+ /*EMPTY*/
+public:
+ sc_user() {}
+ sc_user( const sc_user& ) {}
+};
+
+class sc_halt
+{
+public:
+ sc_halt() {}
+ sc_halt( const sc_halt& ) {}
+};
+
+class sc_kill
+{
+public:
+ sc_kill() {}
+ sc_kill( const sc_kill& ) {}
+};
+
+class sc_unwind_exception : public std::exception
+{
+ friend class sc_simcontext;
+ friend class sc_process_b;
+ friend class sc_method_process;
+ friend class sc_thread_process;
+ friend void sc_thread_cor_fn( void* arg );
+
+ public:
+ virtual bool is_reset() const { return m_is_reset; }
+ virtual const char* what() const throw();
+
+ public:
+
+ // enable catch by value
+ sc_unwind_exception( const sc_unwind_exception& );
+ virtual ~sc_unwind_exception() throw();
+
+ protected:
+ explicit
+ sc_unwind_exception( sc_process_b* target_p, bool is_reset = false );
+
+ bool active() const;
+ void clear() const;
+
+ private:
+ // disabled
+ sc_unwind_exception& operator=( const sc_unwind_exception& );
+
+ mutable sc_process_b* m_proc_p; // used to check, if caught by the kernel
+ const bool m_is_reset; // true if this is an unwind of a reset
+
+};
+
+inline
+sc_unwind_exception::sc_unwind_exception( const sc_unwind_exception& that )
+ : std::exception( that )
+ , m_proc_p( that.m_proc_p )
+ , m_is_reset( that.m_is_reset )
+{
+ that.m_proc_p = 0; // move to new instance
+}
+
+//------------------------------------------------------------------------------
+// global exception handling
+//------------------------------------------------------------------------------
+
+class sc_report;
+sc_report* sc_handle_exception();
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Gene Bushuyev. Synopsys, Inc.
+ Description of Modification: - Had to add empty public default and copy
+ constructors to satisfy VC6.0.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_except.h,v $
+// Revision 1.11 2011/08/26 21:40:26 acg
+// Philipp A. Hartmann: fix up sc_unwind_exception copy-ctor.
+//
+// Revision 1.10 2011/08/26 20:46:09 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.9 2011/08/24 22:05:50 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.8 2011/05/09 04:07:48 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.7 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.6 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.5 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.4 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.2 2008/05/22 17:06:25 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.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_externs.h b/ext/systemc/src/sysc/kernel/sc_externs.h
new file mode 100644
index 000000000..1d1818089
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_externs.h
@@ -0,0 +1,65 @@
+/*****************************************************************************
+
+ 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_externs.h -- Declaration of `sc_main' and other global variables.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_EXTERNS_H
+#define SC_EXTERNS_H
+
+
+
+extern "C" int sc_main( int argc, char* argv[] );
+
+namespace sc_core {
+ extern "C" int sc_elab_and_sim( int argc, char* argv[] );
+ extern "C" int sc_argc();
+ extern "C" const char* const* sc_argv();
+
+} // namespace sc_core
+
+// $Log: sc_externs.h,v $
+// Revision 1.5 2011/08/26 20:46:09 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.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:25 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.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_join.cpp b/ext/systemc/src/sysc/kernel/sc_join.cpp
new file mode 100644
index 000000000..25f6f6cea
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_join.cpp
@@ -0,0 +1,143 @@
+/*****************************************************************************
+
+ 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_join.cpp -- Join Process Synchronization Implementation
+
+ Original Author: Andy Goodrich, Forte Design Systems, 5 May 2003
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include <cassert>
+#include <cstdlib>
+#include <cstddef>
+
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_thread_process.h"
+#include "sysc/kernel/sc_join.h"
+
+namespace sc_core {
+
+//------------------------------------------------------------------------------
+//"sc_join::sc_join"
+//
+// This is the object instance constructor for this class.
+//------------------------------------------------------------------------------
+sc_join::sc_join()
+ : m_join_event( (std::string(SC_KERNEL_EVENT_PREFIX)+"_join_event").c_str() )
+ , m_threads_n(0)
+{}
+
+//------------------------------------------------------------------------------
+//"sc_join::add_process - sc_process_b*"
+//
+// This method adds a process to this join object instance. This consists of
+// incrementing the count of processes in the join process and adding this
+// object instance to the supplied thread's monitoring queue.
+// process_p -> thread to be monitored.
+//------------------------------------------------------------------------------
+void sc_join::add_process( sc_process_b* process_p )
+{
+ sc_thread_handle handle = DCAST<sc_thread_handle>(process_p);
+ assert( handle != 0 );
+ m_threads_n++;
+ handle->add_monitor( this );
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_join::add_process - sc_process_handle"
+//
+// This method adds a process to this join object instance. This consists of
+// incrementing the count of processes in the join process and adding this
+// object instance to the supplied thread's monitoring queue.
+// process_h = handle for process to be monitored.
+//------------------------------------------------------------------------------
+void sc_join::add_process( sc_process_handle process_h )
+{
+ sc_thread_handle thread_p; // Thread within process_h.
+
+ thread_p = process_h.operator sc_thread_handle();
+ if ( thread_p )
+ {
+ m_threads_n++;
+ thread_p->add_monitor( this );
+ }
+ else
+ {
+ SC_REPORT_ERROR( SC_ID_JOIN_ON_METHOD_HANDLE_, 0 );
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_join::signal"
+//
+// This virtual method is called when a process being monitored by this object
+// instance sends a signal. If the signal type is spm_exit and the count of
+// threads that we are waiting to terminate on goes to zero we fire our join
+// event.
+// thread_p -> thread that is signalling.
+// type = type of signal being sent.
+//------------------------------------------------------------------------------
+void sc_join::signal(sc_thread_handle thread_p, int type)
+{
+ switch ( type )
+ {
+ case sc_process_monitor::spm_exit:
+ thread_p->remove_monitor(this);
+ if ( --m_threads_n == 0 ) m_join_event.notify();
+ break;
+ }
+}
+
+} // namespace sc_core
+
+// $Log: sc_join.cpp,v $
+// Revision 1.7 2011/08/26 21:45:00 acg
+// Andy Goodrich: fix internal event naming.
+//
+// Revision 1.6 2011/08/26 20:46:09 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.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2009/07/28 01:10:53 acg
+// Andy Goodrich: updates for 2.3 release candidate.
+//
+// Revision 1.2 2008/05/22 17:06:25 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.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_join.h b/ext/systemc/src/sysc/kernel/sc_join.h
new file mode 100644
index 000000000..e240f51a2
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_join.h
@@ -0,0 +1,136 @@
+/*****************************************************************************
+
+ 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_join.h -- Join Process Synchronization Definition
+
+ Original Author: Andy Goodrich, Forte Design Systems, 5 May 2003
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+// $Log: sc_join.h,v $
+// Revision 1.8 2011/08/26 21:45:00 acg
+// Andy Goodrich: fix internal event naming.
+//
+// Revision 1.7 2011/08/26 20:46:09 acg
+// Andy Goodrich: moved the modification log to the end of the file to
+// eliminate source line number skew when check-ins are done.
+//
+
+#ifndef SC_JOIN_H
+#define SC_JOIN_H
+
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_wait.h"
+
+namespace sc_core {
+
+//==============================================================================
+// CLASS sc_join
+//
+// This class provides a way of waiting for a set of threads to complete their
+// execution. The threads whose completion is to be monitored are registered,
+// and upon their completion an event notification will occur.
+//==============================================================================
+class sc_join : public sc_process_monitor {
+ friend class sc_process_b;
+ friend class sc_process_handle;
+ public:
+ sc_join();
+ void add_process( sc_process_handle process_h );
+ inline int process_count();
+ virtual void signal(sc_thread_handle thread_p, int type);
+ inline void wait();
+ inline void wait_clocked();
+
+ protected:
+ void add_process( sc_process_b* process_p );
+
+ protected:
+ sc_event m_join_event; // Event to notify when all threads have reported.
+ int m_threads_n; // # of threads still need to wait for.
+};
+
+int sc_join::process_count() { return m_threads_n; }
+
+// suspend a thread that does not have a sensitivity list:
+
+inline void sc_join::wait() { ::sc_core::wait(m_join_event); }
+
+// suspend a thread that has a sensitivity list:
+
+inline void sc_join::wait_clocked()
+{
+ do { ::sc_core::wait(); } while (m_threads_n != 0);
+}
+
+#define SC_CJOIN \
+ }; \
+ sc_core::sc_join join; \
+ for ( unsigned int i = 0; \
+ i < sizeof(forkees)/sizeof(sc_core::sc_process_handle); \
+ i++ ) \
+ join.add_process(forkees[i]); \
+ join.wait_clocked(); \
+}
+
+#define SC_FORK \
+{ \
+ sc_core::sc_process_handle forkees[] = {
+
+#define SC_JOIN \
+ }; \
+ sc_core::sc_join join; \
+ for ( unsigned int i = 0; \
+ i < sizeof(forkees)/sizeof(sc_core::sc_process_handle); \
+ i++ ) \
+ join.add_process(forkees[i]); \
+ join.wait(); \
+}
+
+} // namespace sc_core
+
+// Revision 1.6 2011/08/24 22:05:50 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2009/07/28 01:10:53 acg
+// Andy Goodrich: updates for 2.3 release candidate.
+//
+// Revision 1.2 2008/05/22 17:06:25 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/28 21:38:27 acg
+// Andy Goodrich: fixed loop constraint that was using sizeof(sc_thread_handle)
+// rather than sizeof(sc_process_handle).
+//
+// Revision 1.4 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+
+#endif // SC_JOIN_H
diff --git a/ext/systemc/src/sysc/kernel/sc_kernel_ids.h b/ext/systemc/src/sysc/kernel/sc_kernel_ids.h
new file mode 100644
index 000000000..32846df12
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_kernel_ids.h
@@ -0,0 +1,321 @@
+/*****************************************************************************
+
+ 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_kernel_ids.h -- Report ids for the kernel code.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2002-01-17
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_KERNEL_IDS_H
+#define SC_KERNEL_IDS_H
+
+
+#include "sysc/utils/sc_report.h"
+
+
+// ----------------------------------------------------------------------------
+// Report ids (kernel)
+//
+// Report ids in the range of 500-599.
+// ----------------------------------------------------------------------------
+
+#ifndef SC_DEFINE_MESSAGE
+#define SC_DEFINE_MESSAGE(id,unused1,unused2) \
+ namespace sc_core { extern const char id[]; }
+namespace sc_core {
+ extern const char SC_ID_REGISTER_ID_FAILED_[]; // in sc_report_handler.cpp
+}
+#endif
+
+SC_DEFINE_MESSAGE(SC_ID_NO_BOOL_RETURNED_ , 500,
+ "operator does not return boolean")
+SC_DEFINE_MESSAGE(SC_ID_NO_INT_RETURNED_ , 501,
+ "operator does not return int")
+SC_DEFINE_MESSAGE(SC_ID_NO_SC_LOGIC_RETURNED_ , 502,
+ "operator does not return sc_logic")
+SC_DEFINE_MESSAGE(SC_ID_OPERAND_NOT_SC_LOGIC_ , 503,
+ "operand is not sc_logic")
+SC_DEFINE_MESSAGE(SC_ID_OPERAND_NOT_BOOL_ , 504,
+ "operand is not bool")
+SC_DEFINE_MESSAGE(SC_ID_INSTANCE_EXISTS_ , 505,
+ "object already exists")
+SC_DEFINE_MESSAGE(SC_ID_ILLEGAL_CHARACTERS_ , 506,
+ "illegal characters" )
+SC_DEFINE_MESSAGE(SC_ID_VC6_PROCESS_HELPER_ , 507,
+ "internal error: sc_vc6_process_helper" )
+SC_DEFINE_MESSAGE(SC_ID_VC6_MAX_PROCESSES_EXCEEDED_ , 508,
+ "maximum number of processes per module exceeded (VC6)" )
+SC_DEFINE_MESSAGE(SC_ID_END_MODULE_NOT_CALLED_ , 509,
+ "module construction not properly completed: did "
+ "you forget to add a sc_module_name parameter to "
+ "your module constructor?" )
+SC_DEFINE_MESSAGE(SC_ID_HIER_NAME_INCORRECT_ , 510,
+ "hierarchical name as shown may be incorrect due to previous errors" )
+SC_DEFINE_MESSAGE(SC_ID_SET_STACK_SIZE_ , 511,
+ "set_stack_size() is only allowed for SC_THREADs and SC_CTHREADs" )
+SC_DEFINE_MESSAGE(SC_ID_SC_MODULE_NAME_USE_ , 512,
+ "incorrect use of sc_module_name" )
+SC_DEFINE_MESSAGE(SC_ID_SC_MODULE_NAME_REQUIRED_ , 513,
+ "an sc_module_name parameter for your constructor is required" )
+SC_DEFINE_MESSAGE(SC_ID_SET_TIME_RESOLUTION_ , 514,
+ "set time resolution failed" )
+SC_DEFINE_MESSAGE(SC_ID_SET_DEFAULT_TIME_UNIT_ , 515,
+ "set default time unit failed" )
+SC_DEFINE_MESSAGE(SC_ID_DEFAULT_TIME_UNIT_CHANGED_ , 516,
+ "default time unit changed to time resolution" )
+SC_DEFINE_MESSAGE(SC_ID_INCONSISTENT_API_CONFIG_ , 517,
+ "inconsistent library configuration detected" )
+// available message number 518
+SC_DEFINE_MESSAGE(SC_ID_WAIT_NOT_ALLOWED_ , 519,
+ "wait() is only allowed in SC_THREADs and SC_CTHREADs" )
+SC_DEFINE_MESSAGE(SC_ID_NEXT_TRIGGER_NOT_ALLOWED_ , 520,
+ "next_trigger() is only allowed in SC_METHODs" )
+SC_DEFINE_MESSAGE(SC_ID_IMMEDIATE_NOTIFICATION_ , 521,
+ "immediate notification is not allowed during the update phase" )
+SC_DEFINE_MESSAGE(SC_ID_HALT_NOT_ALLOWED_ , 522,
+ "halt() is only allowed in SC_CTHREADs" )
+SC_DEFINE_MESSAGE(SC_ID_WATCHING_NOT_ALLOWED_ , 523,
+ "watching() has been deprecated, use reset_signal_is()" )
+SC_DEFINE_MESSAGE(SC_ID_DONT_INITIALIZE_ , 524,
+ "dont_initialize() has no effect for SC_CTHREADs" )
+SC_DEFINE_MESSAGE(SC_ID_WAIT_N_INVALID_ , 525,
+ "wait(n) is only valid for n > 0" )
+SC_DEFINE_MESSAGE(SC_ID_MAKE_SENSITIVE_ , 526,
+ "make sensitive failed" )
+SC_DEFINE_MESSAGE(SC_ID_MAKE_SENSITIVE_POS_ , 527,
+ "make sensitive pos failed" )
+SC_DEFINE_MESSAGE(SC_ID_MAKE_SENSITIVE_NEG_ , 528,
+ "make sensitive neg failed" )
+SC_DEFINE_MESSAGE(SC_ID_INSERT_MODULE_ , 529,
+ "insert module failed" )
+SC_DEFINE_MESSAGE(SC_ID_REMOVE_MODULE_ , 530,
+ "remove module failed" )
+SC_DEFINE_MESSAGE(SC_ID_NOTIFY_DELAYED_ , 531,
+ "notify_delayed() cannot be called on events "
+ "that have pending notifications" )
+SC_DEFINE_MESSAGE(SC_ID_GEN_UNIQUE_NAME_ , 532,
+ "cannot generate unique name from null string" )
+SC_DEFINE_MESSAGE(SC_ID_MODULE_NAME_STACK_EMPTY_ , 533,
+ "module name stack is empty: did you forget to "
+ "add a sc_module_name parameter to your module "
+ "constructor?" )
+// available message number 534
+// available message number 535
+SC_DEFINE_MESSAGE( SC_ID_IMMEDIATE_SELF_NOTIFICATION_, 536,
+ "immediate self-notification ignored as of IEEE 1666-2011" )
+SC_DEFINE_MESSAGE( SC_ID_WAIT_DURING_UNWINDING_ , 537,
+ "wait() not allowed during unwinding" )
+SC_DEFINE_MESSAGE(SC_ID_CYCLE_MISSES_EVENTS_ , 538,
+ "the simulation contains timed-events but they are "
+ "ignored by sc_cycle() ==> the simulation will be "
+ "incorrect" )
+SC_DEFINE_MESSAGE( SC_ID_RETHROW_UNWINDING_ , 539,
+ "sc_unwind_exception not re-thrown during kill/reset" )
+SC_DEFINE_MESSAGE( SC_ID_PROCESS_ALREADY_UNWINDING_ , 540,
+ "kill/reset ignored during unwinding" )
+SC_DEFINE_MESSAGE(SC_ID_MODULE_METHOD_AFTER_START_ , 541,
+ "call to SC_METHOD in sc_module while simulation running" )
+SC_DEFINE_MESSAGE(SC_ID_MODULE_THREAD_AFTER_START_ , 542,
+ "call to SC_THREAD in sc_module while simulation running" )
+SC_DEFINE_MESSAGE(SC_ID_MODULE_CTHREAD_AFTER_START_ , 543,
+ "call to SC_CTHREAD in sc_module while simulation running" )
+SC_DEFINE_MESSAGE(SC_ID_SIMULATION_TIME_OVERFLOW_ , 544,
+ "simulation time value overflow, simulation aborted" )
+SC_DEFINE_MESSAGE(SC_ID_SIMULATION_STOP_CALLED_TWICE_ , 545,
+ "sc_stop has already been called" )
+SC_DEFINE_MESSAGE(SC_ID_SIMULATION_START_AFTER_STOP_ , 546,
+ "sc_start called after sc_stop has been called" )
+SC_DEFINE_MESSAGE(SC_ID_STOP_MODE_AFTER_START_ , 547,
+ "attempt to set sc_stop mode after start will be ignored" )
+SC_DEFINE_MESSAGE( SC_ID_SIMULATION_START_AFTER_ERROR_, 548,
+ "attempt to restart simulation after error" )
+SC_DEFINE_MESSAGE( SC_ID_SIMULATION_UNCAUGHT_EXCEPTION_, 549,
+ "uncaught exception" )
+SC_DEFINE_MESSAGE(SC_ID_PHASE_CALLBACKS_UNSUPPORTED_ , 550,
+ "simulation phase callbacks not enabled")
+SC_DEFINE_MESSAGE(SC_ID_PHASE_CALLBACK_NOT_IMPLEMENTED_, 551,
+ "empty simulation phase callback called" )
+SC_DEFINE_MESSAGE(SC_ID_PHASE_CALLBACK_REGISTER_, 552,
+ "register simulation phase callback" )
+SC_DEFINE_MESSAGE(SC_ID_PHASE_CALLBACK_FORBIDDEN_, 553,
+ "forbidden action in simulation phase callback" )
+// available message number 554
+// available message number 555
+SC_DEFINE_MESSAGE(SC_ID_THROW_IT_IGNORED_ , 556,
+ "throw_it on method/non-running process is being ignored " )
+SC_DEFINE_MESSAGE(SC_ID_NOT_EXPECTING_DYNAMIC_EVENT_NOTIFY_ , 557,
+ "dynamic event notification encountered when sensitivity is static" )
+SC_DEFINE_MESSAGE(SC_ID_DISABLE_WILL_ORPHAN_PROCESS_ , 558,
+ "disable() or dont_initialize() called on process with no static sensitivity, it will be orphaned" )
+SC_DEFINE_MESSAGE(SC_ID_PROCESS_CONTROL_CORNER_CASE_ , 559,
+ "Undefined process control interaction" )
+SC_DEFINE_MESSAGE(SC_ID_METHOD_TERMINATION_EVENT_ , 560,
+ "Attempt to get terminated event for a method process" )
+SC_DEFINE_MESSAGE(SC_ID_JOIN_ON_METHOD_HANDLE_ , 561,
+ "Attempt to register method process with sc_join object" )
+SC_DEFINE_MESSAGE(SC_ID_NO_PROCESS_SEMANTICS_ , 563,
+ "Attempt to invoke process with no semantics() method" )
+SC_DEFINE_MESSAGE(SC_ID_EVENT_ON_NULL_PROCESS_ , 564,
+ "Attempt to get an event for non-existent process" )
+// available message number 565
+SC_DEFINE_MESSAGE(SC_ID_UNKNOWN_PROCESS_TYPE_, 566,
+ "Unknown process type" )
+// available message number 567
+SC_DEFINE_MESSAGE(SC_ID_NEGATIVE_SIMULATION_TIME_, 568,
+ "negative simulation interval specified in sc_start call" )
+SC_DEFINE_MESSAGE(SC_ID_BAD_SC_MODULE_CONSTRUCTOR_ , 569,
+ "sc_module(const char*), sc_module(const std::string&) "
+ "have been deprecated, use sc_module(const sc_module_name&)" )
+SC_DEFINE_MESSAGE(SC_ID_EMPTY_PROCESS_HANDLE_ , 570,
+ "attempt to use an empty process handle ignored" )
+SC_DEFINE_MESSAGE(SC_ID_NO_SC_START_ACTIVITY_ , 571,
+ "no activity or clock movement for sc_start() invocation" )
+SC_DEFINE_MESSAGE(SC_ID_KILL_PROCESS_WHILE_UNITIALIZED_ , 572,
+ "a process may not be killed before it is initialized" )
+SC_DEFINE_MESSAGE(SC_ID_RESET_PROCESS_WHILE_NOT_RUNNING_ , 573,
+ "a process may not be asynchronously reset while the simulation is not running" )
+SC_DEFINE_MESSAGE(SC_ID_THROW_IT_WHILE_NOT_RUNNING_ , 574,
+ "throw_it not allowed unless simulation is running " )
+
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_kernel_ids.h,v $
+// Revision 1.25 2011/08/26 22:06:34 acg
+// Torsten Maehne: formating fix.
+//
+// Revision 1.24 2011/08/07 19:08:04 acg
+// Andy Goodrich: moved logs to end of file so line number synching works
+// better between versions.
+//
+// Revision 1.23 2011/07/24 11:15:47 acg
+// Philipp A. Hartmann: Improvements to error/warning messages related to
+// process control.
+//
+// Revision 1.22 2011/05/09 04:07:48 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.21 2011/04/19 19:15:41 acg
+// Andy Goodrich: fix so warning message is always issued for a throw_it()
+// on a method process.
+//
+// Revision 1.20 2011/04/19 15:04:27 acg
+// Philipp A. Hartmann: clean up SC_ID messages.
+//
+// Revision 1.19 2011/04/19 02:39:09 acg
+// Philipp A. Hartmann: added checks for additional throws during stack unwinds.
+//
+// Revision 1.18 2011/04/05 06:23:45 acg
+// Andy Goodrich: comments for throws while the simulator is not running.
+//
+// Revision 1.17 2011/04/01 22:30:39 acg
+// Andy Goodrich: change hard assertion to warning for trigger_dynamic()
+// getting called when there is only STATIC sensitivity. This can result
+// because of sc_process_handle::throw_it().
+//
+// Revision 1.16 2011/03/28 13:02:51 acg
+// Andy Goodrich: Changes for disable() interactions.
+//
+// Revision 1.15 2011/03/07 17:34:21 acg
+// Andy Goodrich: changed process control corner case message. Added more
+// place holders for unused message numbers.
+//
+// Revision 1.14 2011/03/06 19:57:11 acg
+// Andy Goodrich: refinements for the illegal suspend - synchronous reset
+// interaction.
+//
+// Revision 1.13 2011/03/06 15:56:29 acg
+// Andy Goodrich: added process control corner case error message, remove
+// unused messages.
+//
+// Revision 1.12 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.11 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.10 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.9 2011/02/13 21:29:16 acg
+// Andy Goodrich: added error messages for throws that occur before
+// simulator intialization.
+//
+// Revision 1.8 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.7 2011/02/07 19:17:20 acg
+// Andy Goodrich: changes for IEEE 1666 compatibility.
+//
+// Revision 1.6 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.5 2010/07/30 05:21:22 acg
+// Andy Goodrich: release 2.3 fixes.
+//
+// Revision 1.4 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.3 2008/11/17 15:57:15 acg
+// Andy Goodrich: added deprecation message for sc_module(const char*)
+//
+// Revision 1.2 2008/05/22 17:06:25 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.7 2006/08/29 23:37:13 acg
+// Andy Goodrich: Added check for negative time.
+//
+// Revision 1.6 2006/04/20 17:08:16 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.5 2006/01/25 00:31:19 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.4 2006/01/24 20:49:04 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_macros.h b/ext/systemc/src/sysc/kernel/sc_macros.h
new file mode 100644
index 000000000..baa6d6e3b
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_macros.h
@@ -0,0 +1,136 @@
+/*****************************************************************************
+
+ 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_macros.h -- Miscellaneous definitions that are needed by the headers.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_MACROS_H
+#define SC_MACROS_H
+
+
+namespace sc_dt {
+
+template <class T>
+inline
+const T
+sc_min( const T& a, const T& b )
+{
+ return ( ( a <= b ) ? a : b );
+}
+
+template <class T>
+inline
+const T
+sc_max( const T& a, const T& b )
+{
+ return ( ( a >= b ) ? a : b );
+}
+
+template <class T>
+inline
+const T
+sc_abs( const T& a )
+{
+ // return ( a >= 0 ? a : -a );
+ // the code below is functionaly the same as the code above; the
+ // difference is that the code below works for all arithmetic
+ // SystemC datatypes.
+ T z( a );
+ z = 0;
+ if( a >= z ) {
+ return a;
+ } else {
+ T c( a );
+ c = -a;
+ return c;
+ }
+}
+
+} // namespace sc_dt
+
+namespace sc_core {
+
+// token stringification
+
+#define SC_STRINGIFY_HELPER_( Arg ) \
+ SC_STRINGIFY_HELPER_DEFERRED_( Arg )
+#define SC_STRINGIFY_HELPER_DEFERRED_( Arg ) \
+ SC_STRINGIFY_HELPER_MORE_DEFERRED_( Arg )
+#define SC_STRINGIFY_HELPER_MORE_DEFERRED_( Arg ) \
+ #Arg
+
+
+// token concatenation
+
+#define SC_CONCAT_HELPER_( a, b ) \
+ SC_CONCAT_HELPER_DEFERRED_( a, b )
+#define SC_CONCAT_HELPER_DEFERRED_( a, b ) \
+ SC_CONCAT_HELPER_MORE_DEFERRED_( a,b )
+#define SC_CONCAT_HELPER_MORE_DEFERRED_( a, b ) \
+ a ## b
+#define SC_CONCAT_UNDERSCORE_( a, b ) \
+ SC_CONCAT_HELPER_( a, SC_CONCAT_HELPER_( _, b ) )
+
+/*
+ * These help debugging --
+ * -- user can find out where each process is stopped at.
+ */
+
+#define WAIT() \
+ ::sc_core::sc_set_location( __FILE__, __LINE__ ); \
+ ::sc_core::wait()
+
+#define WAITN(n) \
+ ::sc_core::sc_set_location( __FILE__, __LINE__ ); \
+ ::sc_core::wait(n)
+
+#define WAIT_UNTIL(expr) \
+ ::sc_core::sc_set_location( __FILE__, __LINE__ ); \
+ do { ::sc_core::wait(); } while( !(expr) )
+
+} // namespace sc_core
+
+// $Log: sc_macros.h,v $
+// Revision 1.5 2011/08/26 20:46:09 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.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:25 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.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_main.cpp b/ext/systemc/src/sysc/kernel/sc_main.cpp
new file mode 100644
index 000000000..a5f780d70
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_main.cpp
@@ -0,0 +1,58 @@
+/*****************************************************************************
+
+ 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_main.cpp - Wrapper around user's toplevel routine `sc_main'.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include "sysc/kernel/sc_cmnhdr.h"
+#include "sysc/kernel/sc_externs.h"
+
+int
+main( int argc, char* argv[] )
+{
+ return sc_core::sc_elab_and_sim( argc, argv );
+}
+
+// $Log: sc_main.cpp,v $
+// Revision 1.5 2011/08/26 20:46:09 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.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:25 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.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_main_main.cpp b/ext/systemc/src/sysc/kernel/sc_main_main.cpp
new file mode 100644
index 000000000..1cdf1eb49
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_main_main.cpp
@@ -0,0 +1,167 @@
+/*****************************************************************************
+
+ 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_main_main.cpp - Wrapper around user's toplevel routine `sc_main'.
+
+ Original Author: Andy Goodrich, Forte Design Systems
+
+ CHANGE LOG APPEARS AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include "sysc/kernel/sc_cmnhdr.h"
+#include "sysc/kernel/sc_externs.h"
+#include "sysc/kernel/sc_except.h"
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/utils/sc_report.h"
+#include "sysc/utils/sc_report_handler.h"
+#include "sysc/utils/sc_utils_ids.h"
+#include <vector>
+
+namespace sc_core {
+
+extern void pln();
+
+static int argc_copy; // Copy of argc value passed to sc_elab_and_sim.
+static char** argv_copy; // Copy of argv value passed to sc_elab_and_sim.
+
+static
+inline
+void
+message_function( const char* s )
+{
+ ::std::cout << "\n" << s << ::std::endl;
+}
+
+bool sc_in_action = false;
+
+int sc_argc()
+{
+ return argc_copy;
+}
+
+const char* const* sc_argv()
+{
+ return argv_copy;
+}
+
+
+int
+sc_elab_and_sim( int argc, char* argv[] )
+{
+ int status = 1;
+ argc_copy = argc;
+ argv_copy = argv;
+ std::vector<char*> argv_call;
+ for ( int i = 0; i < argc; i++ )
+ argv_call.push_back(argv[i]);
+
+ try
+ {
+ pln();
+
+ // Perform initialization here
+ sc_in_action = true;
+
+ status = sc_main( argc, &argv_call[0] );
+
+ // Perform cleanup here
+ sc_in_action = false;
+ }
+ catch( const sc_report& x )
+ {
+ message_function( x.what() );
+ }
+ catch( ... )
+ {
+ // translate other escaping exceptions
+ sc_report* err_p = sc_handle_exception();
+ if( err_p ) message_function( err_p->what() );
+ delete err_p;
+ }
+
+ // IF DEPRECATION WARNINGS WERE ISSUED TELL THE USER HOW TO TURN THEM OFF
+
+ if ( sc_report_handler::get_count( SC_ID_IEEE_1666_DEPRECATION_ ) > 0 )
+ {
+ std::stringstream ss;
+
+# define MSGNL "\n "
+# define CODENL "\n "
+
+ ss <<
+ "You can turn off warnings about" MSGNL
+ "IEEE 1666 deprecated features by placing this method call" MSGNL
+ "as the first statement in your sc_main() function:\n" CODENL
+ "sc_core::sc_report_handler::set_actions( "
+ "\"" << SC_ID_IEEE_1666_DEPRECATION_ << "\"," CODENL
+ " " /* indent param */
+ "sc_core::SC_DO_NOTHING );"
+ << std::endl;
+
+ SC_REPORT_INFO( SC_ID_IEEE_1666_DEPRECATION_, ss.str().c_str() );
+ }
+
+ return status;
+}
+
+} // namespace sc_core
+
+// $Log: sc_main_main.cpp,v $
+// Revision 1.9 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.8 2011/05/09 04:07:48 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.7 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.6 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.5 2010/03/15 18:29:25 acg
+// Andy Goodrich: Changed the default stack size to 128K from 64K.
+//
+// Revision 1.4 2009/10/14 19:06:48 acg
+// Andy Goodrich: changed the way the "copy" of argv is handled. It is
+// now passed to sc_main, and the original is referenced via argv_copy.
+//
+// Revision 1.3 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2008/04/11 20:41:28 acg
+// Andy Goodrich: changed the return value in sc_elab_and_sim() to be 1
+// when an exception occurs in sc_main() rather than 0.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.4 2006/01/25 00:31:19 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_method_process.cpp b/ext/systemc/src/sysc/kernel/sc_method_process.cpp
new file mode 100644
index 000000000..994e495ad
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_method_process.cpp
@@ -0,0 +1,1023 @@
+/*****************************************************************************
+
+ 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_method_process.cpp -- Method process implementation
+
+ Original Author: Andy Goodrich, Forte Design Systems, 4 August 2005
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_method_process.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_spawn_options.h"
+
+// DEBUGGING MACROS:
+//
+// DEBUG_MSG(NAME,P,MSG)
+// MSG = message to print
+// NAME = name that must match the process for the message to print, or
+// null if the message should be printed unconditionally.
+// P = pointer to process message is for, or NULL in which case the
+// message will not print.
+#if 0
+# define DEBUG_NAME ""
+# define DEBUG_MSG(NAME,P,MSG) \
+ { \
+ if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
+ std::cout << "**** " << sc_time_stamp() << " (" \
+ << sc_get_current_process_name() << "): " << MSG \
+ << " - " << P->name() << std::endl; \
+ }
+#else
+# define DEBUG_MSG(NAME,P,MSG)
+#endif
+
+namespace sc_core {
+
+// +----------------------------------------------------------------------------
+// |"sc_method_process::check_for_throws"
+// |
+// | This method checks to see if this method process should throw an exception
+// | or not. It is called from sc_simcontext::preempt_with() to see if the
+// | thread that was executed during the preemption did a kill or other
+// | manipulation on this object instance that requires it to throw an
+// | exception.
+// +----------------------------------------------------------------------------
+void sc_method_process::check_for_throws()
+{
+ if ( !m_unwinding )
+ {
+ switch( m_throw_status )
+ {
+ case THROW_ASYNC_RESET:
+ simcontext()->preempt_with(this);
+ break;
+ case THROW_KILL:
+ throw sc_unwind_exception( this, false );
+ default:
+ break;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_method_process::clear_trigger"
+//
+// This method clears any pending trigger for this object instance.
+//------------------------------------------------------------------------------
+void sc_method_process::clear_trigger()
+{
+ switch( m_trigger_type ) {
+ case STATIC:
+ return;
+ case EVENT:
+ m_event_p->remove_dynamic( this );
+ m_event_p = 0;
+ break;
+ case OR_LIST:
+ m_event_list_p->remove_dynamic( this, 0 );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ break;
+ case AND_LIST:
+ m_event_list_p->remove_dynamic( this, 0 );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_event_count = 0;
+ break;
+ case TIMEOUT:
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ break;
+ case EVENT_TIMEOUT:
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ m_event_p->remove_dynamic( this );
+ m_event_p = 0;
+ break;
+ case OR_LIST_TIMEOUT:
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ m_event_list_p->remove_dynamic( this, 0 );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ break;
+ case AND_LIST_TIMEOUT:
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ m_event_list_p->remove_dynamic( this, 0 );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_event_count = 0;
+ break;
+ }
+ m_trigger_type = STATIC;
+}
+
+//------------------------------------------------------------------------------
+//"sc_method_process::disable_process"
+//
+// This virtual method disables this process and its children if requested to.
+// descendants = indicator of whether this process' children should also
+// be suspended
+//------------------------------------------------------------------------------
+void sc_method_process::disable_process(
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF NEEDED PROPOGATE THE SUSPEND REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*>& children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->disable_process(descendants);
+ }
+ }
+
+ // DON'T ALLOW CORNER CASE BY DEFAULT:
+
+ if ( !sc_allow_process_control_corners )
+ {
+ switch( m_trigger_type )
+ {
+ case AND_LIST_TIMEOUT:
+ case EVENT_TIMEOUT:
+ case OR_LIST_TIMEOUT:
+ case TIMEOUT:
+ report_error( SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "attempt to disable a method with timeout wait" );
+ break;
+ default:
+ break;
+ }
+ }
+
+ // DISABLE OUR OBJECT INSTANCE:
+
+ m_state = m_state | ps_bit_disabled;
+
+ // IF THIS CALL IS BEFORE THE SIMULATION DON'T RUN THE METHOD:
+
+ if ( !sc_is_running() )
+ {
+ sc_get_curr_simcontext()->remove_runnable_method(this);
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_method_process::enable_process"
+//
+// This method enables the execution of this process, and if requested, its
+// descendants. If the process was suspended and has a resumption pending it
+// will be dispatched in the next delta cycle. Otherwise the state will be
+// adjusted to indicate it is no longer suspended, but no immediate execution
+// will occur.
+//------------------------------------------------------------------------------
+void sc_method_process::enable_process(
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF NEEDED PROPOGATE THE RESUME REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*>& children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->enable_process(descendants);
+ }
+ }
+
+ // ENABLE THIS OBJECT INSTANCE:
+ //
+ // If it was disabled and ready to run then put it on the run queue.
+
+ m_state = m_state & ~ps_bit_disabled;
+ if ( m_state == ps_bit_ready_to_run )
+ {
+ m_state = ps_normal;
+ if ( next_runnable() == 0 )
+ simcontext()->push_runnable_method(this);
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_method_process::kill_process"
+//
+// This method removes throws a kill for this object instance. It calls the
+// sc_process_b::kill_process() method to perform low level clean up.
+//------------------------------------------------------------------------------
+void sc_method_process::kill_process(sc_descendant_inclusion_info descendants)
+{
+
+ // IF THE SIMULATION HAS NOT BEEN INITIALIZED YET THAT IS AN ERROR:
+
+ if ( sc_get_status() == SC_ELABORATION )
+ {
+ report_error( SC_ID_KILL_PROCESS_WHILE_UNITIALIZED_ );
+ }
+
+ // IF NEEDED, PROPOGATE THE KILL REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*> children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->kill_process(descendants);
+ }
+ }
+
+ // IF THE PROCESS IS CURRENTLY UNWINDING OR IS ALREADY A ZOMBIE
+ // IGNORE THE KILL:
+
+ if ( m_unwinding )
+ {
+ SC_REPORT_WARNING( SC_ID_PROCESS_ALREADY_UNWINDING_, name() );
+ return;
+ }
+
+ if ( m_state & ps_bit_zombie )
+ return;
+
+
+ // REMOVE OUR PROCESS FROM EVENTS, ETC., AND IF ITS THE ACTIVE PROCESS
+ // THROW ITS KILL.
+ //
+ // Note we set the throw status to kill regardless if we throw or not.
+ // That lets check_for_throws stumble across it if we were in the call
+ // chain when the kill call occurred.
+
+ if ( next_runnable() != 0 )
+ simcontext()->remove_runnable_method( this );
+ disconnect_process();
+
+ m_throw_status = THROW_KILL;
+ if ( sc_get_current_process_b() == this )
+ {
+ throw sc_unwind_exception( this, false );
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_method_process::sc_method_process"
+//
+// This is the object instance constructor for this class.
+//------------------------------------------------------------------------------
+sc_method_process::sc_method_process( const char* name_p,
+ bool free_host, SC_ENTRY_FUNC method_p,
+ sc_process_host* host_p, const sc_spawn_options* opt_p
+):
+ sc_process_b(
+ name_p ? name_p : sc_gen_unique_name("method_p"),
+ false, free_host, method_p, host_p, opt_p),
+ m_cor(0), m_stack_size(0), m_monitor_q()
+{
+
+ // CHECK IF THIS IS AN sc_module-BASED PROCESS AND SIMUALTION HAS STARTED:
+
+ if ( DCAST<sc_module*>(host_p) != 0 && sc_is_running() )
+ {
+ report_error( SC_ID_MODULE_METHOD_AFTER_START_, "" );
+ }
+
+ // INITIALIZE VALUES:
+ //
+ // If there are spawn options use them.
+
+ m_process_kind = SC_METHOD_PROC_;
+ if (opt_p) {
+ m_dont_init = opt_p->m_dont_initialize;
+
+ // traverse event sensitivity list
+ for (unsigned int i = 0; i < opt_p->m_sensitive_events.size(); i++) {
+ sc_sensitive::make_static_sensitivity(
+ this, *opt_p->m_sensitive_events[i]);
+ }
+
+ // traverse port base sensitivity list
+ for ( unsigned int i = 0; i < opt_p->m_sensitive_port_bases.size(); i++)
+ {
+ sc_sensitive::make_static_sensitivity(
+ this, *opt_p->m_sensitive_port_bases[i]);
+ }
+
+ // traverse interface sensitivity list
+ for ( unsigned int i = 0; i < opt_p->m_sensitive_interfaces.size(); i++)
+ {
+ sc_sensitive::make_static_sensitivity(
+ this, *opt_p->m_sensitive_interfaces[i]);
+ }
+
+ // traverse event finder sensitivity list
+ for ( unsigned int i = 0; i < opt_p->m_sensitive_event_finders.size();
+ i++)
+ {
+ sc_sensitive::make_static_sensitivity(
+ this, *opt_p->m_sensitive_event_finders[i]);
+ }
+
+ // process any reset signal specification:
+
+ opt_p->specify_resets();
+ }
+
+ else
+ {
+ m_dont_init = false;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_method_process::sc_method_process"
+//
+// This is the object instance destructor for this class.
+//------------------------------------------------------------------------------
+sc_method_process::~sc_method_process()
+{
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_method_process::suspend_process"
+//
+// This virtual method suspends this process and its children if requested to.
+// descendants = indicator of whether this process' children should also
+// be suspended
+//------------------------------------------------------------------------------
+void sc_method_process::suspend_process(
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF NEEDED PROPOGATE THE SUSPEND REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*>& children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->suspend_process(descendants);
+ }
+ }
+
+ // CORNER CASE CHECKS, THE FOLLOWING ARE ERRORS:
+ // (a) if this method has a reset_signal_is specification
+ // (b) if this method is in synchronous reset
+
+ if ( !sc_allow_process_control_corners && m_has_reset_signal )
+ {
+ report_error(SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "attempt to suspend a method that has a reset signal");
+ }
+ else if ( !sc_allow_process_control_corners && m_sticky_reset )
+ {
+ report_error(SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "attempt to suspend a method in synchronous reset");
+ }
+
+ // SUSPEND OUR OBJECT INSTANCE:
+ //
+ // (1) If we are on the runnable queue then set suspended and ready_to_run,
+ // and remove ourselves from the run queue.
+ // (2) If this is a self-suspension then a resume should cause immediate
+ // scheduling of the process.
+
+ m_state = m_state | ps_bit_suspended;
+ if ( next_runnable() != 0 )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ simcontext()->remove_runnable_method( this );
+ }
+ if ( sc_get_current_process_b() == DCAST<sc_process_b*>(this) )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_method_process::resume_process"
+//
+// This method resumes the execution of this process, and if requested, its
+// descendants. If the process was suspended and has a resumption pending it
+// will be dispatched in the next delta cycle. Otherwise the state will be
+// adjusted to indicate it is no longer suspended, but no immediate execution
+// will occur.
+//------------------------------------------------------------------------------
+void sc_method_process::resume_process(
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF NEEDED PROPOGATE THE RESUME REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*>& children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->resume_process(descendants);
+ }
+ }
+
+
+ // BY DEFAULT THE CORNER CASE IS AN ERROR:
+
+ if ( !sc_allow_process_control_corners && (m_state & ps_bit_disabled) &&
+ (m_state & ps_bit_suspended) )
+ {
+ m_state = m_state & ~ps_bit_suspended;
+ report_error( SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "call to resume() on a disabled suspended method");
+ }
+
+ // CLEAR THE SUSPENDED BIT:
+
+ m_state = m_state & ~ps_bit_suspended;
+
+ // RESUME OBJECT INSTANCE:
+ //
+ // If this is not a self-resume and the method is ready to run then
+ // put it on the runnable queue.
+
+ if ( m_state & ps_bit_ready_to_run )
+ {
+ m_state = m_state & ~ps_bit_ready_to_run;
+ if ( next_runnable() == 0 &&
+ ( sc_get_current_process_b() != DCAST<sc_process_b*>(this) ) )
+ {
+ simcontext()->push_runnable_method(this);
+ remove_dynamic_events();
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_method_process::throw_reset"
+//
+// This virtual method is invoked to "throw" a reset.
+//
+// If the reset is synchronous this is a no-op, except for triggering the
+// reset event if it is present.
+//
+// If the reset is asynchronous we:
+// (a) cancel any dynamic waits
+// (b) if it is the active process actually throw a reset exception.
+// (c) if it was not the active process and does not have a static
+// sensitivity emit an error if corner cases are to be considered
+// errors.
+//
+// Notes:
+// (1) If the process had a reset event it will have been triggered in
+// sc_process_b::semantics()
+//
+// Arguments:
+// async = true if this is an asynchronous reset.
+//------------------------------------------------------------------------------
+void sc_method_process::throw_reset( bool async )
+{
+ // IF THE PROCESS IS CURRENTLY UNWINDING OR IS ALREADY A ZOMBIE
+ // IGNORE THE RESET:
+
+ if ( m_unwinding )
+ {
+ SC_REPORT_WARNING( SC_ID_PROCESS_ALREADY_UNWINDING_, name() );
+ return;
+ }
+
+ if ( m_state & ps_bit_zombie )
+ return;
+
+ // Set the throw status and if its an asynchronous reset throw an
+ // exception:
+
+ m_throw_status = async ? THROW_ASYNC_RESET : THROW_SYNC_RESET;
+ if ( async )
+ {
+ remove_dynamic_events();
+ if ( sc_get_current_process_b() == this )
+ {
+ DEBUG_MSG(DEBUG_NAME,this,"throw_reset: throwing exception");
+ m_throw_status = THROW_ASYNC_RESET;
+ throw sc_unwind_exception( this, true );
+ }
+ else
+ {
+ DEBUG_MSG(DEBUG_NAME,this,
+ "throw_reset: queueing this method for execution");
+ simcontext()->preempt_with(this);
+ }
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_method_process::throw_user"
+//
+// This virtual method is invoked when a user exception is to be thrown.
+// If requested it will also throw the exception to the children of this
+// object instance. Since this is a method no throw will occur for this
+// object instance. The children will be awakened from youngest child to
+// eldest.
+// helper_p -> object to use to throw the exception.
+// descendants = indicator of whether this process' children should also
+// be suspended
+//------------------------------------------------------------------------------
+void sc_method_process::throw_user( const sc_throw_it_helper& helper,
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF THE SIMULATION IS NOT ACTUALLY RUNNING THIS IS AN ERROR:
+
+ if ( sc_get_status() != SC_RUNNING )
+ {
+ report_error( SC_ID_THROW_IT_WHILE_NOT_RUNNING_ );
+ }
+
+ // IF NEEDED PROPOGATE THE THROW REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*> children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p )
+ {
+ DEBUG_MSG(DEBUG_NAME,child_p,"about to throw user on");
+ child_p->throw_user(helper, descendants);
+ }
+ }
+ }
+
+#if 0 // shouldn't we throw, if we're currently running?
+
+ if ( sc_get_current_process_b() == (sc_process_b*)this )
+ {
+ remove_dynamic_events();
+ m_throw_status = THROW_USER;
+ if ( m_throw_helper_p != 0 ) delete m_throw_helper_p;
+ m_throw_helper_p = helper.clone();
+ m_throw_helper_p->throw_it();
+ }
+
+ // throw_it HAS NO EFFECT ON A METHOD, ISSUE A WARNING:
+
+ else
+
+#endif
+ {
+ SC_REPORT_WARNING( SC_ID_THROW_IT_IGNORED_, name() );
+ }
+
+
+}
+
+//------------------------------------------------------------------------------
+//"sc_method_process::trigger_dynamic"
+//
+// This method sets up a dynamic trigger on an event.
+//
+// Notes:
+// (1) This method is identical to sc_thread_process::trigger_dynamic(),
+// but they cannot be combined as sc_process_b::trigger_dynamic()
+// because the signatures things like sc_event::remove_dynamic()
+// have different overloads for sc_method_process* and sc_thread_process*.
+// So if you change code here you'll also need to change it in
+// sc_thread_process.cpp.
+//
+// Result is true if this process should be removed from the event's list,
+// false if not.
+//
+// If the triggering process is the same process, the trigger is
+// ignored as well, unless SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
+// is defined.
+//------------------------------------------------------------------------------
+bool sc_method_process::trigger_dynamic( sc_event* e )
+{
+ // No time outs yet, and keep gcc happy.
+
+ m_timed_out = false;
+
+ // Escape cases:
+ // (a) If this method issued the notify() don't schedule it for
+ // execution, but leave the sensitivity in place.
+ // (b) If this method is already runnable can't trigger an event.
+
+#if ! defined( SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS )
+ if( SC_UNLIKELY_( sc_get_current_process_b() == this ) )
+ {
+ report_immediate_self_notification();
+ return false;
+ }
+#endif // SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
+
+ if( is_runnable() )
+ return true;
+
+ // If a process is disabled then we ignore any events, leaving them enabled:
+ //
+ // But if this is a time out event we need to remove both it and the
+ // event that was being waited for.
+
+ if ( m_state & ps_bit_disabled )
+ {
+ if ( e == m_timeout_event_p )
+ {
+ remove_dynamic_events( true );
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+ // Process based on the event type and current process state:
+ //
+ // Every case needs to set 'rc' and continue on to the end of
+ // this method to allow suspend processing to work correctly.
+
+ switch( m_trigger_type )
+ {
+ case EVENT:
+ m_event_p = 0;
+ m_trigger_type = STATIC;
+ break;
+
+ case AND_LIST:
+ -- m_event_count;
+ if ( m_event_count == 0 )
+ {
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+ else
+ {
+ return true;
+ }
+ break;
+
+ case OR_LIST:
+ m_event_list_p->remove_dynamic( this, e );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ break;
+
+ case TIMEOUT:
+ m_trigger_type = STATIC;
+ break;
+
+ case EVENT_TIMEOUT:
+ if ( e == m_timeout_event_p )
+ {
+ m_timed_out = true;
+ m_event_p->remove_dynamic( this );
+ m_event_p = 0;
+ m_trigger_type = STATIC;
+ }
+ else
+ {
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ m_event_p = 0;
+ m_trigger_type = STATIC;
+ }
+ break;
+
+ case OR_LIST_TIMEOUT:
+ if ( e == m_timeout_event_p )
+ {
+ m_timed_out = true;
+ m_event_list_p->remove_dynamic( this, e );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+
+ else
+ {
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ m_event_list_p->remove_dynamic( this, e );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+ break;
+
+ case AND_LIST_TIMEOUT:
+ if ( e == m_timeout_event_p )
+ {
+ m_timed_out = true;
+ m_event_list_p->remove_dynamic( this, e );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+
+ else
+ {
+ -- m_event_count;
+ if ( m_event_count == 0 )
+ {
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ // no need to remove_dynamic
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+ else
+ {
+ return true;
+ }
+ }
+ break;
+
+ case STATIC: {
+ // we should never get here, but throw_it() can make it happen.
+ SC_REPORT_WARNING(SC_ID_NOT_EXPECTING_DYNAMIC_EVENT_NOTIFY_, name());
+ return true;
+ }
+ }
+
+ // If we get here then the method has satisfied its next_trigger, if its
+ // suspended mark its state as ready to run. If its not suspended then push
+ // it onto the runnable queue.
+
+ if ( (m_state & ps_bit_suspended) )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ }
+ else
+ {
+ simcontext()->push_runnable_method(this);
+ }
+
+ return true;
+}
+
+} // namespace sc_core
+
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_method_process.cpp,v $
+// Revision 1.49 2011/08/29 18:24:47 acg
+// Andy Goodrich: remove temporary comment flagging new preempt_with() call.
+//
+// Revision 1.48 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.47 2011/08/24 22:05:50 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.46 2011/08/07 19:08:04 acg
+// Andy Goodrich: moved logs to end of file so line number synching works
+// better between versions.
+//
+// Revision 1.45 2011/07/29 22:42:45 acg
+// Andy Goodrich: added check_for_throws() to fix case where a method is
+// deleted by a process it resets or kills so that it can throw itself.
+// Philipp A. Hartmann: changes to handle case where a process control
+// invocation on a child process causes the list of child processes to change.
+//
+// Revision 1.44 2011/07/24 11:27:04 acg
+// Andy Goodrich: moved the check for unwinding processes until after the
+// descendants have been processed in throw_user and kill.
+//
+// Revision 1.43 2011/07/24 11:20:03 acg
+// Philipp A. Hartmann: process control error message improvements:
+// (1) Downgrade error to warning for re-kills of processes.
+// (2) Add process name to process messages.
+// (3) drop some superfluous colons in messages.
+//
+// Revision 1.42 2011/05/05 17:45:27 acg
+// Philip A. Hartmann: changes in WIN64 support.
+// Andy Goodrich: additional DEBUG_MSG instances to trace process handling.
+//
+// Revision 1.41 2011/04/19 19:15:41 acg
+// Andy Goodrich: fix so warning message is always issued for a throw_it()
+// on a method process.
+//
+// Revision 1.40 2011/04/19 15:04:27 acg
+// Philipp A. Hartmann: clean up SC_ID messages.
+//
+// Revision 1.39 2011/04/19 02:39:09 acg
+// Philipp A. Hartmann: added checks for additional throws during stack unwinds.
+//
+// Revision 1.38 2011/04/13 02:41:34 acg
+// Andy Goodrich: eliminate warning messages generated when the DEBUG_MSG
+// macro is used.
+//
+// Revision 1.37 2011/04/11 22:10:46 acg
+// Andy Goodrich:
+// (1) Add DEBUG_MSG macro and use it to generate a journal of method
+// throws if it is enabled.
+// (2) Trim down to the expected behavior of scheduling a method that
+// is asynchronously reset in anticipation of IEEE 1666 being revised.
+//
+// Revision 1.36 2011/04/10 22:15:29 acg
+// Andy Goodrich: change to call methods on asynchronous reset.
+//
+// Revision 1.35 2011/04/08 22:31:40 acg
+// Andy Goodrich: removed unused code.
+//
+// Revision 1.34 2011/04/08 18:24:07 acg
+// Andy Goodrich: fix asynchronous reset dispatch and when the reset_event()
+// is fired.
+//
+// Revision 1.33 2011/04/05 20:50:56 acg
+// Andy Goodrich:
+// (1) changes to make sure that event(), posedge() and negedge() only
+// return true if the clock has not moved.
+// (2) fixes for method self-resumes.
+// (3) added SC_PRERELEASE_VERSION
+// (4) removed kernel events from the object hierarchy, added
+// sc_hierarchy_name_exists().
+//
+// Revision 1.32 2011/04/01 22:30:39 acg
+// Andy Goodrich: change hard assertion to warning for trigger_dynamic()
+// getting called when there is only STATIC sensitivity. This can result
+// because of sc_process_handle::throw_it().
+//
+// Revision 1.31 2011/03/28 13:02:51 acg
+// Andy Goodrich: Changes for disable() interactions.
+//
+// Revision 1.30 2011/03/23 16:17:52 acg
+// Andy Goodrich: don't emit an error message for a resume on a disabled
+// process that is not suspended.
+//
+// Revision 1.29 2011/03/20 13:43:23 acg
+// Andy Goodrich: added async_signal_is() plus suspend() as a corner case.
+//
+// Revision 1.28 2011/03/08 20:49:30 acg
+// Andy Goodrich: implement coarse checking for synchronous reset - suspend
+// interaction.
+//
+// Revision 1.27 2011/03/08 20:32:28 acg
+// Andy Goodrich: implemented "coarse" checking for undefined process
+// control interactions.
+//
+// Revision 1.26 2011/03/07 18:25:19 acg
+// Andy Goodrich: tightening of check for resume on a disabled process to
+// only produce an error if it is ready to run.
+//
+// Revision 1.25 2011/03/07 17:38:43 acg
+// Andy Goodrich: tightening up of checks for undefined interaction between
+// synchronous reset and suspend.
+//
+// Revision 1.24 2011/03/06 23:30:13 acg
+// Andy Goodrich: refining suspend - sync reset corner case checking so that
+// the following are error situations:
+// (1) Calling suspend on a process with a reset_signal_is() specification
+// or sync_reset_on() is active.
+// (2) Calling sync_reset_on() on a suspended process.
+//
+// Revision 1.23 2011/03/06 19:57:11 acg
+// Andy Goodrich: refinements for the illegal suspend - synchronous reset
+// interaction.
+//
+// Revision 1.22 2011/03/06 16:47:09 acg
+// Andy Goodrich: changes for testing sync_reset - suspend corner cases.
+//
+// Revision 1.21 2011/03/06 15:57:08 acg
+// Andy Goodrich: added process control corner case checks.
+//
+// Revision 1.20 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.19 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.18 2011/02/17 19:50:43 acg
+// Andy Goodrich:
+// (1) Changed signature of trigger_dynamic back to a bool.
+// (2) Added run queue processing into trigger dynamic.
+// (3) Simplified process control support.
+//
+// Revision 1.17 2011/02/16 22:37:30 acg
+// Andy Goodrich: clean up to remove need for ps_disable_pending.
+//
+// Revision 1.16 2011/02/13 23:09:58 acg
+// Andy Goodrich: only remove dynamic events for asynchronous resets.
+//
+// Revision 1.15 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.14 2011/02/13 21:31:02 acg
+// Andy Goodrich: added error messages for throws when simulator has not
+// been initialized. Added missing remove_dynamic_events() call to the
+// reset code.
+//
+// Revision 1.13 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.12 2011/02/07 19:17:20 acg
+// Andy Goodrich: changes for IEEE 1666 compatibility.
+//
+// Revision 1.11 2011/02/04 15:27:36 acg
+// Andy Goodrich: changes for suspend-resume semantics.
+//
+// Revision 1.10 2011/02/01 23:01:53 acg
+// Andy Goodrich: removed dead code.
+//
+// Revision 1.9 2011/02/01 21:05:05 acg
+// Andy Goodrich: Changes in trigger_dynamic methods to handle new
+// process control rules about event sensitivity.
+//
+// Revision 1.8 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.7 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.6 2011/01/06 18:02:43 acg
+// Andy Goodrich: added check for ps_disabled to method_dynamic().
+//
+// Revision 1.5 2010/11/20 17:10:56 acg
+// Andy Goodrich: reset processing changes for new IEEE 1666 standard.
+//
+// Revision 1.4 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.2 2008/05/22 17:06:25 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.7 2006/04/20 17:08:16 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.6 2006/04/11 23:13:20 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.5 2006/01/26 21:04:54 acg
+// Andy Goodrich: deprecation message changes and additional messages.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_method_process.h b/ext/systemc/src/sysc/kernel/sc_method_process.h
new file mode 100644
index 000000000..00f6e37e7
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_method_process.h
@@ -0,0 +1,467 @@
+/*****************************************************************************
+
+ 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_method_process.h -- Method process declarations
+
+ Original Author: Andy Goodrich, Forte Design Systems, 4 August 2005
+
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+// $Log: sc_method_process.h,v $
+// Revision 1.23 2011/09/05 21:20:22 acg
+// Andy Goodrich: result of automake invocation.
+//
+// Revision 1.22 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.21 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.
+//
+
+#if !defined(sc_method_process_h_INCLUDED)
+#define sc_method_process_h_INCLUDED
+
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_spawn_options.h"
+#include "sysc/kernel/sc_cor.h"
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_except.h"
+
+
+// DEBUGGING MACROS:
+//
+// DEBUG_MSG(NAME,P,MSG)
+// MSG = message to print
+// NAME = name that must match the process for the message to print, or
+// null if the message should be printed unconditionally.
+// P = pointer to process message is for, or NULL in which case the
+// message will not print.
+#if 0
+# define DEBUG_NAME ""
+# define DEBUG_MSG(NAME,P,MSG) \
+ { \
+ if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
+ std::cout << "**** " << sc_time_stamp() << " (" \
+ << sc_get_current_process_name() << "): " << MSG \
+ << " - " << P->name() << std::endl; \
+ }
+#else
+# define DEBUG_MSG(NAME,P,MSG)
+#endif
+
+
+namespace sc_core {
+
+// forward function and class declarations:
+
+void sc_method_cor_fn( void* );
+void sc_cmethod_cor_fn( void* );
+void sc_set_stack_size( sc_method_handle, std::size_t );
+class sc_event;
+class sc_module;
+class sc_process_table;
+class sc_process_handle;
+class sc_simcontext;
+class sc_runnable;
+
+void next_trigger( sc_simcontext* );
+void next_trigger( const sc_event&, sc_simcontext* );
+void next_trigger( const sc_event_or_list&, sc_simcontext* );
+void next_trigger( const sc_event_and_list&, sc_simcontext* );
+void next_trigger( const sc_time&, sc_simcontext* );
+void next_trigger( const sc_time&, const sc_event&, sc_simcontext* );
+void next_trigger( const sc_time&, const sc_event_or_list&, sc_simcontext* );
+void next_trigger( const sc_time&, const sc_event_and_list&, sc_simcontext* );
+
+struct sc_invoke_method;
+//==============================================================================
+// sc_method_process -
+//
+//==============================================================================
+class sc_method_process : public sc_process_b {
+ friend struct sc_invoke_method;
+ friend void sc_method_cor_fn( void* );
+ friend void sc_cmethod_cor_fn( void* );
+ friend void sc_set_stack_size( sc_method_handle, std::size_t );
+ friend class sc_event;
+ friend class sc_module;
+ friend class sc_process_table;
+ friend class sc_process_handle;
+ friend class sc_simcontext;
+ friend class sc_runnable;
+
+ friend void next_trigger( sc_simcontext* );
+ friend void next_trigger( const sc_event&,
+ sc_simcontext* );
+ friend void next_trigger( const sc_event_or_list&,
+ sc_simcontext* );
+ friend void next_trigger( const sc_event_and_list&,
+ sc_simcontext* );
+ friend void next_trigger( const sc_time&,
+ sc_simcontext* );
+ friend void next_trigger( const sc_time&, const sc_event&,
+ sc_simcontext* );
+ friend void next_trigger( const sc_time&, const sc_event_or_list&,
+ sc_simcontext* );
+ friend void next_trigger( const sc_time&, const sc_event_and_list&,
+ sc_simcontext* );
+
+ public:
+ sc_method_process( const char* name_p, bool free_host,
+ SC_ENTRY_FUNC method_p, sc_process_host* host_p,
+ const sc_spawn_options* opt_p );
+
+ virtual const char* kind() const
+ { return "sc_method_process"; }
+
+ protected:
+ void check_for_throws();
+ virtual void disable_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ virtual void enable_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ inline bool run_process();
+ virtual void kill_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ sc_method_handle next_exist();
+ sc_method_handle next_runnable();
+ void clear_trigger();
+ void next_trigger( const sc_event& );
+ void next_trigger( const sc_event_or_list& );
+ void next_trigger( const sc_event_and_list& );
+ void next_trigger( const sc_time& );
+ void next_trigger( const sc_time&, const sc_event& );
+ void next_trigger( const sc_time&, const sc_event_or_list& );
+ void next_trigger( const sc_time&, const sc_event_and_list& );
+ virtual void resume_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ void set_next_exist( sc_method_handle next_p );
+ void set_next_runnable( sc_method_handle next_p );
+ void set_stack_size( std::size_t size );
+ virtual void suspend_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ virtual void throw_reset( bool async );
+ virtual void throw_user( const sc_throw_it_helper& helper,
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ bool trigger_dynamic( sc_event* );
+ inline void trigger_static();
+
+ protected:
+ sc_cor* m_cor; // Thread's coroutine.
+ std::size_t m_stack_size; // Thread stack size.
+ std::vector<sc_process_monitor*> m_monitor_q; // Thread monitors.
+
+ private:
+ // may not be deleted manually (called from sc_process_b)
+ virtual ~sc_method_process();
+
+ private: // disabled
+ sc_method_process( const sc_method_process& );
+ const sc_method_process& operator = ( const sc_method_process& );
+
+};
+
+inline
+void
+sc_method_process::next_trigger( const sc_event& e )
+{
+ clear_trigger();
+ e.add_dynamic( this );
+ m_event_p = &e;
+ m_trigger_type = EVENT;
+}
+
+inline
+void
+sc_method_process::next_trigger( const sc_event_or_list& el )
+{
+ clear_trigger();
+ el.add_dynamic( this );
+ m_event_list_p = &el;
+ m_trigger_type = OR_LIST;
+}
+
+inline
+void
+sc_method_process::next_trigger( const sc_event_and_list& el )
+{
+ clear_trigger();
+ el.add_dynamic( this );
+ m_event_list_p = &el;
+ m_event_count = el.size();
+ m_trigger_type = AND_LIST;
+}
+
+inline
+void
+sc_method_process::next_trigger( const sc_time& t )
+{
+ clear_trigger();
+ m_timeout_event_p->notify_internal( t );
+ m_timeout_event_p->add_dynamic( this );
+ m_trigger_type = TIMEOUT;
+}
+
+inline
+void
+sc_method_process::next_trigger( const sc_time& t, const sc_event& e )
+{
+ clear_trigger();
+ m_timeout_event_p->notify_internal( t );
+ m_timeout_event_p->add_dynamic( this );
+ e.add_dynamic( this );
+ m_event_p = &e;
+ m_trigger_type = EVENT_TIMEOUT;
+}
+
+inline
+void
+sc_method_process::next_trigger( const sc_time& t, const sc_event_or_list& el )
+{
+ clear_trigger();
+ m_timeout_event_p->notify_internal( t );
+ m_timeout_event_p->add_dynamic( this );
+ el.add_dynamic( this );
+ m_event_list_p = &el;
+ m_trigger_type = OR_LIST_TIMEOUT;
+}
+
+inline
+void
+sc_method_process::next_trigger( const sc_time& t, const sc_event_and_list& el )
+{
+ clear_trigger();
+ m_timeout_event_p->notify_internal( t );
+ m_timeout_event_p->add_dynamic( this );
+ el.add_dynamic( this );
+ m_event_list_p = &el;
+ m_event_count = el.size();
+ m_trigger_type = AND_LIST_TIMEOUT;
+}
+
+inline
+void sc_method_process::set_next_exist(sc_method_handle next_p)
+{
+ m_exist_p = next_p;
+}
+
+inline
+sc_method_handle sc_method_process::next_exist()
+{
+ return (sc_method_handle)m_exist_p;
+}
+
+
+inline
+void sc_method_process::set_next_runnable(sc_method_handle next_p)
+{
+ m_runnable_p = next_p;
+}
+
+inline
+sc_method_handle sc_method_process::next_runnable()
+{
+ return (sc_method_handle)m_runnable_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_method_process::run_process"
+// |
+// | This method executes this object instance, including fielding exceptions.
+// |
+// | Result is false if an unfielded exception occurred, true if not.
+// +----------------------------------------------------------------------------
+inline bool sc_method_process::run_process()
+{
+ // Execute this object instance's semantics and catch any exceptions that
+ // are generated:
+
+ bool restart = false;
+ do {
+ try {
+ DEBUG_MSG(DEBUG_NAME,this,"executing method semantics");
+ semantics();
+ restart = false;
+ }
+ catch( sc_unwind_exception& ex ) {
+ DEBUG_MSG(DEBUG_NAME,this,"caught unwind exception");
+ ex.clear();
+ restart = ex.is_reset();
+ }
+ catch( ... ) {
+ sc_report* err_p = sc_handle_exception();
+ simcontext()->set_error( err_p );
+ return false;
+ }
+ } while( restart );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+//"sc_method_process::trigger_static"
+//
+// This inline method adds the current method to the queue of runnable
+// processes, if required. This is the case if the following criteria
+// are met:
+// (1) The process is in a runnable state.
+// (2) The process is not already on the run queue.
+// (3) The process is expecting a static trigger,
+// dynamic event waits take priority.
+//
+//
+// If the triggering process is the same process, the trigger is
+// ignored as well, unless SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
+// is defined.
+//------------------------------------------------------------------------------
+inline
+void
+sc_method_process::trigger_static()
+{
+ if ( (m_state & ps_bit_disabled) || is_runnable() ||
+ m_trigger_type != STATIC )
+ return;
+
+#if ! defined( SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS )
+ if( SC_UNLIKELY_( sc_get_current_process_b() == this ) )
+ {
+ report_immediate_self_notification();
+ return;
+ }
+#endif // SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
+
+ // If we get here then the method is has satisfied its wait, if its
+ // suspended mark its state as ready to run. If its not suspended then
+ // push it onto the runnable queue.
+
+ if ( m_state & ps_bit_suspended )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ }
+ else
+ {
+ simcontext()->push_runnable_method(this);
+ }
+}
+
+#undef DEBUG_MSG
+
+} // namespace sc_core
+
+// Revision 1.20 2011/08/24 22:05:50 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.19 2011/07/29 22:43:15 acg
+// Andy Goodrich: addition of check_for_throws() method.
+//
+// Revision 1.18 2011/07/24 11:18:09 acg
+// Philipp A. Hartmann: add code to restart a method process after a
+// self-reset.
+//
+// Revision 1.17 2011/05/09 04:07:48 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.16 2011/04/13 02:41:34 acg
+// Andy Goodrich: eliminate warning messages generated when the DEBUG_MSG
+// macro is used.
+//
+// Revision 1.15 2011/04/10 22:12:32 acg
+// Andy Goodrich: adding debugging macros.
+//
+// Revision 1.14 2011/04/08 22:31:21 acg
+// Andy Goodrich: added new inline method run_process() to hide the process
+// implementation for sc_simcontext.
+//
+// Revision 1.13 2011/04/05 20:50:56 acg
+// Andy Goodrich:
+// (1) changes to make sure that event(), posedge() and negedge() only
+// return true if the clock has not moved.
+// (2) fixes for method self-resumes.
+// (3) added SC_PRERELEASE_VERSION
+// (4) removed kernel events from the object hierarchy, added
+// sc_hierarchy_name_exists().
+//
+// Revision 1.12 2011/04/01 21:24:57 acg
+// Andy Goodrich: removed unused code.
+//
+// Revision 1.11 2011/02/19 08:30:53 acg
+// Andy Goodrich: Moved process queueing into trigger_static from
+// sc_event::notify.
+//
+// Revision 1.10 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.9 2011/02/17 19:51:34 acg
+// Andy Goodrich:
+// (1) Changed the signature of trigger_dynamic back to a bool.
+// (2) Removed ready_to_run().
+// (3) Simplified process control usage.
+//
+// Revision 1.8 2011/02/16 22:37:30 acg
+// Andy Goodrich: clean up to remove need for ps_disable_pending.
+//
+// Revision 1.7 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.6 2011/02/01 21:05:05 acg
+// Andy Goodrich: Changes in trigger_dynamic methods to handle new
+// process control rules about event sensitivity.
+//
+// Revision 1.5 2011/01/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.4 2009/07/28 01:10:53 acg
+// Andy Goodrich: updates for 2.3 release candidate.
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.2 2008/05/22 17:06:25 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.7 2006/05/08 17:57:13 acg
+// Andy Goodrich: Added David Long's forward declarations for friend functions
+// to keep the Microsoft C++ compiler happy.
+//
+// Revision 1.6 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.5 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+
+#endif // !defined(sc_method_process_h_INCLUDED)
diff --git a/ext/systemc/src/sysc/kernel/sc_module.cpp b/ext/systemc/src/sysc/kernel/sc_module.cpp
new file mode 100644
index 000000000..efca2a4dc
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_module.cpp
@@ -0,0 +1,846 @@
+/*****************************************************************************
+
+ 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_module.cpp -- Base class of all sequential and combinational processes.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include <cassert>
+#include <math.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_module_registry.h"
+#include "sysc/kernel/sc_name_gen.h"
+#include "sysc/kernel/sc_object_manager.h"
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_object_int.h"
+#include "sysc/kernel/sc_reset.h"
+#include "sysc/communication/sc_communication_ids.h"
+#include "sysc/communication/sc_interface.h"
+#include "sysc/communication/sc_port.h"
+#include "sysc/communication/sc_signal.h"
+#include "sysc/communication/sc_signal_ports.h"
+#include "sysc/utils/sc_utils_ids.h"
+#include "sysc/utils/sc_iostream.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_module_dynalloc_list
+//
+// Garbage collection for modules dynamically allocated with SC_NEW.
+// ----------------------------------------------------------------------------
+
+class sc_module_dynalloc_list
+{
+public:
+
+ sc_module_dynalloc_list() : m_list()
+ {}
+
+ ~sc_module_dynalloc_list();
+
+ void add( sc_module* p )
+ { m_list.push_back( p ); }
+
+private:
+
+ sc_plist<sc_module*> m_list;
+};
+
+
+//------------------------------------------------------------------------------
+//"~sc_module_dynalloc_list"
+//
+// Note we clear the m_parent field for the module being deleted. This because
+// we process the list front to back so the parent has already been deleted,
+// and we don't want ~sc_object() to try to access the parent which may
+// contain garbage.
+//------------------------------------------------------------------------------
+sc_module_dynalloc_list::~sc_module_dynalloc_list()
+{
+ sc_plist<sc_module*>::iterator it( m_list );
+ while( ! it.empty() ) {
+ (*it)->m_parent = 0;
+ delete *it;
+ it ++;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+
+sc_module*
+sc_module_dynalloc( sc_module* module_ )
+{
+ static sc_module_dynalloc_list dynalloc_list;
+ dynalloc_list.add( module_ );
+ return module_;
+}
+
+
+// ----------------------------------------------------------------------------
+// STRUCT : sc_bind_proxy
+//
+// Struct for temporarily storing a pointer to an interface or port.
+// Used for positional binding.
+// ----------------------------------------------------------------------------
+
+sc_bind_proxy::sc_bind_proxy()
+: iface( 0 ),
+ port( 0 )
+{}
+
+sc_bind_proxy::sc_bind_proxy( sc_interface& iface_ )
+: iface( &iface_ ),
+ port( 0 )
+{}
+
+sc_bind_proxy::sc_bind_proxy( sc_port_base& port_ )
+: iface( 0 ),
+ port( &port_ )
+{}
+
+
+const sc_bind_proxy SC_BIND_PROXY_NIL;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_module
+//
+// Base class for all structural entities.
+// ----------------------------------------------------------------------------
+
+void
+sc_module::sc_module_init()
+{
+ simcontext()->get_module_registry()->insert( *this );
+ simcontext()->hierarchy_push( this );
+ m_end_module_called = false;
+ m_module_name_p = 0;
+ m_port_vec = new std::vector<sc_port_base*>;
+ m_port_index = 0;
+ m_name_gen = new sc_name_gen;
+}
+
+/*
+ * This form of the constructor assumes that the user has
+ * used an sc_module_name parameter for his/her constructor.
+ * That parameter object has been pushed onto the stack,
+ * and can be looked up by calling the
+ * top_of_module_name_stack() function of the object manager.
+ * This technique has two advantages:
+ *
+ * 1) The user no longer has to write sc_module(name) in the
+ * constructor initializer.
+ * 2) The user no longer has to call end_module() at the end
+ * of the constructor -- a common negligence.
+ *
+ * But it is important to note that sc_module_name may be used
+ * in the user's constructor's parameter. If it is used anywhere
+ * else, unexpected things will happen. The error-checking
+ * mechanism builtin here cannot hope to catch all misuses.
+ *
+ */
+
+sc_module::sc_module()
+: sc_object(::sc_core::sc_get_curr_simcontext()
+ ->get_object_manager()
+ ->top_of_module_name_stack()
+ ->operator const char*()),
+ sensitive(this),
+ sensitive_pos(this),
+ sensitive_neg(this),
+ m_end_module_called(false),
+ m_port_vec(),
+ m_port_index(0),
+ m_name_gen(0),
+ m_module_name_p(0)
+{
+ /* When this form is used, we better have a fresh sc_module_name
+ on the top of the stack */
+ sc_module_name* mod_name =
+ simcontext()->get_object_manager()->top_of_module_name_stack();
+ if (0 == mod_name || 0 != mod_name->m_module_p)
+ SC_REPORT_ERROR( SC_ID_SC_MODULE_NAME_REQUIRED_, 0 );
+ sc_module_init();
+ mod_name->set_module( this );
+ m_module_name_p = mod_name; // must come after sc_module_init call.
+}
+
+sc_module::sc_module( const sc_module_name& )
+: sc_object(::sc_core::sc_get_curr_simcontext()
+ ->get_object_manager()
+ ->top_of_module_name_stack()
+ ->operator const char*()),
+ sensitive(this),
+ sensitive_pos(this),
+ sensitive_neg(this),
+ m_end_module_called(false),
+ m_port_vec(),
+ m_port_index(0),
+ m_name_gen(0),
+ m_module_name_p(0)
+{
+ /* For those used to the old style of passing a name to sc_module,
+ this constructor will reduce the chance of making a mistake */
+
+ /* When this form is used, we better have a fresh sc_module_name
+ on the top of the stack */
+ sc_module_name* mod_name =
+ simcontext()->get_object_manager()->top_of_module_name_stack();
+ if (0 == mod_name || 0 != mod_name->m_module_p)
+ SC_REPORT_ERROR( SC_ID_SC_MODULE_NAME_REQUIRED_, 0 );
+ sc_module_init();
+ mod_name->set_module( this );
+ m_module_name_p = mod_name; // must come after sc_module_init call.
+}
+
+/* --------------------------------------------------------------------
+ *
+ * Deprecated constructors:
+ * sc_module( const char* )
+ * sc_module( const std::string& )
+ */
+sc_module::sc_module( const char* nm )
+: sc_object(nm),
+ sensitive(this),
+ sensitive_pos(this),
+ sensitive_neg(this),
+ m_end_module_called(false),
+ m_port_vec(),
+ m_port_index(0),
+ m_name_gen(0),
+ m_module_name_p(0)
+{
+ SC_REPORT_WARNING( SC_ID_BAD_SC_MODULE_CONSTRUCTOR_, nm );
+ sc_module_init();
+}
+
+sc_module::sc_module( const std::string& s )
+: sc_object( s.c_str() ),
+ sensitive(this),
+ sensitive_pos(this),
+ sensitive_neg(this),
+ m_end_module_called(false),
+ m_port_vec(),
+ m_port_index(0),
+ m_name_gen(0),
+ m_module_name_p(0)
+{
+ SC_REPORT_WARNING( SC_ID_BAD_SC_MODULE_CONSTRUCTOR_, s.c_str() );
+ sc_module_init();
+}
+
+/* -------------------------------------------------------------------- */
+
+sc_module::~sc_module()
+{
+ delete m_port_vec;
+ delete m_name_gen;
+ orphan_child_objects();
+ if ( m_module_name_p )
+ {
+ m_module_name_p->clear_module( this ); // must be before end_module()
+ end_module();
+ }
+ simcontext()->get_module_registry()->remove( *this );
+}
+
+
+const ::std::vector<sc_object*>&
+sc_module::get_child_objects() const
+{
+ return m_child_objects;
+}
+
+// set SC_THREAD asynchronous reset sensitivity
+
+void
+sc_module::async_reset_signal_is( const sc_in<bool>& port, bool level )
+{
+ sc_reset::reset_signal_is(true, port, level);
+}
+
+void
+sc_module::async_reset_signal_is( const sc_inout<bool>& port, bool level )
+{
+ sc_reset::reset_signal_is(true, port, level);
+}
+
+void
+sc_module::async_reset_signal_is( const sc_out<bool>& port, bool level )
+{
+ sc_reset::reset_signal_is(true, port, level);
+}
+
+void
+sc_module::async_reset_signal_is(const sc_signal_in_if<bool>& iface, bool level)
+{
+ sc_reset::reset_signal_is(true, iface, level);
+}
+
+void
+sc_module::end_module()
+{
+ if( ! m_end_module_called ) {
+ /* TBD: Can check here to alert the user that end_module
+ was not called for a previous module. */
+ (void)sc_get_curr_simcontext()->hierarchy_pop();
+ sc_get_curr_simcontext()->reset_curr_proc();
+ sensitive.reset();
+ sensitive_pos.reset();
+ sensitive_neg.reset();
+ m_end_module_called = true;
+ m_module_name_p = 0; // make sure we are not called in ~sc_module().
+ }
+}
+
+
+// to prevent initialization for SC_METHODs and SC_THREADs
+
+void
+sc_module::dont_initialize()
+{
+ sc_process_handle last_proc = sc_get_last_created_process_handle();
+ last_proc.dont_initialize( true );
+}
+
+// set SC_THREAD synchronous reset sensitivity
+
+void
+sc_module::reset_signal_is( const sc_in<bool>& port, bool level )
+{
+ sc_reset::reset_signal_is(false, port, level);
+}
+
+void
+sc_module::reset_signal_is( const sc_inout<bool>& port, bool level )
+{
+ sc_reset::reset_signal_is(false, port, level);
+}
+
+void
+sc_module::reset_signal_is( const sc_out<bool>& port, bool level )
+{
+ sc_reset::reset_signal_is(false, port, level);
+}
+
+void
+sc_module::reset_signal_is( const sc_signal_in_if<bool>& iface, bool level )
+{
+ sc_reset::reset_signal_is(false, iface, level);
+}
+
+// to generate unique names for objects in an MT-Safe way
+
+const char*
+sc_module::gen_unique_name( const char* basename_, bool preserve_first )
+{
+ return m_name_gen->gen_unique_name( basename_, preserve_first );
+}
+
+
+// called by construction_done
+
+void
+sc_module::before_end_of_elaboration()
+{}
+
+// We push the sc_module instance onto the stack of open objects so
+// that any objects that are created in before_end_of_elaboration have
+// the proper parent. After the call we pop the hierarchy.
+void
+sc_module::construction_done()
+{
+ hierarchy_scope scope(this);
+ before_end_of_elaboration();
+}
+
+// called by elaboration_done (does nothing by default)
+
+void
+sc_module::end_of_elaboration()
+{}
+
+
+// We push the sc_module instance onto the stack of open objects so
+// that any objects that are created in end_of_elaboration have
+// the proper parent. After the call we pop the hierarchy.
+void
+sc_module::elaboration_done( bool& error_ )
+{
+ if( ! m_end_module_called ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "module '%s'", name() );
+ SC_REPORT_WARNING( SC_ID_END_MODULE_NOT_CALLED_, msg );
+ if( error_ ) {
+ SC_REPORT_WARNING( SC_ID_HIER_NAME_INCORRECT_, 0 );
+ }
+ error_ = true;
+ }
+ hierarchy_scope scope(this);
+ end_of_elaboration();
+}
+
+// called by start_simulation (does nothing by default)
+
+void
+sc_module::start_of_simulation()
+{}
+
+void
+sc_module::start_simulation()
+{
+ hierarchy_scope scope(this);
+ start_of_simulation();
+}
+
+// called by simulation_done (does nothing by default)
+
+void
+sc_module::end_of_simulation()
+{}
+
+void
+sc_module::simulation_done()
+{
+ hierarchy_scope scope(this);
+ end_of_simulation();
+}
+
+void
+sc_module::set_stack_size( std::size_t size )
+{
+ sc_process_handle proc_h(
+ sc_is_running() ?
+ sc_get_current_process_handle() :
+ sc_get_last_created_process_handle()
+ );
+ sc_thread_handle thread_h; // Current process as thread.
+
+
+ thread_h = (sc_thread_handle)proc_h;
+ if ( thread_h )
+ {
+ thread_h->set_stack_size( size );
+ }
+ else
+ {
+ SC_REPORT_WARNING( SC_ID_SET_STACK_SIZE_, 0 );
+ }
+}
+
+
+int
+sc_module::append_port( sc_port_base* port_ )
+{
+ int index = m_port_vec->size();
+ m_port_vec->push_back( port_ );
+ return index;
+}
+
+
+// positional binding methods
+
+static void sc_warn_arrow_arrow_bind()
+{
+ static bool warn_arrow_arrow_bind=true;
+ if ( warn_arrow_arrow_bind )
+ {
+ warn_arrow_arrow_bind = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "positional binding using << or , is deprecated, use () instead.");
+ }
+}
+
+sc_module&
+sc_module::operator << ( sc_interface& interface_ )
+{
+ sc_warn_arrow_arrow_bind();
+ positional_bind(interface_);
+ return *this;
+}
+
+sc_module&
+sc_module::operator << ( sc_port_base& port_ )
+{
+ sc_warn_arrow_arrow_bind();
+ positional_bind(port_);
+ return *this;
+}
+
+
+void
+sc_module::positional_bind( sc_interface& interface_ )
+{
+ if( m_port_index == (int)m_port_vec->size() ) {
+ char msg[BUFSIZ];
+ if( m_port_index == 0 ) {
+ std::sprintf( msg, "module `%s' has no ports", name() );
+ } else {
+ std::sprintf( msg, "all ports of module `%s' are bound", name() );
+ }
+ SC_REPORT_ERROR( SC_ID_BIND_IF_TO_PORT_, msg );
+ }
+ int status = (*m_port_vec)[m_port_index]->pbind( interface_ );
+ if( status != 0 ) {
+ char msg[BUFSIZ];
+ switch( status ) {
+ case 1:
+ std::sprintf( msg, "port %d of module `%s' is already bound",
+ m_port_index, name() );
+ break;
+ case 2:
+ std::sprintf( msg, "type mismatch on port %d of module `%s'",
+ m_port_index, name() );
+ break;
+ default:
+ std::sprintf( msg, "unknown error" );
+ break;
+ }
+ SC_REPORT_ERROR( SC_ID_BIND_IF_TO_PORT_, msg );
+ }
+ ++ m_port_index;
+}
+
+void
+sc_module::positional_bind( sc_port_base& port_ )
+{
+ if( m_port_index == (int)m_port_vec->size() ) {
+ char msg[BUFSIZ];
+ if( m_port_index == 0 ) {
+ std::sprintf( msg, "module `%s' has no ports", name() );
+ } else {
+ std::sprintf( msg, "all ports of module `%s' are bound", name() );
+ }
+ SC_REPORT_ERROR( SC_ID_BIND_PORT_TO_PORT_, msg );
+ }
+ int status = (*m_port_vec)[m_port_index]->pbind( port_ );
+ if( status != 0 ) {
+ char msg[BUFSIZ];
+ switch( status ) {
+ case 1:
+ std::sprintf( msg, "port %d of module `%s' is already bound",
+ m_port_index, name() );
+ break;
+ case 2:
+ std::sprintf( msg, "type mismatch on port %d of module `%s'",
+ m_port_index, name() );
+ break;
+ default:
+ std::sprintf( msg, "unknown error" );
+ break;
+ }
+ SC_REPORT_ERROR( SC_ID_BIND_PORT_TO_PORT_, msg );
+ }
+ ++ m_port_index;
+}
+
+
+#define TRY_BIND( p ) \
+ if( (p).iface != 0 ) { \
+ positional_bind( *(p).iface ); \
+ } else if( (p).port != 0 ) { \
+ positional_bind( *(p).port ); \
+ } else { \
+ return; \
+ }
+
+
+void
+sc_module::operator () ( const sc_bind_proxy& p001,
+ const sc_bind_proxy& p002,
+ const sc_bind_proxy& p003,
+ const sc_bind_proxy& p004,
+ const sc_bind_proxy& p005,
+ const sc_bind_proxy& p006,
+ const sc_bind_proxy& p007,
+ const sc_bind_proxy& p008,
+ const sc_bind_proxy& p009,
+ const sc_bind_proxy& p010,
+ const sc_bind_proxy& p011,
+ const sc_bind_proxy& p012,
+ const sc_bind_proxy& p013,
+ const sc_bind_proxy& p014,
+ const sc_bind_proxy& p015,
+ const sc_bind_proxy& p016,
+ const sc_bind_proxy& p017,
+ const sc_bind_proxy& p018,
+ const sc_bind_proxy& p019,
+ const sc_bind_proxy& p020,
+ const sc_bind_proxy& p021,
+ const sc_bind_proxy& p022,
+ const sc_bind_proxy& p023,
+ const sc_bind_proxy& p024,
+ const sc_bind_proxy& p025,
+ const sc_bind_proxy& p026,
+ const sc_bind_proxy& p027,
+ const sc_bind_proxy& p028,
+ const sc_bind_proxy& p029,
+ const sc_bind_proxy& p030,
+ const sc_bind_proxy& p031,
+ const sc_bind_proxy& p032,
+ const sc_bind_proxy& p033,
+ const sc_bind_proxy& p034,
+ const sc_bind_proxy& p035,
+ const sc_bind_proxy& p036,
+ const sc_bind_proxy& p037,
+ const sc_bind_proxy& p038,
+ const sc_bind_proxy& p039,
+ const sc_bind_proxy& p040,
+ const sc_bind_proxy& p041,
+ const sc_bind_proxy& p042,
+ const sc_bind_proxy& p043,
+ const sc_bind_proxy& p044,
+ const sc_bind_proxy& p045,
+ const sc_bind_proxy& p046,
+ const sc_bind_proxy& p047,
+ const sc_bind_proxy& p048,
+ const sc_bind_proxy& p049,
+ const sc_bind_proxy& p050,
+ const sc_bind_proxy& p051,
+ const sc_bind_proxy& p052,
+ const sc_bind_proxy& p053,
+ const sc_bind_proxy& p054,
+ const sc_bind_proxy& p055,
+ const sc_bind_proxy& p056,
+ const sc_bind_proxy& p057,
+ const sc_bind_proxy& p058,
+ const sc_bind_proxy& p059,
+ const sc_bind_proxy& p060,
+ const sc_bind_proxy& p061,
+ const sc_bind_proxy& p062,
+ const sc_bind_proxy& p063,
+ const sc_bind_proxy& p064 )
+{
+ static bool warn_only_once=true;
+ if ( m_port_index > 0 && warn_only_once )
+ {
+ warn_only_once = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "multiple () binding deprecated, use explicit port binding instead." );
+ }
+
+ TRY_BIND( p001 );
+ TRY_BIND( p002 );
+ TRY_BIND( p003 );
+ TRY_BIND( p004 );
+ TRY_BIND( p005 );
+ TRY_BIND( p006 );
+ TRY_BIND( p007 );
+ TRY_BIND( p008 );
+ TRY_BIND( p009 );
+ TRY_BIND( p010 );
+ TRY_BIND( p011 );
+ TRY_BIND( p012 );
+ TRY_BIND( p013 );
+ TRY_BIND( p014 );
+ TRY_BIND( p015 );
+ TRY_BIND( p016 );
+ TRY_BIND( p017 );
+ TRY_BIND( p018 );
+ TRY_BIND( p019 );
+ TRY_BIND( p020 );
+ TRY_BIND( p021 );
+ TRY_BIND( p022 );
+ TRY_BIND( p023 );
+ TRY_BIND( p024 );
+ TRY_BIND( p025 );
+ TRY_BIND( p026 );
+ TRY_BIND( p027 );
+ TRY_BIND( p028 );
+ TRY_BIND( p029 );
+ TRY_BIND( p030 );
+ TRY_BIND( p031 );
+ TRY_BIND( p032 );
+ TRY_BIND( p033 );
+ TRY_BIND( p034 );
+ TRY_BIND( p035 );
+ TRY_BIND( p036 );
+ TRY_BIND( p037 );
+ TRY_BIND( p038 );
+ TRY_BIND( p039 );
+ TRY_BIND( p040 );
+ TRY_BIND( p041 );
+ TRY_BIND( p042 );
+ TRY_BIND( p043 );
+ TRY_BIND( p044 );
+ TRY_BIND( p045 );
+ TRY_BIND( p046 );
+ TRY_BIND( p047 );
+ TRY_BIND( p048 );
+ TRY_BIND( p049 );
+ TRY_BIND( p050 );
+ TRY_BIND( p051 );
+ TRY_BIND( p052 );
+ TRY_BIND( p053 );
+ TRY_BIND( p054 );
+ TRY_BIND( p055 );
+ TRY_BIND( p056 );
+ TRY_BIND( p057 );
+ TRY_BIND( p058 );
+ TRY_BIND( p059 );
+ TRY_BIND( p060 );
+ TRY_BIND( p061 );
+ TRY_BIND( p062 );
+ TRY_BIND( p063 );
+ TRY_BIND( p064 );
+}
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
+ Description of Modification: - Implementation of operator() and operator,
+ positional connection method.
+ - Implementation of error checking in
+ operator<<'s.
+ - Implementation of the function test_module_prm.
+ - Implementation of set_stack_size().
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems 20 May 2003
+ Description of Modification: Inherit from sc_process_host
+
+ Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+ Description of Modification: dont_initialize() uses
+ sc_get_last_created_process_handle() instead of
+ sc_get_current_process_b()
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems 25 Mar 2003
+ Description of Modification: Fixed bug in SC_NEW, see comments on
+ ~sc_module_dynalloc_list below.
+
+
+ *****************************************************************************/
+
+
+// $Log: sc_module.cpp,v $
+// Revision 1.14 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.13 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.12 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.11 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.10 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.9 2011/02/16 22:37:30 acg
+// Andy Goodrich: clean up to remove need for ps_disable_pending.
+//
+// Revision 1.8 2011/02/14 17:51:40 acg
+// Andy Goodrich: proper pushing an poppping of the module hierarchy for
+// start_of_simulation() and end_of_simulation.
+//
+// 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 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.4 2008/11/17 15:57:15 acg
+// Andy Goodrich: added deprecation message for sc_module(const char*)
+//
+// Revision 1.3 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2007/05/17 20:16:33 acg
+// Andy Goodrich: changes for beta release to LWG.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.9 2006/12/02 20:58:18 acg
+// Andy Goodrich: updates from 2.2 for IEEE 1666 support.
+//
+// Revision 1.8 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.7 2006/03/14 23:56:58 acg
+// Andy Goodrich: This fixes a bug when an exception is thrown in
+// sc_module::sc_module() for a dynamically allocated sc_module
+// object. We are calling sc_module::end_module() on a module that has
+// already been deleted. The scenario runs like this:
+//
+// a) the sc_module constructor is entered
+// b) the exception is thrown
+// c) the exception processor deletes the storage for the sc_module
+// d) the stack is unrolled causing the sc_module_name instance to be deleted
+// e) ~sc_module_name() calls end_module() with its pointer to the sc_module
+// f) because the sc_module has been deleted its storage is corrupted,
+// either by linking it to a free space chain, or by reuse of some sort
+// g) the m_simc field is garbage
+// h) the m_object_manager field is also garbage
+// i) an exception occurs
+//
+// This does not happen for automatic sc_module instances since the
+// storage for the module is not reclaimed its just part of the stack.
+//
+// I am fixing this by having the destructor for sc_module clear the
+// module pointer in its sc_module_name instance. That cuts things at
+// step (e) above, since the pointer will be null if the module has
+// already been deleted. To make sure the module stack is okay, I call
+// end-module() in ~sc_module in the case where there is an
+// sc_module_name pointer lying around.
+//
+// Revision 1.6 2006/01/26 21:04:54 acg
+// Andy Goodrich: deprecation message changes and additional messages.
+//
+// Revision 1.5 2006/01/25 00:31:19 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:29 acg
+// Added $Log to record CVS changes into the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_module.h b/ext/systemc/src/sysc/kernel/sc_module.h
new file mode 100644
index 000000000..8a68cb049
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_module.h
@@ -0,0 +1,583 @@
+/*****************************************************************************
+
+ 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_module.h -- Base class of all hierarchical modules and channels.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_MODULE_H
+#define SC_MODULE_H
+
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_module_name.h"
+#include "sysc/kernel/sc_sensitive.h"
+#include "sysc/kernel/sc_time.h"
+#include "sysc/kernel/sc_wait.h"
+#include "sysc/kernel/sc_wait_cthread.h"
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/utils/sc_list.h"
+
+namespace sc_core {
+
+class sc_name_gen;
+template<class T> class sc_in;
+template<class T> class sc_inout;
+template<class T> class sc_out;
+
+// ----------------------------------------------------------------------------
+// STRUCT : sc_bind_proxy
+//
+// Struct for temporarily storing a pointer to an interface or port.
+// Used for positional binding.
+// ----------------------------------------------------------------------------
+
+struct sc_bind_proxy
+{
+ sc_interface* iface;
+ sc_port_base* port;
+
+ sc_bind_proxy();
+ sc_bind_proxy( sc_interface& );
+ sc_bind_proxy( sc_port_base& );
+};
+
+
+extern const sc_bind_proxy SC_BIND_PROXY_NIL;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_module
+//
+// Base class for all structural entities.
+// ----------------------------------------------------------------------------
+
+class sc_module
+: public sc_object, public sc_process_host
+{
+ friend class sc_module_name;
+ friend class sc_module_registry;
+ friend class sc_object;
+ friend class sc_port_registry;
+ friend class sc_process_b;
+ friend class sc_simcontext;
+
+public:
+
+ sc_simcontext* sc_get_curr_simcontext()
+ { return simcontext(); }
+
+ // to generate unique names for objects in an MT-Safe way
+ const char* gen_unique_name( const char* basename_, bool preserve_first );
+
+ virtual const char* kind() const
+ { return "sc_module"; }
+
+protected:
+
+ // called by construction_done
+ virtual void before_end_of_elaboration();
+
+ void construction_done();
+
+ // called by elaboration_done (does nothing by default)
+ virtual void end_of_elaboration();
+
+ void elaboration_done( bool& );
+
+ // called by start_simulation (does nothing by default)
+ virtual void start_of_simulation();
+
+ void start_simulation();
+
+ // called by simulation_done (does nothing by default)
+ virtual void end_of_simulation();
+
+ void simulation_done();
+
+ void sc_module_init();
+
+ // constructor
+ sc_module();
+ sc_module( const sc_module_name& nm ); /* for those used to old style */
+
+ /* DEPRECATED */ sc_module( const char* nm );
+ /* DEPRECATED */ sc_module( const std::string& nm );
+
+public:
+
+ // destructor
+ virtual ~sc_module();
+
+ // positional binding methods
+
+ sc_module& operator << ( sc_interface& );
+ sc_module& operator << ( sc_port_base& );
+
+ sc_module& operator , ( sc_interface& interface_ )
+ { return operator << ( interface_ ); }
+
+ sc_module& operator , ( sc_port_base& port_ )
+ { return operator << ( port_ ); }
+
+ // operator() is declared at the end of the class.
+
+ const ::std::vector<sc_object*>& get_child_objects() const;
+
+protected:
+
+ // this must be called by user-defined modules
+ void end_module();
+
+
+ // to prevent initialization for SC_METHODs and SC_THREADs
+ void dont_initialize();
+
+ // positional binding code - used by operator ()
+
+ void positional_bind( sc_interface& );
+ void positional_bind( sc_port_base& );
+
+ // set reset sensitivity for SC_xTHREADs
+ void async_reset_signal_is( const sc_in<bool>& port, bool level );
+ void async_reset_signal_is( const sc_inout<bool>& port, bool level );
+ void async_reset_signal_is( const sc_out<bool>& port, bool level );
+ void async_reset_signal_is( const sc_signal_in_if<bool>& iface, bool level);
+ void reset_signal_is( const sc_in<bool>& port, bool level );
+ void reset_signal_is( const sc_inout<bool>& port, bool level );
+ void reset_signal_is( const sc_out<bool>& port, bool level );
+ void reset_signal_is( const sc_signal_in_if<bool>& iface, bool level );
+
+ // static sensitivity for SC_THREADs and SC_CTHREADs
+
+ void wait()
+ { ::sc_core::wait( simcontext() ); }
+
+ // dynamic sensitivity for SC_THREADs and SC_CTHREADs
+
+ void wait( const sc_event& e )
+ { ::sc_core::wait( e, simcontext() ); }
+
+ void wait( const sc_event_or_list& el )
+ { ::sc_core::wait( el, simcontext() ); }
+
+ void wait( const sc_event_and_list& el )
+ { ::sc_core::wait( el, simcontext() ); }
+
+ void wait( const sc_time& t )
+ { ::sc_core::wait( t, simcontext() ); }
+
+ void wait( double v, sc_time_unit tu )
+ { ::sc_core::wait( sc_time( v, tu, simcontext() ), simcontext() ); }
+
+ void wait( const sc_time& t, const sc_event& e )
+ { ::sc_core::wait( t, e, simcontext() ); }
+
+ void wait( double v, sc_time_unit tu, const sc_event& e )
+ { ::sc_core::wait(
+ sc_time( v, tu, simcontext() ), e, simcontext() ); }
+
+ void wait( const sc_time& t, const sc_event_or_list& el )
+ { ::sc_core::wait( t, el, simcontext() ); }
+
+ void wait( double v, sc_time_unit tu, const sc_event_or_list& el )
+ { ::sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); }
+
+ void wait( const sc_time& t, const sc_event_and_list& el )
+ { ::sc_core::wait( t, el, simcontext() ); }
+
+ void wait( double v, sc_time_unit tu, const sc_event_and_list& el )
+ { ::sc_core::wait( sc_time( v, tu, simcontext() ), el, simcontext() ); }
+
+
+ // static sensitivity for SC_METHODs
+
+ void next_trigger()
+ { ::sc_core::next_trigger( simcontext() ); }
+
+
+ // dynamic sensitivty for SC_METHODs
+
+ void next_trigger( const sc_event& e )
+ { ::sc_core::next_trigger( e, simcontext() ); }
+
+ void next_trigger( const sc_event_or_list& el )
+ { ::sc_core::next_trigger( el, simcontext() ); }
+
+ void next_trigger( const sc_event_and_list& el )
+ { ::sc_core::next_trigger( el, simcontext() ); }
+
+ void next_trigger( const sc_time& t )
+ { ::sc_core::next_trigger( t, simcontext() ); }
+
+ void next_trigger( double v, sc_time_unit tu )
+ { ::sc_core::next_trigger(
+ sc_time( v, tu, simcontext() ), simcontext() ); }
+
+ void next_trigger( const sc_time& t, const sc_event& e )
+ { ::sc_core::next_trigger( t, e, simcontext() ); }
+
+ void next_trigger( double v, sc_time_unit tu, const sc_event& e )
+ { ::sc_core::next_trigger(
+ sc_time( v, tu, simcontext() ), e, simcontext() ); }
+
+ void next_trigger( const sc_time& t, const sc_event_or_list& el )
+ { ::sc_core::next_trigger( t, el, simcontext() ); }
+
+ void next_trigger( double v, sc_time_unit tu, const sc_event_or_list& el )
+ { ::sc_core::next_trigger(
+ sc_time( v, tu, simcontext() ), el, simcontext() ); }
+
+ void next_trigger( const sc_time& t, const sc_event_and_list& el )
+ { ::sc_core::next_trigger( t, el, simcontext() ); }
+
+ void next_trigger( double v, sc_time_unit tu, const sc_event_and_list& el )
+ { ::sc_core::next_trigger(
+ sc_time( v, tu, simcontext() ), el, simcontext() ); }
+
+
+ // for SC_METHODs and SC_THREADs and SC_CTHREADs
+
+ bool timed_out()
+ { return ::sc_core::timed_out(); }
+
+
+ // for SC_CTHREADs
+
+ void halt()
+ { ::sc_core::halt( simcontext() ); }
+
+ void wait( int n )
+ { ::sc_core::wait( n, simcontext() ); }
+
+ void at_posedge( const sc_signal_in_if<bool>& s )
+ { ::sc_core::at_posedge( s, simcontext() ); }
+
+ void at_posedge( const sc_signal_in_if<sc_dt::sc_logic>& s )
+ { ::sc_core::at_posedge( s, simcontext() ); }
+
+ void at_negedge( const sc_signal_in_if<bool>& s )
+ { ::sc_core::at_negedge( s, simcontext() ); }
+
+ void at_negedge( const sc_signal_in_if<sc_dt::sc_logic>& s )
+ { ::sc_core::at_negedge( s, simcontext() ); }
+
+ // Catch uses of watching:
+ void watching( bool /* expr */ )
+ { SC_REPORT_ERROR(SC_ID_WATCHING_NOT_ALLOWED_,""); }
+
+ // These are protected so that user derived classes can refer to them.
+ sc_sensitive sensitive;
+ sc_sensitive_pos sensitive_pos;
+ sc_sensitive_neg sensitive_neg;
+
+ // Function to set the stack size of the current (c)thread process.
+ void set_stack_size( std::size_t );
+
+ int append_port( sc_port_base* );
+
+private:
+ sc_module( const sc_module& );
+ const sc_module& operator = ( const sc_module& );
+
+private:
+
+ bool m_end_module_called;
+ std::vector<sc_port_base*>* m_port_vec;
+ int m_port_index;
+ sc_name_gen* m_name_gen;
+ sc_module_name* m_module_name_p;
+
+public:
+
+ void defunct() { }
+
+ // positional binding methods (cont'd)
+
+ void operator () ( const sc_bind_proxy& p001,
+ const sc_bind_proxy& p002 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p003 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p004 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p005 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p006 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p007 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p008 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p009 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p010 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p011 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p012 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p013 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p014 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p015 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p016 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p017 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p018 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p019 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p020 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p021 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p022 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p023 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p024 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p025 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p026 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p027 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p028 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p029 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p030 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p031 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p032 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p033 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p034 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p035 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p036 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p037 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p038 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p039 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p040 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p041 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p042 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p043 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p044 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p045 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p046 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p047 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p048 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p049 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p050 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p051 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p052 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p053 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p054 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p055 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p056 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p057 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p058 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p059 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p060 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p061 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p062 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p063 = SC_BIND_PROXY_NIL,
+ const sc_bind_proxy& p064 = SC_BIND_PROXY_NIL );
+
+};
+
+extern sc_module* sc_module_dynalloc(sc_module*);
+#define SC_NEW(x) ::sc_core::sc_module_dynalloc(new x);
+
+
+// -----------------------------------------------------------------------------
+// SOME MACROS TO SIMPLIFY SYNTAX:
+// -----------------------------------------------------------------------------
+
+#define SC_MODULE(user_module_name) \
+ struct user_module_name : ::sc_core::sc_module
+
+#define SC_CTOR(user_module_name) \
+ typedef user_module_name SC_CURRENT_USER_MODULE; \
+ user_module_name( ::sc_core::sc_module_name )
+
+// the SC_HAS_PROCESS macro call must be followed by a ;
+#define SC_HAS_PROCESS(user_module_name) \
+ typedef user_module_name SC_CURRENT_USER_MODULE
+
+// The this-> construct on sensitive operators in the macros below is
+// required for gcc 4.x when a templated class has a templated parent that is
+// derived from sc_module:
+//
+// template<typename X>
+// class B : public sc_module;
+// template<typename X>
+// class A : public B<X>
+
+#define declare_method_process(handle, name, host_tag, func) \
+ { \
+ ::sc_core::sc_process_handle handle = \
+ sc_core::sc_get_curr_simcontext()->create_method_process( \
+ name, false, SC_MAKE_FUNC_PTR( host_tag, func ), \
+ this, 0 ); \
+ this->sensitive << handle; \
+ this->sensitive_pos << handle; \
+ this->sensitive_neg << handle; \
+ }
+
+#define declare_thread_process(handle, name, host_tag, func) \
+ { \
+ ::sc_core::sc_process_handle handle = \
+ sc_core::sc_get_curr_simcontext()->create_thread_process( \
+ name, false, \
+ SC_MAKE_FUNC_PTR( host_tag, func ), this, 0 ); \
+ this->sensitive << handle; \
+ this->sensitive_pos << handle; \
+ this->sensitive_neg << handle; \
+ }
+
+#define declare_cthread_process(handle, name, host_tag, func, edge) \
+ { \
+ ::sc_core::sc_process_handle handle = \
+ sc_core::sc_get_curr_simcontext()->create_cthread_process( \
+ name, false, \
+ SC_MAKE_FUNC_PTR( host_tag, func ), this, 0 ); \
+ this->sensitive.operator() ( handle, edge );\
+ }
+
+#define SC_CTHREAD(func, edge) \
+ declare_cthread_process( func ## _handle, \
+ #func, \
+ SC_CURRENT_USER_MODULE, \
+ func, \
+ edge )
+
+#define SC_METHOD(func) \
+ declare_method_process( func ## _handle, \
+ #func, \
+ SC_CURRENT_USER_MODULE, \
+ func )
+
+#define SC_THREAD(func) \
+ declare_thread_process( func ## _handle, \
+ #func, \
+ SC_CURRENT_USER_MODULE, \
+ func )
+
+
+
+// ----------------------------------------------------------------------------
+// TYPEDEFS
+// ----------------------------------------------------------------------------
+
+typedef sc_module sc_channel;
+typedef sc_module sc_behavior;
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
+ Description of Modification: - Implementation of operator() and operator,
+ positional connection method.
+ - Implementation of error checking in
+ operator<<'s.
+ - Implementation of the function test_module_prm.
+ - Implementation of set_stack_size().
+
+ Name, Affiliation, Date: Gene Bushuyev, Synopsys, Inc.
+ Description of Modification: - Change implementation for VC6.
+
+ Name, Affiliation, Date: Andy Godorich, Forte
+ Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+ Description of Modification: inherit from sc_process_host as a part of
+ implementing dynamic processes
+
+ *****************************************************************************/
+
+// $Log: sc_module.h,v $
+// Revision 1.11 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.10 2011/08/15 16:43:24 acg
+// Torsten Maehne: changes to remove unused argument warnings.
+//
+// Revision 1.9 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// 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/18 20:10:44 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.5 2010/12/07 20:09:12 acg
+// Andy Goodrich: remove unused signal declaration
+//
+// Revision 1.4 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.3 2008/05/22 17:06:25 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2007/01/24 20:14:40 acg
+// Andy Goodrich: improved comments about the use of this-> in the macros
+// that access sensitive.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.10 2006/12/02 20:58:18 acg
+// Andy Goodrich: updates from 2.2 for IEEE 1666 support.
+//
+// Revision 1.7 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.6 2006/03/15 17:53:34 acg
+// Andy Goodrich, Forte Design
+// Reordered includes to pick up <cassert> for use by sc_process_name.h
+//
+// Revision 1.5 2006/03/14 23:56:58 acg
+// Andy Goodrich: This fixes a bug when an exception is thrown in
+// sc_module::sc_module() for a dynamically allocated sc_module
+// object. We are calling sc_module::end_module() on a module that has
+// already been deleted. The scenario runs like this:
+//
+// a) the sc_module constructor is entered
+// b) the exception is thrown
+// c) the exception processor deletes the storage for the sc_module
+// d) the stack is unrolled causing the sc_module_name instance to be deleted
+// e) ~sc_module_name() calls end_module() with its pointer to the sc_module
+// f) because the sc_module has been deleted its storage is corrupted,
+// either by linking it to a free space chain, or by reuse of some sort
+// g) the m_simc field is garbage
+// h) the m_object_manager field is also garbage
+// i) an exception occurs
+//
+// This does not happen for automatic sc_module instances since the
+// storage for the module is not reclaimed its just part of the stack.
+//
+// I am fixing this by having the destructor for sc_module clear the
+// module pointer in its sc_module_name instance. That cuts things at
+// step (e) above, since the pointer will be null if the module has
+// already been deleted. To make sure the module stack is okay, I call
+// end-module() in ~sc_module in the case where there is an
+// sc_module_name pointer lying around.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_module_name.cpp b/ext/systemc/src/sysc/kernel/sc_module_name.cpp
new file mode 100644
index 000000000..a5352690f
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_module_name.cpp
@@ -0,0 +1,123 @@
+/*****************************************************************************
+
+ 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_module_name.cpp -- An object used to help manage object names
+ and hierarchy
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include <cstdlib>
+
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_module_name.h"
+#include "sysc/kernel/sc_object_manager.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/utils/sc_iostream.h"
+
+namespace sc_core {
+
+sc_module_name::sc_module_name( const char* name_ )
+: m_name( name_ ),
+ m_module_p( 0 ),
+ m_next( 0 ),
+ m_simc( sc_get_curr_simcontext() ),
+ m_pushed( true )
+{
+ m_simc->get_object_manager()->push_module_name( this );
+}
+
+sc_module_name::sc_module_name( const sc_module_name& name_ )
+: m_name( name_.m_name ),
+ m_module_p( 0 ),
+ m_next( 0 ),
+ m_simc( name_.m_simc ),
+ m_pushed( false )
+{}
+
+sc_module_name::~sc_module_name()
+{
+ if( m_pushed ) {
+ sc_module_name* smn = m_simc->get_object_manager()->pop_module_name();
+ if( this != smn ) {
+ SC_REPORT_ERROR( SC_ID_SC_MODULE_NAME_USE_, 0 );
+ }
+ if ( m_module_p ) m_module_p->end_module();
+ }
+}
+
+sc_module_name::operator const char*() const
+{
+ return m_name;
+}
+
+} // namespace sc_core
+
+// $Log: sc_module_name.cpp,v $
+// Revision 1.5 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.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// 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.4 2006/03/14 23:56:58 acg
+// Andy Goodrich: This fixes a bug when an exception is thrown in
+// sc_module::sc_module() for a dynamically allocated sc_module
+// object. We are calling sc_module::end_module() on a module that has
+// already been deleted. The scenario runs like this:
+//
+// a) the sc_module constructor is entered
+// b) the exception is thrown
+// c) the exception processor deletes the storage for the sc_module
+// d) the stack is unrolled causing the sc_module_name instance to be deleted
+// e) ~sc_module_name() calls end_module() with its pointer to the sc_module
+// f) because the sc_module has been deleted its storage is corrupted,
+// either by linking it to a free space chain, or by reuse of some sort
+// g) the m_simc field is garbage
+// h) the m_object_manager field is also garbage
+// i) an exception occurs
+//
+// This does not happen for automatic sc_module instances since the
+// storage for the module is not reclaimed its just part of the stack.
+//
+// I am fixing this by having the destructor for sc_module clear the
+// module pointer in its sc_module_name instance. That cuts things at
+// step (e) above, since the pointer will be null if the module has
+// already been deleted. To make sure the module stack is okay, I call
+// end-module() in ~sc_module in the case where there is an
+// sc_module_name pointer lying around.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_module_name.h b/ext/systemc/src/sysc/kernel/sc_module_name.h
new file mode 100644
index 000000000..a2149cc6a
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_module_name.h
@@ -0,0 +1,140 @@
+/*****************************************************************************
+
+ 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_module_name.h -- An object used to help manage object names
+ and hierarchy.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+// $Log: sc_module_name.h,v $
+// Revision 1.5 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.
+//
+
+#ifndef SC_MODULE_NAME_H
+#define SC_MODULE_NAME_H
+
+
+namespace sc_core {
+
+class sc_module;
+class sc_simcontext;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_module_name
+//
+// Module name class.
+// ----------------------------------------------------------------------------
+
+class sc_module_name
+{
+ friend class sc_module;
+ friend class sc_object_manager;
+
+public:
+
+ sc_module_name( const char* );
+ sc_module_name( const sc_module_name& );
+
+ ~sc_module_name();
+
+ operator const char*() const;
+
+protected:
+ inline void clear_module( sc_module* module_p );
+ inline void set_module( sc_module* module_p );
+
+private:
+
+ const char* m_name;
+ sc_module* m_module_p;
+ sc_module_name* m_next;
+ sc_simcontext* m_simc;
+ bool m_pushed;
+
+private:
+
+ // disabled
+ sc_module_name();
+ sc_module_name& operator = ( const sc_module_name& );
+};
+
+inline void sc_module_name::clear_module( sc_module* module_p )
+{
+ assert( m_module_p == module_p );
+ m_module_p = 0;
+}
+
+inline void sc_module_name::set_module( sc_module* module_p )
+{
+ m_module_p = module_p;
+}
+
+} // namespace sc_core
+
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// 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.4 2006/03/14 23:56:58 acg
+// Andy Goodrich: This fixes a bug when an exception is thrown in
+// sc_module::sc_module() for a dynamically allocated sc_module
+// object. We are calling sc_module::end_module() on a module that has
+// already been deleted. The scenario runs like this:
+//
+// a) the sc_module constructor is entered
+// b) the exception is thrown
+// c) the exception processor deletes the storage for the sc_module
+// d) the stack is unrolled causing the sc_module_name instance to be deleted
+// e) ~sc_module_name() calls end_module() with its pointer to the sc_module
+// f) because the sc_module has been deleted its storage is corrupted,
+// either by linking it to a free space chain, or by reuse of some sort
+// g) the m_simc field is garbage
+// h) the m_object_manager field is also garbage
+// i) an exception occurs
+//
+// This does not happen for automatic sc_module instances since the
+// storage for the module is not reclaimed its just part of the stack.
+//
+// I am fixing this by having the destructor for sc_module clear the
+// module pointer in its sc_module_name instance. That cuts things at
+// step (e) above, since the pointer will be null if the module has
+// already been deleted. To make sure the module stack is okay, I call
+// end-module() in ~sc_module in the case where there is an
+// sc_module_name pointer lying around.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_module_registry.cpp b/ext/systemc/src/sysc/kernel/sc_module_registry.cpp
new file mode 100644
index 000000000..2d8b02c34
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_module_registry.cpp
@@ -0,0 +1,184 @@
+/*****************************************************************************
+
+ 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_module_registry.cpp -- Registry for all modules.
+ FOR INTERNAL USE ONLY.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_module_registry.h"
+#include "sysc/kernel/sc_simcontext.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_module_registry
+//
+// Registry for all modules.
+// FOR INTERNAL USE ONLY!
+// ----------------------------------------------------------------------------
+
+void
+sc_module_registry::insert( sc_module& module_ )
+{
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_INSERT_MODULE_, "simulation running" );
+ }
+
+ if( m_simc->elaboration_done() ) {
+ SC_REPORT_ERROR( SC_ID_INSERT_MODULE_, "elaboration done" );
+ }
+
+#ifdef DEBUG_SYSTEMC
+ // check if module_ is already inserted
+ for( int i = size() - 1; i >= 0; -- i ) {
+ if( &module_ == m_module_vec[i] ) {
+ SC_REPORT_ERROR( SC_ID_INSERT_MODULE_, "already inserted" );
+ }
+ }
+#endif
+
+ // insert
+ m_module_vec.push_back( &module_ );
+}
+
+void
+sc_module_registry::remove( sc_module& module_ )
+{
+ int i;
+ for( i = 0; i < size(); ++ i ) {
+ if( &module_ == m_module_vec[i] ) {
+ break;
+ }
+ }
+ if( i == size() ) {
+ SC_REPORT_ERROR( SC_ID_REMOVE_MODULE_, 0 );
+ }
+
+ // remove
+ m_module_vec[i] = m_module_vec[size() - 1];
+ m_module_vec.resize(m_module_vec.size()-1);
+}
+
+
+// constructor
+
+sc_module_registry::sc_module_registry( sc_simcontext& simc_ )
+ : m_construction_done(0), m_module_vec(), m_simc( &simc_ )
+{}
+
+
+// destructor
+
+sc_module_registry::~sc_module_registry()
+{}
+
+// called when construction is done
+
+bool
+sc_module_registry::construction_done()
+{
+ if( size() == m_construction_done )
+ // nothing has been updated
+ return true;
+
+ for( ; m_construction_done < size(); ++m_construction_done ) {
+ m_module_vec[m_construction_done]->construction_done();
+ }
+ return false;
+}
+
+// called when elaboration is done
+
+void
+sc_module_registry::elaboration_done()
+{
+ bool error = false;
+ for( int i = 0; i < size(); ++ i ) {
+ m_module_vec[i]->elaboration_done( error );
+ }
+}
+
+// called before simulation begins
+
+void
+sc_module_registry::start_simulation()
+{
+ for( int i = 0; i < size(); ++ i ) {
+ m_module_vec[i]->start_simulation();
+ }
+}
+
+// called after simulation ends
+
+void
+sc_module_registry::simulation_done()
+{
+ for( int i = 0; i < size(); ++ i ) {
+ m_module_vec[i]->simulation_done();
+ }
+}
+
+} // namespace sc_core
+
+// $Log: sc_module_registry.cpp,v $
+// Revision 1.8 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.7 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.6 2011/05/09 04:07:49 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/14 17:51:40 acg
+// Andy Goodrich: proper pushing an poppping of the module hierarchy for
+// start_of_simulation() and end_of_simulation.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// 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.4 2006/01/26 21:04:54 acg
+// Andy Goodrich: deprecation message changes and additional messages.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_module_registry.h b/ext/systemc/src/sysc/kernel/sc_module_registry.h
new file mode 100644
index 000000000..3e1bb5dff
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_module_registry.h
@@ -0,0 +1,124 @@
+/*****************************************************************************
+
+ 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_module_registry.h -- Registry for all modules.
+ FOR INTERNAL USE ONLY.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_MODULE_REGISTRY_H
+#define SC_MODULE_REGISTRY_H
+
+
+namespace sc_core {
+
+class sc_module;
+class sc_simcontext;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_module_registry
+//
+// Registry for all modules.
+// FOR INTERNAL USE ONLY!
+// ----------------------------------------------------------------------------
+
+class sc_module_registry
+{
+ friend class sc_simcontext;
+
+public:
+
+ void insert( sc_module& );
+ void remove( sc_module& );
+
+ int size() const
+ { return m_module_vec.size(); }
+
+private:
+
+ // constructor
+ explicit sc_module_registry( sc_simcontext& simc_ );
+
+ // destructor
+ ~sc_module_registry();
+
+ // called when construction is done
+ bool construction_done();
+
+ // called when elaboration is done
+ void elaboration_done();
+
+ // called before simulation begins
+ void start_simulation();
+
+ // called after simulation ends
+ void simulation_done();
+
+
+private:
+
+ int m_construction_done;
+ std::vector<sc_module*> m_module_vec;
+ sc_simcontext* m_simc;
+
+private:
+
+ // disabled
+ sc_module_registry();
+ sc_module_registry( const sc_module_registry& );
+ sc_module_registry& operator = ( const sc_module_registry& );
+};
+
+} // namespace sc_core
+
+#endif
+
+// $Log: sc_module_registry.h,v $
+// Revision 1.6 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.5 2011/05/09 04:07:49 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// 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.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_name_gen.cpp b/ext/systemc/src/sysc/kernel/sc_name_gen.cpp
new file mode 100644
index 000000000..16f6ad78f
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_name_gen.cpp
@@ -0,0 +1,109 @@
+/*****************************************************************************
+
+ 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_name_gen.cpp -- Unique name generator.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_name_gen.h"
+#include "sysc/utils/sc_iostream.h"
+
+#if defined(_MSC_VER) && _MSC_VER >= 1310
+// "C4351: new behavior: elements of array will be default initialized"
+#pragma warning(disable: 4351)
+#endif
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_name_gen
+//
+// Unique name generator class.
+// ----------------------------------------------------------------------------
+
+sc_name_gen::sc_name_gen() : m_unique_name_map(), m_unique_name()
+{}
+
+sc_name_gen::~sc_name_gen()
+{
+ sc_strhash<int*>::iterator it( m_unique_name_map );
+ for( ; ! it.empty(); it ++ ) {
+ delete it.contents();
+ }
+ m_unique_name_map.erase();
+}
+
+
+// to generate unique names for objects in an MT-Safe way
+
+const char*
+sc_name_gen::gen_unique_name( const char* basename_, bool preserve_first )
+{
+ if( basename_ == 0 ) {
+ SC_REPORT_ERROR( SC_ID_GEN_UNIQUE_NAME_, 0 );
+ }
+ int* c = m_unique_name_map[basename_];
+ if( c == 0 ) {
+ c = new int( 0 );
+ m_unique_name_map.insert( CCAST<char*>( basename_ ), c );
+ if (preserve_first) {
+ std::sprintf( m_unique_name, "%s", basename_ );
+ } else {
+ std::sprintf( m_unique_name, "%s_%d", basename_, *c );
+ }
+ } else {
+ std::sprintf( m_unique_name, "%s_%d", basename_, ++ (*c) );
+ }
+ return m_unique_name;
+}
+
+} // namespace sc_core
+
+// $Log: sc_name_gen.cpp,v $
+// Revision 1.6 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.5 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// 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.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_name_gen.h b/ext/systemc/src/sysc/kernel/sc_name_gen.h
new file mode 100644
index 000000000..0910e014a
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_name_gen.h
@@ -0,0 +1,93 @@
+/*****************************************************************************
+
+ 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_name_gen.h -- Unique name generator.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_NAME_GEN
+#define SC_NAME_GEN
+
+
+#include <cstdio>
+
+#include "sysc/utils/sc_hash.h"
+
+namespace sc_core{
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_name_gen
+//
+// Unique name generator class.
+// ----------------------------------------------------------------------------
+
+class sc_name_gen
+{
+public:
+
+ sc_name_gen();
+ ~sc_name_gen();
+
+ const char* gen_unique_name( const char* basename_,
+ bool preserve_first = false
+ );
+
+private:
+
+ sc_strhash<int*> m_unique_name_map;
+ char m_unique_name[BUFSIZ];
+
+private:
+
+ // disabled
+ sc_name_gen( const sc_name_gen& );
+ sc_name_gen& operator = ( const sc_name_gen& );
+};
+
+} // namespace sc_core
+
+// $Log: sc_name_gen.h,v $
+// Revision 1.5 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.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// 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.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif
+
+// Taf!
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.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_object.h b/ext/systemc/src/sysc/kernel/sc_object.h
new file mode 100644
index 000000000..c6e0957a8
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_object.h
@@ -0,0 +1,244 @@
+/*****************************************************************************
+
+ 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.h -- Abstract base class of all SystemC `simulation' objects.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_OBJECT_H
+#define SC_OBJECT_H
+
+
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/kernel/sc_attribute.h"
+
+namespace sc_core {
+
+class sc_event;
+class sc_module;
+class sc_phase_callback_registry;
+class sc_runnable;
+class sc_simcontext;
+class sc_trace_file;
+class sc_trace_file_base;
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_object
+//
+// Abstract base class of all SystemC `simulation' objects.
+// ----------------------------------------------------------------------------
+
+class sc_object
+{
+ friend class sc_event;
+ friend class sc_module;
+ friend struct sc_invoke_method;
+ friend class sc_module_dynalloc_list;
+ friend class sc_object_manager;
+ friend class sc_phase_callback_registry;
+ friend class sc_process_b;
+ friend class sc_runnable;
+ friend class sc_simcontext;
+ friend class sc_trace_file_base;
+
+public:
+ typedef unsigned phase_cb_mask;
+
+ const char* name() const
+ { return m_name.c_str(); }
+
+ const char* basename() const;
+
+ virtual void print(::std::ostream& os=::std::cout ) const;
+
+ // dump() is more detailed than print()
+ virtual void dump(::std::ostream& os=::std::cout ) const;
+
+ virtual void trace( sc_trace_file* tf ) const;
+
+ virtual const char* kind() const { return "sc_object"; }
+
+ sc_simcontext* simcontext() const
+ { return m_simc; }
+
+ // add attribute
+ bool add_attribute( sc_attr_base& );
+
+ // get attribute by name
+ sc_attr_base* get_attribute( const std::string& name_ );
+ const sc_attr_base* get_attribute( const std::string& name_ ) const;
+
+ // remove attribute by name
+ sc_attr_base* remove_attribute( const std::string& name_ );
+
+ // remove all attributes
+ void remove_all_attributes();
+
+ // get the number of attributes
+ int num_attributes() const;
+
+ // get the attribute collection
+ sc_attr_cltn& attr_cltn();
+ const sc_attr_cltn& attr_cltn() const;
+
+ virtual const std::vector<sc_event*>& get_child_events() const
+ { return m_child_events; }
+
+ virtual const std::vector<sc_object*>& get_child_objects() const
+ { return m_child_objects; }
+
+ sc_object* get_parent() const;
+ sc_object* get_parent_object() const { return m_parent; }
+
+protected:
+
+ sc_object();
+ sc_object(const char* nm);
+
+ sc_object( const sc_object& );
+ sc_object& operator=( const sc_object& );
+
+
+ virtual ~sc_object();
+
+ virtual void add_child_event( sc_event* event_p );
+ virtual void add_child_object( sc_object* object_p );
+ virtual bool remove_child_event( sc_event* event_p );
+ virtual bool remove_child_object( sc_object* object_p );
+
+ phase_cb_mask register_simulation_phase_callback( phase_cb_mask );
+ phase_cb_mask unregister_simulation_phase_callback( phase_cb_mask );
+
+ class hierarchy_scope;
+
+private:
+ void do_simulation_phase_callback();
+ virtual void simulation_phase_callback();
+
+ void detach();
+ virtual void orphan_child_events();
+ virtual void orphan_child_objects();
+ void sc_object_init(const char* nm);
+
+private:
+
+ /* Each simulation object is associated with a simulation context */
+ mutable sc_attr_cltn* m_attr_cltn_p; // attributes for this object.
+ std::vector<sc_event*> m_child_events; // list of child events.
+ std::vector<sc_object*> m_child_objects; // list of child objects.
+ std::string m_name; // name of this object.
+ sc_object* m_parent; // parent for this object.
+ sc_simcontext* m_simc; // simcontext ptr / empty indicator
+};
+
+inline
+sc_object&
+sc_object::operator=( sc_object const & )
+{
+ // deliberately do nothing
+ return *this;
+}
+
+// ----------------------------------------------------------------------------
+
+extern const char SC_HIERARCHY_CHAR;
+extern bool sc_enable_name_checking;
+
+
+inline
+sc_object* sc_get_parent( const sc_object* obj_p )
+{
+ return obj_p->get_parent_object();
+}
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ 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.h,v $
+// Revision 1.13 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.12 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.11 2011/03/06 15:55:11 acg
+// Andy Goodrich: Changes for named events.
+//
+// Revision 1.10 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// 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/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// 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/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif // SC_OBJECT_H
diff --git a/ext/systemc/src/sysc/kernel/sc_object_int.h b/ext/systemc/src/sysc/kernel/sc_object_int.h
new file mode 100644
index 000000000..aca230f8b
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_object_int.h
@@ -0,0 +1,99 @@
+/*****************************************************************************
+
+ 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_int.h -- For inline definitions of some utility functions.
+ DO NOT EXPORT THIS INCLUDE FILE.
+
+ Original Author: Philipp A. Hartmann, OFFIS, 2013-02-10
+
+ *****************************************************************************/
+
+#ifndef SC_OBJECT_INT_H_INCLUDED_
+#define SC_OBJECT_INT_H_INCLUDED_
+
+#include "sysc/kernel/sc_object.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_phase_callback_registry.h"
+
+namespace sc_core {
+
+class sc_object::hierarchy_scope
+{
+public:
+ explicit hierarchy_scope(sc_object* obj);
+ explicit hierarchy_scope(sc_module* mod);
+ ~hierarchy_scope();
+
+private:
+ sc_module * scope_;
+
+private:
+ hierarchy_scope( hierarchy_scope const & other ) /* = delete */;
+ hierarchy_scope& operator=(hierarchy_scope const&) /* = delete */;
+};
+
+
+inline
+sc_object::hierarchy_scope::hierarchy_scope( sc_object* obj )
+ : scope_(0)
+{
+ if( !obj ) return;
+
+ scope_ = dynamic_cast<sc_module*>(obj);
+ if( !scope_ )
+ scope_ = dynamic_cast<sc_module*>(obj->get_parent_object());
+ if( scope_ )
+ scope_->simcontext()->hierarchy_push(scope_);
+}
+
+
+inline
+sc_object::hierarchy_scope::hierarchy_scope( sc_module* mod )
+ : scope_(mod)
+{
+ if( scope_ )
+ scope_->simcontext()->hierarchy_push(scope_);
+}
+
+
+inline
+sc_object::hierarchy_scope::~hierarchy_scope()
+{
+ if( scope_ )
+ scope_->simcontext()->hierarchy_pop();
+}
+
+
+// -----------------------------------------------------------------------
+
+inline void
+sc_object::do_simulation_phase_callback()
+{
+ simulation_phase_callback();
+}
+
+// -----------------------------------------------------------------------
+
+} // namespace sc_core
+
+#endif // SC_OBJECT_INT_H_INCLUDED_
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_object_manager.cpp b/ext/systemc/src/sysc/kernel/sc_object_manager.cpp
new file mode 100644
index 000000000..e46413928
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_object_manager.cpp
@@ -0,0 +1,462 @@
+/*****************************************************************************
+
+ 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_manager.cpp -- Manager of objects (naming, &c.)
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include <stdio.h>
+#include <cstdlib>
+#include <cassert>
+#include <ctype.h>
+#include <stddef.h>
+#include <algorithm> // pick up std::sort.
+
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/kernel/sc_object.h"
+#include "sysc/utils/sc_hash.h"
+#include "sysc/utils/sc_list.h"
+#include "sysc/utils/sc_mempool.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_object_manager.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_module_name.h"
+
+namespace sc_core {
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_object_manager
+//
+// Manager of objects.
+// ----------------------------------------------------------------------------
+
+sc_object_manager::sc_object_manager() :
+ m_event_it(),
+ m_event_walk_ok(0),
+ m_instance_table(),
+ m_module_name_stack(0),
+ m_object_it(),
+ m_object_stack(),
+ m_object_walk_ok()
+{
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::~sc_object_manager"
+// |
+// | This is the object instance destructor for this class. It goes through
+// | each sc_object instance in the instance table and sets its m_simc field
+// | to NULL.
+// +----------------------------------------------------------------------------
+sc_object_manager::~sc_object_manager()
+{
+ instance_table_t::iterator it; // instance table iterator.
+
+ for ( it = m_instance_table.begin(); it != m_instance_table.end(); it++)
+ {
+ sc_object* obj_p = it->second.m_object_p;
+ if ( obj_p ) obj_p->m_simc = 0;
+ }
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::create_name"
+// |
+// | This method creates a hierarchical name based on the name of the active
+// | object and the supplied leaf name. If the resultant name is not unique it
+// | will be made unique and a warning message issued.
+// |
+// | Arguments:
+// | leaf_name = name to use for the leaf of the hierarchy.
+// | Result is an std::string containing the name.
+// +----------------------------------------------------------------------------
+std::string sc_object_manager::create_name(const char* leaf_name)
+{
+ bool clash; // true if path name exists in obj table
+ std::string leafname_string; // string containing the leaf name.
+ std::string parentname_string; // parent path name
+ sc_object* parent_p; // parent for this instance or NULL.
+ std::string result_orig_string; // save for warning message.
+ std::string result_string; // name to return.
+
+ // CONSTRUCT PATHNAME TO THE NAME TO BE RETURNED:
+ //
+ // If there is not a leaf name generate one.
+
+ parent_p = sc_get_curr_simcontext()->active_object();
+ parentname_string = parent_p ? parent_p->name() : "";
+ leafname_string = leaf_name;
+ if (parent_p) {
+ result_string = parentname_string;
+ result_string += SC_HIERARCHY_CHAR;
+ result_string += leafname_string;
+ } else {
+ result_string = leafname_string;
+ }
+
+ // SAVE the original path name
+
+ result_orig_string = result_string;
+
+ // MAKE SURE THE ENTITY NAME IS UNIQUE:
+ //
+ // If not use unique name generator to make it unique.
+
+ clash = false;
+ for (;;)
+ {
+ instance_table_t::iterator it = m_instance_table.find(result_string);
+ if ( it == m_instance_table.end() ||
+ (it->second.m_event_p == NULL && it->second.m_object_p == NULL ) )
+ {
+ break;
+ }
+ clash = true;
+ leafname_string = sc_gen_unique_name(leafname_string.c_str(), false);
+ if (parent_p) {
+ result_string = parentname_string;
+ result_string += SC_HIERARCHY_CHAR;
+ result_string += leafname_string;
+ } else {
+ result_string = leafname_string;
+ }
+ }
+ if (clash) {
+ std::string message = result_orig_string;
+ message += ". Latter declaration will be renamed to ";
+ message += result_string;
+ SC_REPORT_WARNING( SC_ID_INSTANCE_EXISTS_, message.c_str());
+ }
+
+ return result_string;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::find_event"
+// |
+// | This method returns the sc_event with the supplied name, or a NULL if
+// | the event does not exist.
+// |
+// | Arguments:
+// | name = name of the event
+// | Result is a pointer to the event or NULL if it does not exist.
+// +----------------------------------------------------------------------------
+sc_event*
+sc_object_manager::find_event(const char* name)
+{
+ instance_table_t::iterator it;
+ it = m_instance_table.find(name);
+ return it == m_instance_table.end() ? NULL : it->second.m_event_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::find_object"
+// |
+// | This method returns the sc_object with the supplied name, or a NULL if
+// | the object does not exist.
+// |
+// | Arguments:
+// | name = name of the object
+// | Result is a pointer to the object or NULL if it does not exist.
+// +----------------------------------------------------------------------------
+sc_object*
+sc_object_manager::find_object(const char* name)
+{
+ instance_table_t::iterator it;
+ it = m_instance_table.find(name);
+ return it == m_instance_table.end() ? NULL : it->second.m_object_p;
+}
+
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::first_object"
+// |
+// | This method initializes the object iterator to point to the first object
+// | in the instance table, and returns its address. If there are no objects
+// | in the table a NULL value is returned.
+// +----------------------------------------------------------------------------
+sc_object*
+sc_object_manager::first_object()
+{
+ sc_object* result_p; // result to return.
+
+ m_object_walk_ok = true;
+ result_p = NULL;
+ for ( m_object_it = m_instance_table.begin();
+ m_object_it != m_instance_table.end();
+ m_object_it++ )
+ {
+ result_p = m_object_it->second.m_object_p;
+ if ( result_p ) break;
+ }
+ return result_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::hierarchy_curr"
+// |
+// | This method returns the current object in the object hierarchy or NULL
+// | if it does not exist.
+// +----------------------------------------------------------------------------
+sc_object*
+sc_object_manager::hierarchy_curr()
+{
+ size_t hierarchy_n; // current size of the hierarchy.
+
+ hierarchy_n = m_object_stack.size();
+ return hierarchy_n ? m_object_stack[hierarchy_n-1] : 0;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::hierarchy_pop"
+// |
+// | This method pops the current object off the object hierarchy and returns
+// | it.
+// +----------------------------------------------------------------------------
+sc_object*
+sc_object_manager::hierarchy_pop()
+{
+ size_t hierarchy_n; // current size of the hierarchy.
+ sc_object* result_p; // object to return.
+
+ hierarchy_n = m_object_stack.size();
+ if ( hierarchy_n == 0 ) return NULL;
+ hierarchy_n--;
+ result_p = m_object_stack[hierarchy_n];
+ m_object_stack.pop_back();
+ return result_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::hierarchy_push"
+// |
+// | This method pushes down the sc_object hierarchy to make the supplied
+// | object the current object in the hierarchy.
+// |
+// | Arguments:
+// | object_p -> object to become the new current object in the hierarchy.
+// +----------------------------------------------------------------------------
+void
+sc_object_manager::hierarchy_push(sc_object* object_p)
+{
+ m_object_stack.push_back(object_p);
+}
+
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::hierarchy_size"
+// |
+// | This method returns the current size of the object hierarchy stack.
+// +----------------------------------------------------------------------------
+int
+sc_object_manager::hierarchy_size()
+{
+ return m_object_stack.size();
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::insert_event"
+// |
+// | This method inserts the supplied sc_event instance into the instance
+// | table using the supplied name.
+// |
+// | Arguments:
+// | name = name of the event to be inserted.
+// | event_p -> event to be inserted.
+// +----------------------------------------------------------------------------
+void
+sc_object_manager::insert_event(const std::string& name, sc_event* event_p)
+{
+ m_instance_table[name].m_event_p = event_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::insert_object"
+// |
+// | This method inserts the supplied sc_object instance into the instance
+// | table using the supplied name.
+// |
+// | Arguments:
+// | name = name of the event to be inserted.
+// | object_p -> object to be inserted.
+// +----------------------------------------------------------------------------
+void
+sc_object_manager::insert_object(const std::string& name, sc_object* object_p)
+{
+ m_instance_table[name].m_object_p = object_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::next_object"
+// |
+// | This method returns the next object pointed to by the instance iterator.
+// +----------------------------------------------------------------------------
+sc_object*
+sc_object_manager::next_object()
+{
+ sc_object* result_p; // result to return.
+
+ assert( m_object_walk_ok );
+
+ if ( m_object_it == m_instance_table.end() ) return NULL;
+ m_object_it++;
+
+ for ( result_p = NULL; m_object_it != m_instance_table.end();
+ m_object_it++ )
+ {
+ result_p = m_object_it->second.m_object_p;
+ if ( result_p ) break;
+ }
+ return result_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::pop_module_name"
+// |
+// | This method pops an entry off the module name stack and returns it.
+// +----------------------------------------------------------------------------
+sc_module_name*
+sc_object_manager::pop_module_name()
+{
+ sc_module_name* mod_name = m_module_name_stack;
+ m_module_name_stack = m_module_name_stack->m_next;
+ mod_name->m_next = 0;
+ return mod_name;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::push_module_name"
+// |
+// | This method pushes the supplied entry onto the module name stack.
+// |
+// | Arguments:
+// | mod_name_p -> entry to push onto the module name stack.
+// +----------------------------------------------------------------------------
+void
+sc_object_manager::push_module_name(sc_module_name* mod_name_p)
+{
+ mod_name_p->m_next = m_module_name_stack;
+ m_module_name_stack = mod_name_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::top_of_module_name_stack"
+// |
+// | This method returns the module name that is on the top of the module
+// | name stack.
+// +----------------------------------------------------------------------------
+sc_module_name*
+sc_object_manager::top_of_module_name_stack()
+{
+ if( m_module_name_stack == 0 ) {
+ SC_REPORT_ERROR( SC_ID_MODULE_NAME_STACK_EMPTY_, 0 );
+ }
+ return m_module_name_stack;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::remove_event"
+// |
+// | This method removes the sc_event instance with the supplied name from
+// | the table of instances. Note we just clear the pointer since if the name
+// | was for an sc_object the m_event_p pointer will be null anyway.
+// |
+// | Arguments:
+// | name = name of the event to be removed.
+// +----------------------------------------------------------------------------
+void
+sc_object_manager::remove_event(const std::string& name)
+{
+ instance_table_t::iterator it; // instance table iterator.
+ it = m_instance_table.find(name);
+ if ( it != m_instance_table.end() ) it->second.m_event_p = NULL;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_object_manager::remove_object"
+// |
+// | This method removes the sc_object instance with the supplied name from
+// | the table of instances. Note we just clear the pointer since if the name
+// | was for an sc_event the m_object_p pointer will be null anyway.
+// |
+// | Arguments:
+// | name = name of the object to be removed.
+// +----------------------------------------------------------------------------
+void
+sc_object_manager::remove_object(const std::string& name)
+{
+ instance_table_t::iterator it; // instance table iterator.
+ it = m_instance_table.find(name);
+ if ( it != m_instance_table.end() ) it->second.m_object_p = NULL;
+}
+
+} // namespace sc_core
+
+// $Log: sc_object_manager.cpp,v $
+// Revision 1.13 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.12 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.11 2011/06/25 17:08:39 acg
+// Andy Goodrich: Jerome Cornet's changes to use libtool to build the
+// library.
+//
+// Revision 1.10 2011/04/01 21:27:54 acg
+// Andy Goodrich: documentation of event and object insertion methods.
+//
+// Revision 1.9 2011/03/06 15:55:11 acg
+// Andy Goodrich: Changes for named events.
+//
+// Revision 1.8 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.7 2011/03/05 04:45:16 acg
+// Andy Goodrich: moved active process calculation to the sc_simcontext class.
+//
+// Revision 1.6 2011/03/05 01:39:21 acg
+// Andy Goodrich: changes for named events.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// 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.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_object_manager.h b/ext/systemc/src/sysc/kernel/sc_object_manager.h
new file mode 100644
index 000000000..753252c33
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_object_manager.h
@@ -0,0 +1,139 @@
+/*****************************************************************************
+
+ 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_manager.h -- Manager of objects (naming, &c.)
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_OBJECT_MANAGER_H
+#define SC_OBJECT_MANAGER_H
+
+#include <map>
+#include <vector>
+
+namespace sc_core {
+
+class sc_event;
+class sc_object;
+class sc_module_name;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_object_manager
+//
+// Manager of objects.
+// ----------------------------------------------------------------------------
+
+class sc_object_manager
+{
+ friend class sc_event;
+ friend class sc_object;
+ friend class sc_simcontext;
+
+protected:
+ struct table_entry
+ {
+ table_entry() : m_event_p(NULL), m_object_p(NULL) {}
+
+ sc_event* m_event_p; // if non-null this is an sc_event.
+ sc_object* m_object_p; // if non-null this is an sc_object.
+ };
+
+public:
+ typedef std::map<std::string,table_entry> instance_table_t;
+ typedef std::vector<sc_object*> object_vector_t;
+
+ sc_object_manager();
+ ~sc_object_manager();
+
+ sc_event* find_event(const char* name);
+
+ sc_object* find_object(const char* name);
+ sc_object* first_object();
+ sc_object* next_object();
+
+ void hierarchy_push(sc_object* mdl);
+ sc_object* hierarchy_pop();
+ sc_object* hierarchy_curr();
+ int hierarchy_size();
+
+ void push_module_name(sc_module_name* mod_name);
+ sc_module_name* pop_module_name();
+ sc_module_name* top_of_module_name_stack();
+
+
+private:
+ std::string create_name( const char* leaf_name );
+ void insert_event(const std::string& name, sc_event* obj);
+ void insert_object(const std::string& name, sc_object* obj);
+ void remove_event(const std::string& name);
+ void remove_object(const std::string& name);
+
+private:
+
+ instance_table_t::iterator m_event_it; // event instance iterator.
+ bool m_event_walk_ok; // true if can walk events.
+ instance_table_t m_instance_table; // table of instances.
+ sc_module_name* m_module_name_stack; // sc_module_name stack.
+ instance_table_t::iterator m_object_it; // object instance iterator.
+ object_vector_t m_object_stack; // sc_object stack.
+ bool m_object_walk_ok; // true if can walk objects.
+};
+
+} // namespace sc_core
+
+// $Log: sc_object_manager.h,v $
+// Revision 1.9 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.8 2011/03/06 15:55:11 acg
+// Andy Goodrich: Changes for named events.
+//
+// Revision 1.7 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.6 2011/03/05 01:39:21 acg
+// Andy Goodrich: changes for named events.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// 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.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_phase_callback_registry.cpp b/ext/systemc/src/sysc/kernel/sc_phase_callback_registry.cpp
new file mode 100644
index 000000000..84f15c93f
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_phase_callback_registry.cpp
@@ -0,0 +1,301 @@
+/*****************************************************************************
+
+ 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_phase_callback_registry.cpp -- Implementation of phase callback registry
+
+ Original Author: Philipp A. Hartmann, OFFIS, 2013-02-15
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_object.h"
+#include "sysc/kernel/sc_phase_callback_registry.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/utils/sc_report.h"
+
+#include <algorithm>
+#include <functional>
+
+namespace sc_core {
+
+#if SC_HAS_PHASE_CALLBACKS_
+
+sc_phase_callback_registry::sc_phase_callback_registry( sc_simcontext& simc )
+ : m_simc( &simc )
+#if 0
+ , m_cb_eval_vec()
+#endif
+ , m_cb_update_vec()
+ , m_cb_timestep_vec()
+{}
+
+sc_phase_callback_registry::~sc_phase_callback_registry()
+{}
+
+static const sc_phase_callback_registry::mask_type
+ SC_PHASE_CALLBACK_MASK = SC_STATUS_ANY;
+
+namespace /* anonymous */ {
+
+struct entry_match
+ : std::unary_function< sc_phase_callback_registry::entry, bool >
+{
+ typedef sc_phase_callback_registry::cb_type* ref_type;
+
+ explicit
+ entry_match( ref_type ref )
+ : ref_(ref)
+ {}
+
+ result_type operator()( argument_type e )
+ { return e.target == ref_; }
+private:
+ sc_phase_callback_registry::cb_type * ref_;
+
+}; // entry_match
+
+template< typename T >
+inline void
+erase_remove( std::vector<T>* vec, T const& t )
+{
+ vec->erase( std::remove( vec->begin(), vec->end(), t ) );
+}
+
+} // namespace anonymous
+
+
+sc_phase_callback_registry::mask_type
+sc_phase_callback_registry::validate_mask( cb_type& cb
+ , mask_type m
+ , bool warn = false )
+{
+ if( SC_UNLIKELY_(m & ~SC_PHASE_CALLBACK_MASK) )
+ {
+ if( warn )
+ {
+ std::stringstream ss;
+ ss << cb.name() << ": invalid phase callback mask: "
+ << (sc_status)m;
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_REGISTER_
+ , ss.str().c_str() );
+ }
+ m &= SC_PHASE_CALLBACK_MASK;
+ }
+
+ mask_type check_mask;
+
+ // elaboration callbacks
+ check_mask = ( SC_ELABORATION
+ | SC_BEFORE_END_OF_ELABORATION
+ | SC_END_OF_ELABORATION );
+ if( SC_UNLIKELY_( (m & check_mask ) && m_simc->elaboration_done() ) )
+ {
+ if( warn )
+ {
+ std::stringstream ss;
+ ss << cb.name() << ": elaboration done\n\t "
+ << (sc_status)( m & check_mask ) << " callback(s) ignored";
+ SC_REPORT_WARNING(SC_ID_PHASE_CALLBACK_REGISTER_
+ , ss.str().c_str() );
+ }
+ m &= ~check_mask;
+ }
+
+ check_mask = (SC_BEFORE_END_OF_ELABORATION | SC_END_OF_ELABORATION);
+ if( SC_UNLIKELY_(m & SC_ELABORATION) )
+ {
+ if( warn )
+ {
+ std::stringstream ss;
+ ss << cb.name() << ": " << SC_ELABORATION
+ << ":\n\t substituted by " << (sc_status)(check_mask);
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_REGISTER_
+ , ss.str().c_str() );
+ }
+ m &= ~SC_ELABORATION;
+ m |= check_mask;
+ }
+
+ check_mask = ( SC_END_OF_INITIALIZATION
+#if 0
+ | SC_END_OF_EVALUATION
+#endif
+ | SC_END_OF_UPDATE
+ | SC_BEFORE_TIMESTEP );
+ if( SC_UNLIKELY_(m & SC_RUNNING) )
+ {
+ if( warn )
+ {
+ std::stringstream ss;
+ ss << cb.name() << ": " << SC_RUNNING
+ << ":\n\t substituted by " << (sc_status)(check_mask);
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_REGISTER_
+ , ss.str().c_str() );
+ }
+ m &= ~SC_RUNNING;
+ m |= check_mask;
+ }
+ return m;
+}
+
+
+sc_phase_callback_registry::mask_type
+sc_phase_callback_registry::register_callback( cb_type& cb, mask_type m )
+{
+ storage_type::iterator it =
+ find_if( m_cb_vec.begin(), m_cb_vec.end(), entry_match(&cb) );
+
+ m = validate_mask(cb, m, /* warn */ true );
+
+ mask_type diff_mask = m;
+ mask_type new_mask = m;
+
+ if( it != m_cb_vec.end() ) // update existing entry
+ {
+ // update masks
+ new_mask = (*it).mask | m;
+ diff_mask = ~(*it).mask & m;
+ (*it).mask = new_mask;
+ }
+ else // new entry
+ {
+ if( !m ) // empty, do nothing
+ return SC_UNITIALIZED;
+
+ entry new_entry = { &cb, new_mask };
+ m_cb_vec.push_back( new_entry );
+ }
+
+ // add to callback shortcut sets
+#if 0
+ if( diff_mask & SC_END_OF_EVALUATION )
+ m_cb_eval_vec.push_back( &cb );
+#endif
+ if( diff_mask & SC_END_OF_UPDATE )
+ m_cb_update_vec.push_back( &cb );
+ if( diff_mask & SC_BEFORE_TIMESTEP )
+ m_cb_timestep_vec.push_back( &cb );
+
+ return new_mask;
+}
+
+
+sc_phase_callback_registry::mask_type
+sc_phase_callback_registry::unregister_callback( cb_type& cb, mask_type m )
+{
+ storage_type::iterator it =
+ find_if( m_cb_vec.begin(), m_cb_vec.end(), entry_match(&cb) );
+
+ m = validate_mask(cb, m);
+
+ mask_type diff_mask = m;
+ mask_type new_mask = m;
+
+ if( it == m_cb_vec.end() ) { // not registered
+ return SC_UNITIALIZED;
+ }
+
+ // update masks
+ new_mask = (*it).mask & ~m;
+ diff_mask = (*it).mask & m;
+ (*it).mask = new_mask;
+
+ if( !new_mask )
+ m_cb_vec.erase(it);
+
+ // drop from callback shortcut sets
+#if 0
+ if( diff_mask & SC_END_OF_EVALUATION )
+ erase_remove( &m_cb_eval_vec, &cb );
+#endif
+ if( diff_mask & SC_END_OF_UPDATE )
+ erase_remove( &m_cb_update_vec, &cb );
+ if( diff_mask & SC_BEFORE_TIMESTEP )
+ erase_remove( &m_cb_timestep_vec, &cb );
+
+ return new_mask;
+}
+
+
+// generic implementation (for non-critical callbacks)
+// - also restores hierarchy around callback object
+void
+sc_phase_callback_registry::do_callback( sc_status s ) const
+{
+ typedef storage_type::const_iterator it_type;
+ storage_type const & vec = m_cb_vec;
+
+ for(it_type it = vec.begin(), end = vec.end(); it != end; ++it) {
+ if( s & it->mask ) {
+ sc_object::hierarchy_scope scope(it->target);
+ it->target->do_simulation_phase_callback();
+ }
+ }
+}
+
+#else // ! SC_HAS_PHASE_CALLBACKS_
+
+sc_phase_callback_registry::sc_phase_callback_registry( sc_simcontext& ){}
+sc_phase_callback_registry::~sc_phase_callback_registry(){}
+
+static inline void
+warn_phase_callbacks( sc_core::sc_object const& obj )
+{
+ static bool warned = false;
+ if (!warned)
+ {
+ std::stringstream ss;
+ ss << obj.name() << ".\n"
+ << "Please recompile SystemC with "
+ "\"SC_ENABLE_SIMULATION_PHASE_CALLBACKS\" defined.";
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACKS_UNSUPPORTED_
+ , ss.str().c_str() );
+ }
+}
+
+sc_phase_callback_registry::mask_type
+sc_phase_callback_registry::register_callback( cb_type& cb, mask_type )
+{
+ warn_phase_callbacks( cb );
+ return SC_UNITIALIZED;
+}
+
+sc_phase_callback_registry::mask_type
+sc_phase_callback_registry::unregister_callback( cb_type& cb, mask_type )
+{
+ warn_phase_callbacks( cb );
+ return SC_UNITIALIZED;
+}
+
+#endif // ! SC_HAS_PHASE_CALLBACKS_
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_phase_callback_registry.h b/ext/systemc/src/sysc/kernel/sc_phase_callback_registry.h
new file mode 100644
index 000000000..9510c0d3f
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_phase_callback_registry.h
@@ -0,0 +1,276 @@
+/*****************************************************************************
+
+ 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_phase_callback_registry.h -- Definition of the simulation phase callbacks
+
+ The most critical functions are defined inline in this file. Only active,
+ if SC_ENABLE_SIMULATION_PHASE_CALLBACKS[_TRACING] is defined during the
+ SystemC library build.
+
+ Original Author: Philipp A. Hartmann, OFFIS, 2013-02-15
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#ifndef SC_PHASE_CALLBACK_REGISTRY_H_INCLUDED_
+#define SC_PHASE_CALLBACK_REGISTRY_H_INCLUDED_
+
+#if defined( SC_ENABLE_SIMULATION_PHASE_CALLBACKS ) \
+ || defined( SC_ENABLE_SIMULATION_PHASE_CALLBACKS_TRACING )
+# define SC_HAS_PHASE_CALLBACKS_ 1
+#else
+# define SC_HAS_PHASE_CALLBACKS_ 0
+#endif
+
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_object_int.h"
+#include "sysc/kernel/sc_status.h"
+
+#include <vector>
+
+namespace sc_core {
+
+class sc_simcontext;
+class sc_object;
+
+class sc_phase_callback_registry
+{
+public:
+ typedef sc_phase_callback_registry this_type;
+ typedef sc_object cb_type;
+ typedef cb_type::phase_cb_mask mask_type;
+
+ struct entry
+ {
+ cb_type* target;
+ mask_type mask;
+ };
+
+ friend class sc_simcontext;
+ friend class sc_object;
+
+private: // interface completely internal
+
+ explicit
+ sc_phase_callback_registry( sc_simcontext& simc );
+
+ ~sc_phase_callback_registry();
+
+ // --- callback forwarders
+
+ bool construction_done() const; //< returns false
+ void elaboration_done() const;
+ void initialization_done() const;
+ void start_simulation() const;
+
+ void evaluation_done() const;
+ void update_done() const;
+ void before_timestep() const;
+
+ void simulation_paused() const;
+ void simulation_stopped() const;
+ void simulation_done() const;
+
+
+ // --- callback registration and implementation
+
+ mask_type register_callback( cb_type&, mask_type mask );
+ mask_type unregister_callback( cb_type&, mask_type mask );
+
+ // generic caller
+ void do_callback( sc_status ) const;
+
+private:
+ typedef std::vector<entry> storage_type;
+ typedef std::vector<cb_type*> single_storage_type;
+
+#if SC_HAS_PHASE_CALLBACKS_
+
+ // set and restore simulation status
+ struct scoped_status
+ {
+ scoped_status( sc_status& ref, sc_status s )
+ : ref_(ref), prev_(ref) { ref_ = s;}
+ ~scoped_status() { ref_ = prev_; }
+ private:
+ sc_status& ref_;
+ sc_status prev_;
+ }; // scoped_status
+
+ mask_type validate_mask( cb_type&, mask_type, bool warn );
+
+private:
+
+ sc_simcontext* m_simc;
+ storage_type m_cb_vec; // all callbacks
+#if 0
+ single_storage_type m_cb_eval_vec; // - eval cb shortcut
+#endif
+ single_storage_type m_cb_update_vec; // - update cb shortcut
+ single_storage_type m_cb_timestep_vec; // - timestep cb shortcut
+
+#endif // SC_HAS_PHASE_CALLBACKS_
+
+private:
+ // disabled
+ sc_phase_callback_registry( const this_type& );
+ this_type& operator=(const this_type&);
+
+}; // sc_phase_callback_registry
+
+
+// -------------------- callback implementations --------------------
+// (empty, if feature is disabled)
+
+inline bool
+sc_phase_callback_registry::construction_done() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+ do_callback( SC_BEFORE_END_OF_ELABORATION );
+#endif
+ return false;
+}
+
+inline void
+sc_phase_callback_registry::elaboration_done() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+ do_callback( SC_END_OF_ELABORATION );
+#endif
+}
+
+inline void
+sc_phase_callback_registry::start_simulation() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+ do_callback( SC_START_OF_SIMULATION );
+#endif
+}
+
+inline void
+sc_phase_callback_registry::initialization_done() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+ scoped_status scope( m_simc->m_simulation_status
+ , SC_END_OF_INITIALIZATION );
+
+ do_callback( SC_END_OF_INITIALIZATION );
+#endif
+}
+
+inline void
+sc_phase_callback_registry::simulation_paused() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+ do_callback( SC_PAUSED );
+#endif
+}
+
+inline void
+sc_phase_callback_registry::simulation_stopped() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+ do_callback( SC_STOPPED );
+#endif
+}
+
+inline void
+sc_phase_callback_registry::simulation_done() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+ do_callback( SC_END_OF_SIMULATION );
+#endif
+}
+
+// -------------- specialized callback implementations --------------
+
+#if 0
+inline void
+sc_phase_callback_registry::evaluation_done() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+
+ if( !m_cb_eval_vec.size() ) return;
+
+ typedef single_storage_type::const_iterator it_type;
+ single_storage_type const & vec = m_cb_eval_vec;
+
+ scoped_status scope( m_simc->m_simulation_status
+ , SC_END_OF_EVALUATION );
+
+ for(it_type it = vec.begin(), end = vec.end(); it != end; ++it)
+ (*it)->do_simulation_phase_callback();
+#endif
+}
+#endif
+
+inline void
+sc_phase_callback_registry::update_done() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+
+ if( !m_cb_update_vec.size() ) return;
+
+ typedef single_storage_type::const_iterator it_type;
+ single_storage_type const & vec = m_cb_update_vec;
+
+ scoped_status scope( m_simc->m_simulation_status
+ , SC_END_OF_UPDATE );
+
+ for(it_type it = vec.begin(), end = vec.end(); it != end; ++it)
+ (*it)->do_simulation_phase_callback();
+#endif
+}
+
+inline void
+sc_phase_callback_registry::before_timestep() const
+{
+#if SC_HAS_PHASE_CALLBACKS_
+
+ if( !m_cb_timestep_vec.size() ) return;
+
+ typedef single_storage_type::const_iterator it_type;
+ single_storage_type const & vec = m_cb_timestep_vec;
+
+ scoped_status scope( m_simc->m_simulation_status
+ , SC_BEFORE_TIMESTEP );
+
+ for(it_type it = vec.begin(), end = vec.end(); it != end; ++it)
+ (*it)->do_simulation_phase_callback();
+#endif
+}
+
+// ------------------------------------------------------------------
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+#endif /* SC_PHASE_CALLBACK_REGISTRY_H_INCLUDED_ */
+// Taf!
+
diff --git a/ext/systemc/src/sysc/kernel/sc_process.cpp b/ext/systemc/src/sysc/kernel/sc_process.cpp
new file mode 100644
index 000000000..353eddd6a
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_process.cpp
@@ -0,0 +1,854 @@
+/*****************************************************************************
+
+ 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_process.cpp -- Base process implementation.
+
+ Original Authors: Andy Goodrich, Forte Design Systems, 17 June 2003
+ Stuart Swan, Cadence
+ Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_name_gen.h"
+#include "sysc/kernel/sc_cthread_process.h"
+#include "sysc/kernel/sc_method_process.h"
+#include "sysc/kernel/sc_thread_process.h"
+#include "sysc/kernel/sc_sensitive.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_event.h"
+#include <sstream>
+
+namespace sc_core {
+
+// sc_process_handle entities that are returned for null pointer instances:
+//
+// Note the special name for 'non_event' - this makes sure it does not
+// appear as a named event.
+
+std::vector<sc_event*> sc_process_handle::empty_event_vector;
+std::vector<sc_object*> sc_process_handle::empty_object_vector;
+sc_event sc_process_handle::non_event(SC_KERNEL_EVENT_PREFIX);
+
+// Last process that was created:
+
+sc_process_b* sc_process_b::m_last_created_process_p = 0;
+
+//------------------------------------------------------------------------------
+//"sc_process_b::add_static_event"
+//
+// This method adds an event to the list of static events, and sets the
+// event up to call back this process when it fires.
+//------------------------------------------------------------------------------
+void sc_process_b::add_static_event( const sc_event& e )
+{
+ sc_method_handle method_h; // This process as a method.
+ sc_thread_handle thread_h; // This process as a thread.
+
+
+ // CHECK TO SEE IF WE ARE ALREADY REGISTERED WITH THE EVENT:
+
+ for( int i = m_static_events.size() - 1; i >= 0; -- i ) {
+ if( &e == m_static_events[i] ) {
+ return;
+ }
+ }
+
+ // REMEMBER THE EVENT AND THEN REGISTER OUR OBJECT INSTANCE WITH IT:
+
+ m_static_events.push_back( &e );
+
+ switch ( m_process_kind )
+ {
+ case SC_THREAD_PROC_:
+ case SC_CTHREAD_PROC_:
+ thread_h = SCAST<sc_thread_handle>( this );
+ e.add_static( thread_h );
+ break;
+ case SC_METHOD_PROC_:
+ method_h = SCAST<sc_method_handle>( this );
+ e.add_static( method_h );
+ break;
+ default:
+ assert( false );
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::disconnect_process"
+//
+// This method removes this object instance from use. It will be called by
+// the kill_process() methods of classes derived from it. This object instance
+// will be removed from any data structures it resides, other than existence.
+//------------------------------------------------------------------------------
+void sc_process_b::disconnect_process()
+{
+ int mon_n; // monitor queue size.
+ sc_thread_handle thread_h; // This process as a thread.
+
+ // IF THIS OBJECT IS PINING FOR THE FJORDS WE ARE DONE:
+
+ if ( m_state & ps_bit_zombie ) return;
+
+ // IF THIS IS A THREAD SIGNAL ANY MONITORS WAITING FOR IT TO EXIT:
+
+ switch ( m_process_kind )
+ {
+ case SC_THREAD_PROC_:
+ case SC_CTHREAD_PROC_:
+ thread_h = SCAST<sc_thread_handle>(this);
+ mon_n = thread_h->m_monitor_q.size();
+ if ( mon_n )
+ {
+ for ( int mon_i = 0; mon_i < mon_n; mon_i++ )
+ {
+ thread_h->m_monitor_q[mon_i]->signal( thread_h,
+ sc_process_monitor::spm_exit);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ // REMOVE EVENT WAITS, AND REMOVE THE PROCESS FROM ITS SC_RESET:
+
+ remove_dynamic_events();
+ remove_static_events();
+
+ for ( std::vector<sc_reset*>::size_type rst_i = 0; rst_i < m_resets.size(); rst_i++ )
+ {
+ m_resets[rst_i]->remove_process( this );
+ }
+ m_resets.resize(0);
+
+
+ // FIRE THE TERMINATION EVENT, MARK AS TERMINATED, AND DECREMENT THE COUNT:
+ //
+ // (1) We wait to set the process kind until after doing the removals
+ // above.
+ // (2) Decrementing the reference count will result in actual object
+ // deletion if we hit zero.
+
+ m_state = ps_bit_zombie;
+ if ( m_term_event_p ) m_term_event_p->notify();
+ reference_decrement();
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::delete_process"
+//
+// This method deletes the current instance, if it is not the running
+// process. Otherwise, it is put in the simcontext's process deletion
+// queue.
+//
+// The reason for the two step deletion process is that the process from which
+// reference_decrement() is called may be the running process, so we may need
+// to wait until it goes idle.
+//------------------------------------------------------------------------------
+void sc_process_b::delete_process()
+{
+ assert( m_references_n == 0 );
+
+ // Immediate deletion:
+
+ if ( this != sc_get_current_process_b() )
+ {
+ delete this;
+ }
+
+ // Deferred deletion: note we set the reference count to one for the call
+ // to reference_decrement that occurs in sc_simcontext::crunch().
+
+ else
+ {
+ m_references_n = 1;
+ detach();
+ simcontext()->mark_to_collect_process( this );
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::dont_initialize"
+//
+// This virtual method sets the initialization switch for this object instance.
+//------------------------------------------------------------------------------
+void sc_process_b::dont_initialize( bool dont )
+{
+ m_dont_init = dont;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::dump_state"
+//
+// This method returns the process state as a string.
+//------------------------------------------------------------------------------
+std::string sc_process_b::dump_state() const
+{
+ std::string result;
+ result = "[";
+ if ( m_state == ps_normal )
+ {
+ result += " normal";
+ }
+ else
+ {
+ if ( m_state & ps_bit_disabled )
+ result += "disabled ";
+ if ( m_state & ps_bit_suspended )
+ result += "suspended ";
+ if ( m_state & ps_bit_ready_to_run )
+ result += "ready_to_run ";
+ if ( m_state & ps_bit_zombie )
+ result += "zombie ";
+ }
+ result += "]";
+ return result;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::gen_unique_name"
+//
+// This method generates a unique name within this object instance's namespace.
+//------------------------------------------------------------------------------
+const char* sc_process_b::gen_unique_name( const char* basename_,
+ bool preserve_first )
+{
+ if ( ! m_name_gen_p ) m_name_gen_p = new sc_name_gen;
+ return m_name_gen_p->gen_unique_name( basename_, preserve_first );
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::remove_dynamic_events"
+//
+// This method removes this object instance from the events in its dynamic
+// event lists.
+//
+// Arguments:
+// skip_timeout = skip cleaning up the timeout event, it will be done
+// by sc_event_notify().
+//------------------------------------------------------------------------------
+void
+sc_process_b::remove_dynamic_events( bool skip_timeout )
+{
+ sc_method_handle method_h; // This process as a method.
+ sc_thread_handle thread_h; // This process as a thread.
+
+ m_trigger_type = STATIC;
+ switch ( m_process_kind )
+ {
+ case SC_THREAD_PROC_:
+ case SC_CTHREAD_PROC_:
+ thread_h = SCAST<sc_thread_handle>(this);
+ if ( thread_h->m_timeout_event_p && !skip_timeout ) {
+ thread_h->m_timeout_event_p->remove_dynamic(thread_h);
+ thread_h->m_timeout_event_p->cancel();
+ }
+ if ( m_event_p ) m_event_p->remove_dynamic( thread_h );
+ if ( m_event_list_p )
+ {
+ m_event_list_p->remove_dynamic( thread_h, 0 );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ }
+ break;
+ case SC_METHOD_PROC_:
+ method_h = SCAST<sc_method_handle>(this);
+ if ( method_h->m_timeout_event_p && !skip_timeout ) {
+ method_h->m_timeout_event_p->remove_dynamic(method_h);
+ method_h->m_timeout_event_p->cancel();
+ }
+ if ( m_event_p ) m_event_p->remove_dynamic( method_h );
+ if ( m_event_list_p )
+ {
+ m_event_list_p->remove_dynamic( method_h, 0 );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ }
+ break;
+ default: // Some other type, it needs to clean up itself.
+ // std::cout << "Check " << __FILE__ << ":" << __LINE__ << std::endl;
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::remove_static_events"
+//
+// This method removes this object instance from the events in its static
+// event list.
+//------------------------------------------------------------------------------
+void
+sc_process_b::remove_static_events()
+{
+ sc_method_handle method_h; // This process as a method.
+ sc_thread_handle thread_h; // This process as a thread.
+
+ switch ( m_process_kind )
+ {
+ case SC_THREAD_PROC_:
+ case SC_CTHREAD_PROC_:
+ thread_h = SCAST<sc_thread_handle>( this );
+ for( int i = m_static_events.size() - 1; i >= 0; -- i ) {
+ m_static_events[i]->remove_static( thread_h );
+ }
+ m_static_events.resize(0);
+ break;
+ case SC_METHOD_PROC_:
+ method_h = DCAST<sc_method_handle>( this );
+ assert( method_h != 0 );
+ for( int i = m_static_events.size() - 1; i >= 0; -- i ) {
+ m_static_events[i]->remove_static( method_h );
+ }
+ m_static_events.resize(0);
+ break;
+ default: // Some other type, it needs to clean up itself.
+ // std::cout << "Check " << __FILE__ << ":" << __LINE__ << std::endl;
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+// "sc_process_b::report_error"
+//
+// This method can be used to issue a report from within a process.
+// The error of the given ID is reported with the given message and
+// the process' name() appended to the report.
+//------------------------------------------------------------------------------
+void
+sc_process_b::report_error( const char* msgid, const char* msg ) const
+{
+ std::stringstream sstr;
+ if( msg && msg[0] )
+ sstr << msg << ": ";
+ sstr << name();
+ SC_REPORT_ERROR( msgid, sstr.str().c_str() );
+}
+
+
+//------------------------------------------------------------------------------
+// "sc_process_b::report_immediate_self_notification"
+//
+// This method is used to report an immediate self-notification
+// that used to trigger the process before the clarification in 1666-2011.
+// The warning is only reported once.
+//------------------------------------------------------------------------------
+void
+sc_process_b::report_immediate_self_notification() const
+{
+ static bool once = false;
+ if( !once ) {
+ SC_REPORT_WARNING( SC_ID_IMMEDIATE_SELF_NOTIFICATION_, name() );
+ once = true;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::reset_changed"
+//
+// This method is called when there is a change in the value of the
+// signal that was specified via reset_signal_is, or the value of the
+// m_sticky_reset field. We get called any time m_sticky_reset changes
+// or a signal value changes since, since we may need to throw an exception
+// or clear one. Note that this method may be called when there is no
+// active process, but rather the main simulator is executing so we must
+// check for that case.
+//
+// Arguments:
+// async = true if this is an asynchronous reset.
+// asserted = true if reset being asserted, false if being deasserted.
+//------------------------------------------------------------------------------
+void sc_process_b::reset_changed( bool async, bool asserted )
+{
+
+ // Error out on the corner case:
+
+ if ( !sc_allow_process_control_corners && !async &&
+ (m_state & ps_bit_suspended) )
+ {
+ report_error( SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "synchronous reset changed on a suspended process" );
+ }
+
+ // IF THIS OBJECT IS PUSHING UP DAISIES WE ARE DONE:
+
+ if ( m_state & ps_bit_zombie ) return;
+
+ // Reset is being asserted:
+
+ if ( asserted )
+ {
+ // if ( m_reset_event_p ) m_reset_event_p->notify();
+ if ( async )
+ {
+ m_active_areset_n++;
+ if ( sc_is_running() ) throw_reset(true);
+ }
+ else
+ {
+ m_active_reset_n++;
+ if ( sc_is_running() ) throw_reset(false);
+ }
+ }
+
+ // Reset is being deasserted:
+
+ else
+ {
+ if ( async )
+ {
+ m_active_areset_n--;
+ }
+ else
+ {
+ m_active_reset_n--;
+ }
+ }
+
+ // Clear the throw type if there are no active resets.
+
+ if ( (m_throw_status == THROW_SYNC_RESET ||
+ m_throw_status == THROW_ASYNC_RESET) &&
+ m_active_areset_n == 0 && m_active_reset_n == 0 && !m_sticky_reset )
+ {
+ m_throw_status = THROW_NONE;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::reset_event"
+//
+// This method returns a reference to the reset event for this object
+// instance. If no event exists one is allocated.
+//------------------------------------------------------------------------------
+sc_event& sc_process_b::reset_event()
+{
+ if ( !m_reset_event_p )
+ {
+ m_reset_event_p = new sc_event(
+ (std::string(SC_KERNEL_EVENT_PREFIX)+"_reset_event").c_str() );
+ }
+ return *m_reset_event_p;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::reset_process"
+//
+// This inline method changes the reset state of this object instance and
+// conditionally its descendants.
+//
+// Notes:
+// (1) It is called for sync_reset_on() and sync_reset_off(). It is not used
+// for signal sensitive resets, though all reset flow ends up in
+// reset_changed().
+//
+// Arguments:
+// rt = source of the reset:
+// * reset_asynchronous - sc_process_handle::reset()
+// * reset_synchronous_off - sc_process_handle::sync_reset_off()
+// * reset_synchronous_on - sc_process_handle::sync_reset_on()
+// descendants = indication of how to process descendants.
+//------------------------------------------------------------------------------
+void sc_process_b::reset_process( reset_type rt,
+ sc_descendant_inclusion_info descendants )
+{
+
+ // PROCESS THIS OBJECT INSTANCE'S DESCENDANTS IF REQUESTED TO:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*> children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->reset_process(rt, descendants);
+ }
+ }
+
+ // PROCESS THIS OBJECT INSTANCE:
+
+ switch (rt)
+ {
+ // One-shot asynchronous reset: remove dynamic sensitivity and throw:
+ //
+ // If this is an sc_method only throw if it is active.
+
+ case reset_asynchronous:
+ if ( sc_get_status() != SC_RUNNING )
+ {
+ report_error(SC_ID_RESET_PROCESS_WHILE_NOT_RUNNING_);
+ }
+ else
+ {
+ remove_dynamic_events();
+ throw_reset(true);
+ }
+ break;
+
+ // Turn on sticky synchronous reset: use standard reset mechanism.
+
+ case reset_synchronous_on:
+ if ( m_sticky_reset == false )
+ {
+ m_sticky_reset = true;
+ reset_changed( false, true );
+ }
+ break;
+
+ // Turn off sticky synchronous reset: use standard reset mechanism.
+
+ default:
+ if ( m_sticky_reset == true )
+ {
+ m_sticky_reset = false;
+ reset_changed( false, false );
+ }
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::sc_process_b"
+//
+// This is the object instance constructor for this class.
+//------------------------------------------------------------------------------
+sc_process_b::sc_process_b( const char* name_p, bool is_thread, bool free_host,
+ SC_ENTRY_FUNC method_p, sc_process_host* host_p,
+ const sc_spawn_options* /* opt_p */
+) :
+ sc_object( name_p ),
+ file(0),
+ lineno(0),
+ proc_id( simcontext()->next_proc_id()),
+ m_active_areset_n(0),
+ m_active_reset_n(0),
+ m_dont_init( false ),
+ m_dynamic_proc( simcontext()->elaboration_done() ),
+ m_event_p(0),
+ m_event_count(0),
+ m_event_list_p(0),
+ m_exist_p(0),
+ m_free_host( free_host ),
+ m_has_reset_signal( false ),
+ m_has_stack(false),
+ m_is_thread(is_thread),
+ m_last_report_p(0),
+ m_name_gen_p(0),
+ m_process_kind(SC_NO_PROC_),
+ m_references_n(1),
+ m_resets(),
+ m_reset_event_p(0),
+ m_resume_event_p(0),
+ m_runnable_p(0),
+ m_semantics_host_p( host_p ),
+ m_semantics_method_p ( method_p ),
+ m_state(ps_normal),
+ m_static_events(),
+ m_sticky_reset(false),
+ m_term_event_p(0),
+ m_throw_helper_p(0),
+ m_throw_status( THROW_NONE ),
+ m_timed_out(false),
+ m_timeout_event_p(0),
+ m_trigger_type(STATIC),
+ m_unwinding(false)
+{
+
+ // THIS OBJECT INSTANCE IS NOW THE LAST CREATED PROCESS:
+
+ m_last_created_process_p = this;
+ m_timeout_event_p = new sc_event(
+ (std::string(SC_KERNEL_EVENT_PREFIX)+"_free_event").c_str() );
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::~sc_process_b"
+//
+// This is the object instance destructor for this class.
+//------------------------------------------------------------------------------
+sc_process_b::~sc_process_b()
+{
+
+ // REDIRECT ANY CHILDREN AS CHILDREN OF THE SIMULATION CONTEXT:
+
+ orphan_child_objects();
+
+
+ // DELETE SEMANTICS OBJECTS IF NEED BE:
+
+ if ( m_free_host ) delete m_semantics_host_p;
+# if !defined(SC_USE_MEMBER_FUNC_PTR) // Remove invocation object.
+ delete m_semantics_method_p;
+# endif
+
+
+ // REMOVE ANY STRUCTURES THAT MAY HAVE BEEN BUILT:
+
+ delete m_last_report_p;
+ delete m_name_gen_p;
+ delete m_reset_event_p;
+ delete m_resume_event_p;
+ delete m_term_event_p;
+ delete m_throw_helper_p;
+ delete m_timeout_event_p;
+
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::terminated_event"
+//
+// This method returns a reference to the terminated event for this object
+// instance. If no event exists one is allocated.
+//------------------------------------------------------------------------------
+sc_event& sc_process_b::terminated_event()
+{
+ if ( !m_term_event_p )
+ {
+ m_term_event_p = new sc_event(
+ (std::string(SC_KERNEL_EVENT_PREFIX)+"_term_event").c_str() );
+ }
+ return *m_term_event_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_process_b::trigger_reset_event"
+// |
+// | This method triggers the notify event. It exists because we can't get
+// | sc_event context in sc_process.h because the includes would be
+// | circular... sigh...
+// +----------------------------------------------------------------------------
+void sc_process_b::trigger_reset_event()
+{
+ if ( m_reset_event_p ) m_reset_event_p->notify();
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::operator sc_cthread_handle"
+//
+//------------------------------------------------------------------------------
+sc_process_handle::operator sc_cthread_handle()
+{
+ return DCAST<sc_cthread_handle>(m_target_p);
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::sc_method_handle"
+//
+//------------------------------------------------------------------------------
+sc_process_handle::operator sc_method_handle()
+{
+ return DCAST<sc_method_handle>(m_target_p);
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::sc_thread_handle"
+//
+//------------------------------------------------------------------------------
+sc_process_handle::operator sc_thread_handle()
+{
+ return DCAST<sc_thread_handle>(m_target_p);
+}
+
+} // namespace sc_core
+
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems, 12 Aug 05
+ Description of Modification: This is the rewrite of process support. It
+ contains some code from the now-defunct
+ sc_process_b.cpp, as well as the former
+ version of sc_process_b.cpp.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_process.cpp,v $
+// Revision 1.37 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.36 2011/08/15 16:43:24 acg
+// Torsten Maehne: changes to remove unused argument warnings.
+//
+// Revision 1.35 2011/08/07 19:08:04 acg
+// Andy Goodrich: moved logs to end of file so line number synching works
+// better between versions.
+//
+// Revision 1.34 2011/07/29 22:55:01 acg
+// Philipp A. Hartmann: add missing include.
+//
+// Revision 1.33 2011/07/29 22:43:41 acg
+// Philipp A. Hartmann: changes to handle case where a process control
+// invocation on a child process causes the list of child processes to change.
+//
+// Revision 1.32 2011/07/24 11:20:03 acg
+// Philipp A. Hartmann: process control error message improvements:
+// (1) Downgrade error to warning for re-kills of processes.
+// (2) Add process name to process messages.
+// (3) drop some superfluous colons in messages.
+//
+// Revision 1.31 2011/04/19 15:04:27 acg
+// Philipp A. Hartmann: clean up SC_ID messages.
+//
+// Revision 1.30 2011/04/14 22:33:43 acg
+// Andy Goodrich: added missing checks for a process being a zombie.
+//
+// Revision 1.29 2011/04/13 05:00:43 acg
+// Andy Goodrich: removed check for method process in termination_event()
+// since with the new IEEE 1666 2011 its legal.
+//
+// Revision 1.28 2011/04/13 02:44:26 acg
+// Andy Goodrich: added m_unwinding flag in place of THROW_NOW because the
+// throw status will be set back to THROW_*_RESET if reset is active and
+// the check for an unwind being complete was expecting THROW_NONE as the
+// clearing of THROW_NOW.
+//
+// Revision 1.27 2011/04/10 22:17:35 acg
+// Andy Goodrich: added trigger_reset_event() to allow sc_process.h to
+// contain the run_process() inline method. sc_process.h cannot have
+// sc_simcontext information because of recursive includes.
+//
+// Revision 1.26 2011/04/08 22:33:08 acg
+// Andy Goodrich: moved the semantics() method to the header file and made
+// it an inline method.
+//
+// Revision 1.25 2011/04/08 18:24:48 acg
+// Andy Goodrich: moved reset_changed() to .cpp since it needs visibility
+// to sc_simcontext.
+//
+// Revision 1.24 2011/04/05 20:50:57 acg
+// Andy Goodrich:
+// (1) changes to make sure that event(), posedge() and negedge() only
+// return true if the clock has not moved.
+// (2) fixes for method self-resumes.
+// (3) added SC_PRERELEASE_VERSION
+// (4) removed kernel events from the object hierarchy, added
+// sc_hierarchy_name_exists().
+//
+// Revision 1.23 2011/04/05 06:25:38 acg
+// Andy Goodrich: new checks for simulation running in reset_process().
+//
+// Revision 1.22 2011/03/20 13:43:23 acg
+// Andy Goodrich: added async_signal_is() plus suspend() as a corner case.
+//
+// Revision 1.21 2011/03/12 21:07:51 acg
+// Andy Goodrich: changes to kernel generated event support.
+//
+// Revision 1.20 2011/03/07 17:38:43 acg
+// Andy Goodrich: tightening up of checks for undefined interaction between
+// synchronous reset and suspend.
+//
+// Revision 1.19 2011/03/06 23:30:13 acg
+// Andy Goodrich: refining suspend - sync reset corner case checking so that
+// the following are error situations:
+// (1) Calling suspend on a process with a reset_signal_is() specification
+// or sync_reset_on() is active.
+// (2) Calling sync_reset_on() on a suspended process.
+//
+// Revision 1.18 2011/03/06 19:57:11 acg
+// Andy Goodrich: refinements for the illegal suspend - synchronous reset
+// interaction.
+//
+// Revision 1.17 2011/03/06 16:47:09 acg
+// Andy Goodrich: changes for testing sync_reset - suspend corner cases.
+//
+// Revision 1.16 2011/03/06 15:57:57 acg
+// Andy Goodrich: added process control corner case checks. Changes for
+// named events.
+//
+// Revision 1.15 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.14 2011/02/17 19:52:13 acg
+// Andy Goodrich:
+// (1) Simplfied process control usage.
+// (2) Changed dump_status() to dump_state with new signature.
+//
+// Revision 1.13 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.12 2011/02/13 21:41:34 acg
+// Andy Goodrich: get the log messages for the previous check in correct.
+//
+// Revision 1.11 2011/02/13 21:32:24 acg
+// Andy Goodrich: moved sc_process_b::reset_process() from header file
+// to cpp file. Added dump_status() to print out the status of a
+// process.
+//
+// Revision 1.10 2011/02/04 15:27:36 acg
+// Andy Goodrich: changes for suspend-resume semantics.
+//
+// Revision 1.9 2011/02/01 21:06:12 acg
+// Andy Goodrich: new layout for the process_state enum.
+//
+// Revision 1.8 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.7 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.6 2011/01/18 20:10:45 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.5 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.4 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.3 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2007/09/20 20:32:35 acg
+// Andy Goodrich: changes to the semantics of throw_it() to match the
+// specification. A call to throw_it() will immediately suspend the calling
+// thread until all the throwees have executed. At that point the calling
+// thread will be restarted before the execution of any other threads.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.6 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.5 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_process.h b/ext/systemc/src/sysc/kernel/sc_process.h
new file mode 100644
index 000000000..298e2462f
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_process.h
@@ -0,0 +1,887 @@
+/*****************************************************************************
+
+ 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_process.h -- Process base class support.
+
+ Original Author: Andy Goodrich, Forte Design Systems, 04 August 2005
+
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#if !defined(sc_process_h_INCLUDED)
+#define sc_process_h_INCLUDED
+
+#include <cassert>
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/kernel/sc_constants.h"
+#include "sysc/kernel/sc_object.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/communication/sc_export.h"
+
+namespace sc_core {
+
+// Forward declarations:
+class sc_process_handle;
+class sc_thread_process;
+class sc_reset;
+
+const char* sc_gen_unique_name( const char*, bool preserve_first );
+sc_process_handle sc_get_current_process_handle();
+void sc_thread_cor_fn( void* arg );
+bool timed_out( sc_simcontext* );
+
+extern bool sc_allow_process_control_corners; // see sc_simcontext.cpp.
+
+
+// Process handles as forward references:
+
+typedef class sc_cthread_process* sc_cthread_handle;
+typedef class sc_method_process* sc_method_handle;
+typedef class sc_thread_process* sc_thread_handle;
+
+
+// Standard process types:
+
+enum sc_curr_proc_kind
+{
+ SC_NO_PROC_,
+ SC_METHOD_PROC_,
+ SC_THREAD_PROC_,
+ SC_CTHREAD_PROC_
+};
+
+// Descendant information for process hierarchy operations:
+
+enum sc_descendant_inclusion_info {
+ SC_NO_DESCENDANTS=0,
+ SC_INCLUDE_DESCENDANTS,
+ SC_INVALID_DESCENDANTS
+};
+
+//==============================================================================
+// CLASS sc_process_host
+//
+// This is the base class for objects which may have processes defined for
+// their methods (e.g., sc_module)
+//==============================================================================
+
+class sc_process_host
+{
+ public:
+ sc_process_host() {}
+ virtual ~sc_process_host() { } // Needed for cast check for sc_module.
+ void defunct() {}
+};
+
+
+//==============================================================================
+// CLASS sc_process_monitor
+//
+// This class provides a way of monitoring a process' status (e.g., waiting
+// for a thread to complete its execution.) This class is intended to be a base
+// class for classes which need to monitor a process or processes (e.g.,
+// sc_join.) Its methods should be overloaded where notifications are desired.
+//==============================================================================
+
+class sc_process_monitor {
+ public:
+ enum {
+ spm_exit = 0
+ };
+ virtual ~sc_process_monitor() {}
+ virtual void signal(sc_thread_handle thread_p, int type);
+};
+inline void sc_process_monitor::signal(sc_thread_handle , int ) {}
+
+//------------------------------------------------------------------------------
+// PROCESS INVOCATION METHOD OR FUNCTION:
+//
+// Define SC_USE_MEMBER_FUNC_PTR if we want to use member function pointers
+// to implement process dispatch. Otherwise, we'll use a hack that involves
+// creating a templated invocation object which will invoke the member
+// function. This should not be necessary, but some compilers (e.g., VC++)
+// do not allow the conversion from `void (callback_tag::*)()' to
+// `void (sc_process_host::*)()'. This is supposed to be OK as long as the
+// dynamic type is correct. C++ Standard 5.4 "Explicit type conversion",
+// clause 7: a pointer to member of derived class type may be explicitly
+// converted to a pointer to member of an unambiguous non-virtual base class
+// type.
+//-----------------------------------------------------------------------------
+
+#if defined(_MSC_VER)
+#if ( _MSC_VER > 1200 )
+# define SC_USE_MEMBER_FUNC_PTR
+#endif
+#else
+# define SC_USE_MEMBER_FUNC_PTR
+#endif
+
+
+// COMPILER DOES SUPPORT CAST TO void (sc_process_host::*)() from (T::*)():
+
+#if defined(SC_USE_MEMBER_FUNC_PTR)
+
+ typedef void (sc_process_host::*SC_ENTRY_FUNC)();
+# define SC_DECL_HELPER_STRUCT(callback_tag, func) /*EMPTY*/
+# define SC_MAKE_FUNC_PTR(callback_tag, func) \
+ static_cast<sc_core::SC_ENTRY_FUNC>(&callback_tag::func)
+
+
+// COMPILER NOT DOES SUPPORT CAST TO void (sc_process_host::*)() from (T::*)():
+
+#else // !defined(SC_USE_MEMBER_FUNC_PTR)
+ class sc_process_call_base {
+ public:
+ inline sc_process_call_base()
+ {
+ }
+
+ virtual ~sc_process_call_base()
+ {
+ }
+
+ virtual void invoke(sc_process_host* host_p)
+ {
+ }
+ };
+ extern sc_process_call_base sc_process_defunct;
+
+ template<class T>
+ class sc_process_call : public sc_process_call_base {
+ public:
+ sc_process_call( void (T::*method_p)() ) :
+ sc_process_call_base()
+ {
+ m_method_p = method_p;
+ }
+
+ virtual ~sc_process_call()
+ {
+ }
+
+ virtual void invoke(sc_process_host* host_p)
+ {
+ (((T*)host_p)->*m_method_p)();
+ }
+
+ protected:
+ void (T::*m_method_p)(); // Method implementing the process.
+ };
+
+ typedef sc_process_call_base* SC_ENTRY_FUNC;
+# define SC_DECL_HELPER_STRUCT(callback_tag, func) /*EMPTY*/
+# define SC_MAKE_FUNC_PTR(callback_tag, func) \
+ (::sc_core::SC_ENTRY_FUNC) (new \
+ ::sc_core::sc_process_call<callback_tag>(&callback_tag::func))
+
+#endif // !defined(SC_USE_MEMBER_FUNC_PTR)
+
+
+extern void sc_set_stack_size( sc_thread_handle, std::size_t );
+
+class sc_event;
+class sc_event_list;
+class sc_name_gen;
+class sc_spawn_options;
+class sc_unwind_exception;
+
+//==============================================================================
+// CLASS sc_throw_it<EXCEPT> - ARBITRARY EXCEPTION CLASS
+//
+// This class serves as a way of throwing an execption for an aribtrary type
+// without knowing what that type is. A true virtual method in the base
+// class is used to actually throw the execption. A pointer to the base
+// class is used internally removing the necessity of knowing what the type
+// of EXCEPT is for code internal to the library.
+//
+// Note the clone() true virtual method. This is used to allow instances
+// of the sc_throw_it<EXCEPT> class to be easily garbage collected. Since
+// an exception may be propogated to more than one process knowing when
+// to garbage collect is non-trivial. So when a call is made to
+// sc_process_handle::throw_it() an instance of sc_throw_it<EXCEPT> is
+// allocated on the stack. For each process throwing the exception a copy is
+// made via clone(). That allows those objects to be deleted by the individual
+// processes when they are no longer needed (in this implementation of SystemC
+// that deletion will occur each time a new exception is thrown ( see
+// sc_thread_process::suspend_me() ).
+//==============================================================================
+class sc_throw_it_helper {
+ public:
+ virtual sc_throw_it_helper* clone() const = 0;
+ virtual void throw_it() = 0;
+ sc_throw_it_helper() {}
+ virtual ~sc_throw_it_helper() {}
+};
+
+template<typename EXCEPT>
+class sc_throw_it : public sc_throw_it_helper
+{
+ typedef sc_throw_it<EXCEPT> this_type;
+ public:
+ sc_throw_it( const EXCEPT& value ) : m_value(value) { }
+ virtual ~sc_throw_it() {}
+ virtual inline this_type* clone() const { return new this_type(m_value); }
+ virtual inline void throw_it() { throw m_value; }
+ protected:
+ EXCEPT m_value; // value to be thrown.
+};
+
+//==============================================================================
+// CLASS sc_process_b - USER INITIATED DYNAMIC PROCESS SUPPORT:
+//
+// This class implements the base class for a threaded process_base process
+// whose semantics are provided by the true virtual method semantics().
+// Classes derived from this one will provide a version of semantics which
+// implements the desired semantics. See the sc_spawn_xxx classes below.
+//
+// Notes:
+// (1) Object instances of this class maintain a reference count of
+// outstanding handles. When the handle count goes to zero the
+// object will be deleted.
+// (2) Descriptions of the methods and operators in this class appear with
+// their implementations.
+// (3) The m_sticky_reset field is used to handle synchronous resets that
+// are enabled via the sc_process_handle::sync_reset_on() method. These
+// resets are not generated by a signal, but rather are modal by
+// method call: sync_reset_on - sync_reset_off.
+//
+//==============================================================================
+class sc_process_b : public sc_object {
+ friend class sc_simcontext; // Allow static processes to have base.
+ friend class sc_cthread_process; // Child can access parent.
+ friend class sc_method_process; // Child can access parent.
+ friend class sc_process_handle; // Allow handles to modify ref. count.
+ friend class sc_thread_process; // Child can access parent.
+
+ friend class sc_object;
+ friend class sc_port_base;
+ friend class sc_runnable;
+ friend class sc_sensitive;
+ friend class sc_sensitive_pos;
+ friend class sc_sensitive_neg;
+ friend class sc_module;
+ friend class sc_report_handler;
+ friend class sc_reset;
+ friend class sc_reset_finder;
+ friend class sc_unwind_exception;
+
+ friend const char* sc_gen_unique_name( const char*, bool preserve_first );
+ friend sc_process_handle sc_get_current_process_handle();
+ friend void sc_thread_cor_fn( void* arg );
+ friend bool timed_out( sc_simcontext* );
+
+ public:
+ enum process_throw_type {
+ THROW_NONE = 0,
+ THROW_KILL,
+ THROW_USER,
+ THROW_ASYNC_RESET,
+ THROW_SYNC_RESET
+ };
+
+ enum process_state {
+ ps_bit_disabled = 1, // process is disabled.
+ ps_bit_ready_to_run = 2, // process is ready to run.
+ ps_bit_suspended = 4, // process is suspended.
+ ps_bit_zombie = 8, // process is a zombie.
+ ps_normal = 0 // must be zero.
+ };
+
+ enum reset_type { // types for sc_process_b::reset_process()
+ reset_asynchronous = 0, // asynchronous reset.
+ reset_synchronous_off, // turn off synchronous reset sticky bit.
+ reset_synchronous_on // turn on synchronous reset sticky bit.
+ };
+
+ enum trigger_t
+ {
+ STATIC,
+ EVENT,
+ OR_LIST,
+ AND_LIST,
+ TIMEOUT,
+ EVENT_TIMEOUT,
+ OR_LIST_TIMEOUT,
+ AND_LIST_TIMEOUT
+ };
+
+ public:
+ sc_process_b( const char* name_p, bool is_thread, bool free_host,
+ SC_ENTRY_FUNC method_p, sc_process_host* host_p,
+ const sc_spawn_options* opt_p );
+
+ protected:
+ // may not be deleted manually (called from destroy_process())
+ virtual ~sc_process_b();
+
+ public:
+ inline int current_state() { return m_state; }
+ bool dont_initialize() const { return m_dont_init; }
+ virtual void dont_initialize( bool dont );
+ std::string dump_state() const;
+ const ::std::vector<sc_object*>& get_child_objects() const;
+ inline sc_curr_proc_kind proc_kind() const;
+ sc_event& reset_event();
+ sc_event& terminated_event();
+
+ public:
+ static inline sc_process_handle last_created_process_handle();
+
+ protected:
+ virtual void add_child_object( sc_object* );
+ void add_static_event( const sc_event& );
+ bool dynamic() const { return m_dynamic_proc; }
+ const char* gen_unique_name( const char* basename_, bool preserve_first );
+ inline sc_report* get_last_report() { return m_last_report_p; }
+ inline bool is_disabled() const;
+ inline bool is_runnable() const;
+ static inline sc_process_b* last_created_process_base();
+ virtual bool remove_child_object( sc_object* );
+ void remove_dynamic_events( bool skip_timeout = false );
+ void remove_static_events();
+ inline void set_last_report( sc_report* last_p )
+ {
+ delete m_last_report_p;
+ m_last_report_p = last_p;
+ }
+ inline bool timed_out() const;
+ void report_error( const char* msgid, const char* msg = "" ) const;
+ void report_immediate_self_notification() const;
+
+ protected: // process control methods:
+ virtual void disable_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
+ void disconnect_process();
+ virtual void enable_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
+ inline void initially_in_reset( bool async );
+ inline bool is_unwinding() const;
+ inline bool start_unwinding();
+ inline bool clear_unwinding();
+ virtual void kill_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
+ void reset_changed( bool async, bool asserted );
+ void reset_process( reset_type rt,
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ virtual void resume_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
+ virtual void suspend_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
+ virtual void throw_user( const sc_throw_it_helper& helper,
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
+ virtual void throw_reset( bool async ) = 0;
+ virtual bool terminated() const;
+ void trigger_reset_event();
+
+ private:
+ void delete_process();
+ inline void reference_decrement();
+ inline void reference_increment();
+
+ protected:
+ inline void semantics();
+
+ // debugging stuff:
+
+ public:
+ const char* file;
+ int lineno;
+ int proc_id;
+
+ protected:
+ int m_active_areset_n; // number of aresets active.
+ int m_active_reset_n; // number of resets active.
+ bool m_dont_init; // true: no initialize call.
+ bool m_dynamic_proc; // true: after elaboration.
+ const sc_event* m_event_p; // Dynamic event waiting on.
+ int m_event_count; // number of events.
+ const sc_event_list* m_event_list_p; // event list waiting on.
+ sc_process_b* m_exist_p; // process existence link.
+ bool m_free_host; // free sc_semantic_host_p.
+ bool m_has_reset_signal; // has reset_signal_is.
+ bool m_has_stack; // true is stack present.
+ bool m_is_thread; // true if this is thread.
+ sc_report* m_last_report_p; // last report this process.
+ sc_name_gen* m_name_gen_p; // subprocess name generator
+ sc_curr_proc_kind m_process_kind; // type of process.
+ int m_references_n; // outstanding handles.
+ std::vector<sc_reset*> m_resets; // resets for process.
+ sc_event* m_reset_event_p; // reset event.
+ sc_event* m_resume_event_p; // resume event.
+ sc_process_b* m_runnable_p; // sc_runnable link
+ sc_process_host* m_semantics_host_p; // host for semantics.
+ SC_ENTRY_FUNC m_semantics_method_p; // method for semantics.
+ int m_state; // process state.
+ std::vector<const sc_event*> m_static_events; // static events waiting on.
+ bool m_sticky_reset; // see note 3 above.
+ sc_event* m_term_event_p; // terminated event.
+ sc_throw_it_helper* m_throw_helper_p; // what to throw.
+ process_throw_type m_throw_status; // exception throwing status
+ bool m_timed_out; // true if we timed out.
+ sc_event* m_timeout_event_p; // timeout event.
+ trigger_t m_trigger_type; // type of trigger using.
+ bool m_unwinding; // true if unwinding stack.
+
+ protected:
+ static sc_process_b* m_last_created_process_p; // Last process created.
+};
+
+typedef sc_process_b sc_process_b; // For compatibility.
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::XXXX_child_YYYYY"
+//
+// These methods provide child object support.
+//------------------------------------------------------------------------------
+inline void
+sc_process_b::add_child_object( sc_object* object_p )
+{
+ sc_object::add_child_object( object_p );
+ reference_increment();
+}
+
+inline bool
+sc_process_b::remove_child_object( sc_object* object_p )
+{
+ if ( sc_object::remove_child_object( object_p ) ) {
+ reference_decrement();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+inline const ::std::vector<sc_object*>&
+sc_process_b::get_child_objects() const
+{
+ return m_child_objects;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::initially_in_reset"
+//
+// This inline method is a callback to indicate that a reset is active at
+// start up. This is because the signal will have been initialized before
+// a reset linkage for it is set up, so we won't get a reset_changed()
+// callback.
+// async = true if this an asynchronous reset.
+//------------------------------------------------------------------------------
+inline void sc_process_b::initially_in_reset( bool async )
+{
+ if ( async )
+ m_active_areset_n++;
+ else
+ m_active_reset_n++;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::is_disabled"
+//
+// This method returns true if this process is disabled.
+//------------------------------------------------------------------------------
+inline bool sc_process_b::is_disabled() const
+{
+ return (m_state & ps_bit_disabled) ? true : false;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::is_runnable"
+//
+// This method returns true if this process is runnable. That is indicated
+// by a non-zero m_runnable_p field.
+//------------------------------------------------------------------------------
+inline bool sc_process_b::is_runnable() const
+{
+ return m_runnable_p != 0;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::is_unwinding"
+//
+// This method returns true if this process is unwinding from a kill or reset.
+//------------------------------------------------------------------------------
+inline bool sc_process_b::is_unwinding() const
+{
+ return m_unwinding;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::start_unwinding"
+//
+// This method flags that this object instance should start unwinding if the
+// current throw status requires an unwind.
+//
+// Result is true if the flag is set, false if the flag is already set.
+//------------------------------------------------------------------------------
+inline bool sc_process_b::start_unwinding()
+{
+ if ( !m_unwinding )
+ {
+ switch( m_throw_status )
+ {
+ case THROW_KILL:
+ case THROW_ASYNC_RESET:
+ case THROW_SYNC_RESET:
+ m_unwinding = true;
+ return true;
+ case THROW_USER:
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::clear_unwinding"
+//
+// This method clears this object instance's throw status and always returns
+// true.
+//------------------------------------------------------------------------------
+inline bool sc_process_b::clear_unwinding()
+{
+ m_unwinding = false;
+ return true;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::last_created_process_base"
+//
+// This virtual method returns the sc_process_b pointer for the last
+// created process. It is only used internally by the simulator.
+//------------------------------------------------------------------------------
+inline sc_process_b* sc_process_b::last_created_process_base()
+{
+ return m_last_created_process_p;
+}
+
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::proc_kind"
+//
+// This method returns the kind of this process.
+//------------------------------------------------------------------------------
+inline sc_curr_proc_kind sc_process_b::proc_kind() const
+{
+ return m_process_kind;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::reference_decrement"
+//
+// This inline method decrements the number of outstanding references to this
+// object instance. If the number of references goes to zero, this object
+// can be deleted in "sc_process_b::delete_process()".
+//------------------------------------------------------------------------------
+inline void sc_process_b::reference_decrement()
+{
+ m_references_n--;
+ if ( m_references_n == 0 ) delete_process();
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::reference_increment"
+//
+// This inline method increments the number of outstanding references to this
+// object instance.
+//------------------------------------------------------------------------------
+inline void sc_process_b::reference_increment()
+{
+ assert(m_references_n != 0);
+ m_references_n++;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_b::semantics"
+//
+// This inline method invokes the semantics for this object instance.
+// We check to see if we are initially in reset and then invoke the
+// process semantics.
+//
+// Notes:
+// (1) For a description of the process reset mechanism see the top of
+// the file sc_reset.cpp.
+//------------------------------------------------------------------------------
+struct scoped_flag
+{
+ scoped_flag( bool& b ) : ref(b){ ref = true; }
+ ~scoped_flag() { ref = false; }
+ bool& ref;
+};
+inline void sc_process_b::semantics()
+{
+
+ // within this function, the process has a stack associated
+
+ scoped_flag scoped_stack_flag( m_has_stack );
+
+ assert( m_process_kind != SC_NO_PROC_ );
+
+ // Determine the reset status of this object instance and potentially
+ // trigger its notify event:
+
+ // See if we need to trigger the notify event:
+
+ if ( m_reset_event_p &&
+ ( (m_throw_status == THROW_SYNC_RESET) ||
+ (m_throw_status == THROW_ASYNC_RESET) )
+ ) {
+ trigger_reset_event();
+ }
+
+ // Set the new reset status of this object based on the reset counts:
+
+ m_throw_status = m_active_areset_n ? THROW_ASYNC_RESET :
+ ( m_active_reset_n ? THROW_SYNC_RESET : THROW_NONE);
+
+ // Dispatch the actual semantics for the process:
+
+# ifndef SC_USE_MEMBER_FUNC_PTR
+ m_semantics_method_p->invoke( m_semantics_host_p );
+# else
+ (m_semantics_host_p->*m_semantics_method_p)();
+# endif
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::terminated"
+//
+// This inline method returns true if this object has terminated.
+//------------------------------------------------------------------------------
+inline bool sc_process_b::terminated() const
+{
+ return (m_state & ps_bit_zombie) != 0;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::timed_out"
+//
+// This inline method returns true if this object instance timed out.
+//------------------------------------------------------------------------------
+inline bool sc_process_b::timed_out() const
+{
+ return m_timed_out;
+}
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems, 12 Aug 05
+ Description of Modification: This is the rewrite of process support. It
+ contains some code from the original
+ sc_process.h by Stan Liao, and the now-defunct
+ sc_process_b.h by Stan Liao and Martin
+ Janssen, all of Synopsys, Inc., It also contains
+ code from the original sc_process_b.h by
+ Andy Goodrich of Forte Design Systems and
+ Bishnupriya Bhattacharya of Cadence Design
+ Systems.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_process.h,v $
+// Revision 1.36 2011/08/26 22:44:30 acg
+// Torsten Maehne: eliminate unused argument warning.
+//
+// Revision 1.35 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.34 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.33 2011/08/15 16:43:24 acg
+// Torsten Maehne: changes to remove unused argument warnings.
+//
+// Revision 1.32 2011/07/24 11:20:03 acg
+// Philipp A. Hartmann: process control error message improvements:
+// (1) Downgrade error to warning for re-kills of processes.
+// (2) Add process name to process messages.
+// (3) drop some superfluous colons in messages.
+//
+// Revision 1.31 2011/04/13 02:44:26 acg
+// Andy Goodrich: added m_unwinding flag in place of THROW_NOW because the
+// throw status will be set back to THROW_*_RESET if reset is active and
+// the check for an unwind being complete was expecting THROW_NONE as the
+// clearing of THROW_NOW.
+//
+// Revision 1.30 2011/04/11 22:07:27 acg
+// Andy Goodrich: check for reset event notification before resetting the
+// throw_status value.
+//
+// Revision 1.29 2011/04/10 22:17:36 acg
+// Andy Goodrich: added trigger_reset_event() to allow sc_process.h to
+// contain the run_process() inline method. sc_process.h cannot have
+// sc_simcontext information because of recursive includes.
+//
+// Revision 1.28 2011/04/08 22:34:06 acg
+// Andy Goodrich: moved the semantics() method to this file and made it
+// an inline method. Added reset processing to the semantics() method.
+//
+// Revision 1.27 2011/04/08 18:24:48 acg
+// Andy Goodrich: moved reset_changed() to .cpp since it needs visibility
+// to sc_simcontext.
+//
+// Revision 1.26 2011/04/01 21:24:57 acg
+// Andy Goodrich: removed unused code.
+//
+// Revision 1.25 2011/03/28 13:02:51 acg
+// Andy Goodrich: Changes for disable() interactions.
+//
+// Revision 1.24 2011/03/20 13:43:23 acg
+// Andy Goodrich: added async_signal_is() plus suspend() as a corner case.
+//
+// Revision 1.23 2011/03/12 21:07:51 acg
+// Andy Goodrich: changes to kernel generated event support.
+//
+// Revision 1.22 2011/03/08 20:49:31 acg
+// Andy Goodrich: implement coarse checking for synchronous reset - suspend
+// interaction.
+//
+// Revision 1.21 2011/03/07 17:38:43 acg
+// Andy Goodrich: tightening up of checks for undefined interaction between
+// synchronous reset and suspend.
+//
+// Revision 1.20 2011/03/06 19:57:11 acg
+// Andy Goodrich: refinements for the illegal suspend - synchronous reset
+// interaction.
+//
+// Revision 1.19 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.18 2011/02/19 08:30:53 acg
+// Andy Goodrich: Moved process queueing into trigger_static from
+// sc_event::notify.
+//
+// Revision 1.17 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.16 2011/02/18 20:10:44 acg
+// Philipp A. Hartmann: force return expression to be a bool to keep MSVC
+// happy.
+//
+// Revision 1.15 2011/02/17 19:52:45 acg
+// Andy Goodrich:
+// (1) Simplified process control usage.
+// (2) Changed dump_status() to dump_state() with new signature.
+//
+// Revision 1.14 2011/02/16 22:37:30 acg
+// Andy Goodrich: clean up to remove need for ps_disable_pending.
+//
+// Revision 1.13 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.12 2011/02/13 21:41:34 acg
+// Andy Goodrich: get the log messages for the previous check in correct.
+//
+// Revision 1.11 2011/02/13 21:32:24 acg
+// Andy Goodrich: moved sc_process_b::reset_process() implementation
+// from header to cpp file . Added dump_status() to print out the status of a
+// process.
+//
+// Revision 1.10 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.9 2011/02/04 15:27:36 acg
+// Andy Goodrich: changes for suspend-resume semantics.
+//
+// Revision 1.8 2011/02/01 21:06:12 acg
+// Andy Goodrich: new layout for the process_state enum.
+//
+// Revision 1.7 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.6 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.5 2011/01/18 20:10:45 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.4 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// 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.11 2006/05/08 17:58:10 acg
+// Andy Goodrich: added David Long's forward declarations for friend
+// functions, methods, and operators to keep the Microsoft compiler happy.
+//
+// Revision 1.10 2006/04/28 23:29:01 acg
+// Andy Goodrich: added an sc_core:: prefix to SC_FUNC_PTR in the
+// SC_MAKE_FUNC_PTR macro to allow its transpareuse outside of the sc_core
+// namespace.
+//
+// Revision 1.9 2006/04/28 21:52:57 acg
+// Andy Goodrich: changed SC_MAKE_FUNC_PTR to use a static cast to address
+// and AIX issue wrt sc_module's inherited classes.
+//
+// Revision 1.8 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.7 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.6 2006/03/13 20:26:50 acg
+// Andy Goodrich: Addition of forward class declarations, e.g.,
+// sc_reset, to keep gcc 4.x happy.
+//
+// Revision 1.5 2006/01/31 20:09:10 acg
+// Andy Goodrich: added explaination of static vs dynamic waits to
+// sc_process_b::trigger_static.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif // !defined(sc_process_h_INCLUDED)
diff --git a/ext/systemc/src/sysc/kernel/sc_process_handle.h b/ext/systemc/src/sysc/kernel/sc_process_handle.h
new file mode 100644
index 000000000..c219f5fad
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_process_handle.h
@@ -0,0 +1,608 @@
+/*****************************************************************************
+
+ 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_process_handle.h -- Process access support.
+
+ Original Author: Andy Goodrich, Forte Design Systems, 17 June 2003
+
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+// $Log: sc_process_handle.h,v $
+// Revision 1.21 2011/08/26 21:54:04 acg
+// Torsten Maehne: Simplify use of dynamic_cast<> for initializing m_target.
+//
+// Revision 1.20 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.
+//
+
+#if !defined(sc_process_handle_h_INCLUDED)
+#define sc_process_handle_h_INCLUDED
+
+#include "sysc/kernel/sc_module.h"
+
+namespace sc_core {
+
+// forward operator declarations:
+
+class sc_process_handle;
+bool
+operator == ( const sc_process_handle& left, const sc_process_handle& right );
+bool
+operator != ( const sc_process_handle& left, const sc_process_handle& right );
+bool
+operator < ( const sc_process_handle& left, const sc_process_handle& right );
+
+
+
+//=============================================================================
+// CLASS sc_process_handle
+//
+// This class provides access to an sc_process_b object instance in a
+// manner which allows some persistence after the deletion of the actual
+// process.
+//=============================================================================
+class sc_simcontext;
+class sc_process_handle {
+ typedef sc_process_handle this_type;
+
+ friend bool operator == ( const this_type& left, const this_type& right );
+ friend bool operator != ( const this_type& left, const this_type& right );
+ friend bool operator < ( const this_type& left, const this_type& right );
+ friend class sc_object;
+ friend class sc_join;
+ friend class sc_module;
+ friend class sc_reset;
+ friend class sc_sensitive;
+ friend class sc_sensitive_pos;
+ friend class sc_sensitive_neg;
+ friend class sc_thread_process;
+
+ public:
+ inline sc_process_handle();
+ inline explicit sc_process_handle( sc_object* object_p );
+ inline explicit sc_process_handle( sc_process_b* process_p );
+ inline sc_process_handle( const sc_process_handle& orig );
+ inline ~sc_process_handle();
+ inline sc_process_handle& operator = ( sc_process_handle src );
+ inline void swap( sc_process_handle& other );
+
+ public:
+ inline void disable(
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline bool dynamic() const;
+ inline void enable(
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline const std::vector<sc_event*>& get_child_events() const;
+ inline const std::vector<sc_object*>& get_child_objects() const;
+ inline sc_object* get_parent_object() const;
+ inline sc_object* get_process_object() const;
+ inline bool is_unwinding() const;
+ inline void kill(
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline const char* name() const;
+ inline sc_curr_proc_kind proc_kind() const;
+ inline void reset(
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline sc_event& reset_event() const;
+ inline void resume(
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline void suspend(
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline void sync_reset_off(
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline void sync_reset_on(
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline sc_event& terminated_event();
+ inline bool terminated() const;
+ template<typename EXCEPT>
+ inline void throw_it( const EXCEPT& exception,
+ sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS );
+ inline bool valid() const;
+
+ public: // implementation specific methods:
+ inline std::string dump_state() const;
+
+ protected:
+ inline bool dont_initialize() const
+ { return m_target_p ? m_target_p->dont_initialize() : false; }
+ inline void dont_initialize( bool dont );
+
+ public:
+ operator sc_process_b* ()
+ { return m_target_p; }
+ operator sc_cthread_handle ();
+ operator sc_method_handle ();
+ operator sc_thread_handle ();
+
+ protected:
+ sc_process_b* m_target_p; // Target for this object instance.
+
+ protected:
+ static std::vector<sc_event*> empty_event_vector; // If m_target_p == 0.
+ static std::vector<sc_object*> empty_object_vector; // If m_target_p == 0.
+ static sc_event non_event; // If m_target_p == 0.
+};
+
+inline bool operator == (
+ const sc_process_handle& left, const sc_process_handle& right )
+{
+ return (left.m_target_p != 0) && (right.m_target_p != 0) &&
+ (left.m_target_p == right.m_target_p);
+}
+
+inline bool operator != (
+ const sc_process_handle& left, const sc_process_handle& right )
+{
+ return (left.m_target_p == 0) || (right.m_target_p == 0) ||
+ (left.m_target_p != right.m_target_p);
+}
+
+inline bool operator < (
+ const sc_process_handle& left, const sc_process_handle& right )
+{
+ return left.m_target_p < right.m_target_p;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::sc_process_handle - non-pointer constructor"
+//
+// This version of the object instance constructor for this class creates
+// an object instance whose target needs to be supplied via an assignment.
+//------------------------------------------------------------------------------
+inline sc_process_handle::sc_process_handle() : m_target_p(0)
+{
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::sc_process_handle - pointer constructor"
+//
+// This version of the object instance constructor for this class creates
+// an object instance whose target is the supplied sc_object instance.
+// The supplied sc_object must in fact be an sc_process_b instance.
+// object_p -> sc_object instance this is handle for.
+//------------------------------------------------------------------------------
+inline sc_process_handle::sc_process_handle( sc_object* object_p ) :
+ m_target_p(DCAST<sc_process_b*>(object_p))
+{
+ if ( m_target_p ) m_target_p->reference_increment();
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::sc_process_handle - pointer constructor"
+//
+// This version of the object instance constructor for this class creates
+// an object instance whose target is the supplied sc_process_b instance.
+// This saves a dynamic cast compared to the sc_object* case.
+// process_p -> process instance this is handle for.
+//------------------------------------------------------------------------------
+inline sc_process_handle::sc_process_handle( sc_process_b* process_p ) :
+ m_target_p(process_p)
+{
+ if ( m_target_p ) m_target_p->reference_increment();
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::sc_process_handle - copy constructor"
+//
+// This version of the object instance constructor for this class provides
+// the copy constructor for the class. It clones the supplied original
+// handle and increments the references to its target.
+// orig = sc_process_handle object instance to be copied from.
+//------------------------------------------------------------------------------
+inline sc_process_handle::sc_process_handle( const sc_process_handle& orig ) :
+ m_target_p(orig.m_target_p)
+{
+ if ( m_target_p ) m_target_p->reference_increment();
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::operator ="
+//
+// This assignment operator signature is call by value rather than reference.
+// This means that an sc_process_handle instance will be created and the
+// target for that instance will be incremented before the assignment is done.
+// The assignment is done using the swap() method, which simply swaps the
+// targets of 'orig' and this object instance. We don't need to increment
+// the reference count for our new target since that was done when 'orig'
+// was created. Our old target's reference count will be decremented when
+// 'orig' is deleted.
+// orig = sc_process_handle object instance to be copied from.
+// Result is a reference for this object instance.
+//------------------------------------------------------------------------------
+inline sc_process_handle&
+sc_process_handle::operator = ( sc_process_handle orig )
+{
+ swap( orig );
+ return *this;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::~sc_process_handle"
+//
+// This is the object instance destructor for this class. It decrements
+// the reference count for its target.
+//------------------------------------------------------------------------------
+inline sc_process_handle::~sc_process_handle()
+{
+ if ( m_target_p ) m_target_p->reference_decrement();
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::inline methods"
+//
+// These are short inline methods.
+//------------------------------------------------------------------------------
+
+// disable this object instance's target.
+
+inline void sc_process_handle::disable(sc_descendant_inclusion_info descendants)
+{
+ if ( m_target_p )
+ m_target_p->disable_process(descendants);
+ else
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "disable()");
+}
+
+// call dont_initialize() on this object instance's target.
+
+inline void sc_process_handle::dont_initialize( bool dont )
+{
+ if ( m_target_p )
+ m_target_p->dont_initialize( dont );
+ else
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "dont_initialize()");
+}
+
+// dump the status of this object instance's target:
+
+inline std::string sc_process_handle::dump_state() const
+{
+ return m_target_p ? m_target_p->dump_state() : std::string("NO TARGET");
+}
+
+// return whether this object instance's target is dynamic or not.
+
+inline bool sc_process_handle::dynamic() const
+{
+ return m_target_p ? m_target_p->dynamic() : false;
+}
+
+// enable this object instance's target.
+
+inline void sc_process_handle::enable(sc_descendant_inclusion_info descendants)
+{
+ if ( m_target_p )
+ m_target_p->enable_process(descendants);
+ else
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "enable()");
+}
+
+// return the child objects for this object instance's target.
+
+inline
+const std::vector<sc_event*>& sc_process_handle::get_child_events() const
+{
+ return m_target_p ? m_target_p->get_child_events() : empty_event_vector;
+}
+
+// return the child objects for this object instance's target.
+
+inline
+const std::vector<sc_object*>& sc_process_handle::get_child_objects() const
+{
+ return m_target_p ? m_target_p->get_child_objects() : empty_object_vector;
+}
+
+// return the parent object for this object instance's target.
+
+inline sc_object* sc_process_handle::get_parent_object() const
+{
+ return m_target_p ? m_target_p->get_parent_object() : NULL;
+}
+
+// return this object instance's target.
+
+inline sc_object* sc_process_handle::get_process_object() const
+{
+ return m_target_p;
+}
+
+// return whether this object instance is unwinding or not.
+
+inline bool sc_process_handle::is_unwinding() const
+{
+ if ( m_target_p )
+ return m_target_p->is_unwinding();
+ else {
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "is_unwinding()");
+ return false;
+ }
+}
+
+// kill this object instance's target.
+
+inline void sc_process_handle::kill( sc_descendant_inclusion_info descendants )
+{
+ if ( m_target_p )
+ m_target_p->kill_process( descendants );
+ else
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "kill()");
+}
+
+// return the name of this object instance's target.
+
+inline const char* sc_process_handle::name() const
+{
+ return m_target_p ? m_target_p->name() : "";
+}
+
+// return the process kind for this object instance's target.
+
+inline sc_curr_proc_kind sc_process_handle::proc_kind() const
+{
+ return m_target_p ? m_target_p->proc_kind() : SC_NO_PROC_;
+}
+
+// reset this object instance's target.
+
+inline void sc_process_handle::reset( sc_descendant_inclusion_info descendants )
+{
+ if ( m_target_p )
+ m_target_p->reset_process( sc_process_b::reset_asynchronous,
+ descendants );
+ else
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "reset()");
+}
+
+// return the reset event for this object instance's target.
+
+inline sc_event& sc_process_handle::reset_event() const
+{
+ if ( m_target_p )
+ return m_target_p->reset_event();
+ else
+ {
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "reset()");
+ return sc_process_handle::non_event;
+ }
+}
+
+// resume this object instance's target.
+
+inline void sc_process_handle::resume(sc_descendant_inclusion_info descendants)
+{
+ if ( m_target_p )
+ m_target_p->resume_process(descendants);
+ else
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "resume()");
+}
+
+// suspend this object instance's target.
+
+inline void sc_process_handle::suspend(sc_descendant_inclusion_info descendants)
+{
+ if ( m_target_p )
+ m_target_p->suspend_process(descendants);
+ else
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "suspend()");
+}
+
+// swap targets of this process handle with the supplied one.
+
+inline void sc_process_handle::swap( sc_process_handle& other )
+{
+ sc_process_b* tmp = m_target_p;
+ m_target_p = other.m_target_p;
+ other.m_target_p = tmp;
+}
+
+// turn sync_reset off for this object instance's target.
+
+inline void sc_process_handle::sync_reset_off(
+ sc_descendant_inclusion_info descendants)
+{
+ if ( m_target_p )
+ m_target_p->reset_process( sc_process_b::reset_synchronous_off,
+ descendants);
+ else
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "sync_reset_off()");
+}
+
+// turn sync_reset on for this object instance's target.
+
+inline void sc_process_handle::sync_reset_on(
+ sc_descendant_inclusion_info descendants)
+{
+ if ( m_target_p )
+ {
+ m_target_p->reset_process(sc_process_b::reset_synchronous_on,
+ descendants);
+ }
+ else
+ {
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "sync_reset_on()");
+ }
+}
+
+// terminate this object instance's target.
+
+inline bool sc_process_handle::terminated() const
+{
+ return m_target_p ? m_target_p->terminated() : false;
+}
+
+// return the termination event for this object instance's target.
+
+inline sc_event& sc_process_handle::terminated_event()
+{
+ if ( m_target_p )
+ return m_target_p->terminated_event();
+ else
+ {
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "terminated_event()");
+ return sc_process_handle::non_event;
+ }
+}
+
+// return true if this object instance has a target, false it not.
+
+inline bool sc_process_handle::valid() const
+{
+ return m_target_p ? true : false;
+}
+
+//------------------------------------------------------------------------------
+//"sc_process_handle::sc_throw_it"
+//
+// This method throws the supplied exception to the process whose handle this
+// object instance is, and optionally to the process' descendants. Once the
+// exception is thrown the currently executed process will suspend to allow
+// the exception to be propagated. Once the propagation has occurred the
+// current process will be resumed.
+//
+// Notes:
+// (1) We allocate the helper function on the stack, see the description of
+// sc_throw_it<EXCEPT>, in sc_process.h, for why.
+//
+// Arguments:
+// exception = exception to be thrown
+// descendants = indication of whether descendant processes should also
+// receive the throw.
+//------------------------------------------------------------------------------
+template<typename EXCEPT>
+inline void sc_process_handle::throw_it( const EXCEPT& exception,
+ sc_descendant_inclusion_info descendants)
+{
+ sc_throw_it<EXCEPT> helper(exception); // helper to throw the exception.
+
+ if ( !m_target_p )
+ {
+ SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "throw_it()");
+ return;
+ }
+ m_target_p->throw_user(helper, descendants);
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_process_b::last_created_process_handle"
+//
+// This method returns the kind of this process.
+//------------------------------------------------------------------------------
+inline sc_process_handle sc_process_b::last_created_process_handle()
+{
+ return sc_process_handle(m_last_created_process_p);
+}
+
+inline sc_process_handle sc_get_last_created_process_handle()
+{
+ return sc_process_b::last_created_process_handle();
+}
+
+} // namespace sc_core
+
+// Revision 1.19 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.18 2011/04/01 22:08:26 acg
+// Andy Goodrich: remove unused variable.
+//
+// Revision 1.17 2011/03/12 21:07:51 acg
+// Andy Goodrich: changes to kernel generated event support.
+//
+// Revision 1.16 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.15 2011/02/17 19:53:03 acg
+// Andy Goodrich: changed dump_status() to dump_state() with new signature.
+//
+// Revision 1.14 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.13 2011/02/13 21:33:30 acg
+// Andy Goodrich: added dump_status() to allow the dumping of the status
+// of a process handle's target.
+//
+// Revision 1.12 2011/02/01 23:01:53 acg
+// Andy Goodrich: removed dead code.
+//
+// Revision 1.11 2011/02/01 21:07:36 acg
+// Andy Goodrich: defering of run queue manipulations to the
+// sc_thread_process::throw_it() method.
+//
+// Revision 1.10 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.9 2011/01/20 16:52:20 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.8 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.7 2011/01/18 20:10:45 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.6 2010/07/30 05:21:22 acg
+// Andy Goodrich: release 2.3 fixes.
+//
+// Revision 1.5 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.4 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.3 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2007/09/20 20:32:35 acg
+// Andy Goodrich: changes to the semantics of throw_it() to match the
+// specification. A call to throw_it() will immediately suspend the calling
+// thread until all the throwees have executed. At that point the calling
+// thread will be restarted before the execution of any other threads.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.7 2006/05/08 17:58:24 acg
+// Andy Goodrich: added David Long's forward declarations for friend
+// functions, methods, and operators to keep the Microsoft compiler happy.
+//
+// Revision 1.6 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.5 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif // !defined(sc_spawn_h_INCLUDED)
diff --git a/ext/systemc/src/sysc/kernel/sc_reset.cpp b/ext/systemc/src/sysc/kernel/sc_reset.cpp
new file mode 100644
index 000000000..2e4bc6c6e
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_reset.cpp
@@ -0,0 +1,440 @@
+/*****************************************************************************
+
+ 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_reset.cpp -- Support for reset.
+
+ Original Author: Andy Goodrich, Forte Design Systems
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_reset.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/communication/sc_signal.h"
+#include "sysc/communication/sc_signal_ports.h"
+
+
+// THE SYSTEMC PROOF OF CONCEPT SIMULATOR RESET SIGNAL IMPLEMENTATION:
+//
+// (1) An instance of the sc_reset class is attached to each sc_signal<bool>
+// that is used as a reset signal.
+//
+// (2) Each process that is senstive to a reset signal will be registered in the
+// sc_reset class attached to that reset signal.
+//
+// (3) When a change in the value of a reset signal occurs it invokes the
+// notify_processes() method of its sc_reset object instance. The
+// notify_processes() method will call the reset_changed() method of each
+// process that is registered with it to inform the process that
+// state of the reset signal has changed.
+//
+// (4) A process may have multiple reset signals, so counters are kept for the
+// number of active asynchronous, and synchronous, reset signals that are
+// active. Those counters are incremented and decremented in the process'
+// reset_changed() method.
+//
+// (5) When a process' semantics() method is called the current reset state is
+// checked, and a reset sequence is initiated if the process is in reset.
+// This will occur every time an SC_METHOD is dispatched. SC_CTHREAD and
+// and SC_THREAD instances, only go through the semantics() method they
+// initially start up. So the reset check is duplicated in the suspend_me()
+// method, the tail of which will execute each time the thread is
+// dispatched.
+
+namespace sc_core {
+
+class sc_reset_finder;
+static sc_reset_finder* reset_finder_q=0; // Q of reset finders to reconcile.
+
+//==============================================================================
+// sc_reset_finder - place holder class for a port reset signal until it is
+// bound and an interface class is available. When the port
+// has been bound the information in this class will be used
+// to initialize its sc_reset object instance.
+//==============================================================================
+class sc_reset_finder {
+ friend class sc_reset;
+ public:
+ sc_reset_finder( bool async, const sc_in<bool>* port_p, bool level,
+ sc_process_b* target_p);
+ sc_reset_finder( bool async, const sc_inout<bool>* port_p, bool level,
+ sc_process_b* target_p);
+ sc_reset_finder( bool async, const sc_out<bool>* port_p, bool level,
+ sc_process_b* target_p);
+
+ protected:
+ bool m_async; // True if asynchronous reset.
+ bool m_level; // Level for reset.
+ sc_reset_finder* m_next_p; // Next reset finder in list.
+ const sc_in<bool>* m_in_p; // Port for which reset is needed.
+ const sc_inout<bool>* m_inout_p; // Port for which reset is needed.
+ const sc_out<bool>* m_out_p; // Port for which reset is needed.
+ sc_process_b* m_target_p; // Process to reset.
+
+ private: // disabled
+ sc_reset_finder( const sc_reset_finder& );
+ const sc_reset_finder& operator = ( const sc_reset_finder& );
+};
+
+inline sc_reset_finder::sc_reset_finder(
+ bool async, const sc_in<bool>* port_p, bool level, sc_process_b* target_p) :
+ m_async(async), m_level(level), m_next_p(0), m_in_p(port_p), m_inout_p(0),
+ m_out_p(0), m_target_p(target_p)
+{
+ m_next_p = reset_finder_q;
+ reset_finder_q = this;
+}
+
+inline sc_reset_finder::sc_reset_finder(
+ bool async, const sc_inout<bool>* port_p, bool level, sc_process_b* target_p
+) :
+ m_async(async), m_level(level), m_next_p(0), m_in_p(0), m_inout_p(port_p),
+ m_out_p(0), m_target_p(target_p)
+{
+ m_next_p = reset_finder_q;
+ reset_finder_q = this;
+}
+
+inline sc_reset_finder::sc_reset_finder(
+ bool async, const sc_out<bool>* port_p, bool level, sc_process_b* target_p
+) :
+ m_async(async), m_level(level), m_next_p(0), m_in_p(0), m_inout_p(0),
+ m_out_p(port_p), m_target_p(target_p)
+{
+ m_next_p = reset_finder_q;
+ reset_finder_q = this;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_reset::notify_processes"
+//
+// Notify processes that there is a change in the reset signal value.
+//------------------------------------------------------------------------------
+void sc_reset::notify_processes()
+{
+ bool active; // true if reset is active.
+ sc_reset_target* entry_p; // reset entry processing.
+ std::vector<sc_reset_target>::size_type process_i; // index of process resetting.
+ std::vector<sc_reset_target>::size_type process_n; // # of processes to reset.
+ bool value; // value of our signal.
+
+ value = m_iface_p->read();
+ process_n = m_targets.size();
+ for ( process_i = 0; process_i < process_n; process_i++ )
+ {
+ entry_p = &m_targets[process_i];
+ active = ( entry_p->m_level == value );
+ entry_p->m_process_p->reset_changed( entry_p->m_async, active );
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_reset::reconcile_resets"
+//
+// This static method processes the sc_reset_finders to establish the actual
+// reset connections.
+//
+// Notes:
+// (1) If reset is asserted we tell the process that it is in reset.
+//------------------------------------------------------------------------------
+void sc_reset::reconcile_resets()
+{
+ const sc_signal_in_if<bool>* iface_p; // Interface to reset signal.
+ sc_reset_finder* next_p; // Next finder to process.
+ sc_reset_finder* now_p; // Finder currently processing.
+ sc_reset_target reset_target; // Target's reset entry.
+ sc_reset* reset_p; // Reset object to use.
+
+ for ( now_p = reset_finder_q; now_p; now_p = next_p )
+ {
+ next_p = now_p->m_next_p;
+ if ( now_p->m_in_p )
+ {
+ iface_p = DCAST<const sc_signal_in_if<bool>*>(
+ now_p->m_in_p->get_interface());
+ }
+ else if ( now_p->m_inout_p )
+ {
+ iface_p = DCAST<const sc_signal_in_if<bool>*>(
+ now_p->m_inout_p->get_interface());
+ }
+ else
+ {
+ iface_p = DCAST<const sc_signal_in_if<bool>*>(
+ now_p->m_out_p->get_interface());
+ }
+ assert( iface_p != 0 );
+ reset_p = iface_p->is_reset();
+ now_p->m_target_p->m_resets.push_back(reset_p);
+ reset_target.m_async = now_p->m_async;
+ reset_target.m_level = now_p->m_level;
+ reset_target.m_process_p = now_p->m_target_p;
+ reset_p->m_targets.push_back(reset_target);
+ if ( iface_p->read() == now_p->m_level ) // see note 1 above
+ now_p->m_target_p->initially_in_reset( now_p->m_async );
+ delete now_p;
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_reset::remove_process"
+//
+// This method removes the supplied process from the list of processes that
+// should be notified when there is a change in the value of the reset signal.
+//
+// Arguments:
+// process_p -> process to be removed.
+//------------------------------------------------------------------------------
+void sc_reset::remove_process( sc_process_b* process_p )
+{
+ int process_i; // Index of process resetting.
+ int process_n; // # of processes to reset.
+
+ process_n = m_targets.size();
+ for ( process_i = 0; process_i < process_n; )
+ {
+ if ( m_targets[process_i].m_process_p == process_p )
+ {
+ m_targets[process_i] = m_targets[process_n-1];
+ process_n--;
+ m_targets.resize(process_n);
+ }
+ else
+ {
+ process_i++;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_reset::reset_signal_is - ports"
+//
+// These overloads of the reset_signal_is() method will register the active
+// process with the sc_reset object instance associated with the supplied port.
+// If the port does not yet have a pointer to its sc_signal<bool> instance it
+// will create an sc_reset_finder class object instance that will be used
+// to set the process' reset information when the port has been bound.
+//
+// Arguments:
+// async = true if the reset signal is asynchronous, false if not.
+// port = port for sc_signal<bool> that will provide the reset signal.
+// level = level at which reset is active, either true or false.
+//------------------------------------------------------------------------------
+void sc_reset::reset_signal_is( bool async, const sc_in<bool>& port, bool level)
+{
+ const sc_signal_in_if<bool>* iface_p;
+ sc_process_b* process_p;
+
+ process_p = (sc_process_b*)sc_get_current_process_handle();
+ assert( process_p );
+ process_p->m_has_reset_signal = true;
+ switch ( process_p->proc_kind() )
+ {
+ case SC_THREAD_PROC_:
+ case SC_METHOD_PROC_:
+ case SC_CTHREAD_PROC_:
+ iface_p = DCAST<const sc_signal_in_if<bool>*>(port.get_interface());
+ if ( iface_p )
+ reset_signal_is( async, *iface_p, level );
+ else
+ new sc_reset_finder( async, &port, level, process_p );
+ break;
+ default:
+ SC_REPORT_ERROR(SC_ID_UNKNOWN_PROCESS_TYPE_, process_p->name());
+ break;
+ }
+}
+
+void sc_reset::reset_signal_is(
+ bool async, const sc_inout<bool>& port, bool level )
+{
+ const sc_signal_in_if<bool>* iface_p;
+ sc_process_b* process_p;
+
+ process_p = (sc_process_b*)sc_get_current_process_handle();
+ assert( process_p );
+ process_p->m_has_reset_signal = true;
+ switch ( process_p->proc_kind() )
+ {
+ case SC_THREAD_PROC_:
+ case SC_METHOD_PROC_:
+ case SC_CTHREAD_PROC_:
+ iface_p = DCAST<const sc_signal_in_if<bool>*>(port.get_interface());
+ if ( iface_p )
+ reset_signal_is( async, *iface_p, level );
+ else
+ new sc_reset_finder( async, &port, level, process_p );
+ break;
+ default:
+ SC_REPORT_ERROR(SC_ID_UNKNOWN_PROCESS_TYPE_, process_p->name());
+ break;
+ }
+}
+
+void sc_reset::reset_signal_is(
+ bool async, const sc_out<bool>& port, bool level )
+{
+ const sc_signal_in_if<bool>* iface_p;
+ sc_process_b* process_p;
+
+ process_p = (sc_process_b*)sc_get_current_process_handle();
+ assert( process_p );
+ process_p->m_has_reset_signal = true;
+ switch ( process_p->proc_kind() )
+ {
+ case SC_THREAD_PROC_:
+ case SC_METHOD_PROC_:
+ case SC_CTHREAD_PROC_:
+ iface_p = DCAST<const sc_signal_in_if<bool>*>(port.get_interface());
+ if ( iface_p )
+ reset_signal_is( async, *iface_p, level );
+ else
+ new sc_reset_finder( async, &port, level, process_p );
+ break;
+ default:
+ SC_REPORT_ERROR(SC_ID_UNKNOWN_PROCESS_TYPE_, process_p->name());
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_reset::reset_signal_is"
+//
+// This static method will register the active process instance as being
+// reset by the sc_signal<bool> whose interface has been supplied. If no
+// sc_reset object instance has been attached to the sc_signal<bool> yet, it
+// will be created and attached. The active process instance is pushed into
+// the list of processes that the sc_reset object instance should notify if
+// the value of the reset signal changes.
+//
+// Arguments:
+// async = true if the reset signal is asynchronous, false if not.
+// iface = interface for the reset signal.
+// level = is the level at which reset is active, either true or false.
+// Notes:
+// (1) If reset is asserted we tell the process that it is in reset
+// initially.
+//------------------------------------------------------------------------------
+void sc_reset::reset_signal_is(
+ bool async, const sc_signal_in_if<bool>& iface, bool level )
+{
+ sc_process_b* process_p; // process adding reset for.
+ sc_reset_target reset_target; // entry to build for the process.
+ sc_reset* reset_p; // reset object.
+
+ process_p = sc_process_b::last_created_process_base();
+ assert( process_p );
+ process_p->m_has_reset_signal = true;
+ switch ( process_p->proc_kind() )
+ {
+ case SC_METHOD_PROC_:
+ case SC_CTHREAD_PROC_:
+ case SC_THREAD_PROC_:
+ reset_p = iface.is_reset();
+ process_p->m_resets.push_back(reset_p);
+ reset_target.m_async = async;
+ reset_target.m_level = level;
+ reset_target.m_process_p = process_p;
+ reset_p->m_targets.push_back(reset_target);
+ if ( iface.read() == level ) process_p->initially_in_reset( async );
+ break;
+ default:
+ SC_REPORT_ERROR(SC_ID_UNKNOWN_PROCESS_TYPE_, process_p->name());
+ break;
+ }
+}
+
+} // namespace sc_core
+
+// $Log: sc_reset.cpp,v $
+// Revision 1.16 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.15 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.14 2011/04/08 22:37:34 acg
+// Andy Goodrich: documentation of the reset mechanism and additional
+// documentation of methods. Removal of check for SC_METHODs in
+// sc_reset_signal_is() that should not have been there.
+//
+// Revision 1.13 2011/03/20 15:13:01 acg
+// Andy Goodrich: set the reset flag for async_reset_signal_is to catch
+// the suspend() corner case.
+//
+// Revision 1.12 2011/03/20 13:43:23 acg
+// Andy Goodrich: added async_signal_is() plus suspend() as a corner case.
+//
+// Revision 1.11 2011/03/06 19:57:11 acg
+// Andy Goodrich: refinements for the illegal suspend - synchronous reset
+// interaction.
+//
+// Revision 1.10 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.9 2011/02/13 21:47:37 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.8 2011/02/01 21:08:26 acg
+// Andy Goodrich: new multiple reset support.
+//
+// Revision 1.7 2011/01/06 18:04:38 acg
+// Andy Goodrich: removed commented out code.
+//
+// Revision 1.6 2010/12/07 20:09:13 acg
+// Andy Goodrich: removed sc_signal overloads since already have sc_signal_in_if overloads.
+//
+// Revision 1.5 2010/11/20 17:10:56 acg
+// Andy Goodrich: reset processing changes for new IEEE 1666 standard.
+//
+// Revision 1.4 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.3 2009/03/12 22:59:58 acg
+// Andy Goodrich: updates for 2.4 stuff.
+//
+// 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.7 2006/12/02 20:58:19 acg
+// Andy Goodrich: updates from 2.2 for IEEE 1666 support.
+//
+// Revision 1.5 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_reset.h b/ext/systemc/src/sysc/kernel/sc_reset.h
new file mode 100644
index 000000000..f0992bb16
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_reset.h
@@ -0,0 +1,164 @@
+/*****************************************************************************
+
+ 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_reset.h -- Process reset support.
+
+ Original Author: Andy Goodrich, Forte Design Systems, 17 June 2003
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#if !defined(sc_reset_h_INCLUDED)
+#define sc_reset_h_INCLUDED
+
+#include "sysc/communication/sc_writer_policy.h"
+
+namespace sc_core {
+
+// FORWARD CLASS REFERENCES:
+
+template<typename DATA> class sc_signal_in_if;
+template<typename IF, sc_writer_policy POL> class sc_signal;
+template<typename DATA> class sc_in;
+template<typename DATA> class sc_inout;
+template<typename DATA> class sc_out;
+template<typename SOURCE> class sc_spawn_reset;
+class sc_reset;
+class sc_process_b;
+
+//==============================================================================
+// CLASS sc_reset_target - RESET ENTRY FOR AN sc_process_b TARGET
+//
+// This class describes a reset condition associated with an sc_process_b
+// instance.
+//==============================================================================
+class sc_reset_target {
+ public:
+ bool m_async; // true asynchronous reset, false synchronous.
+ bool m_level; // level for reset.
+ sc_process_b* m_process_p; // process this reset entry is for.
+};
+
+inline std::ostream& operator << ( std::ostream& os,
+ const sc_reset_target& target )
+{
+ os << "[";
+ os << target.m_async << ",";
+ os << target.m_level << ",";
+ os << target.m_process_p << ",";
+ return os;
+}
+
+//==============================================================================
+// CLASS sc_reset - RESET INFORMATION FOR A RESET SIGNAL
+//
+// See the top of sc_reset.cpp for an explaination of how the reset mechanism
+// is implemented.
+//==============================================================================
+class sc_reset {
+ friend class sc_cthread_process;
+ friend class sc_method_process;
+ friend class sc_module;
+ friend class sc_process_b;
+ friend class sc_signal<bool, SC_ONE_WRITER>;
+ friend class sc_signal<bool, SC_MANY_WRITERS>;
+ friend class sc_signal<bool, SC_UNCHECKED_WRITERS>;
+ friend class sc_simcontext;
+ template<typename SOURCE> friend class sc_spawn_reset;
+ friend class sc_thread_process;
+
+ protected:
+ static void reconcile_resets();
+ static void
+ reset_signal_is(bool async, const sc_signal_in_if<bool>& iface,
+ bool level);
+ static void
+ reset_signal_is( bool async, const sc_in<bool>& iface, bool level);
+ static void
+ reset_signal_is( bool async, const sc_inout<bool>& iface, bool level);
+ static void
+ reset_signal_is( bool async, const sc_out<bool>& iface, bool level);
+
+ protected:
+ sc_reset( const sc_signal_in_if<bool>* iface_p ) :
+ m_iface_p(iface_p), m_targets() {}
+ void notify_processes();
+ void remove_process( sc_process_b* );
+
+ protected:
+ const sc_signal_in_if<bool>* m_iface_p; // Interface to read.
+ std::vector<sc_reset_target> m_targets; // List of processes to reset.
+
+ private: // disabled
+ sc_reset( const sc_reset& );
+ const sc_reset& operator = ( const sc_reset& );
+};
+
+// $Log: sc_reset.h,v $
+// Revision 1.11 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.10 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.9 2011/04/08 22:38:30 acg
+// Andy Goodrich: added comment pointing to the description of how the
+// reset mechanism works that is in sc_reset.cpp.
+//
+// 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/06 18:00:32 acg
+// Andy Goodrich: Removed commented out code.
+//
+// Revision 1.5 2010/12/07 20:09:14 acg
+// Andy Goodrich: removed sc_signal signatures since already have sc_signal_in_if signatures.
+//
+// Revision 1.4 2010/11/20 17:10:57 acg
+// Andy Goodrich: reset processing changes for new IEEE 1666 standard.
+//
+// Revision 1.3 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// 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.6 2006/12/02 20:58:19 acg
+// Andy Goodrich: updates from 2.2 for IEEE 1666 support.
+//
+// Revision 1.4 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+} // namespace sc_core
+
+#endif // !defined(sc_reset_h_INCLUDED)
diff --git a/ext/systemc/src/sysc/kernel/sc_runnable.h b/ext/systemc/src/sysc/kernel/sc_runnable.h
new file mode 100644
index 000000000..028a9b311
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_runnable.h
@@ -0,0 +1,144 @@
+/*****************************************************************************
+
+ 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_runnable.h --
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_RUNNABLE_H
+#define SC_RUNNABLE_H
+
+
+#include "sysc/kernel/sc_process.h"
+
+namespace sc_core {
+
+//=============================================================================
+// CLASS : sc_runnable
+//
+// Class that manages the ready-to-run queues.
+//=============================================================================
+
+class sc_runnable
+{
+
+ public:
+ sc_runnable();
+ ~sc_runnable();
+
+ inline void init();
+ inline void toggle_methods();
+ inline void toggle_threads();
+
+ inline void remove_method( sc_method_handle );
+ inline void remove_thread( sc_thread_handle );
+
+ inline void execute_method_next( sc_method_handle );
+ inline void execute_thread_next( sc_thread_handle );
+
+ inline void push_back_method( sc_method_handle );
+ inline void push_back_thread( sc_thread_handle );
+ inline void push_front_method( sc_method_handle );
+ inline void push_front_thread( sc_thread_handle );
+
+ inline bool is_initialized() const;
+ inline bool is_empty() const;
+
+ inline sc_method_handle pop_method();
+ inline sc_thread_handle pop_thread();
+
+ public: // diagnostics:
+ void dump() const;
+
+ private:
+ sc_method_handle m_methods_push_head;
+ sc_method_handle m_methods_push_tail;
+ sc_method_handle m_methods_pop;
+ sc_thread_handle m_threads_push_head;
+ sc_thread_handle m_threads_push_tail;
+ sc_thread_handle m_threads_pop;
+
+ private:
+ // disabled
+ sc_runnable( const sc_runnable& );
+ sc_runnable& operator = ( const sc_runnable& );
+};
+
+} // namespace sc_core
+
+#endif
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Andy Goodrich, 30 June 2003, Forte Design Systems
+ Description of Modification: Total rewrite using linked list rather than
+ fixed vector.
+
+
+ Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+ Description of Modification: Add tail pointers for m_methods_push and
+ m_threads_push to maintain the same scheduler
+ ordering as 2.0.1
+
+ *****************************************************************************/
+
+// $Log: sc_runnable.h,v $
+// Revision 1.9 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.8 2011/04/08 18:26:07 acg
+// Andy Goodrich: added execute_method_next() to handle method dispatch
+// for asynchronous notifications that occur outside the evaluation phase.
+//
+// Revision 1.7 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.6 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.5 2011/02/02 06:37:03 acg
+// Andy Goodrich: removed toggle() method since it is no longer used.
+//
+// Revision 1.4 2011/02/01 21:09:13 acg
+// Andy Goodrich: addition of toggle_methods() and toggle_threads() calls.
+//
+// Revision 1.3 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// 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.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_runnable_int.h b/ext/systemc/src/sysc/kernel/sc_runnable_int.h
new file mode 100644
index 000000000..510e93758
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_runnable_int.h
@@ -0,0 +1,574 @@
+/*****************************************************************************
+
+ 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_runnable_int.h -- For inline definitions of some utility functions.
+ DO NOT EXPORT THIS INCLUDE FILE. Include this file
+ after "sc_process_int.h" so that we can get the base
+ class right.
+
+ Original Author: Bishnupriya Bhattacharya , Cadence Design, 28th July, 2003
+
+ CHANGE LOG AT THE END OF THE FILE
+ ******************************************************************************/
+
+#ifndef SC_RUNNABLE_INT_H
+#define SC_RUNNABLE_INT_H
+
+
+#include "sysc/kernel/sc_runnable.h"
+#include "sysc/kernel/sc_method_process.h"
+#include "sysc/kernel/sc_thread_process.h"
+
+// DEBUGGING MACROS:
+//
+// DEBUG_MSG(NAME,P,MSG)
+// MSG = message to print
+// NAME = name that must match the process for the message to print, or
+// null if the message should be printed unconditionally.
+// P = pointer to process message is for, or NULL in which case the
+// message will not print.
+#if 0
+# define DEBUG_NAME ""
+# define DEBUG_MSG(NAME,P,MSG) \
+ { \
+ if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
+ std::cout << "**** " << sc_time_stamp() << " (" \
+ << sc_get_current_process_name() << "): " << MSG \
+ << " - " << P->name() << std::endl; \
+ }
+#else
+# define DEBUG_MSG(NAME,P,MSG)
+#endif
+
+namespace sc_core {
+
+// The values below are used to indicate when a queue is empty. A non-zero
+// non-legal pointer value is used for this so that a zero value in the
+// m_execute_p field of an sc_process_b instance can be used to indicate
+// that is has not been queued for run. (If we did not use a non-zero
+// queue empty indicator then a sc_process_b instance that was queued
+// twice in a row might end up on the queue twice if it were the first
+// one that was queued!)
+
+#define SC_NO_METHODS ((sc_method_handle)0xdb)
+#define SC_NO_THREADS ((sc_thread_handle)0xdb)
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::dump"
+//
+// This method dumps the contents of this object instance.
+//------------------------------------------------------------------------------
+inline void sc_runnable::dump() const
+{
+ // Dump the thread queues:
+
+ std::cout << "thread pop queue: " << std::endl;
+ for ( sc_thread_handle p = m_threads_pop; p != SC_NO_THREADS;
+ p = p->next_runnable() )
+ {
+ std::cout << " " << p << std::endl;
+ }
+
+ std::cout << "thread push queue: " << std::endl;
+ for ( sc_thread_handle p = m_threads_push_head->next_runnable();
+ p != SC_NO_THREADS; p = p->next_runnable() )
+ {
+ std::cout << " " << p << std::endl;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_runnable::execute_method_next"
+//
+// This method pushes the the supplied method to execute as the next process.
+// This is done by pushing it onto the front of the m_methods_pop.
+// method_h -> method process to add to the queue.
+//------------------------------------------------------------------------------
+inline void sc_runnable::execute_method_next( sc_method_handle method_h )
+{
+ DEBUG_MSG(DEBUG_NAME,method_h,"pushing this method to execute next");
+ method_h->set_next_runnable( m_methods_pop );
+ m_methods_pop = method_h;
+}
+
+//------------------------------------------------------------------------------
+//"sc_runnable::execute_thread_next"
+//
+// This method pushes the the supplied thread to execute as the next process.
+// This is done by pushing it onto the front of the m_threads_pop.
+// thread_h -> thread process to add to the queue.
+//------------------------------------------------------------------------------
+inline void sc_runnable::execute_thread_next( sc_thread_handle thread_h )
+{
+ DEBUG_MSG(DEBUG_NAME,thread_h,"pushing this thread to execute next");
+ thread_h->set_next_runnable( m_threads_pop );
+ m_threads_pop = thread_h;
+}
+
+//------------------------------------------------------------------------------
+//"sc_runnable::init"
+//
+// This method initializes this object instance. Note we allocate the queue
+// heads if necessary. This is done here rather than in the constructor for
+// this class to eliminate CTOR processing errors with gcc.
+//------------------------------------------------------------------------------
+inline void sc_runnable::init()
+{
+ m_methods_pop = SC_NO_METHODS;
+ if ( !m_methods_push_head )
+ {
+ m_methods_push_head = new sc_method_process("methods_push_head", true,
+ (SC_ENTRY_FUNC)0, 0, 0);
+ m_methods_push_head->dont_initialize(true);
+ m_methods_push_head->detach();
+ }
+ m_methods_push_tail = m_methods_push_head;
+ m_methods_push_head->set_next_runnable(SC_NO_METHODS);
+
+ m_threads_pop = SC_NO_THREADS;
+ if ( !m_threads_push_head )
+ {
+ m_threads_push_head = new sc_thread_process("threads_push_head", true,
+ (SC_ENTRY_FUNC)0, 0, 0);
+ m_threads_push_head->dont_initialize(true);
+ m_threads_push_head->detach();
+ }
+ m_threads_push_head->set_next_runnable(SC_NO_THREADS);
+ m_threads_push_tail = m_threads_push_head;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::is_empty"
+//
+// This method returns true if the push queue is empty, or false if not.
+//------------------------------------------------------------------------------
+inline bool sc_runnable::is_empty() const
+{
+ return m_methods_push_head->next_runnable() == SC_NO_METHODS &&
+ m_methods_pop == SC_NO_METHODS &&
+ m_threads_push_head->next_runnable() == SC_NO_THREADS &&
+ m_threads_pop == SC_NO_THREADS;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::is_initialized"
+//
+// This method returns true if the push queue is already initialized.
+//------------------------------------------------------------------------------
+inline bool sc_runnable::is_initialized() const
+{
+ return m_methods_push_head && m_threads_push_head;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::push_back_method"
+//
+// This method pushes the supplied method process onto the back of the queue of
+// runnable method processes.
+// method_h -> method process to add to the queue.
+//------------------------------------------------------------------------------
+inline void sc_runnable::push_back_method( sc_method_handle method_h )
+{
+ // assert( method_h->next_runnable() == 0 ); // Can't queue twice.
+ DEBUG_MSG(DEBUG_NAME,method_h,"pushing back method");
+ method_h->set_next_runnable(SC_NO_METHODS);
+ m_methods_push_tail->set_next_runnable(method_h);
+ m_methods_push_tail = method_h;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::push_back_thread"
+//
+// This method pushes the supplied thread process onto the back of the queue of
+// runnable thread processes.
+// thread_h -> thread process to add to the queue.
+//------------------------------------------------------------------------------
+inline void sc_runnable::push_back_thread( sc_thread_handle thread_h )
+{
+ // assert( thread_h->next_runnable() == 0 ); // Can't queue twice.
+ DEBUG_MSG(DEBUG_NAME,thread_h,"pushing back thread");
+ thread_h->set_next_runnable(SC_NO_THREADS);
+ m_threads_push_tail->set_next_runnable(thread_h);
+ m_threads_push_tail = thread_h;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::push_front_method"
+//
+// This method pushes the supplied method process onto the front of the queue of
+// runnable method processes. If the queue is empty the process is the tail
+// also.
+// method_h -> method process to add to the queue.
+//------------------------------------------------------------------------------
+inline void sc_runnable::push_front_method( sc_method_handle method_h )
+{
+ // assert( method_h->next_runnable() == 0 ); // Can't queue twice.
+ DEBUG_MSG(DEBUG_NAME,method_h,"pushing front method");
+ method_h->set_next_runnable(m_methods_push_head->next_runnable());
+ if ( m_methods_push_tail == m_methods_push_head ) // Empty queue.
+ {
+ m_methods_push_tail->set_next_runnable(method_h);
+ m_methods_push_tail = method_h;
+ }
+ else // Non-empty queue.
+ {
+ m_methods_push_head->set_next_runnable(method_h);
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::push_front_thread"
+//
+// This method pushes the supplied thread process onto the front of the queue of
+// runnable thread processes. If the queue is empty the process is the tail
+// also.
+// thread_h -> thread process to add to the queue.
+//------------------------------------------------------------------------------
+inline void sc_runnable::push_front_thread( sc_thread_handle thread_h )
+{
+ // assert( thread_h->next_runnable() == 0 ); // Can't queue twice.
+ DEBUG_MSG(DEBUG_NAME,thread_h,"pushing front thread");
+ thread_h->set_next_runnable(m_threads_push_head->next_runnable());
+ if ( m_threads_push_tail == m_threads_push_head ) // Empty queue.
+ {
+ m_threads_push_tail->set_next_runnable(thread_h);
+ m_threads_push_tail = thread_h;
+ }
+ else // Non-empty queue.
+ {
+ m_threads_push_head->set_next_runnable(thread_h);
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_runnable::pop_method"
+//
+// This method pops the next method process to be executed, or returns a null
+// if no method processes are available for execution.
+//------------------------------------------------------------------------------
+inline sc_method_handle sc_runnable::pop_method()
+{
+ sc_method_handle result_p;
+
+ result_p = m_methods_pop;
+ if ( result_p != SC_NO_METHODS )
+ {
+ m_methods_pop = result_p->next_runnable();
+ result_p->set_next_runnable(0);
+ }
+ else
+ {
+ result_p = 0;
+ }
+ DEBUG_MSG(DEBUG_NAME,result_p,"popping method");
+ return result_p;
+
+}
+
+//------------------------------------------------------------------------------
+//"sc_runnable::pop_thread"
+//
+// This method pops the next thread process to be executed, or returns a null
+// if no thread processes are available for execution.
+//------------------------------------------------------------------------------
+inline sc_thread_handle sc_runnable::pop_thread()
+{
+ sc_thread_handle result_p;
+
+ result_p = m_threads_pop;
+ if ( result_p != SC_NO_THREADS )
+ {
+ m_threads_pop = result_p->next_runnable();
+ result_p->set_next_runnable(0);
+ }
+ else
+ {
+ result_p = 0;
+ }
+ DEBUG_MSG(DEBUG_NAME,result_p,"popping thread for execution");
+ return result_p;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::remove_method"
+//
+// This method removes the supplied method process from the push queue if it is
+// present. Note we clear the method's next pointer so that it may be queued
+// again.
+// remove_p -> method process to remove from the run queue.
+//------------------------------------------------------------------------------
+inline void sc_runnable::remove_method( sc_method_handle remove_p )
+{
+ sc_method_handle now_p; // Method now checking.
+ sc_method_handle prior_p; // Method prior to now_p.
+
+ // Don't try to remove things if we have not been initialized.
+
+ if ( !is_initialized() ) return;
+
+ // Search the push queue:
+
+ prior_p = m_methods_push_head;
+ for ( now_p = m_methods_push_head; now_p!= SC_NO_METHODS;
+ now_p = now_p->next_runnable() )
+ {
+ if ( remove_p == now_p )
+ {
+ prior_p->set_next_runnable( now_p->next_runnable() );
+ if (now_p == m_methods_push_tail) {
+ m_methods_push_tail = prior_p;
+ }
+ now_p->set_next_runnable(0);
+ DEBUG_MSG(DEBUG_NAME,now_p,"removing method from push queue");
+ return;
+ }
+ prior_p = now_p;
+ }
+
+ // Search the pop queue:
+
+ prior_p = NULL;
+ for ( now_p = m_methods_pop; now_p != SC_NO_METHODS;
+ now_p = now_p->next_runnable() )
+ {
+ if ( remove_p == now_p )
+ {
+ if ( prior_p )
+ prior_p->set_next_runnable( now_p->next_runnable() );
+ else
+ m_methods_pop = now_p->next_runnable();
+ now_p->set_next_runnable(0);
+ DEBUG_MSG(DEBUG_NAME,now_p,"removing method from pop queue");
+ return;
+ }
+ prior_p = now_p;
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::remove_thread"
+//
+// This method removes the supplied thread process from the push or pop
+// queue if it is present. Note we clear the thread's next pointer so that it
+// may be queued again.
+// remove_p -> thread process to remove from the run queue.
+//------------------------------------------------------------------------------
+inline void sc_runnable::remove_thread( sc_thread_handle remove_p )
+{
+ sc_thread_handle now_p; // Thread now checking.
+ sc_thread_handle prior_p; // Thread prior to now_p.
+
+ // Don't try to remove things if we have not been initialized.
+
+ if ( !is_initialized() ) return;
+
+ // Search the push queue:
+
+ prior_p = m_threads_push_head;
+ for ( now_p = m_threads_push_head; now_p != SC_NO_THREADS;
+ now_p = now_p->next_runnable() )
+ {
+ if ( remove_p == now_p )
+ {
+ prior_p->set_next_runnable( now_p->next_runnable() );
+ if (now_p == m_threads_push_tail) {
+ m_threads_push_tail = prior_p;
+ }
+ now_p->set_next_runnable(0);
+ DEBUG_MSG(DEBUG_NAME,now_p,"removing thread from push queue");
+ return;
+ }
+ prior_p = now_p;
+ }
+
+ // Search the pop queue:
+
+ prior_p = NULL;
+ for ( now_p = m_threads_pop; now_p != SC_NO_THREADS;
+ now_p = now_p->next_runnable() )
+ {
+ if ( remove_p == now_p )
+ {
+ if ( prior_p )
+ prior_p->set_next_runnable( now_p->next_runnable() );
+ else
+ m_threads_pop = now_p->next_runnable();
+ now_p->set_next_runnable(0);
+ DEBUG_MSG(DEBUG_NAME,now_p,"removing thread from pop queue");
+ return;
+ }
+ prior_p = now_p;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_runnable::sc_runnable"
+//
+// This is the object instance constructor for this class.
+//------------------------------------------------------------------------------
+inline sc_runnable::sc_runnable() :
+ m_methods_push_head(0), m_methods_push_tail(0), m_methods_pop(SC_NO_METHODS),
+ m_threads_push_head(0), m_threads_push_tail(0), m_threads_pop(SC_NO_THREADS)
+{}
+
+//------------------------------------------------------------------------------
+//"sc_runnable::~sc_runnable"
+//
+// This is the object instance destructor for this class.
+//------------------------------------------------------------------------------
+inline sc_runnable::~sc_runnable()
+{
+ delete m_methods_push_head;
+ delete m_threads_push_head;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::toggle_methods"
+//
+// This method moves the methods push queue to the pop queue and zeros the push
+// queue. This will only be done if the pop queue is presently empty.
+//------------------------------------------------------------------------------
+inline void sc_runnable::toggle_methods()
+{
+ if ( m_methods_pop == SC_NO_METHODS )
+ {
+ m_methods_pop = m_methods_push_head->next_runnable();
+ m_methods_push_head->set_next_runnable(SC_NO_METHODS);
+ m_methods_push_tail = m_methods_push_head;
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_runnable::toggle_threads"
+//
+// This method moves the threads push queue to the pop queue and zeros the push
+// queue. This will only be done if the pop queue is presently empty.
+//------------------------------------------------------------------------------
+inline void sc_runnable::toggle_threads()
+{
+ if ( m_threads_pop == SC_NO_THREADS )
+ {
+ m_threads_pop = m_threads_push_head->next_runnable();
+ m_threads_push_head->set_next_runnable(SC_NO_THREADS);
+ m_threads_push_tail = m_threads_push_head;
+ }
+}
+
+#undef SC_NO_METHODS
+#undef SC_NO_THREADS
+#undef DEBUG_MSG
+
+} // namespace sc_core
+
+
+/*******************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+ Andy Goodrich, Forte Design Systems, 2 September 2003
+ Changed queue heads to instances to eliminate the checks for null heads.
+
+ ******************************************************************************/
+
+// $Log: sc_runnable_int.h,v $
+// Revision 1.19 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.18 2011/08/07 19:08:04 acg
+// Andy Goodrich: moved logs to end of file so line number synching works
+// better between versions.
+//
+// Revision 1.17 2011/04/13 02:45:11 acg
+// Andy Goodrich: eliminated warning message that occurred if the DEBUG_MSG
+// macro was used.
+//
+// Revision 1.16 2011/04/10 22:18:23 acg
+// Andy Goodrich: debugging message clean up.
+//
+// Revision 1.15 2011/04/08 18:26:07 acg
+// Andy Goodrich: added execute_method_next() to handle method dispatch
+// for asynchronous notifications that occur outside the evaluation phase.
+//
+// Revision 1.14 2011/04/01 21:31:10 acg
+// Andy Goodrich: turn off diagnostic messages by default.
+//
+// Revision 1.13 2011/04/01 21:30:02 acg
+// Andy Goodrich: inserted conditional displays for queue manipulations.
+//
+// Revision 1.12 2011/03/30 00:01:34 acg
+// Philip A. Hartmann: change break to return in remove_method() to short
+// circuit the search the way remove_thread() works.
+//
+// Revision 1.11 2011/03/28 13:02:52 acg
+// Andy Goodrich: Changes for disable() interactions.
+//
+// Revision 1.10 2011/03/06 15:58:17 acg
+// Andy Goodrich: formatting changes.
+//
+// Revision 1.9 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.8 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.7 2011/02/02 06:37:03 acg
+// Andy Goodrich: removed toggle() method since it is no longer used.
+//
+// Revision 1.6 2011/02/01 21:09:13 acg
+// Andy Goodrich: addition of toggle_methods() and toggle_threads() calls.
+//
+// Revision 1.5 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.4 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// 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.4 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
+
+#endif // SC_RUNNABLE_INT_H
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_sensitive.cpp b/ext/systemc/src/sysc/kernel/sc_sensitive.cpp
new file mode 100644
index 000000000..210c2670e
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_sensitive.cpp
@@ -0,0 +1,959 @@
+/*****************************************************************************
+
+ 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_sensitive.cpp --
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_cthread_process.h"
+#include "sysc/kernel/sc_method_process.h"
+#include "sysc/kernel/sc_thread_process.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_sensitive.h"
+#include "sysc/communication/sc_signal_ports.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+namespace sc_core {
+
+// support functions
+
+static
+sc_method_handle
+as_method_handle( sc_process_b* handle_ )
+{
+ return DCAST<sc_method_handle>( handle_ );
+}
+
+static
+sc_thread_handle
+as_thread_handle( sc_process_b* handle_ )
+{
+ return DCAST<sc_thread_handle>( handle_ );
+}
+
+static
+void
+warn_no_parens()
+{
+ static bool warn_no_parentheses=true;
+ if ( warn_no_parentheses )
+ {
+ warn_no_parentheses=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "use of () to specify sensitivity is deprecated, use << instead" );
+ }
+}
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_sensitive
+//
+// Static sensitivity class for events.
+// ----------------------------------------------------------------------------
+
+// constructor
+
+sc_sensitive::sc_sensitive( sc_module* module_ )
+: m_module( module_ ),
+ m_mode( SC_NONE_ ),
+ m_handle( 0 )
+{}
+
+
+// destructor
+
+sc_sensitive::~sc_sensitive()
+{}
+
+
+// changing between process handles
+
+sc_sensitive&
+sc_sensitive::operator << ( sc_process_handle handle_ )
+{
+ switch ( handle_.proc_kind() )
+ {
+ case SC_CTHREAD_PROC_:
+ case SC_THREAD_PROC_:
+ m_mode = SC_THREAD_;
+ break;
+ case SC_METHOD_PROC_:
+ m_mode = SC_METHOD_;
+ break;
+ default:
+ assert(0);
+ }
+ m_handle = (sc_process_b*)handle_;
+ return *this;
+}
+
+sc_sensitive&
+sc_sensitive::operator << ( const sc_event& event_ )
+{
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_:
+ case SC_THREAD_: {
+ m_handle->add_static_event( event_ );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+void
+sc_sensitive::make_static_sensitivity(
+ sc_process_b* handle_, const sc_event& event_)
+{
+ handle_->add_static_event( event_ );
+}
+
+
+sc_sensitive&
+sc_sensitive::operator << ( const sc_interface& interface_ )
+{
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_:
+ case SC_THREAD_: {
+ m_handle->add_static_event( interface_.default_event() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+void
+sc_sensitive::make_static_sensitivity(
+ sc_process_b* handle_, const sc_interface& interface_)
+{
+ handle_->add_static_event( interface_.default_event() );
+}
+
+sc_sensitive&
+sc_sensitive::operator << ( const sc_port_base& port_ )
+{
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ) );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ) );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+void
+sc_sensitive::make_static_sensitivity(
+ sc_process_b* handle_, const sc_port_base& port_)
+{
+ sc_method_handle handle_m = as_method_handle( handle_ );
+ if ( handle_m ) {
+ port_.make_sensitive( handle_m );
+ return;
+ }
+ sc_thread_handle handle_t = as_thread_handle( handle_ );
+ // assert(handle_t);
+ port_.make_sensitive( handle_t );
+}
+
+sc_sensitive&
+sc_sensitive::operator << ( sc_event_finder& event_finder_ )
+{
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ event_finder_.port().make_sensitive( as_method_handle( m_handle ),
+ &event_finder_ );
+ break;
+ }
+ case SC_THREAD_: {
+ event_finder_.port().make_sensitive( as_thread_handle( m_handle ),
+ &event_finder_ );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+void
+sc_sensitive::make_static_sensitivity(
+ sc_process_b* handle_, sc_event_finder& event_finder_)
+{
+ if (sc_is_running()) {
+ handle_->add_static_event( event_finder_.find_event() );
+ } else {
+ sc_method_handle handle_m = as_method_handle( handle_ );
+ if ( handle_m ) {
+ event_finder_.port().make_sensitive( handle_m, &event_finder_ );
+ return;
+ }
+ sc_thread_handle handle_t = as_thread_handle( handle_ );
+ // assert(handle_t);
+ event_finder_.port().make_sensitive( handle_t, &event_finder_);
+ }
+}
+
+
+sc_sensitive&
+sc_sensitive::operator () ( const sc_event& event_ )
+{
+ warn_no_parens();
+ return operator << ( event_ );
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( const sc_interface& interface_ )
+{
+ warn_no_parens();
+ return operator << ( interface_ );
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( const sc_port_base& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( sc_event_finder& event_finder_ )
+{
+ warn_no_parens();
+ return operator << ( event_finder_ );
+}
+
+
+sc_sensitive&
+sc_sensitive::operator () ( sc_cthread_handle handle_,
+ sc_event_finder& event_finder_ )
+{
+ event_finder_.port().make_sensitive( handle_, &event_finder_ );
+ return *this;
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( sc_cthread_handle handle_,
+ const in_if_b_type& interface_ )
+{
+ handle_->add_static_event( interface_.posedge_event() );
+ return *this;
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( sc_cthread_handle handle_,
+ const in_if_l_type& interface_ )
+{
+ handle_->add_static_event( interface_.posedge_event() );
+ return *this;
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( sc_cthread_handle handle_,
+ const in_port_b_type& port_ )
+{
+ port_.make_sensitive( handle_, &port_.pos() );
+ return *this;
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( sc_cthread_handle handle_,
+ const in_port_l_type& port_ )
+{
+ port_.make_sensitive( handle_, &port_.pos() );
+ return *this;
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( sc_cthread_handle handle_,
+ const inout_port_b_type& port_ )
+{
+ port_.make_sensitive( handle_, &port_.pos() );
+ return *this;
+}
+
+sc_sensitive&
+sc_sensitive::operator () ( sc_cthread_handle handle_,
+ const inout_port_l_type& port_ )
+{
+ port_.make_sensitive( handle_, &port_.pos() );
+ return *this;
+}
+
+void sc_sensitive::reset()
+{
+ m_mode = SC_NONE_;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_sensitive_pos
+//
+// Static sensitivity class for positive edge events.
+// ----------------------------------------------------------------------------
+
+static void sc_deprecated_sensitive_pos()
+{
+ static bool warn_sensitive_pos=true;
+ if ( warn_sensitive_pos )
+ {
+ warn_sensitive_pos=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_sensitive_pos is deprecated use sc_sensitive << with pos() instead" );
+ }
+}
+
+// constructor
+
+sc_sensitive_pos::sc_sensitive_pos( sc_module* module_ )
+: m_module( module_ ),
+ m_mode( SC_NONE_ ),
+ m_handle( 0 )
+{}
+
+
+// destructor
+
+sc_sensitive_pos::~sc_sensitive_pos()
+{}
+
+
+// changing between process handles
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( sc_process_handle handle_ )
+{
+ switch ( handle_.proc_kind() )
+ {
+ case SC_CTHREAD_PROC_:
+ case SC_THREAD_PROC_:
+ m_mode = SC_THREAD_;
+ break;
+ case SC_METHOD_PROC_:
+ m_mode = SC_METHOD_;
+ break;
+ default:
+ assert(0);
+ }
+ m_handle = (sc_process_b*)handle_;
+ return *this;
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( sc_method_handle handle_ )
+{
+ m_mode = SC_METHOD_;
+ m_handle = handle_;
+ return *this;
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( sc_thread_handle handle_ )
+{
+ m_mode = SC_THREAD_;
+ m_handle = handle_;
+ return *this;
+}
+
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( const in_if_b_type& interface_ )
+{
+ sc_deprecated_sensitive_pos();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_POS_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_:
+ case SC_THREAD_: {
+ m_handle->add_static_event( interface_.posedge_event() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( const in_if_l_type& interface_ )
+{
+ sc_deprecated_sensitive_pos();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_POS_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_:
+ case SC_THREAD_: {
+ m_handle->add_static_event( interface_.posedge_event() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( const in_port_b_type& port_ )
+{
+ sc_deprecated_sensitive_pos();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_POS_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ), &port_.pos() );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ), &port_.pos() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( const in_port_l_type& port_ )
+{
+ sc_deprecated_sensitive_pos();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_POS_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ), &port_.pos() );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ), &port_.pos() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( const inout_port_b_type& port_ )
+{
+ sc_deprecated_sensitive_pos();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_POS_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ), &port_.pos() );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ), &port_.pos() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator << ( const inout_port_l_type& port_ )
+{
+ sc_deprecated_sensitive_pos();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_POS_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ), &port_.pos() );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ), &port_.pos() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator () ( const in_if_b_type& interface_ )
+{
+ warn_no_parens();
+ return operator << ( interface_ );
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator () ( const in_if_l_type& interface_ )
+{
+ warn_no_parens();
+ return operator << ( interface_ );
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator () ( const in_port_b_type& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator () ( const in_port_l_type& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator () ( const inout_port_b_type& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+sc_sensitive_pos&
+sc_sensitive_pos::operator () ( const inout_port_l_type& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+void sc_sensitive_pos::reset()
+{
+ m_mode = SC_NONE_;
+}
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_sensitive_neg
+//
+// Static sensitivity class for negative edge events.
+// ----------------------------------------------------------------------------
+
+static void sc_deprecated_sensitive_neg()
+{
+ static bool warn_sensitive_neg=true;
+ if ( warn_sensitive_neg )
+ {
+ warn_sensitive_neg=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_sensitive_neg is deprecated use sc_sensitive << with neg() instead" );
+ }
+}
+
+// constructor
+
+sc_sensitive_neg::sc_sensitive_neg( sc_module* module_ )
+: m_module( module_ ),
+ m_mode( SC_NONE_ ),
+ m_handle( 0 )
+{}
+
+
+// destructor
+
+sc_sensitive_neg::~sc_sensitive_neg()
+{}
+
+
+// changing between process handles
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( sc_process_handle handle_ )
+{
+ switch ( handle_.proc_kind() )
+ {
+ case SC_CTHREAD_PROC_:
+ case SC_THREAD_PROC_:
+ m_mode = SC_THREAD_;
+ break;
+ case SC_METHOD_PROC_:
+ m_mode = SC_METHOD_;
+ break;
+ default:
+ assert(0);
+ }
+ m_handle = (sc_process_b*)handle_;
+ return *this;
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( sc_method_handle handle_ )
+{
+ m_mode = SC_METHOD_;
+ m_handle = handle_;
+ return *this;
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( sc_thread_handle handle_ )
+{
+ m_mode = SC_THREAD_;
+ m_handle = handle_;
+ return *this;
+}
+
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( const in_if_b_type& interface_ )
+{
+ sc_deprecated_sensitive_neg();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_NEG_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_:
+ case SC_THREAD_: {
+ m_handle->add_static_event( interface_.negedge_event() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( const in_if_l_type& interface_ )
+{
+ sc_deprecated_sensitive_neg();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_NEG_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_:
+ case SC_THREAD_: {
+ m_handle->add_static_event( interface_.negedge_event() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( const in_port_b_type& port_ )
+{
+ sc_deprecated_sensitive_neg();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_NEG_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ), &port_.neg() );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ), &port_.neg() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( const in_port_l_type& port_ )
+{
+ sc_deprecated_sensitive_neg();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_NEG_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ), &port_.neg() );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ), &port_.neg() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( const inout_port_b_type& port_ )
+{
+ sc_deprecated_sensitive_neg();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_NEG_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ), &port_.neg() );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ), &port_.neg() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator << ( const inout_port_l_type& port_ )
+{
+ sc_deprecated_sensitive_neg();
+ // check
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_MAKE_SENSITIVE_NEG_, "simulation running" );
+ }
+
+ // make sensitive
+ switch( m_mode ) {
+ case SC_METHOD_: {
+ port_.make_sensitive( as_method_handle( m_handle ), &port_.neg() );
+ break;
+ }
+ case SC_THREAD_: {
+ port_.make_sensitive( as_thread_handle( m_handle ), &port_.neg() );
+ break;
+ }
+ case SC_NONE_:
+ /* do nothing */
+ break;
+ }
+
+ return *this;
+}
+
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator () ( const in_if_b_type& interface_ )
+{
+ warn_no_parens();
+ return operator << ( interface_ );
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator () ( const in_if_l_type& interface_ )
+{
+ warn_no_parens();
+ return operator << ( interface_ );
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator () ( const in_port_b_type& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator () ( const in_port_l_type& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator () ( const inout_port_b_type& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+sc_sensitive_neg&
+sc_sensitive_neg::operator () ( const inout_port_l_type& port_ )
+{
+ warn_no_parens();
+ return operator << ( port_ );
+}
+
+void sc_sensitive_neg::reset()
+{
+ m_mode = SC_NONE_;
+}
+
+} // 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: add make_static_sensitivity() routines to support
+ dynamic method process creation with static
+ sensitivity
+
+ *****************************************************************************/
+
+// $Log: sc_sensitive.cpp,v $
+// Revision 1.5 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.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// 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.8 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.7 2006/01/27 17:31:24 acg
+// Andy Goodrich: removed debugging comments from << operator code for types
+// that are deprecated.
+//
+// Revision 1.6 2006/01/26 21:04:54 acg
+// Andy Goodrich: deprecation message changes and additional messages.
+//
+// Revision 1.5 2006/01/25 00:31:19 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_sensitive.h b/ext/systemc/src/sysc/kernel/sc_sensitive.h
new file mode 100644
index 000000000..9d07bd03a
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_sensitive.h
@@ -0,0 +1,306 @@
+/*****************************************************************************
+
+ 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_sensitive.h -- Sensitivity classes. Requires "sc_process.h"
+ for declarations of sc_method_handle, &.c.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_SENSITIVE_H
+#define SC_SENSITIVE_H
+
+#include "sysc/kernel/sc_process.h"
+
+namespace sc_dt
+{
+ class sc_logic;
+}
+
+namespace sc_core {
+
+class sc_process_handle;
+class sc_event;
+class sc_event_finder;
+class sc_interface;
+class sc_module;
+class sc_port_base;
+template <class T> class sc_in;
+template <class T> class sc_inout;
+template <class T> class sc_signal_in_if;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_sensitive
+//
+// Static sensitivity class for events.
+// ----------------------------------------------------------------------------
+
+class sc_sensitive
+{
+ friend class sc_module;
+
+public:
+
+ // typedefs
+ typedef sc_signal_in_if<bool> in_if_b_type;
+ typedef sc_signal_in_if<sc_dt::sc_logic> in_if_l_type;
+ typedef sc_in<bool> in_port_b_type;
+ typedef sc_in<sc_dt::sc_logic> in_port_l_type;
+ typedef sc_inout<bool> inout_port_b_type;
+ typedef sc_inout<sc_dt::sc_logic> inout_port_l_type;
+
+private:
+
+ // constructor
+ explicit sc_sensitive( sc_module* );
+
+ // destructor
+ ~sc_sensitive();
+
+public:
+
+ // changing between process handles
+ sc_sensitive& operator << ( sc_process_handle );
+#if 0
+ sc_sensitive& operator << ( sc_method_handle );
+ sc_sensitive& operator << ( sc_thread_handle );
+#endif // 0
+
+ sc_sensitive& operator () ( const sc_event& );
+ sc_sensitive& operator () ( const sc_interface& );
+ sc_sensitive& operator () ( const sc_port_base& );
+ sc_sensitive& operator () ( sc_event_finder& );
+
+ sc_sensitive& operator << ( const sc_event& );
+ sc_sensitive& operator << ( const sc_interface& );
+ sc_sensitive& operator << ( const sc_port_base& );
+ sc_sensitive& operator << ( sc_event_finder& );
+
+ sc_sensitive& operator () ( sc_cthread_handle, sc_event_finder& );
+ sc_sensitive& operator () ( sc_cthread_handle, const in_if_b_type& );
+ sc_sensitive& operator () ( sc_cthread_handle, const in_if_l_type& );
+ sc_sensitive& operator () ( sc_cthread_handle, const in_port_b_type& );
+ sc_sensitive& operator () ( sc_cthread_handle, const in_port_l_type& );
+ sc_sensitive& operator () ( sc_cthread_handle, const inout_port_b_type& );
+ sc_sensitive& operator () ( sc_cthread_handle, const inout_port_l_type& );
+
+ static void make_static_sensitivity( sc_process_b*, const sc_event& );
+ static void make_static_sensitivity( sc_process_b*, const sc_interface& );
+ static void make_static_sensitivity( sc_process_b*, const sc_port_base&);
+ static void make_static_sensitivity( sc_process_b*, sc_event_finder& );
+
+ void reset();
+
+private:
+
+ sc_module* m_module;
+ enum { SC_NONE_, SC_METHOD_, SC_THREAD_ } m_mode;
+ sc_process_b* m_handle;
+
+private:
+
+ // disabled
+
+ sc_sensitive();
+ sc_sensitive( const sc_sensitive& );
+ sc_sensitive& operator = ( const sc_sensitive& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_sensitive_pos
+//
+// Static sensitivity class for positive edge events.
+// ----------------------------------------------------------------------------
+
+class sc_sensitive_pos
+{
+ friend class sc_module;
+
+public:
+
+ // typedefs
+ typedef sc_signal_in_if<bool> in_if_b_type;
+ typedef sc_signal_in_if<sc_dt::sc_logic> in_if_l_type;
+ typedef sc_in<bool> in_port_b_type;
+ typedef sc_in<sc_dt::sc_logic> in_port_l_type;
+ typedef sc_inout<bool> inout_port_b_type;
+ typedef sc_inout<sc_dt::sc_logic> inout_port_l_type;
+
+private:
+
+ // constructor
+ explicit sc_sensitive_pos( sc_module* );
+
+ // destructor
+ ~sc_sensitive_pos();
+
+public:
+
+ // changing between process handles
+ sc_sensitive_pos& operator << ( sc_process_handle );
+ sc_sensitive_pos& operator << ( sc_method_handle );
+ sc_sensitive_pos& operator << ( sc_thread_handle );
+
+ sc_sensitive_pos& operator () ( const in_if_b_type& );
+ sc_sensitive_pos& operator () ( const in_if_l_type& );
+ sc_sensitive_pos& operator () ( const in_port_b_type& );
+ sc_sensitive_pos& operator () ( const in_port_l_type& );
+ sc_sensitive_pos& operator () ( const inout_port_b_type& );
+ sc_sensitive_pos& operator () ( const inout_port_l_type& );
+
+ sc_sensitive_pos& operator << ( const in_if_b_type& );
+ sc_sensitive_pos& operator << ( const in_if_l_type& );
+ sc_sensitive_pos& operator << ( const in_port_b_type& );
+ sc_sensitive_pos& operator << ( const in_port_l_type& );
+ sc_sensitive_pos& operator << ( const inout_port_b_type& );
+ sc_sensitive_pos& operator << ( const inout_port_l_type& );
+
+ void reset();
+
+private:
+
+ sc_module* m_module;
+ enum { SC_NONE_, SC_METHOD_, SC_THREAD_ } m_mode;
+ sc_process_b* m_handle;
+
+private:
+
+ // disabled
+ sc_sensitive_pos();
+ sc_sensitive_pos( const sc_sensitive_pos& );
+ sc_sensitive_pos& operator = ( const sc_sensitive_pos& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_sensitive_neg
+//
+// Static sensitivity class for negative edge events.
+// ----------------------------------------------------------------------------
+
+class sc_sensitive_neg
+{
+ friend class sc_module;
+
+public:
+
+ // typedefs
+ typedef sc_signal_in_if<bool> in_if_b_type;
+ typedef sc_signal_in_if<sc_dt::sc_logic> in_if_l_type;
+ typedef sc_in<bool> in_port_b_type;
+ typedef sc_in<sc_dt::sc_logic> in_port_l_type;
+ typedef sc_inout<bool> inout_port_b_type;
+ typedef sc_inout<sc_dt::sc_logic> inout_port_l_type;
+
+private:
+
+ // constructor
+ explicit sc_sensitive_neg( sc_module* );
+
+ // destructor
+ ~sc_sensitive_neg();
+
+public:
+
+ // changing between process handles
+ sc_sensitive_neg& operator << ( sc_process_handle );
+ sc_sensitive_neg& operator << ( sc_method_handle );
+ sc_sensitive_neg& operator << ( sc_thread_handle );
+
+ sc_sensitive_neg& operator () ( const in_if_b_type& );
+ sc_sensitive_neg& operator () ( const in_if_l_type& );
+ sc_sensitive_neg& operator () ( const in_port_b_type& );
+ sc_sensitive_neg& operator () ( const in_port_l_type& );
+ sc_sensitive_neg& operator () ( const inout_port_b_type& );
+ sc_sensitive_neg& operator () ( const inout_port_l_type& );
+
+ sc_sensitive_neg& operator << ( const in_if_b_type& );
+ sc_sensitive_neg& operator << ( const in_if_l_type& );
+ sc_sensitive_neg& operator << ( const in_port_b_type& );
+ sc_sensitive_neg& operator << ( const in_port_l_type& );
+ sc_sensitive_neg& operator << ( const inout_port_b_type& );
+ sc_sensitive_neg& operator << ( const inout_port_l_type& );
+
+ void reset();
+
+private:
+
+ sc_module* m_module;
+ enum { SC_NONE_, SC_METHOD_, SC_THREAD_ } m_mode;
+ sc_process_b* m_handle;
+
+private:
+
+ // disabled
+ sc_sensitive_neg();
+ sc_sensitive_neg( const sc_sensitive_neg& );
+ sc_sensitive_neg& operator = ( const sc_sensitive_neg& );
+};
+
+} // namespace sc_core
+
+#endif
+
+/*****************************************************************************
+
+ 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: Add make_static_sensitivity() methods to enable
+ dynamic method process creation with static
+ sensitivity.
+
+ *****************************************************************************/
+
+// $Log: sc_sensitive.h,v $
+// Revision 1.5 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.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// 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.4 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_simcontext.cpp b/ext/systemc/src/sysc/kernel/sc_simcontext.cpp
new file mode 100644
index 000000000..104f7c984
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_simcontext.cpp
@@ -0,0 +1,2284 @@
+/*****************************************************************************
+
+ 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_simcontext.cpp -- Provides a simulation context for use with multiple
+ simulations.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include <algorithm>
+
+#define SC_DISABLE_API_VERSION_CHECK // for in-library sc_ver.h inclusion
+
+#include "sysc/kernel/sc_cor_fiber.h"
+#include "sysc/kernel/sc_cor_pthread.h"
+#include "sysc/kernel/sc_cor_qt.h"
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/kernel/sc_module_registry.h"
+#include "sysc/kernel/sc_name_gen.h"
+#include "sysc/kernel/sc_object_manager.h"
+#include "sysc/kernel/sc_cthread_process.h"
+#include "sysc/kernel/sc_method_process.h"
+#include "sysc/kernel/sc_thread_process.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_reset.h"
+#include "sysc/kernel/sc_ver.h"
+#include "sysc/kernel/sc_boost.h"
+#include "sysc/kernel/sc_spawn.h"
+#include "sysc/kernel/sc_phase_callback_registry.h"
+#include "sysc/communication/sc_port.h"
+#include "sysc/communication/sc_export.h"
+#include "sysc/communication/sc_prim_channel.h"
+#include "sysc/tracing/sc_trace.h"
+#include "sysc/utils/sc_mempool.h"
+#include "sysc/utils/sc_list.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+// DEBUGGING MACROS:
+//
+// DEBUG_MSG(NAME,P,MSG)
+// MSG = message to print
+// NAME = name that must match the process for the message to print, or
+// null if the message should be printed unconditionally.
+// P = pointer to process message is for, or NULL in which case the
+// message will not print.
+#if 0
+# define DEBUG_NAME ""
+# define DEBUG_MSG(NAME,P,MSG) \
+ { \
+ if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
+ std::cout << "**** " << sc_time_stamp() << " (" \
+ << sc_get_current_process_name() << "): " << MSG \
+ << " - " << P->name() << std::endl; \
+ }
+#else
+# define DEBUG_MSG(NAME,P,MSG)
+#endif
+
+#if SC_HAS_PHASE_CALLBACKS_
+# define SC_DO_PHASE_CALLBACK_( Kind ) \
+ m_phase_cb_registry->Kind()
+#else
+# define SC_DO_PHASE_CALLBACK_( Kind ) \
+ ((void)0) /* do nothing */
+#endif
+
+#if defined( SC_ENABLE_SIMULATION_PHASE_CALLBACKS_TRACING )
+// use callback based tracing
+# define SC_SIMCONTEXT_TRACING_ 0
+#else
+// enable tracing via explicit trace_cycle calls from simulator loop
+# define SC_SIMCONTEXT_TRACING_ 1
+#endif
+
+namespace sc_core {
+
+sc_stop_mode stop_mode = SC_STOP_FINISH_DELTA;
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_process_table
+//
+// Container class that keeps track of all method processes,
+// (c)thread processes.
+// ----------------------------------------------------------------------------
+
+class sc_process_table
+{
+ public:
+
+ sc_process_table();
+ ~sc_process_table();
+ void push_front( sc_method_handle );
+ void push_front( sc_thread_handle );
+ sc_method_handle method_q_head();
+ sc_method_handle remove( sc_method_handle );
+ sc_thread_handle thread_q_head();
+ sc_thread_handle remove( sc_thread_handle );
+
+
+ private:
+
+ sc_method_handle m_method_q; // Queue of existing method processes.
+ sc_thread_handle m_thread_q; // Queue of existing thread processes.
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+sc_process_table::sc_process_table() : m_method_q(0), m_thread_q(0)
+{}
+
+sc_process_table::~sc_process_table()
+{
+
+ sc_method_handle method_next_p; // Next method to delete.
+ sc_method_handle method_now_p; // Method now deleting.
+
+ for( method_now_p = m_method_q; method_now_p; method_now_p = method_next_p )
+ {
+ method_next_p = method_now_p->next_exist();
+ delete method_now_p;
+ }
+
+ if ( m_thread_q )
+ {
+ ::std::cout << ::std::endl
+ << "WATCH OUT!! In sc_process_table destructor. "
+ << "Threads and cthreads are not actually getting deleted here. "
+ << "Some memory may leak. Look at the comments here in "
+ << "kernel/sc_simcontext.cpp for more details."
+ << ::std::endl;
+ }
+
+ // don't delete threads and cthreads. If a (c)thread
+ // has died, then it has already been deleted. Only (c)threads created
+ // before simulation-start are in this table. Due to performance
+ // reasons, we don't look up the dying thread in the process table
+ // and remove it from there. simcontext::reset and ~simcontext invoke this
+ // destructor. At present none of these routines are ever invoked.
+ // We can delete threads and cthreads here if a dying thread figured out
+ // it was created before simulation-start and took itself off the
+ // process_table.
+
+#if 0
+ sc_thread_handle thread_next_p; // Next thread to delete.
+ sc_thread_handle thread_now_p; // Thread now deleting.
+
+ for( thread_now_p=m_thread_q; thread_now_p; thread_now_p=thread_next_p )
+ {
+ thread_next_p = thread_now_p->next_exist();
+ delete thread_now_p;
+ }
+#endif // 0
+}
+
+inline
+sc_method_handle
+sc_process_table::method_q_head()
+{
+ return m_method_q;
+}
+
+inline
+void
+sc_process_table::push_front( sc_method_handle handle_ )
+{
+ handle_->set_next_exist(m_method_q);
+ m_method_q = handle_;
+}
+
+inline
+void
+sc_process_table::push_front( sc_thread_handle handle_ )
+{
+ handle_->set_next_exist(m_thread_q);
+ m_thread_q = handle_;
+}
+
+sc_method_handle
+sc_process_table::remove( sc_method_handle handle_ )
+{
+ sc_method_handle now_p; // Entry now examining.
+ sc_method_handle prior_p; // Entry prior to one now examining.
+
+ prior_p = 0;
+ for ( now_p = m_method_q; now_p; now_p = now_p->next_exist() )
+ {
+ if ( now_p == handle_ )
+ {
+ if ( prior_p )
+ prior_p->set_next_exist( now_p->next_exist() );
+ else
+ m_method_q = now_p->next_exist();
+ return handle_;
+ }
+ }
+ return 0;
+}
+
+sc_thread_handle
+sc_process_table::remove( sc_thread_handle handle_ )
+{
+ sc_thread_handle now_p; // Entry now examining.
+ sc_thread_handle prior_p; // Entry prior to one now examining.
+
+ prior_p = 0;
+ for ( now_p = m_thread_q; now_p; now_p = now_p->next_exist() )
+ {
+ if ( now_p == handle_ )
+ {
+ if ( prior_p )
+ prior_p->set_next_exist( now_p->next_exist() );
+ else
+ m_thread_q = now_p->next_exist();
+ return handle_;
+ }
+ }
+ return 0;
+}
+
+inline
+sc_thread_handle
+sc_process_table::thread_q_head()
+{
+ return m_thread_q;
+}
+
+int
+sc_notify_time_compare( const void* p1, const void* p2 )
+{
+ const sc_event_timed* et1 = static_cast<const sc_event_timed*>( p1 );
+ const sc_event_timed* et2 = static_cast<const sc_event_timed*>( p2 );
+
+ const sc_time& t1 = et1->notify_time();
+ const sc_time& t2 = et2->notify_time();
+
+ if( t1 < t2 ) {
+ return 1;
+ } else if( t1 > t2 ) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+
+// +============================================================================
+// | CLASS sc_invoke_method - class to invoke sc_method's to support
+// | sc_simcontext::preempt_with().
+// +============================================================================
+SC_MODULE(sc_invoke_method)
+{
+ SC_CTOR(sc_invoke_method)
+ {
+ // remove from object hierarchy
+ detach();
+ }
+
+ virtual ~sc_invoke_method()
+ {
+ m_invokers.resize(0);
+ }
+
+ // Method to call to execute a method's semantics.
+
+ void invoke_method( sc_method_handle method_h )
+ {
+ sc_process_handle invoker_h; // handle for invocation thread to use.
+ std::vector<sc_process_handle>::size_type invokers_n; // number of invocation threads available.
+
+ m_method = method_h;
+
+ // There is not an invocation thread to use, so allocate one.
+
+ invokers_n = m_invokers.size();
+ if ( invokers_n == 0 )
+ {
+ sc_spawn_options options;
+ options.dont_initialize();
+ options.set_stack_size(0x100000);
+ options.set_sensitivity(&m_dummy);
+ invoker_h = sc_spawn(sc_bind(&sc_invoke_method::invoker,this),
+ sc_gen_unique_name("invoker"), &options);
+ ((sc_process_b*)invoker_h)->detach();
+ }
+
+ // There is an invocation thread to use, use the last one on the list.
+
+ else
+ {
+ invoker_h = m_invokers[invokers_n-1];
+ m_invokers.pop_back();
+ }
+
+ // Fire off the invocation thread to invoke the method's semantics,
+ // When it blocks put it onto the list of invocation threads that
+ // are available.
+
+ sc_get_curr_simcontext()->preempt_with( (sc_thread_handle)invoker_h );
+ DEBUG_MSG( DEBUG_NAME, m_method, "back from preemption" );
+ m_invokers.push_back(invoker_h);
+ }
+
+ // Thread to call method from:
+
+ void invoker()
+ {
+ sc_simcontext* csc_p = sc_get_curr_simcontext();
+ sc_process_b* me = sc_get_current_process_b();
+
+ DEBUG_MSG( DEBUG_NAME, me, "invoker initialization" );
+ for (;; )
+ {
+ DEBUG_MSG( DEBUG_NAME, m_method, "invoker executing method" );
+ csc_p->set_curr_proc( (sc_process_b*)m_method );
+ csc_p->get_active_invokers().push_back((sc_thread_handle)me);
+ m_method->run_process();
+ csc_p->set_curr_proc( me );
+ csc_p->get_active_invokers().pop_back();
+ DEBUG_MSG( DEBUG_NAME, m_method, "back from executing method" );
+ wait();
+ }
+ }
+
+ sc_event m_dummy; // dummy event to wait on.
+ sc_method_handle m_method; // method to be invoked.
+ std::vector<sc_process_handle> m_invokers; // list of invoking threads.
+};
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_simcontext
+//
+// The simulation context.
+// ----------------------------------------------------------------------------
+
+void
+sc_simcontext::init()
+{
+
+ // ALLOCATE VARIOUS MANAGERS AND REGISTRIES:
+
+ m_object_manager = new sc_object_manager;
+ m_module_registry = new sc_module_registry( *this );
+ m_port_registry = new sc_port_registry( *this );
+ m_export_registry = new sc_export_registry( *this );
+ m_prim_channel_registry = new sc_prim_channel_registry( *this );
+ m_phase_cb_registry = new sc_phase_callback_registry( *this );
+ m_name_gen = new sc_name_gen;
+ m_process_table = new sc_process_table;
+ m_current_writer = 0;
+
+
+ // CHECK FOR ENVIRONMENT VARIABLES THAT MODIFY SIMULATOR EXECUTION:
+
+ const char* write_check = std::getenv("SC_SIGNAL_WRITE_CHECK");
+ m_write_check = ( (write_check==0) || strcmp(write_check,"DISABLE") ) ?
+ true : false;
+
+
+ // FINISH INITIALIZATIONS:
+
+ reset_curr_proc();
+ m_next_proc_id = -1;
+ m_timed_events = new sc_ppq<sc_event_timed*>( 128, sc_notify_time_compare );
+ m_something_to_trace = false;
+ m_runnable = new sc_runnable;
+ m_collectable = new sc_process_list;
+ m_time_params = new sc_time_params;
+ m_curr_time = SC_ZERO_TIME;
+ m_max_time = SC_ZERO_TIME;
+ m_change_stamp = 0;
+ m_delta_count = 0;
+ m_forced_stop = false;
+ m_paused = false;
+ m_ready_to_simulate = false;
+ m_elaboration_done = false;
+ m_execution_phase = phase_initialize;
+ m_error = NULL;
+ m_cor_pkg = 0;
+ m_method_invoker_p = NULL;
+ m_cor = 0;
+ m_in_simulator_control = false;
+ m_start_of_simulation_called = false;
+ m_end_of_simulation_called = false;
+ m_simulation_status = SC_ELABORATION;
+}
+
+void
+sc_simcontext::clean()
+{
+ delete m_object_manager;
+ delete m_module_registry;
+ delete m_port_registry;
+ delete m_export_registry;
+ delete m_prim_channel_registry;
+ delete m_phase_cb_registry;
+ delete m_name_gen;
+ delete m_process_table;
+ m_child_objects.resize(0);
+ m_delta_events.resize(0);
+ delete m_timed_events;
+ for( int i = m_trace_files.size() - 1; i >= 0; -- i ) {
+ delete m_trace_files[i];
+ }
+ m_trace_files.resize(0);
+ delete m_runnable;
+ delete m_collectable;
+ delete m_time_params;
+ delete m_cor_pkg;
+ delete m_error;
+}
+
+
+sc_simcontext::sc_simcontext() :
+ m_object_manager(0), m_module_registry(0), m_port_registry(0),
+ m_export_registry(0), m_prim_channel_registry(0),
+ m_phase_cb_registry(0), m_name_gen(0),
+ m_process_table(0), m_curr_proc_info(), m_current_writer(0),
+ m_write_check(false), m_next_proc_id(-1), m_child_events(),
+ m_child_objects(), m_delta_events(), m_timed_events(0), m_trace_files(),
+ m_something_to_trace(false), m_runnable(0), m_collectable(0),
+ m_time_params(), m_curr_time(SC_ZERO_TIME), m_max_time(SC_ZERO_TIME),
+ m_change_stamp(0), m_delta_count(0), m_forced_stop(false), m_paused(false),
+ m_ready_to_simulate(false), m_elaboration_done(false),
+ m_execution_phase(phase_initialize), m_error(0),
+ m_in_simulator_control(false), m_end_of_simulation_called(false),
+ m_simulation_status(SC_ELABORATION), m_start_of_simulation_called(false),
+ m_cor_pkg(0), m_cor(0)
+{
+ init();
+}
+
+sc_simcontext::~sc_simcontext()
+{
+ clean();
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_simcontext::active_object"
+// |
+// | This method returns the currently active object with respect to
+// | additions to the hierarchy. It will be the top of the object hierarchy
+// | stack if it is non-empty, or it will be the active process, or NULL
+// | if there is no active process.
+// +----------------------------------------------------------------------------
+sc_object*
+sc_simcontext::active_object()
+{
+ sc_object* result_p; // pointer to return.
+
+ result_p = m_object_manager->hierarchy_curr();
+ if ( !result_p )
+ result_p = (sc_object*)get_curr_proc_info()->process_handle;
+ return result_p;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_simcontext::crunch"
+// |
+// | This method implements the simulator's execution of processes. It performs
+// | one or more "delta" cycles. Each delta cycle consists of an evaluation,
+// | an update phase, and a notification phase. During the evaluation phase any
+// | processes that are ready to run are executed. After all the processes have
+// | been executed the update phase is entered. During the update phase the
+// | values of any signals that have changed are updated. After the updates
+// | have been performed the notification phase is entered. During that phase
+// | any notifications that need to occur because of of signal values changes
+// | are performed. This will result in the queueing of processes for execution
+// | that are sensitive to those notifications. At that point a delta cycle
+// | is complete, and the process is started again unless 'once' is true.
+// |
+// | Arguments:
+// | once = true if only one delta cycle is to be performed.
+// +----------------------------------------------------------------------------
+inline void
+sc_simcontext::crunch( bool once )
+{
+#ifdef DEBUG_SYSTEMC
+ int num_deltas = 0; // number of delta cycles
+#endif
+
+ while ( true )
+ {
+
+ // EVALUATE PHASE
+
+ m_execution_phase = phase_evaluate;
+ bool empty_eval_phase = true;
+ while( true )
+ {
+
+ // execute method processes
+
+ m_runnable->toggle_methods();
+ sc_method_handle method_h = pop_runnable_method();
+ while( method_h != 0 ) {
+ empty_eval_phase = false;
+ if ( !method_h->run_process() )
+ {
+ goto out;
+ }
+ method_h = pop_runnable_method();
+ }
+
+ // execute (c)thread processes
+
+ m_runnable->toggle_threads();
+ sc_thread_handle thread_h = pop_runnable_thread();
+ while( thread_h != 0 ) {
+ if ( thread_h->m_cor_p != NULL ) break;
+ thread_h = pop_runnable_thread();
+ }
+
+ if( thread_h != 0 ) {
+ empty_eval_phase = false;
+ m_cor_pkg->yield( thread_h->m_cor_p );
+ }
+ if( m_error ) {
+ goto out;
+ }
+
+ // check for call(s) to sc_stop
+ if( m_forced_stop ) {
+ if ( stop_mode == SC_STOP_IMMEDIATE ) goto out;
+ }
+
+ // no more runnable processes
+
+ if( m_runnable->is_empty() ) {
+ break;
+ }
+ }
+
+ // remove finally dead zombies:
+
+ while( ! m_collectable->empty() )
+ {
+ sc_process_b* del_p = m_collectable->front();
+ m_collectable->pop_front();
+ del_p->reference_decrement();
+ }
+
+
+ // UPDATE PHASE
+ //
+ // The change stamp must be updated first so that event_occurred()
+ // will work.
+
+ m_execution_phase = phase_update;
+ if ( !empty_eval_phase )
+ {
+// SC_DO_PHASE_CALLBACK_(evaluation_done);
+ m_change_stamp++;
+ m_delta_count ++;
+ }
+ m_prim_channel_registry->perform_update();
+ SC_DO_PHASE_CALLBACK_(update_done);
+ m_execution_phase = phase_notify;
+
+#if SC_SIMCONTEXT_TRACING_
+ if( m_something_to_trace ) {
+ trace_cycle( /* delta cycle? */ true );
+ }
+#endif
+
+ // check for call(s) to sc_stop
+ if( m_forced_stop ) {
+ break;
+ }
+
+#ifdef DEBUG_SYSTEMC
+ // check for possible infinite loops
+ if( ++ num_deltas > SC_MAX_NUM_DELTA_CYCLES ) {
+ ::std::cerr << "SystemC warning: "
+ << "the number of delta cycles exceeds the limit of "
+ << SC_MAX_NUM_DELTA_CYCLES
+ << ", defined in sc_constants.h.\n"
+ << "This is a possible sign of an infinite loop.\n"
+ << "Increase the limit if this warning is invalid.\n";
+ break;
+ }
+#endif
+
+ // NOTIFICATION PHASE:
+ //
+ // Process delta notifications which will queue processes for
+ // subsequent execution.
+
+ int size = m_delta_events.size();
+ if ( size != 0 )
+ {
+ sc_event** l_events = &m_delta_events[0];
+ int i = size - 1;
+ do {
+ l_events[i]->trigger();
+ } while( -- i >= 0 );
+ m_delta_events.resize(0);
+ }
+
+ if( m_runnable->is_empty() ) {
+ // no more runnable processes
+ break;
+ }
+
+ // if sc_pause() was called we are done.
+
+ if ( m_paused ) break;
+
+ // IF ONLY DOING ONE CYCLE, WE ARE DONE. OTHERWISE EXECUTE NEW CALLBACKS
+
+ if ( once ) break;
+ }
+
+ // When this point is reached the processing of delta cycles is complete,
+ // if the completion was because of an error throw the exception specified
+ // by '*m_error'.
+out:
+ this->reset_curr_proc();
+ if( m_error ) throw *m_error; // re-throw propagated error
+}
+
+inline
+void
+sc_simcontext::cycle( const sc_time& t)
+{
+ sc_time next_event_time;
+
+ m_in_simulator_control = true;
+ crunch();
+ SC_DO_PHASE_CALLBACK_(before_timestep);
+#if SC_SIMCONTEXT_TRACING_
+ if( m_something_to_trace ) {
+ trace_cycle( /* delta cycle? */ false );
+ }
+#endif
+ m_curr_time += t;
+ if ( next_time(next_event_time) && next_event_time <= m_curr_time) {
+ SC_REPORT_WARNING(SC_ID_CYCLE_MISSES_EVENTS_, "");
+ }
+ m_in_simulator_control = false;
+ SC_DO_PHASE_CALLBACK_(simulation_paused);
+}
+
+void
+sc_simcontext::elaborate()
+{
+ if( m_elaboration_done || sim_status() != SC_SIM_OK ) {
+ return;
+ }
+
+ // Instantiate the method invocation module
+ // (not added to public object hierarchy)
+
+ m_method_invoker_p =
+ new sc_invoke_method("$$$$kernel_module$$$$_invoke_method" );
+
+ m_simulation_status = SC_BEFORE_END_OF_ELABORATION;
+ for( int cd = 0; cd != 4; /* empty */ )
+ {
+ cd = m_port_registry->construction_done();
+ cd += m_export_registry->construction_done();
+ cd += m_prim_channel_registry->construction_done();
+ cd += m_module_registry->construction_done();
+
+ // check for call(s) to sc_stop
+ if( m_forced_stop ) {
+ do_sc_stop_action();
+ return;
+ }
+
+ }
+ SC_DO_PHASE_CALLBACK_(construction_done);
+
+ // SIGNAL THAT ELABORATION IS DONE
+ //
+ // We set the switch before the calls in case someone creates a process
+ // in an end_of_elaboration callback. We need the information to flag
+ // the process as being dynamic.
+
+ m_elaboration_done = true;
+ m_simulation_status = SC_END_OF_ELABORATION;
+
+ m_port_registry->elaboration_done();
+ m_export_registry->elaboration_done();
+ m_prim_channel_registry->elaboration_done();
+ m_module_registry->elaboration_done();
+ SC_DO_PHASE_CALLBACK_(elaboration_done);
+ sc_reset::reconcile_resets();
+
+ // check for call(s) to sc_stop
+ if( m_forced_stop ) {
+ do_sc_stop_action();
+ return;
+ }
+}
+
+void
+sc_simcontext::prepare_to_simulate()
+{
+ sc_method_handle method_p; // Pointer to method process accessing.
+ sc_thread_handle thread_p; // Pointer to thread process accessing.
+
+ if( m_ready_to_simulate || sim_status() != SC_SIM_OK ) {
+ return;
+ }
+
+ // instantiate the coroutine package
+ m_cor_pkg = new sc_cor_pkg_t( this );
+ m_cor = m_cor_pkg->get_main();
+
+ // NOTIFY ALL OBJECTS THAT SIMULATION IS ABOUT TO START:
+
+ m_simulation_status = SC_START_OF_SIMULATION;
+ m_port_registry->start_simulation();
+ m_export_registry->start_simulation();
+ m_prim_channel_registry->start_simulation();
+ m_module_registry->start_simulation();
+ SC_DO_PHASE_CALLBACK_(start_simulation);
+ m_start_of_simulation_called = true;
+
+ // CHECK FOR CALL(S) TO sc_stop
+
+ if( m_forced_stop ) {
+ do_sc_stop_action();
+ return;
+ }
+
+ // PREPARE ALL (C)THREAD PROCESSES FOR SIMULATION:
+
+ for ( thread_p = m_process_table->thread_q_head();
+ thread_p; thread_p = thread_p->next_exist() )
+ {
+ thread_p->prepare_for_simulation();
+ }
+
+ m_simulation_status = SC_RUNNING;
+ m_ready_to_simulate = true;
+ m_runnable->init();
+
+ // update phase
+
+ m_execution_phase = phase_update;
+ m_prim_channel_registry->perform_update();
+ m_execution_phase = phase_notify;
+
+ int size;
+
+ // make all method processes runnable
+
+ for ( method_p = m_process_table->method_q_head();
+ method_p; method_p = method_p->next_exist() )
+ {
+ if ( ((method_p->m_state & sc_process_b::ps_bit_disabled) != 0) ||
+ method_p->dont_initialize() )
+ {
+ if ( method_p->m_static_events.size() == 0 )
+ {
+ SC_REPORT_WARNING( SC_ID_DISABLE_WILL_ORPHAN_PROCESS_,
+ method_p->name() );
+ }
+ }
+ else if ( (method_p->m_state & sc_process_b::ps_bit_suspended) == 0)
+ {
+ push_runnable_method_front( method_p );
+ }
+ else
+ {
+ method_p->m_state |= sc_process_b::ps_bit_ready_to_run;
+ }
+ }
+
+ // make thread processes runnable
+ // (cthread processes always have the dont_initialize flag set)
+
+ for ( thread_p = m_process_table->thread_q_head();
+ thread_p; thread_p = thread_p->next_exist() )
+ {
+ if ( ((thread_p->m_state & sc_process_b::ps_bit_disabled) != 0) ||
+ thread_p->dont_initialize() )
+ {
+ if ( thread_p->m_static_events.size() == 0 )
+ {
+ SC_REPORT_WARNING( SC_ID_DISABLE_WILL_ORPHAN_PROCESS_,
+ thread_p->name() );
+ }
+ }
+ else if ( (thread_p->m_state & sc_process_b::ps_bit_suspended) == 0)
+ {
+ push_runnable_thread_front( thread_p );
+ }
+ else
+ {
+ thread_p->m_state |= sc_process_b::ps_bit_ready_to_run;
+ }
+ }
+
+
+ // process delta notifications
+
+ if( ( size = m_delta_events.size() ) != 0 ) {
+ sc_event** l_delta_events = &m_delta_events[0];
+ int i = size - 1;
+ do {
+ l_delta_events[i]->trigger();
+ } while( -- i >= 0 );
+ m_delta_events.resize(0);
+ }
+
+ SC_DO_PHASE_CALLBACK_(initialization_done);
+}
+
+void
+sc_simcontext::initial_crunch( bool no_crunch )
+{
+ if( no_crunch || m_runnable->is_empty() ) {
+ return;
+ }
+
+ // run the delta cycle loop
+
+ crunch();
+ if( m_error ) {
+ return;
+ }
+
+#if SC_SIMCONTEXT_TRACING_
+ if( m_something_to_trace ) {
+ trace_cycle( false );
+ }
+#endif
+
+ // check for call(s) to sc_stop
+ if( m_forced_stop ) {
+ do_sc_stop_action();
+ }
+}
+
+void
+sc_simcontext::initialize( bool no_crunch )
+{
+ m_in_simulator_control = true;
+ elaborate();
+
+ prepare_to_simulate();
+ initial_crunch(no_crunch);
+ m_in_simulator_control = false;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_simcontext::simulate"
+// |
+// | This method runs the simulation for the specified amount of time.
+// |
+// | Notes:
+// | (1) This code always run with an SC_EXIT_ON_STARVATION starvation policy,
+// | so the simulation time on return will be the minimum of the
+// | simulation on entry plus the duration, and the maximum time of any
+// | event present in the simulation. If the simulation policy is
+// | SC_RUN_TO_TIME starvation it is implemented by the caller of this
+// | method, e.g., sc_start(), by artificially setting the simulation
+// | time forward after this method completes.
+// |
+// | Arguments:
+// | duration = amount of time to simulate.
+// +----------------------------------------------------------------------------
+void
+sc_simcontext::simulate( const sc_time& duration )
+{
+ initialize( true );
+
+ if (sim_status() != SC_SIM_OK) {
+ return;
+ }
+
+ sc_time non_overflow_time = sc_max_time() - m_curr_time;
+ if ( duration > non_overflow_time )
+ {
+ SC_REPORT_ERROR(SC_ID_SIMULATION_TIME_OVERFLOW_, "");
+ return;
+ }
+ else if ( duration < SC_ZERO_TIME )
+ {
+ SC_REPORT_ERROR(SC_ID_NEGATIVE_SIMULATION_TIME_,"");
+ }
+
+ m_in_simulator_control = true;
+ m_paused = false;
+
+ sc_time until_t = m_curr_time + duration;
+ sc_time t; // current simulaton time.
+
+ // IF DURATION WAS ZERO WE ONLY CRUNCH ONCE:
+ //
+ // We duplicate the code so that we don't add the overhead of the
+ // check to each loop in the do below.
+ if ( duration == SC_ZERO_TIME )
+ {
+ m_in_simulator_control = true;
+ crunch( true );
+ if( m_error ) {
+ m_in_simulator_control = false;
+ return;
+ }
+#if SC_SIMCONTEXT_TRACING_
+ if( m_something_to_trace )
+ trace_cycle( /* delta cycle? */ false );
+#endif
+ if( m_forced_stop ) {
+ do_sc_stop_action();
+ return;
+ }
+ // return via implicit pause
+ goto exit_pause;
+ }
+
+ // NON-ZERO DURATION: EXECUTE UP TO THAT TIME, OR UNTIL EVENT STARVATION:
+
+ do {
+
+ crunch();
+ if( m_error ) {
+ m_in_simulator_control = false;
+ return;
+ }
+#if SC_SIMCONTEXT_TRACING_
+ if( m_something_to_trace ) {
+ trace_cycle( false );
+ }
+#endif
+ // check for call(s) to sc_stop() or sc_pause().
+ if( m_forced_stop ) {
+ do_sc_stop_action();
+ return;
+ }
+ if( m_paused ) goto exit_pause; // return explicit pause
+
+ t = m_curr_time;
+
+ do {
+ // See note 1 above:
+
+ if ( !next_time(t) || (t > until_t ) ) goto exit_time;
+ if ( t > m_curr_time )
+ {
+ SC_DO_PHASE_CALLBACK_(before_timestep);
+ m_curr_time = t;
+ m_change_stamp++;
+ }
+
+ // PROCESS TIMED NOTIFICATIONS AT THE CURRENT TIME
+
+ do {
+ sc_event_timed* et = m_timed_events->extract_top();
+ sc_event* e = et->event();
+ delete et;
+ if( e != 0 ) {
+ e->trigger();
+ }
+ } while( m_timed_events->size() &&
+ m_timed_events->top()->notify_time() == t );
+
+ } while( m_runnable->is_empty() );
+ } while ( t < until_t ); // hold off on the delta for the until_t time.
+
+exit_time: // final simulation time update, if needed
+ if ( t > m_curr_time && t <= until_t )
+ {
+ SC_DO_PHASE_CALLBACK_(before_timestep);
+ m_curr_time = t;
+ m_change_stamp++;
+ }
+exit_pause: // call pause callback upon implicit or explicit pause
+ m_execution_phase = phase_evaluate;
+ m_in_simulator_control = false;
+ SC_DO_PHASE_CALLBACK_(simulation_paused);
+}
+
+void
+sc_simcontext::do_sc_stop_action()
+{
+ SC_REPORT_INFO("/OSCI/SystemC","Simulation stopped by user.");
+ if (m_start_of_simulation_called) {
+ end();
+ m_in_simulator_control = false;
+ }
+ m_simulation_status = SC_STOPPED;
+ SC_DO_PHASE_CALLBACK_(simulation_stopped);
+}
+
+void
+sc_simcontext::mark_to_collect_process( sc_process_b* zombie )
+{
+ m_collectable->push_back( zombie );
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_simcontext::stop"
+//
+// This method stops the simulator after some amount of further processing.
+// How much processing is done depends upon the value of the global variable
+// stop_mode:
+// SC_STOP_IMMEDIATE - aborts the execution phase of the current delta
+// cycle and performs whatever updates are pending.
+// SC_STOP_FINISH_DELTA - finishes the current delta cycle - both execution
+// and updates.
+// If sc_stop is called outside of the purview of the simulator kernel
+// (e.g., directly from sc_main), the end of simulation notifications
+// are performed. From within the purview of the simulator kernel, these
+// will be performed at a later time.
+//------------------------------------------------------------------------------
+
+void
+sc_simcontext::stop()
+{
+ static bool stop_warning_issued = false;
+ if (m_forced_stop)
+ {
+ if ( !stop_warning_issued )
+ {
+ stop_warning_issued = true; // This must be before the WARNING!!!
+ SC_REPORT_WARNING(SC_ID_SIMULATION_STOP_CALLED_TWICE_, "");
+ }
+ return;
+ }
+ if ( stop_mode == SC_STOP_IMMEDIATE ) m_runnable->init();
+ m_forced_stop = true;
+ if ( !m_in_simulator_control )
+ {
+ do_sc_stop_action();
+ }
+}
+
+void
+sc_simcontext::reset()
+{
+ clean();
+ init();
+}
+
+void
+sc_simcontext::end()
+{
+ m_simulation_status = SC_END_OF_SIMULATION;
+ m_ready_to_simulate = false;
+ m_port_registry->simulation_done();
+ m_export_registry->simulation_done();
+ m_prim_channel_registry->simulation_done();
+ m_module_registry->simulation_done();
+ SC_DO_PHASE_CALLBACK_(simulation_done);
+ m_end_of_simulation_called = true;
+}
+
+void
+sc_simcontext::hierarchy_push( sc_module* mod )
+{
+ m_object_manager->hierarchy_push( mod );
+}
+
+sc_module*
+sc_simcontext::hierarchy_pop()
+{
+ return static_cast<sc_module*>( m_object_manager->hierarchy_pop() );
+}
+
+sc_module*
+sc_simcontext::hierarchy_curr() const
+{
+ return static_cast<sc_module*>( m_object_manager->hierarchy_curr() );
+}
+
+sc_object*
+sc_simcontext::first_object()
+{
+ return m_object_manager->first_object();
+}
+
+sc_object*
+sc_simcontext::next_object()
+{
+ return m_object_manager->next_object();
+}
+
+sc_object*
+sc_simcontext::find_object( const char* name )
+{
+ static bool warn_find_object=true;
+ if ( warn_find_object )
+ {
+ warn_find_object = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_simcontext::find_object() is deprecated,\n" \
+ " use sc_find_object()" );
+ }
+ return m_object_manager->find_object( name );
+}
+
+// to generate unique names for objects in an MT-Safe way
+
+const char*
+sc_simcontext::gen_unique_name( const char* basename_, bool preserve_first )
+{
+ return m_name_gen->gen_unique_name( basename_, preserve_first );
+}
+
+
+sc_process_handle
+sc_simcontext::create_cthread_process(
+ const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,
+ sc_process_host* host_p, const sc_spawn_options* opt_p )
+{
+ sc_thread_handle handle =
+ new sc_cthread_process(name_p, free_host, method_p, host_p, opt_p);
+ if ( m_ready_to_simulate )
+ {
+ handle->prepare_for_simulation();
+ } else {
+ m_process_table->push_front( handle );
+ }
+ return sc_process_handle(handle);
+}
+
+
+sc_process_handle
+sc_simcontext::create_method_process(
+ const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,
+ sc_process_host* host_p, const sc_spawn_options* opt_p )
+{
+ sc_method_handle handle =
+ new sc_method_process(name_p, free_host, method_p, host_p, opt_p);
+ if ( m_ready_to_simulate ) { // dynamic process
+ if ( !handle->dont_initialize() )
+ {
+#ifdef SC_HAS_PHASE_CALLBACKS_
+ if( SC_UNLIKELY_( m_simulation_status
+ & (SC_END_OF_UPDATE|SC_BEFORE_TIMESTEP) ) )
+ {
+ std::stringstream msg;
+ msg << m_simulation_status
+ << ":\n\t immediate method spawning of "
+ "`" << handle->name() << "' ignored";
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_FORBIDDEN_
+ , msg.str().c_str() );
+ }
+ else
+#endif // SC_HAS_PHASE_CALLBACKS_
+ {
+ push_runnable_method( handle );
+ }
+ }
+ else if ( handle->m_static_events.size() == 0 )
+ {
+ SC_REPORT_WARNING( SC_ID_DISABLE_WILL_ORPHAN_PROCESS_,
+ handle->name() );
+ }
+
+ } else {
+ m_process_table->push_front( handle );
+ }
+ return sc_process_handle(handle);
+}
+
+
+sc_process_handle
+sc_simcontext::create_thread_process(
+ const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,
+ sc_process_host* host_p, const sc_spawn_options* opt_p )
+{
+ sc_thread_handle handle =
+ new sc_thread_process(name_p, free_host, method_p, host_p, opt_p);
+ if ( m_ready_to_simulate ) { // dynamic process
+ handle->prepare_for_simulation();
+ if ( !handle->dont_initialize() )
+ {
+#ifdef SC_HAS_PHASE_CALLBACKS_
+ if( SC_UNLIKELY_( m_simulation_status
+ & (SC_END_OF_UPDATE|SC_BEFORE_TIMESTEP) ) )
+ {
+ std::stringstream msg;
+ msg << m_simulation_status
+ << ":\n\t immediate thread spawning of "
+ "`" << handle->name() << "' ignored";
+ SC_REPORT_WARNING( SC_ID_PHASE_CALLBACK_FORBIDDEN_
+ , msg.str().c_str() );
+ }
+ else
+#endif // SC_HAS_PHASE_CALLBACKS_
+ {
+ push_runnable_thread( handle );
+ }
+ }
+ else if ( handle->m_static_events.size() == 0 )
+ {
+ SC_REPORT_WARNING( SC_ID_DISABLE_WILL_ORPHAN_PROCESS_,
+ handle->name() );
+ }
+
+ } else {
+ m_process_table->push_front( handle );
+ }
+ return sc_process_handle(handle);
+}
+
+void
+sc_simcontext::add_trace_file( sc_trace_file* tf )
+{
+ m_trace_files.push_back( tf );
+ m_something_to_trace = true;
+}
+
+void
+sc_simcontext::remove_trace_file( sc_trace_file* tf )
+{
+ m_trace_files.erase(
+ std::remove( m_trace_files.begin(), m_trace_files.end(), tf )
+ );
+ m_something_to_trace = ( m_trace_files.size() > 0 );
+}
+
+sc_cor*
+sc_simcontext::next_cor()
+{
+ if( m_error ) {
+ return m_cor;
+ }
+
+ sc_thread_handle thread_h = pop_runnable_thread();
+ while( thread_h != 0 ) {
+ if ( thread_h->m_cor_p != NULL ) break;
+ thread_h = pop_runnable_thread();
+ }
+
+ if( thread_h != 0 ) {
+ return thread_h->m_cor_p;
+ } else {
+ return m_cor;
+ }
+}
+
+const ::std::vector<sc_object*>&
+sc_simcontext::get_child_objects() const
+{
+ static bool warn_get_child_objects=true;
+ if ( warn_get_child_objects )
+ {
+ warn_get_child_objects = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_simcontext::get_child_objects() is deprecated,\n" \
+ " use sc_get_top_level_objects()" );
+ }
+ return m_child_objects;
+}
+
+void
+sc_simcontext::add_child_event( sc_event* event_ )
+{
+ // no check if object_ is already in the set
+ m_child_events.push_back( event_ );
+}
+
+void
+sc_simcontext::add_child_object( sc_object* object_ )
+{
+ // no check if object_ is already in the set
+ m_child_objects.push_back( object_ );
+}
+
+void
+sc_simcontext::remove_child_event( sc_event* event_ )
+{
+ int size = m_child_events.size();
+ for( int i = 0; i < size; ++ i ) {
+ if( event_ == m_child_events[i] ) {
+ m_child_events[i] = m_child_events[size - 1];
+ m_child_events.resize(size-1);
+ return;
+ }
+ }
+ // no check if event_ is really in the set
+}
+
+void
+sc_simcontext::remove_child_object( sc_object* object_ )
+{
+ int size = m_child_objects.size();
+ for( int i = 0; i < size; ++ i ) {
+ if( object_ == m_child_objects[i] ) {
+ m_child_objects[i] = m_child_objects[size - 1];
+ m_child_objects.resize(size-1);
+ return;
+ }
+ }
+ // no check if object_ is really in the set
+}
+
+sc_dt::uint64
+sc_simcontext::delta_count() const
+{
+ static bool warn_delta_count=true;
+ if ( warn_delta_count )
+ {
+ warn_delta_count = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_simcontext::delta_count() is deprecated, use sc_delta_count()" );
+ }
+ return m_delta_count;
+}
+
+bool
+sc_simcontext::is_running() const
+{
+ static bool warn_is_running=true;
+ if ( warn_is_running )
+ {
+ warn_is_running = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_simcontext::is_running() is deprecated, use sc_is_running()" );
+ }
+ return m_ready_to_simulate;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_simcontext::next_time"
+// |
+// | This method returns the time of the next event. If there are no events
+// | it returns false.
+// |
+// | Arguments:
+// | result = where to place time of the next event, if no event is
+// | found this value will not be changed.
+// | Result is true if an event is found, false if not.
+// +----------------------------------------------------------------------------
+bool
+sc_simcontext::next_time( sc_time& result ) const
+{
+ while( m_timed_events->size() ) {
+ sc_event_timed* et = m_timed_events->top();
+ if( et->event() != 0 ) {
+ result = et->notify_time();
+ return true;
+ }
+ delete m_timed_events->extract_top();
+ }
+ return false;
+}
+
+void
+sc_simcontext::remove_delta_event( sc_event* e )
+{
+ int i = e->m_delta_event_index;
+ int j = m_delta_events.size() - 1;
+ assert( i >= 0 && i <= j );
+ if( i != j ) {
+ sc_event** l_delta_events = &m_delta_events[0];
+ l_delta_events[i] = l_delta_events[j];
+ l_delta_events[i]->m_delta_event_index = i;
+ }
+ m_delta_events.resize(m_delta_events.size()-1);
+ e->m_delta_event_index = -1;
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_simcontext::preempt_with"
+// |
+// | This method executes the supplied method immediately, suspending the
+// | caller. After executing the supplied method the caller's execution will
+// | be restored. It is used to allow a method to immediately throw an
+// | exception, e.g., when the method's kill_process() method was called.
+// | There are three cases to consider:
+// | (1) The caller is a method, e.g., murder by method.
+// | (2) The caller is a thread instance, e.g., murder by thread.
+// | (3) The caller is this method instance, e.g., suicide.
+// |
+// | Arguments:
+// | method_h -> method to be executed.
+// +----------------------------------------------------------------------------
+void
+sc_simcontext::preempt_with( sc_method_handle method_h )
+{
+ sc_curr_proc_info caller_info; // process info for caller.
+ sc_method_handle active_method_h; // active method or null.
+ sc_thread_handle active_thread_h; // active thread or null.
+
+ // Determine the active process and take the thread to be run off the
+ // run queue, if its there, since we will be explicitly causing its
+ // execution.
+
+ active_method_h = DCAST<sc_method_handle>(sc_get_current_process_b());
+ active_thread_h = DCAST<sc_thread_handle>(sc_get_current_process_b());
+ if ( method_h->next_runnable() != NULL )
+ remove_runnable_method( method_h );
+
+ // CALLER IS THE METHOD TO BE RUN:
+ //
+ // Should never get here, ignore it unless we are debugging.
+
+ if ( method_h == active_method_h )
+ {
+ DEBUG_MSG(DEBUG_NAME,method_h,"self preemption of active method");
+ }
+
+ // THE CALLER IS A METHOD:
+ //
+ // (a) Set the current process information to our method.
+ // (b) Invoke our method directly by-passing the run queue.
+ // (c) Restore the process info to the caller.
+ // (d) Check to see if the calling method should throw an exception
+ // because of activity that occurred during the preemption.
+
+ else if ( active_method_h != NULL )
+ {
+ caller_info = m_curr_proc_info;
+ DEBUG_MSG( DEBUG_NAME, method_h,
+ "preempting active method with method" );
+ sc_get_curr_simcontext()->set_curr_proc( (sc_process_b*)method_h );
+ method_h->run_process();
+ sc_get_curr_simcontext()->set_curr_proc((sc_process_b*)active_method_h);
+ active_method_h->check_for_throws();
+ }
+
+ // CALLER IS A THREAD:
+ //
+ // (a) Use an invocation thread to execute the method.
+
+ else if ( active_thread_h != NULL )
+ {
+ DEBUG_MSG( DEBUG_NAME, method_h,
+ "preempting active thread with method" );
+ m_method_invoker_p->invoke_method(method_h);
+ }
+
+ // CALLER IS THE SIMULATOR:
+ //
+ // That is not allowed.
+
+ else
+ {
+ caller_info = m_curr_proc_info;
+ DEBUG_MSG( DEBUG_NAME, method_h,
+ "preempting no active process with method" );
+ sc_get_curr_simcontext()->set_curr_proc( (sc_process_b*)method_h );
+ method_h->run_process();
+ m_curr_proc_info = caller_info;
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_simcontext::requeue_current_process"
+//
+// This method requeues the current process at the beginning of the run queue
+// if it is a thread. This is called by sc_process_handle::throw_it() to assure
+// that a thread that is issuing a throw will execute immediately after the
+// processes it notifies via the throw.
+//------------------------------------------------------------------------------
+void sc_simcontext::requeue_current_process()
+{
+ sc_thread_handle thread_p;
+ thread_p = DCAST<sc_thread_handle>(get_curr_proc_info()->process_handle);
+ if ( thread_p )
+ {
+ execute_thread_next( thread_p );
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_simcontext::suspend_current_process"
+//
+// This method suspends the current process if it is a thread. This is called
+// by sc_process_handle::throw_it() to allow the processes that have received
+// a throw to execute.
+//------------------------------------------------------------------------------
+void sc_simcontext::suspend_current_process()
+{
+ sc_thread_handle thread_p;
+ thread_p = DCAST<sc_thread_handle>(get_curr_proc_info()->process_handle);
+ if ( thread_p )
+ {
+ thread_p->suspend_me();
+ }
+}
+
+void
+sc_simcontext::trace_cycle( bool delta_cycle )
+{
+ int size;
+ if( ( size = m_trace_files.size() ) != 0 ) {
+ sc_trace_file** l_trace_files = &m_trace_files[0];
+ int i = size - 1;
+ do {
+ l_trace_files[i]->cycle( delta_cycle );
+ } while( -- i >= 0 );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+#if 1
+#ifdef PURIFY
+ static sc_simcontext sc_default_global_context;
+ sc_simcontext* sc_curr_simcontext = &sc_default_global_context;
+#else
+ sc_simcontext* sc_curr_simcontext = 0;
+ sc_simcontext* sc_default_global_context = 0;
+#endif
+#else
+// Not MT-safe!
+static sc_simcontext* sc_curr_simcontext = 0;
+
+
+sc_simcontext*
+sc_get_curr_simcontext()
+{
+ if( sc_curr_simcontext == 0 ) {
+#ifdef PURIFY
+ static sc_simcontext sc_default_global_context;
+ sc_curr_simcontext = &sc_default_global_context;
+#else
+ static sc_simcontext* sc_default_global_context = new sc_simcontext;
+ sc_curr_simcontext = sc_default_global_context;
+#endif
+ }
+ return sc_curr_simcontext;
+}
+#endif // 0
+
+// Generates unique names within each module.
+
+const char*
+sc_gen_unique_name( const char* basename_, bool preserve_first )
+{
+ sc_simcontext* simc = sc_get_curr_simcontext();
+ sc_module* curr_module = simc->hierarchy_curr();
+ if( curr_module != 0 ) {
+ return curr_module->gen_unique_name( basename_, preserve_first );
+ } else {
+ sc_process_b* curr_proc_p = sc_get_current_process_b();
+ if ( curr_proc_p )
+ {
+ return curr_proc_p->gen_unique_name( basename_, preserve_first );
+ }
+ else
+ {
+ return simc->gen_unique_name( basename_, preserve_first );
+ }
+ }
+}
+
+// Get a handle for the current process
+//
+// Note that this method should not be called if the current process is
+// in the act of being deleted, it will mess up the reference count management
+// of sc_process_b instance the handle represents. Instead, use the a
+// pointer to the raw sc_process_b instance, which may be acquired via
+// sc_get_current_process_b().
+
+sc_process_handle
+sc_get_current_process_handle()
+{
+ return ( sc_is_running() ) ?
+ sc_process_handle(sc_get_current_process_b()) :
+ sc_get_last_created_process_handle();
+}
+
+// THE FOLLOWING FUNCTION IS DEPRECATED IN 2.1
+sc_process_b*
+sc_get_curr_process_handle()
+{
+ static bool warn=true;
+ if ( warn )
+ {
+ warn = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_get_curr_process_handle deprecated use sc_get_current_process_handle"
+ );
+ }
+
+ return sc_get_curr_simcontext()->get_curr_proc_info()->process_handle;
+}
+
+// Return indication if there are more processes to execute in this delta phase
+
+bool
+sc_simcontext::pending_activity_at_current_time() const
+{
+ return ( m_delta_events.size() != 0) ||
+ ( m_runnable->is_initialized() && !m_runnable->is_empty() ) ||
+ m_prim_channel_registry->pending_updates();
+}
+
+// Return time of next activity.
+
+sc_time sc_time_to_pending_activity( const sc_simcontext* simc_p )
+{
+ // If there is an activity pending at the current time
+ // return a delta of zero.
+
+ sc_time result=SC_ZERO_TIME; // time of pending activity.
+
+ if ( simc_p->pending_activity_at_current_time() )
+ {
+ return result;
+ }
+
+ // Any activity will take place in the future pick up the next event's time.
+
+ else
+ {
+ result = simc_p->max_time();
+ simc_p->next_time(result);
+ result -= sc_time_stamp();
+ }
+ return result;
+}
+
+// Set the random seed for controlled randomization -- not yet implemented
+
+void
+sc_set_random_seed( unsigned int )
+{
+ SC_REPORT_WARNING( SC_ID_NOT_IMPLEMENTED_,
+ "void sc_set_random_seed( unsigned int )" );
+}
+
+
+// +----------------------------------------------------------------------------
+// |"sc_start"
+// |
+// | This function starts, or restarts, the execution of the simulator.
+// |
+// | Arguments:
+// | duration = the amount of time the simulator should execute.
+// | p = event starvation policy.
+// +----------------------------------------------------------------------------
+void
+sc_start( const sc_time& duration, sc_starvation_policy p )
+{
+ sc_simcontext* context_p; // current simulation context.
+ sc_time entry_time; // simulation time upon entry.
+ sc_time exit_time; // simulation time to set upon exit.
+ sc_dt::uint64 starting_delta; // delta count upon entry.
+ int status; // current simulation status.
+
+ // Set up based on the arguments passed to us:
+
+ context_p = sc_get_curr_simcontext();
+ starting_delta = sc_delta_count();
+ entry_time = context_p->m_curr_time;
+ if ( p == SC_RUN_TO_TIME )
+ exit_time = context_p->m_curr_time + duration;
+
+ // called with duration = SC_ZERO_TIME for the first time
+ static bool init_delta_or_pending_updates =
+ ( starting_delta == 0 && exit_time == SC_ZERO_TIME );
+
+ // If the simulation status is bad issue the appropriate message:
+
+ status = context_p->sim_status();
+ if( status != SC_SIM_OK )
+ {
+ if ( status == SC_SIM_USER_STOP )
+ SC_REPORT_ERROR(SC_ID_SIMULATION_START_AFTER_STOP_, "");
+ if ( status == SC_SIM_ERROR )
+ SC_REPORT_ERROR(SC_ID_SIMULATION_START_AFTER_ERROR_, "");
+ return;
+ }
+
+ if ( context_p->m_prim_channel_registry->pending_updates() )
+ init_delta_or_pending_updates = true;
+
+ // If the simulation status is good perform the simulation:
+
+ context_p->simulate( duration );
+
+ // Re-check the status:
+
+ status = context_p->sim_status();
+
+ // Update the current time to the exit time if that is the starvation
+ // policy:
+
+ if ( p == SC_RUN_TO_TIME && !context_p->m_paused && status == SC_SIM_OK )
+ {
+ context_p->m_curr_time = exit_time;
+ }
+
+ // If there was no activity and the simulation clock did not move warn
+ // the user, except if we're in a first sc_start(SC_ZERO_TIME) for
+ // initialisation (only) or there have been pending updates:
+
+ if ( !init_delta_or_pending_updates &&
+ starting_delta == sc_delta_count() &&
+ context_p->m_curr_time == entry_time &&
+ status == SC_SIM_OK )
+ {
+ SC_REPORT_WARNING(SC_ID_NO_SC_START_ACTIVITY_, "");
+ }
+
+ // reset init/update flag for subsequent calls
+ init_delta_or_pending_updates = false;
+}
+
+void
+sc_start()
+{
+ sc_start( sc_max_time() - sc_time_stamp(),
+ SC_EXIT_ON_STARVATION );
+}
+
+// for backward compatibility with 1.0
+#if 0
+void
+sc_start( double duration ) // in default time units
+{
+ static bool warn_sc_start=true;
+ if ( warn_sc_start )
+ {
+ warn_sc_start = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_start(double) deprecated, use sc_start(sc_time) or sc_start()");
+ }
+
+ if( duration == -1 ) // simulate forever
+ {
+ sc_start(
+ sc_time(~sc_dt::UINT64_ZERO, false) - sc_time_stamp() );
+ }
+ else
+ {
+ sc_start( sc_time( duration, true ) );
+ }
+}
+#endif //
+
+void
+sc_stop()
+{
+ sc_get_curr_simcontext()->stop();
+}
+
+
+// The following function is deprecated in favor of sc_start(SC_ZERO_TIME):
+
+void
+sc_initialize()
+{
+ static bool warning_initialize = true;
+
+ if ( warning_initialize )
+ {
+ warning_initialize = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_initialize() is deprecated: use sc_start(SC_ZERO_TIME)" );
+ }
+ sc_get_curr_simcontext()->initialize();
+}
+
+// The following function has been deprecated in favor of sc_start(duration):
+
+void
+sc_cycle( const sc_time& duration )
+{
+ static bool warning_cycle = true;
+
+ if ( warning_cycle )
+ {
+ warning_cycle = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_cycle is deprecated: use sc_start(sc_time)" );
+ }
+ sc_get_curr_simcontext()->cycle( duration );
+}
+
+sc_event* sc_find_event( const char* name )
+{
+ return sc_get_curr_simcontext()->get_object_manager()->find_event( name );
+}
+
+sc_object* sc_find_object( const char* name )
+{
+ return sc_get_curr_simcontext()->get_object_manager()->find_object( name );
+}
+
+
+const sc_time&
+sc_max_time()
+{
+ return sc_get_curr_simcontext()->max_time();
+}
+
+const sc_time&
+sc_time_stamp()
+{
+ return sc_get_curr_simcontext()->time_stamp();
+}
+
+double
+sc_simulation_time()
+{
+ static bool warn_simulation_time=true;
+ if ( warn_simulation_time )
+ {
+ warn_simulation_time=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "sc_simulation_time() is deprecated use sc_time_stamp()" );
+ }
+ return sc_get_curr_simcontext()->time_stamp().to_default_time_units();
+}
+
+void
+sc_defunct_process_function( sc_module* )
+{
+ // This function is pointed to by defunct sc_thread_process'es and
+ // sc_cthread_process'es. In a correctly constructed world, this
+ // function should never be called; hence the assert.
+ assert( false );
+}
+
+//------------------------------------------------------------------------------
+//"sc_set_stop_mode"
+//
+// This function sets the mode of operation when sc_stop() is called.
+// mode = SC_STOP_IMMEDIATE or SC_STOP_FINISH_DELTA.
+//------------------------------------------------------------------------------
+void sc_set_stop_mode(sc_stop_mode mode)
+{
+ if ( sc_is_running() )
+ {
+ SC_REPORT_ERROR(SC_ID_STOP_MODE_AFTER_START_,"");
+ }
+ else
+ {
+ switch( mode )
+ {
+ case SC_STOP_IMMEDIATE:
+ case SC_STOP_FINISH_DELTA:
+ stop_mode = mode;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+sc_stop_mode
+sc_get_stop_mode()
+{
+ return stop_mode;
+}
+
+bool sc_is_unwinding()
+{
+ return sc_get_current_process_handle().is_unwinding();
+}
+
+// The IEEE 1666 Standard for 2011 designates that the treatment of
+// certain process control interactions as being "implementation dependent".
+// These interactions are:
+// (1) What happens when a resume() call is performed on a disabled,
+// suspended process.
+// (2) What happens when sync_reset_on() or sync_reset_off() is called
+// on a suspended process.
+// (3) What happens when the value specified in a reset_signal_is()
+// call changes value while a process is suspended.
+//
+// By default this Proof of Concept implementation reports an error
+// for these interactions. However, the implementation also provides
+// a non-error treatment. The non-error treatment for the interactions is:
+// (1) A resume() call performed on a disabled, suspended process will
+// mark the process as no longer suspended, and if it is capable
+// of execution (not waiting on any events) it will be placed on
+// the queue of runnable processes. See the state diagram below.
+// (2) A call to sync_reset_on() or sync_reset_off() will set or clear
+// the synchronous reset flag. Whether the process is in reset or
+// not will be determined when the process actually executes by
+// looking at the flag's value at that time.
+// (3) If a suspended process has a reset_signal_is() specification
+// the value of the reset variable at the time of its next execution
+// will determine whether it is in reset or not.
+//
+// TO GET THE NON-ERROR BEHAVIOR SET THE VARIABLE BELOW TO TRUE.
+//
+// This can be done in this source before you build the library, or you
+// can use an assignment as the first statement in your sc_main() function:
+// sc_core::sc_allow_process_control_corners = true;
+
+bool sc_allow_process_control_corners = false;
+
+// The state transition diagram for the interaction of disable and suspend
+// when sc_allow_process_control_corners is true is shown below:
+//
+// ......................................................................
+// . ENABLED . DISABLED .
+// . . .
+// . +----------+ disable +----------+ .
+// . +------------>| |-------.-------->| | .
+// . | | runnable | . | runnable | .
+// . | +-------| |<------.---------| |------+ .
+// . | | +----------+ enable +----------+ | .
+// . | | | ^ . | ^ | .
+// . | | suspend | | resume . suspend | | resume | .
+// . | | V | . V | | .
+// . | | +----------+ disable +----------+ | .
+// . | | | suspend |-------.-------->| suspend | | .
+// . t | r | | | . | | | r .
+// . r | u | | ready |<------.---------| ready | | u .
+// . i | n | +----------+ enable +----------+ | n .
+// . g | / | ^ . | / .
+// . g | w | trigger| . | w .
+// . e | a | | . | a .
+// . r | i | +----------+ disable +----------+ | i .
+// . | t | | suspend |-------.-------->| suspend | | t .
+// . | | | | . | | | .
+// . | | | waiting |<------.---------| waiting | | .
+// . | | +----------+ enable +----------+ | .
+// . | | | ^ . | ^ | .
+// . | | suspend | | resume . suspend | | resume | .
+// . | | V | . V | | .
+// . | | +----------+ disable +----------+ | .
+// . | +------>| |-------.-------->| | | .
+// . | | waiting | . | waiting | | .
+// . +-------------| |<------.---------| |<-----+ .
+// . +----------+ enable +----------+ .
+// . . .
+// ......................................................................
+
+// ----------------------------------------------------------------------------
+
+static std::ostream&
+print_status_expression( std::ostream& os, sc_status s );
+
+// utility helper to print a simulation status
+std::ostream& operator << ( std::ostream& os, sc_status s )
+{
+ // print primitive values
+ switch(s)
+ {
+# define PRINT_STATUS( Status ) \
+ case Status: { os << #Status; } break
+
+ PRINT_STATUS( SC_UNITIALIZED );
+ PRINT_STATUS( SC_ELABORATION );
+ PRINT_STATUS( SC_BEFORE_END_OF_ELABORATION );
+ PRINT_STATUS( SC_END_OF_ELABORATION );
+ PRINT_STATUS( SC_START_OF_SIMULATION );
+
+ PRINT_STATUS( SC_RUNNING );
+ PRINT_STATUS( SC_PAUSED );
+ PRINT_STATUS( SC_STOPPED );
+ PRINT_STATUS( SC_END_OF_SIMULATION );
+
+ PRINT_STATUS( SC_END_OF_INITIALIZATION );
+// PRINT_STATUS( SC_END_OF_EVALUATION );
+ PRINT_STATUS( SC_END_OF_UPDATE );
+ PRINT_STATUS( SC_BEFORE_TIMESTEP );
+
+ PRINT_STATUS( SC_STATUS_ANY );
+
+# undef PRINT_STATUS
+ default:
+
+ if( s & SC_STATUS_ANY ) // combination of status bits
+ print_status_expression( os, s );
+ else // invalid number, print hex value
+ os << "0x" << std::hex << +s;
+ }
+
+ return os;
+}
+
+// pretty-print a combination of sc_status bits (i.e. a callback mask)
+static std::ostream&
+print_status_expression( std::ostream& os, sc_status s )
+{
+ std::vector<sc_status> bits;
+ unsigned is_set = SC_ELABORATION;
+
+ // collect bits
+ while( is_set <= SC_STATUS_LAST )
+ {
+ if( s & is_set )
+ bits.push_back( (sc_status)is_set );
+ is_set <<= 1;
+ }
+ if( s & ~SC_STATUS_ANY ) // remaining bits
+ bits.push_back( (sc_status)( s & ~SC_STATUS_ANY ) );
+
+ // print expression
+ std::vector<sc_status>::size_type i=0, n=bits.size();
+ if ( n>1 )
+ os << "(";
+ for( ; i<n-1; ++i )
+ os << bits[i] << "|";
+ os << bits[i];
+ if ( n>1 )
+ os << ")";
+ return os;
+}
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
+ Description of Modification: - Added sc_stop() detection into initial_crunch
+ and crunch. This makes it possible to exit out
+ of a combinational loop using sc_stop().
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems 20 May 2003
+ Description of Modification: - sc_stop mode
+ - phase callbacks
+
+ Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August 2003
+ Description of Modification: - support for dynamic process
+ - support for sc export registry
+ - new member methods elaborate(),
+ prepare_to_simulate(), and initial_crunch()
+ that are invoked by initialize() in that order
+ - implement sc_get_last_created_process_handle() for use
+ before simulation starts
+ - remove "set_curr_proc(handle)" from
+ register_method_process and
+ register_thread_process - led to bugs
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems 04 Sep 2003
+ Description of Modification: - changed process existence structures to
+ linked lists to eliminate exponential
+ execution problem with using sc_pvector.
+ *****************************************************************************/
+// $Log: sc_simcontext.cpp,v $
+// Revision 1.37 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.36 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.35 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.34 2011/08/04 17:15:28 acg
+// Andy Goodrich: added documentation to crunch() routine.
+//
+// Revision 1.32 2011/07/24 11:16:36 acg
+// Philipp A. Hartmann: fix reference counting on deferred deletions of
+// processes.
+//
+// Revision 1.31 2011/07/01 18:49:07 acg
+// Andy Goodrich: moved pln() from sc_simcontext.cpp to sc_ver.cpp.
+//
+// Revision 1.30 2011/05/09 04:07:49 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.29 2011/04/08 22:39:09 acg
+// Andy Goodrich: moved method invocation code to sc_method.h so that the
+// details are hidden from sc_simcontext.
+//
+// Revision 1.28 2011/04/05 20:50:57 acg
+// Andy Goodrich:
+// (1) changes to make sure that event(), posedge() and negedge() only
+// return true if the clock has not moved.
+// (2) fixes for method self-resumes.
+// (3) added SC_PRERELEASE_VERSION
+// (4) removed kernel events from the object hierarchy, added
+// sc_hierarchy_name_exists().
+//
+// Revision 1.27 2011/04/05 06:14:15 acg
+// Andy Goodrich: fix typo.
+//
+// Revision 1.26 2011/04/05 06:03:32 acg
+// Philipp A. Hartmann: added code to set ready to run bit for a suspended
+// process that does not have dont_initialize specified at simulation
+// start up.
+//
+// Revision 1.25 2011/04/01 21:31:55 acg
+// Andy Goodrich: make sure processes suspended before the start of execution
+// don't get scheduled for initial execution.
+//
+// Revision 1.24 2011/03/28 13:02:52 acg
+// Andy Goodrich: Changes for disable() interactions.
+//
+// Revision 1.23 2011/03/12 21:07:51 acg
+// Andy Goodrich: changes to kernel generated event support.
+//
+// Revision 1.22 2011/03/07 17:38:43 acg
+// Andy Goodrich: tightening up of checks for undefined interaction between
+// synchronous reset and suspend.
+//
+// Revision 1.21 2011/03/06 19:57:11 acg
+// Andy Goodrich: refinements for the illegal suspend - synchronous reset
+// interaction.
+//
+// Revision 1.20 2011/03/06 15:58:50 acg
+// Andy Goodrich: added escape to turn off process control corner case
+// checks.
+//
+// Revision 1.19 2011/03/05 04:45:16 acg
+// Andy Goodrich: moved active process calculation to the sc_simcontext class.
+//
+// Revision 1.18 2011/03/05 01:39:21 acg
+// Andy Goodrich: changes for named events.
+//
+// Revision 1.17 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.16 2011/02/17 19:53:28 acg
+// Andy Goodrich: eliminated use of ready_to_run() as part of process control
+// simplification.
+//
+// Revision 1.15 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.14 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.13 2011/02/08 08:42:50 acg
+// Andy Goodrich: fix ordering of check for stopped versus paused.
+//
+// Revision 1.12 2011/02/07 19:17:20 acg
+// Andy Goodrich: changes for IEEE 1666 compatibility.
+//
+// Revision 1.11 2011/02/02 07:18:11 acg
+// Andy Goodrich: removed toggle() calls for the new crunch() toggle usage.
+//
+// Revision 1.10 2011/02/01 23:01:53 acg
+// Andy Goodrich: removed dead code.
+//
+// Revision 1.9 2011/02/01 21:11:59 acg
+// Andy Goodrich:
+// (1) Use of new toggle_methods() and toggle_threads() run queue methods
+// to make sure the thread run queue does not execute when allow preempt_me()
+// is called from an SC_METHOD.
+// (2) Use of execute_thread_next() to allow thread execution in the current
+// delta cycle() rather than push_runnable_thread_front which executed
+// in the following cycle.
+//
+// Revision 1.8 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.7 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.6 2011/01/18 20:10:45 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.5 2010/11/20 17:10:57 acg
+// Andy Goodrich: reset processing changes for new IEEE 1666 standard.
+//
+// Revision 1.4 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.3 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2007/09/20 20:32:35 acg
+// Andy Goodrich: changes to the semantics of throw_it() to match the
+// specification. A call to throw_it() will immediately suspend the calling
+// thread until all the throwees have executed. At that point the calling
+// thread will be restarted before the execution of any other threads.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.21 2006/08/29 23:37:13 acg
+// Andy Goodrich: Added check for negative time.
+//
+// Revision 1.20 2006/05/26 20:33:16 acg
+// Andy Goodrich: changes required by additional platform compilers (i.e.,
+// Microsoft VC++, Sun Forte, HP aCC).
+//
+// Revision 1.19 2006/05/08 17:59:52 acg
+// Andy Goodrich: added a check before m_curr_time is set to make sure it
+// is not set to a time before its current value. This will treat
+// sc_event.notify( ) calls with negative times as calls with a zero time.
+//
+// Revision 1.18 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.17 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.16 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.15 2006/03/13 20:26:50 acg
+// Andy Goodrich: Addition of forward class declarations, e.g.,
+// sc_reset, to keep gcc 4.x happy.
+//
+// Revision 1.14 2006/02/02 23:42:41 acg
+// Andy Goodrich: implemented a much better fix to the sc_event_finder
+// proliferation problem. This new version allocates only a single event
+// finder for each port for each type of event, e.g., pos(), neg(), and
+// value_change(). The event finder persists as long as the port does,
+// which is what the LRM dictates. Because only a single instance is
+// allocated for each event type per port there is not a potential
+// explosion of storage as was true in the 2.0.1/2.1 versions.
+//
+// Revision 1.13 2006/02/02 21:29:10 acg
+// Andy Goodrich: removed the call to sc_event_finder::free_instances() that
+// was in end_of_elaboration(), leaving only the call in clean(). This is
+// because the LRM states that sc_event_finder instances are persistent as
+// long as the sc_module hierarchy is valid.
+//
+// Revision 1.12 2006/02/02 21:09:50 acg
+// Andy Goodrich: added call to sc_event_finder::free_instances in the clean()
+// method.
+//
+// Revision 1.11 2006/02/02 20:43:14 acg
+// Andy Goodrich: Added an existence linked list to sc_event_finder so that
+// the dynamically allocated instances can be freed after port binding
+// completes. This replaces the individual deletions in ~sc_bind_ef, as these
+// caused an exception if an sc_event_finder instance was used more than
+// once, due to a double freeing of the instance.
+//
+// Revision 1.10 2006/01/31 21:43:26 acg
+// Andy Goodrich: added comments in constructor to highlight environmental
+// overrides section.
+//
+// Revision 1.9 2006/01/26 21:04:54 acg
+// Andy Goodrich: deprecation message changes and additional messages.
+//
+// Revision 1.8 2006/01/25 00:31:19 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.7 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.6 2006/01/19 00:29:52 acg
+// Andy Goodrich: Yet another implementation for signal write checking. This
+// one uses an environment variable SC_SIGNAL_WRITE_CHECK, that when set to
+// DISABLE will disable write checking on signals.
+//
+// Revision 1.5 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
+// Revision 1.4 2006/01/03 23:18:44 acg
+// Changed copyright to include 2006.
+//
+// Revision 1.3 2005/12/20 22:11:10 acg
+// Fixed $Log lines.
+//
+// Revision 1.2 2005/12/20 22:02:30 acg
+// Changed where delta cycles are incremented to match IEEE 1666. Added the
+// event_occurred() method to hide how delta cycle comparisions are done within
+// sc_simcontext. Changed the boolean update_phase to an enum that shows all
+// the phases.
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_simcontext.h b/ext/systemc/src/sysc/kernel/sc_simcontext.h
new file mode 100644
index 000000000..997a3f49c
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_simcontext.h
@@ -0,0 +1,903 @@
+/*****************************************************************************
+
+ 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_simcontext.h -- Definition of the simulation context class.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_SIMCONTEXT_H
+#define SC_SIMCONTEXT_H
+
+#include "sysc/kernel/sc_cmnhdr.h"
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_status.h"
+#include "sysc/kernel/sc_time.h"
+#include "sysc/utils/sc_hash.h"
+#include "sysc/utils/sc_pq.h"
+
+namespace sc_core {
+
+// forward declarations
+
+class sc_cor;
+class sc_cor_pkg;
+class sc_event;
+class sc_event_timed;
+class sc_export_registry;
+class sc_module;
+class sc_module_name;
+class sc_module_registry;
+class sc_name_gen;
+class sc_object;
+class sc_object_manager;
+class sc_phase_callback_registry;
+class sc_process_handle;
+class sc_port_registry;
+class sc_prim_channel_registry;
+class sc_process_table;
+class sc_signal_bool_deval;
+class sc_trace_file;
+class sc_runnable;
+class sc_process_host;
+class sc_method_process;
+class sc_cthread_process;
+class sc_thread_process;
+
+template< typename > class sc_plist;
+typedef sc_plist< sc_process_b* > sc_process_list;
+
+struct sc_curr_proc_info
+{
+ sc_process_b* process_handle;
+ sc_curr_proc_kind kind;
+ sc_curr_proc_info() : process_handle( 0 ), kind( SC_NO_PROC_ ) {}
+};
+
+typedef const sc_curr_proc_info* sc_curr_proc_handle;
+
+enum sc_stop_mode { // sc_stop modes:
+ SC_STOP_FINISH_DELTA,
+ SC_STOP_IMMEDIATE
+};
+extern void sc_set_stop_mode( sc_stop_mode mode );
+extern sc_stop_mode sc_get_stop_mode();
+
+enum sc_starvation_policy
+{
+ SC_EXIT_ON_STARVATION,
+ SC_RUN_TO_TIME
+};
+extern void sc_start();
+extern void sc_start( const sc_time& duration,
+ sc_starvation_policy p=SC_RUN_TO_TIME );
+inline void sc_start( int duration, sc_time_unit unit,
+ sc_starvation_policy p=SC_RUN_TO_TIME )
+{
+ sc_start( sc_time((double)duration,unit), p );
+}
+
+inline void sc_start( double duration, sc_time_unit unit,
+ sc_starvation_policy p=SC_RUN_TO_TIME )
+{
+ sc_start( sc_time(duration,unit), p );
+}
+
+extern void sc_stop();
+
+// friend function declarations
+
+sc_dt::uint64 sc_delta_count();
+const std::vector<sc_event*>& sc_get_top_level_events(
+ const sc_simcontext* simc_p);
+const std::vector<sc_object*>& sc_get_top_level_objects(
+ const sc_simcontext* simc_p);
+bool sc_is_running( const sc_simcontext* simc_p );
+void sc_pause();
+bool sc_end_of_simulation_invoked();
+void sc_start( const sc_time&, sc_starvation_policy );
+bool sc_start_of_simulation_invoked();
+void sc_set_time_resolution( double, sc_time_unit );
+sc_time sc_get_time_resolution();
+void sc_set_default_time_unit( double, sc_time_unit );
+sc_time sc_get_default_time_unit();
+bool sc_pending_activity_at_current_time( const sc_simcontext* );
+bool sc_pending_activity_at_future_time( const sc_simcontext* );
+sc_time sc_time_to_pending_activity( const sc_simcontext* );
+
+struct sc_invoke_method;
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_simcontext
+//
+// The simulation context.
+// ----------------------------------------------------------------------------
+
+class sc_simcontext
+{
+ friend struct sc_invoke_method;
+ friend class sc_event;
+ friend class sc_module;
+ friend class sc_object;
+ friend class sc_time;
+ friend class sc_clock;
+ friend class sc_method_process;
+ friend class sc_phase_callback_registry;
+ friend class sc_process_b;
+ friend class sc_process_handle;
+ friend class sc_prim_channel;
+ friend class sc_cthread_process;
+ friend class sc_thread_process;
+ friend sc_dt::uint64 sc_delta_count();
+ friend const std::vector<sc_event*>& sc_get_top_level_events(
+ const sc_simcontext* simc_p);
+ friend const std::vector<sc_object*>& sc_get_top_level_objects(
+ const sc_simcontext* simc_p);
+ friend bool sc_is_running( const sc_simcontext* simc_p );
+ friend void sc_pause();
+ friend bool sc_end_of_simulation_invoked();
+ friend void sc_start( const sc_time&, sc_starvation_policy );
+ friend bool sc_start_of_simulation_invoked();
+ friend void sc_thread_cor_fn(void*);
+ friend sc_time sc_time_to_pending_activity( const sc_simcontext* );
+ friend bool sc_pending_activity_at_current_time( const sc_simcontext* );
+ friend bool sc_pending_activity_at_future_time( const sc_simcontext* );
+
+
+ void init();
+ void clean();
+
+public:
+
+ sc_simcontext();
+ ~sc_simcontext();
+
+ void initialize( bool = false );
+ void cycle( const sc_time& );
+ void simulate( const sc_time& duration );
+ void stop();
+ void end();
+ void reset();
+
+ int sim_status() const;
+ bool elaboration_done() const;
+
+ std::vector<sc_thread_handle>& get_active_invokers();
+
+ sc_object_manager* get_object_manager();
+
+ inline sc_status get_status() const;
+
+ sc_object* active_object();
+
+ void hierarchy_push( sc_module* );
+ sc_module* hierarchy_pop();
+ sc_module* hierarchy_curr() const;
+ sc_object* first_object();
+ sc_object* next_object();
+ sc_object* find_object( const char* name );
+
+ sc_module_registry* get_module_registry();
+ sc_port_registry* get_port_registry();
+ sc_export_registry* get_export_registry();
+ sc_prim_channel_registry* get_prim_channel_registry();
+
+ // to generate unique names for objects in an MT-Safe way
+ const char* gen_unique_name( const char* basename_,
+ bool preserve_first = false
+ );
+
+ // process creation
+ sc_process_handle create_cthread_process(
+ const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,
+ sc_process_host* host_p, const sc_spawn_options* opt_p );
+
+ sc_process_handle create_method_process(
+ const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,
+ sc_process_host* host_p, const sc_spawn_options* opt_p );
+
+ sc_process_handle create_thread_process(
+ const char* name_p, bool free_host, SC_ENTRY_FUNC method_p,
+ sc_process_host* host_p, const sc_spawn_options* opt_p );
+
+ sc_curr_proc_handle get_curr_proc_info();
+ sc_object* get_current_writer() const;
+ bool write_check() const;
+ void set_curr_proc( sc_process_b* );
+ void reset_curr_proc();
+
+ int next_proc_id();
+
+ void add_trace_file( sc_trace_file* );
+ void remove_trace_file( sc_trace_file* );
+
+ friend void sc_set_time_resolution( double, sc_time_unit );
+ friend sc_time sc_get_time_resolution();
+ friend void sc_set_default_time_unit( double, sc_time_unit );
+ friend sc_time sc_get_default_time_unit();
+
+ const sc_time& max_time() const;
+ const sc_time& time_stamp() const;
+
+ sc_dt::uint64 change_stamp() const;
+ sc_dt::uint64 delta_count() const;
+ bool event_occurred( sc_dt::uint64 last_change_count ) const;
+ bool evaluation_phase() const;
+ bool is_running() const;
+ bool update_phase() const;
+ bool notify_phase() const;
+ bool get_error();
+ void set_error( sc_report* );
+
+ sc_cor_pkg* cor_pkg()
+ { return m_cor_pkg; }
+ sc_cor* next_cor();
+
+ const ::std::vector<sc_object*>& get_child_objects() const;
+
+ void elaborate();
+ void prepare_to_simulate();
+ inline void initial_crunch( bool no_crunch );
+ bool next_time( sc_time& t ) const;
+ bool pending_activity_at_current_time() const;
+
+private:
+
+ void add_child_event( sc_event* );
+ void add_child_object( sc_object* );
+ void remove_child_event( sc_event* );
+ void remove_child_object( sc_object* );
+
+ void crunch( bool once=false );
+
+ int add_delta_event( sc_event* );
+ void remove_delta_event( sc_event* );
+ void add_timed_event( sc_event_timed* );
+
+ void trace_cycle( bool delta_cycle );
+
+ const ::std::vector<sc_event*>& get_child_events_internal() const;
+ const ::std::vector<sc_object*>& get_child_objects_internal() const;
+
+ void execute_method_next( sc_method_handle );
+ void execute_thread_next( sc_thread_handle );
+
+ sc_method_handle pop_runnable_method();
+ sc_thread_handle pop_runnable_thread();
+
+ void preempt_with( sc_method_handle );
+ inline void preempt_with( sc_thread_handle );
+
+ void push_runnable_method( sc_method_handle );
+ void push_runnable_thread( sc_thread_handle );
+
+ void push_runnable_method_front( sc_method_handle );
+ void push_runnable_thread_front( sc_thread_handle );
+
+ void remove_runnable_method( sc_method_handle );
+ void remove_runnable_thread( sc_thread_handle );
+
+ void requeue_current_process();
+ void suspend_current_process();
+
+ void do_sc_stop_action();
+ void mark_to_collect_process( sc_process_b* zombie_p );
+
+private:
+
+ enum execution_phases {
+ phase_initialize = 0,
+ phase_evaluate,
+ phase_update,
+ phase_notify
+ };
+ sc_object_manager* m_object_manager;
+
+ sc_module_registry* m_module_registry;
+ sc_port_registry* m_port_registry;
+ sc_export_registry* m_export_registry;
+ sc_prim_channel_registry* m_prim_channel_registry;
+ sc_phase_callback_registry* m_phase_cb_registry;
+
+ sc_name_gen* m_name_gen;
+
+ sc_process_table* m_process_table;
+ sc_curr_proc_info m_curr_proc_info;
+ sc_object* m_current_writer;
+ bool m_write_check;
+ int m_next_proc_id;
+
+ std::vector<sc_thread_handle> m_active_invokers;
+
+ std::vector<sc_event*> m_child_events;
+ std::vector<sc_object*> m_child_objects;
+
+ std::vector<sc_event*> m_delta_events;
+ sc_ppq<sc_event_timed*>* m_timed_events;
+
+ std::vector<sc_trace_file*> m_trace_files;
+ bool m_something_to_trace;
+
+ sc_runnable* m_runnable;
+ sc_process_list* m_collectable;
+
+ sc_time_params* m_time_params;
+ sc_time m_curr_time;
+ mutable sc_time m_max_time;
+
+ sc_invoke_method* m_method_invoker_p;
+ sc_dt::uint64 m_change_stamp; // "time" change occurred.
+ sc_dt::uint64 m_delta_count;
+ bool m_forced_stop;
+ bool m_paused;
+ bool m_ready_to_simulate;
+ bool m_elaboration_done;
+ execution_phases m_execution_phase;
+ sc_report* m_error;
+ bool m_in_simulator_control;
+ bool m_end_of_simulation_called;
+ sc_status m_simulation_status;
+ bool m_start_of_simulation_called;
+
+ sc_cor_pkg* m_cor_pkg; // the simcontext's coroutine package
+ sc_cor* m_cor; // the simcontext's coroutine
+
+private:
+
+ // disabled
+ sc_simcontext( const sc_simcontext& );
+ sc_simcontext& operator = ( const sc_simcontext& );
+};
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// Not MT safe.
+
+#if 1
+extern sc_simcontext* sc_curr_simcontext;
+extern sc_simcontext* sc_default_global_context;
+
+inline sc_simcontext*
+sc_get_curr_simcontext()
+{
+ if( sc_curr_simcontext == 0 ) {
+ sc_default_global_context = new sc_simcontext;
+ sc_curr_simcontext = sc_default_global_context;
+ }
+ return sc_curr_simcontext;
+}
+#else
+ extern sc_simcontext* sc_get_curr_simcontext();
+#endif // 0
+inline sc_status sc_get_status()
+{
+ return sc_get_curr_simcontext()->get_status();
+}
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+inline
+bool
+sc_simcontext::elaboration_done() const
+{
+ return m_elaboration_done;
+}
+
+
+inline sc_status sc_simcontext::get_status() const
+{
+ return m_simulation_status != SC_RUNNING ?
+ m_simulation_status :
+ (m_in_simulator_control ? SC_RUNNING : SC_PAUSED);
+}
+
+inline
+int
+sc_simcontext::sim_status() const
+{
+ if( m_error ) {
+ return SC_SIM_ERROR;
+ }
+ if( m_forced_stop ) {
+ return SC_SIM_USER_STOP;
+ }
+ return SC_SIM_OK;
+}
+
+
+inline
+sc_object_manager*
+sc_simcontext::get_object_manager()
+{
+ return m_object_manager;
+}
+
+inline
+sc_module_registry*
+sc_simcontext::get_module_registry()
+{
+ return m_module_registry;
+}
+
+inline
+sc_port_registry*
+sc_simcontext::get_port_registry()
+{
+ return m_port_registry;
+}
+
+inline
+sc_export_registry*
+sc_simcontext::get_export_registry()
+{
+ return m_export_registry;
+}
+
+inline
+sc_prim_channel_registry*
+sc_simcontext::get_prim_channel_registry()
+{
+ return m_prim_channel_registry;
+}
+
+
+inline
+sc_curr_proc_handle
+sc_simcontext::get_curr_proc_info()
+{
+ return &m_curr_proc_info;
+}
+
+
+inline
+int
+sc_simcontext::next_proc_id()
+{
+ return ( ++ m_next_proc_id );
+}
+
+
+inline
+const sc_time&
+sc_simcontext::max_time() const
+{
+ if ( m_max_time == SC_ZERO_TIME )
+ {
+ m_max_time = sc_time::from_value( ~sc_dt::UINT64_ZERO );
+ }
+ return m_max_time;
+}
+
+inline
+sc_dt::uint64
+sc_simcontext::change_stamp() const
+{
+ return m_change_stamp;
+}
+
+inline
+const sc_time&
+sc_simcontext::time_stamp() const
+{
+ return m_curr_time;
+}
+
+
+inline
+bool
+sc_simcontext::event_occurred(sc_dt::uint64 last_change_stamp) const
+{
+ return m_change_stamp == last_change_stamp;
+}
+
+inline
+bool
+sc_simcontext::evaluation_phase() const
+{
+ return (m_execution_phase == phase_evaluate) &&
+ m_ready_to_simulate;
+}
+
+inline
+bool
+sc_simcontext::update_phase() const
+{
+ return m_execution_phase == phase_update;
+}
+
+inline
+bool
+sc_simcontext::notify_phase() const
+{
+ return m_execution_phase == phase_notify;
+}
+
+inline
+void
+sc_simcontext::set_error( sc_report* err )
+{
+ delete m_error;
+ m_error = err;
+}
+
+
+inline
+bool
+sc_simcontext::get_error()
+{
+ return m_error != NULL;
+}
+
+inline
+int
+sc_simcontext::add_delta_event( sc_event* e )
+{
+ m_delta_events.push_back( e );
+ return ( m_delta_events.size() - 1 );
+}
+
+inline
+void
+sc_simcontext::add_timed_event( sc_event_timed* et )
+{
+ m_timed_events->insert( et );
+}
+
+inline sc_object*
+sc_simcontext::get_current_writer() const
+{
+ return m_current_writer;
+}
+
+inline bool
+sc_simcontext::write_check() const
+{
+ return m_write_check;
+}
+
+// ----------------------------------------------------------------------------
+
+class sc_process_handle;
+sc_process_handle sc_get_current_process_handle();
+
+// Get the current object hierarchy context
+//
+// Returns a pointer the the sc_object (module or process) that
+// would become the parent object of a newly created element
+// of the SystemC object hierarchy, or NULL.
+//
+inline sc_object*
+sc_get_current_object()
+{
+ return sc_get_curr_simcontext()->active_object();
+}
+
+inline
+sc_process_b*
+sc_get_current_process_b()
+{
+ return sc_get_curr_simcontext()->get_curr_proc_info()->process_handle;
+}
+
+// THE FOLLOWING FUNCTION IS DEPRECATED IN 2.1
+extern sc_process_b* sc_get_curr_process_handle();
+
+inline
+sc_curr_proc_kind
+sc_get_curr_process_kind()
+{
+ return sc_get_curr_simcontext()->get_curr_proc_info()->kind;
+}
+
+
+inline int sc_get_simulator_status()
+{
+ return sc_get_curr_simcontext()->sim_status();
+}
+
+
+// Generates unique names within each module.
+extern
+const char*
+sc_gen_unique_name( const char* basename_, bool preserve_first = false );
+
+
+// Set the random seed for controlled randomization -- not yet implemented
+extern
+void
+sc_set_random_seed( unsigned int seed_ );
+
+
+extern void sc_initialize();
+
+extern const sc_time& sc_max_time(); // Get maximum time value.
+extern const sc_time& sc_time_stamp(); // Current simulation time.
+extern double sc_simulation_time(); // Current time in default time units.
+
+inline
+const std::vector<sc_event*>& sc_get_top_level_events(
+ const sc_simcontext* simc_p = sc_get_curr_simcontext() )
+{
+ return simc_p->m_child_events;
+}
+
+inline
+const std::vector<sc_object*>& sc_get_top_level_objects(
+ const sc_simcontext* simc_p = sc_get_curr_simcontext() )
+{
+ return simc_p->m_child_objects;
+}
+
+extern sc_event* sc_find_event( const char* name );
+
+extern sc_object* sc_find_object( const char* name );
+
+inline
+sc_dt::uint64 sc_delta_count()
+{
+ return sc_get_curr_simcontext()->m_delta_count;
+}
+
+inline
+bool sc_is_running( const sc_simcontext* simc_p = sc_get_curr_simcontext() )
+{
+ return simc_p->m_ready_to_simulate;
+}
+
+bool sc_is_unwinding();
+
+inline void sc_pause()
+{
+ sc_get_curr_simcontext()->m_paused = true;
+}
+
+// Return indication if there are more processes to execute in this delta phase
+
+inline bool sc_pending_activity_at_current_time
+ ( const sc_simcontext* simc_p = sc_get_curr_simcontext() )
+{
+ return simc_p->pending_activity_at_current_time();
+}
+
+// Return indication if there are timed notifications in the future
+
+inline bool sc_pending_activity_at_future_time
+ ( const sc_simcontext* simc_p = sc_get_curr_simcontext() )
+{
+ sc_time ignored;
+ return simc_p->next_time( ignored );
+}
+
+// Return indication if there are processes to run,
+// or notifications in the future
+
+inline bool sc_pending_activity
+ ( const sc_simcontext* simc_p = sc_get_curr_simcontext() )
+{
+ return sc_pending_activity_at_current_time( simc_p )
+ || sc_pending_activity_at_future_time( simc_p );
+}
+
+sc_time
+sc_time_to_pending_activity
+ ( const sc_simcontext* simc_p = sc_get_curr_simcontext() );
+
+
+inline
+bool
+sc_end_of_simulation_invoked()
+{
+ return sc_get_curr_simcontext()->m_end_of_simulation_called;
+}
+
+inline bool sc_hierarchical_name_exists( const char* name )
+{
+ return sc_find_object(name) || sc_find_event(name);
+}
+
+inline
+bool
+sc_start_of_simulation_invoked()
+{
+ return sc_get_curr_simcontext()->m_start_of_simulation_called;
+}
+
+// The following variable controls whether process control corners should
+// be considered errors or not. See sc_simcontext.cpp for details on what
+// happens if this value is set to true.
+
+extern bool sc_allow_process_control_corners;
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems 20 May 2003
+ Description of Modification: - phase callbacks
+ - sc_stop mode
+
+ Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+ Description of Modification: - support for dynamic process
+ - support for sc export registry
+ - new member methods elaborate(),
+ prepare_to_simulate(), and initial_crunch()
+ that are invoked by initialize() in that order
+ - add sc_get_last_created_process_handle() for
+ use before simulation starts
+
+ Name, Affiliation, Date: Bishnupriya Bhattacharya, Cadence Design Systems,
+ 3 March, 2004
+ Description of Modification: add sc_get_curr_process_kind()
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+// $Log: sc_simcontext.h,v $
+// Revision 1.26 2011/09/05 21:20:22 acg
+// Andy Goodrich: result of automake invocation.
+//
+// Revision 1.25 2011/09/01 15:28:10 acg
+// Andy Goodrich: the aftermath of automake.
+//
+// Revision 1.24 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.23 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.22 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.21 2011/05/09 04:07:49 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.20 2011/04/08 18:26:07 acg
+// Andy Goodrich: added execute_method_next() to handle method dispatch
+// for asynchronous notifications that occur outside the evaluation phase.
+//
+// Revision 1.19 2011/04/05 20:50:57 acg
+// Andy Goodrich:
+// (1) changes to make sure that event(), posedge() and negedge() only
+// return true if the clock has not moved.
+// (2) fixes for method self-resumes.
+// (3) added SC_PRERELEASE_VERSION
+// (4) removed kernel events from the object hierarchy, added
+// sc_hierarchical_name_exists().
+//
+// Revision 1.18 2011/03/20 13:43:23 acg
+// Andy Goodrich: added async_signal_is() plus suspend() as a corner case.
+//
+// Revision 1.17 2011/03/07 18:25:19 acg
+// Andy Goodrich: tightening of check for resume on a disabled process to
+// only produce an error if it is ready to run.
+//
+// Revision 1.16 2011/03/06 15:58:50 acg
+// Andy Goodrich: added escape to turn off process control corner case
+// checks.
+//
+// Revision 1.15 2011/03/05 04:45:16 acg
+// Andy Goodrich: moved active process calculation to the sc_simcontext class.
+//
+// Revision 1.14 2011/03/05 01:39:21 acg
+// Andy Goodrich: changes for named events.
+//
+// Revision 1.13 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.12 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.11 2011/02/13 21:34:35 acg
+// Andy Goodrich: added SC_UNITIALIZED enum value to process status so
+// its possible to detect throws before initialization.
+//
+// Revision 1.10 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.9 2011/02/01 21:18:56 acg
+// Andy Goodrich: addition of new preempt_with() method used to immediately
+// throw exceptions from threads.
+//
+// Revision 1.8 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.7 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.6 2011/01/18 20:10:45 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.5 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.4 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.3 2008/05/22 17:06:26 acg
+// Andy Goodrich: updated copyright notice to include 2008.
+//
+// Revision 1.2 2007/09/20 20:32:35 acg
+// Andy Goodrich: changes to the semantics of throw_it() to match the
+// specification. A call to throw_it() will immediately suspend the calling
+// thread until all the throwees have executed. At that point the calling
+// thread will be restarted before the execution of any other threads.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.13 2006/05/08 18:00:06 acg
+// Andy Goodrich: added David Long's forward declarations for friend
+// functions, methods, and operators to keep the Microsoft compiler happy.
+//
+// Revision 1.11 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.10 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.9 2006/01/26 21:04:54 acg
+// Andy Goodrich: deprecation message changes and additional messages.
+//
+// Revision 1.8 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.7 2006/01/19 00:29:52 acg
+// Andy Goodrich: Yet another implementation for signal write checking. This
+// one uses an environment variable SC_SIGNAL_WRITE_CHECK, that when set to
+// DISABLE will disable write checking on signals.
+//
+// Revision 1.6 2006/01/18 21:42:37 acg
+// Andy Goodrich: Changes for check writer support.
+//
+// Revision 1.5 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
+// Revision 1.4 2006/01/03 23:18:44 acg
+// Changed copyright to include 2006.
+//
+// Revision 1.3 2005/12/20 22:11:10 acg
+// Fixed $Log lines.
+//
+// Revision 1.2 2005/12/20 22:02:30 acg
+// Changed where delta cycles are incremented to match IEEE 1666. Added the
+// event_occurred() method to hide how delta cycle comparisions are done within
+// sc_simcontext. Changed the boolean update_phase to an enum that shows all
+// the phases.
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_simcontext_int.h b/ext/systemc/src/sysc/kernel/sc_simcontext_int.h
new file mode 100644
index 000000000..039237f4a
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_simcontext_int.h
@@ -0,0 +1,365 @@
+/*****************************************************************************
+
+ 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_simcontext_int.h -- For inline definitions of some utility functions.
+ DO NOT EXPORT THIS INCLUDE FILE. Include this file
+ after "sc_process_int.h" so that we can get the base
+ class right.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_SIMCONTEXT_INT_H
+#define SC_SIMCONTEXT_INT_H
+
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_runnable.h"
+#include "sysc/kernel/sc_runnable_int.h"
+
+// DEBUGGING MACROS:
+//
+// DEBUG_MSG(NAME,P,MSG)
+// MSG = message to print
+// NAME = name that must match the process for the message to print, or
+// null if the message should be printed unconditionally.
+// P = pointer to process message is for, or NULL in which case the
+// message will not print.
+#if 0
+# define DEBUG_NAME ""
+# define DEBUG_MSG(NAME,P,MSG) \
+ { \
+ if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
+ std::cout << "**** " << sc_time_stamp() << " (" \
+ << sc_get_current_process_name() << "): " << MSG \
+ << " - " << P->name() << std::endl; \
+ }
+#else
+# define DEBUG_MSG(NAME,P,MSG)
+#endif
+
+
+namespace sc_core {
+
+inline
+const char*
+sc_get_current_process_name()
+{
+ sc_process_b* active_p; // active process to get name of.
+ const char* result; // name of active process.
+
+ active_p = sc_get_curr_simcontext()->get_curr_proc_info()->process_handle;
+ if ( active_p )
+ result = active_p->name();
+ else
+ result = "** NONE **";
+ return result;
+}
+
+// We use m_current_writer rather than m_curr_proc_info.process_handle to
+// return the active process for sc_signal<T>::check_write since that lets
+// us turn it off a library compile time, and only incur the overhead at
+// the time of process switches rather than having to interrogate an
+// additional switch every time a signal is written.
+
+inline
+void
+sc_simcontext::set_curr_proc( sc_process_b* process_h )
+{
+ m_curr_proc_info.process_handle = process_h;
+ m_curr_proc_info.kind = process_h->proc_kind();
+ m_current_writer = m_write_check ? process_h : (sc_object*)0;
+}
+
+inline
+void
+sc_simcontext::reset_curr_proc()
+{
+ m_curr_proc_info.process_handle = 0;
+ m_curr_proc_info.kind = SC_NO_PROC_;
+ m_current_writer = 0;
+ sc_process_b::m_last_created_process_p = 0;
+}
+
+inline
+void
+sc_simcontext::execute_method_next( sc_method_handle method_h )
+{
+ m_runnable->execute_method_next( method_h );
+}
+
+inline
+void
+sc_simcontext::execute_thread_next( sc_thread_handle thread_h )
+{
+ m_runnable->execute_thread_next( thread_h );
+}
+
+// +----------------------------------------------------------------------------
+// |"sc_simcontext::preempt_with"
+// |
+// | This method executes the supplied thread immediately, suspending the
+// | caller. After executing the supplied thread the caller's execution will
+// | be restored. It is used to allow a thread to immediately throw an
+// | exception, e.g., when the thread's kill_process() method was called.
+// | There are three cases to consider:
+// | (1) The caller is a method, e.g., murder by method.
+// | (2) The caller is another thread instance, e.g., murder by thread.
+// | (3) The caller is this thread instance, e.g., suicide.
+// |
+// | Arguments:
+// | thread_h -> thread to be executed.
+// +----------------------------------------------------------------------------
+inline
+void
+sc_simcontext::preempt_with( sc_thread_handle thread_h )
+{
+ sc_thread_handle active_p; // active thread or null.
+ sc_curr_proc_info caller_info; // process info for caller.
+
+ // Determine the active process and take the thread to be run off the
+ // run queue, if its there, since we will be explicitly causing its
+ // execution.
+
+ active_p = DCAST<sc_thread_handle>(sc_get_current_process_b());
+ if ( thread_h->next_runnable() != NULL )
+ remove_runnable_thread( thread_h );
+
+ // THE CALLER IS A METHOD:
+ //
+ // (a) Set the current process information to our thread.
+ // (b) If the method was called by an invoker thread push that thread
+ // onto the front of the run queue, this will cause the method
+ // to be resumed after this thread waits.
+ // (c) Invoke our thread directly by-passing the run queue.
+ // (d) Restore the process info to the caller.
+ // (e) Check to see if the calling method should throw an exception
+ // because of activity that occurred during the preemption.
+
+ if ( active_p == NULL )
+ {
+ std::vector<sc_thread_handle>* invokers_p; // active invokers stack.
+ sc_thread_handle invoke_thread_p; // latest invocation thread.
+ sc_method_handle method_p; // active method.
+
+ method_p = DCAST<sc_method_handle>(sc_get_current_process_b());
+ invokers_p = &get_active_invokers();
+ caller_info = m_curr_proc_info;
+ if ( invokers_p->size() != 0 )
+ {
+ invoke_thread_p = invokers_p->back();
+ DEBUG_MSG( DEBUG_NAME, invoke_thread_p,
+ "queueing invocation thread to execute next" );
+ execute_thread_next(invoke_thread_p);
+ }
+ DEBUG_MSG( DEBUG_NAME, thread_h, "preempting method with thread" );
+ set_curr_proc( (sc_process_b*)thread_h );
+ m_cor_pkg->yield( thread_h->m_cor_p );
+ m_curr_proc_info = caller_info;
+ DEBUG_MSG(DEBUG_NAME, thread_h, "back from preempting method w/thread");
+ method_p->check_for_throws();
+ }
+
+ // CALLER IS A THREAD, BUT NOT THE THREAD TO BE RUN:
+ //
+ // (a) Push the calling thread onto the front of the runnable queue
+ // so it be the first thread to be run after this thread.
+ // (b) Push the thread to be run onto the front of the runnable queue so
+ // it will execute when we suspend the calling thread.
+ // (c) Suspend the active thread.
+
+ else if ( active_p != thread_h )
+ {
+ DEBUG_MSG( DEBUG_NAME, thread_h,
+ "preempting active thread with thread" );
+ execute_thread_next( active_p );
+ execute_thread_next( thread_h );
+ active_p->suspend_me();
+ }
+
+ // CALLER IS THE THREAD TO BE RUN:
+ //
+ // (a) Push the thread to be run onto the front of the runnable queue so
+ // it will execute when we suspend the calling thread.
+ // (b) Suspend the active thread.
+
+ else
+ {
+ DEBUG_MSG(DEBUG_NAME,thread_h,"self preemption of active thread");
+ execute_thread_next( thread_h );
+ active_p->suspend_me();
+ }
+}
+
+
+inline
+void
+sc_simcontext::push_runnable_method( sc_method_handle method_h )
+{
+ m_runnable->push_back_method( method_h );
+}
+
+inline
+void
+sc_simcontext::push_runnable_method_front( sc_method_handle method_h )
+{
+ m_runnable->push_front_method( method_h );
+}
+
+inline
+void
+sc_simcontext::push_runnable_thread( sc_thread_handle thread_h )
+{
+ m_runnable->push_back_thread( thread_h );
+}
+
+inline
+void
+sc_simcontext::push_runnable_thread_front( sc_thread_handle thread_h )
+{
+ m_runnable->push_front_thread( thread_h );
+}
+
+
+inline
+sc_method_handle
+sc_simcontext::pop_runnable_method()
+{
+ sc_method_handle method_h = m_runnable->pop_method();
+ if( method_h == 0 ) {
+ reset_curr_proc();
+ return 0;
+ }
+ set_curr_proc( (sc_process_b*)method_h );
+ return method_h;
+}
+
+inline
+sc_thread_handle
+sc_simcontext::pop_runnable_thread()
+{
+ sc_thread_handle thread_h = m_runnable->pop_thread();
+ if( thread_h == 0 ) {
+ reset_curr_proc();
+ return 0;
+ }
+ set_curr_proc( (sc_process_b*)thread_h );
+ return thread_h;
+}
+
+inline
+void
+sc_simcontext::remove_runnable_method( sc_method_handle method_h )
+{
+ m_runnable->remove_method( method_h );
+}
+
+inline
+void
+sc_simcontext::remove_runnable_thread( sc_thread_handle thread_h )
+{
+ m_runnable->remove_thread( thread_h );
+}
+
+inline
+std::vector<sc_thread_handle>&
+sc_simcontext::get_active_invokers()
+{
+ return m_active_invokers;
+}
+
+// ----------------------------------------------------------------------------
+
+extern void sc_defunct_process_function( sc_module* );
+
+
+} // namespace sc_core
+
+#undef DEBUG_MSG
+#undef DEBUG_NAME
+
+// $Log: sc_simcontext_int.h,v $
+// Revision 1.14 2011/08/29 18:04:32 acg
+// Philipp A. Hartmann: miscellaneous clean ups.
+//
+// Revision 1.13 2011/08/26 20:46:11 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.12 2011/07/29 22:45:06 acg
+// Andy Goodrich: added invocation of sc_method_process::check_for_throws()
+// to the preempt_with() code to handle case where the preempting process
+// causes a throw on the invoking method process.
+//
+// Revision 1.11 2011/04/13 02:45:11 acg
+// Andy Goodrich: eliminated warning message that occurred if the DEBUG_MSG
+// macro was used.
+//
+// Revision 1.10 2011/04/11 22:05:48 acg
+// Andy Goodrich: use the DEBUG_NAME macro in DEBUG_MSG invocations.
+//
+// Revision 1.9 2011/04/10 22:12:32 acg
+// Andy Goodrich: adding debugging macros.
+//
+// Revision 1.8 2011/04/08 18:26:07 acg
+// Andy Goodrich: added execute_method_next() to handle method dispatch
+// for asynchronous notifications that occur outside the evaluation phase.
+//
+// Revision 1.7 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.6 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.5 2011/02/08 08:17:50 acg
+// Andy Goodrich: fixed bug in preempt_with() where I was resetting the
+// process context rather than saving and restoring it.
+//
+// Revision 1.4 2011/02/01 21:12:56 acg
+// Andy Goodrich: addition of preempt_with() method to allow immediate
+// execution of threads for throws.
+//
+// Revision 1.3 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// 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.6 2006/05/26 20:33:16 acg
+// Andy Goodrich: changes required by additional platform compilers (i.e.,
+// Microsoft VC++, Sun Forte, HP aCC).
+//
+// Revision 1.5 2006/01/19 00:29:52 acg
+// Andy Goodrich: Yet another implementation for signal write checking. This
+// one uses an environment variable SC_SIGNAL_WRITE_CHECK, that when set to
+// DISABLE will disable write checking on signals.
+//
+// Revision 1.4 2006/01/18 21:42:37 acg
+// Andy Goodrich: Changes for check writer support.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_spawn.h b/ext/systemc/src/sysc/kernel/sc_spawn.h
new file mode 100644
index 000000000..e54886929
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_spawn.h
@@ -0,0 +1,337 @@
+/*****************************************************************************
+
+ 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_spawn.h -- Process spawning support.
+
+ Original Authors: Andy Goodrich, Forte Design Systems, 17 June 2003
+ Stuart Swan, Cadence,
+ Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#if !defined(sc_spawn_h_INCLUDED)
+#define sc_spawn_h_INCLUDED
+
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_spawn_options.h"
+
+namespace sc_core {
+
+class sc_event;
+class sc_port_base;
+class sc_interface;
+class sc_event_finder;
+class sc_process_b;
+
+//=============================================================================
+// CLASS sc_spawn_object<T>
+//
+// This templated helper class allows an object to provide the execution
+// semantics for a process via its () operator. An instance of the supplied
+// execution object will be kept to provide the semantics when the process is
+// scheduled for execution. The () operator does not return a value. An example
+// of an object that might be used for this helper function would be void
+// SC_BOOST bound function or method.
+//
+// This class is derived from sc_process_host and overloads
+// sc_process_host::semantics to provide the actual semantic content.
+//
+// sc_spawn_object(T object, const char* name, const sc_spawn_options* opt_p)
+// This is the object instance constructor for this class. It makes a
+// copy of the supplied object. The tp_call constructor is called
+// with an indication that this object instance should be reclaimed when
+// execution completes.
+// object = object whose () operator will be called to provide
+// the process semantics.
+// name_p = optional name for object instance, or zero.
+// opt_p -> spawn options or zero.
+//
+// virtual void semantics()
+// This virtual method provides the execution semantics for its process.
+// It performs a () operation on m_object.
+//=============================================================================
+template<typename T>
+class sc_spawn_object : public sc_process_host {
+ public:
+ sc_spawn_object( T object) : m_object(object)
+ {
+ }
+
+ virtual void semantics()
+ {
+ m_object();
+ }
+
+ protected:
+ T m_object;
+};
+
+
+//------------------------------------------------------------------------------
+//"sc_spawn - semantic object with no return value"
+//
+// This inline function spawns a process for execution. The execution semantics
+// for the process being spawned will be provided by the supplied object
+// instance via its () operator. (E.g., a SC_BOOST bound function)
+// After creating the process it is registered with the simulator.
+// object = object instance providing the execution semantics via its
+// () operator.
+// name_p = optional name for object instance, or zero.
+// opt_p -> optional spawn options for process, or zero for the default.
+//------------------------------------------------------------------------------
+template <typename T>
+inline sc_process_handle sc_spawn(
+ T object,
+ const char* name_p = 0,
+ const sc_spawn_options* opt_p = 0)
+{
+ sc_simcontext* context_p;
+ sc_spawn_object<T>* spawn_p;
+
+ context_p = sc_get_curr_simcontext();
+ spawn_p = new sc_spawn_object<T>(object);
+ if ( !opt_p || !opt_p->is_method() )
+ {
+ sc_process_handle thread_handle = context_p->create_thread_process(
+ name_p, true,
+ SC_MAKE_FUNC_PTR(sc_spawn_object<T>,semantics),
+ spawn_p, opt_p
+ );
+ return thread_handle;
+ }
+ else
+ {
+ sc_process_handle method_handle = context_p->create_method_process(
+ name_p, true,
+ SC_MAKE_FUNC_PTR(sc_spawn_object<T>,semantics),
+ spawn_p, opt_p
+ );
+ return method_handle;
+ }
+}
+
+//=============================================================================
+// CLASS sc_spawn_object_v<T> for all compilers except HP aCC
+// or
+// CLASS sc_spawn_object_v<T, R> for HP aCC which tries to match this
+// one template argument class when the sc_spawn() declared above is
+// invoked with 3 arguments or 2 arguments, and generates compiler errors.
+//
+// This templated helper class allows an object to provide the execution
+// semantics for a process via its () operator. An instance of the supplied
+// object will be kept to provide the semantics when the process is scheduled
+// for execution. The () operator returns a value, which will be stored at the
+// location specified by the supplied pointer. An example of an object that
+// might be used for this helper function would be valued SC_BOOST bound
+// function or method.
+//
+// sc_spawn_object_v( typename F::result_type* r_p, T f, const char* name_p,
+// const sc_spawn_options* opt_p )
+// r_p -> where to place the result of the function invocation.
+// f = information to be executed.
+// name_p = optional name for object instance, or zero.
+// opt_p -> optional spawn options for process, or zero for the default
+// This is the object instance constructor for this class. It makes a
+// copy of the supplied object. The tp_call constructor is called
+// with an indication that this object instance should be reclaimed when
+// execution completes.
+// result_p -> where to place the value of the () operator.
+// object = object whose () operator will be called to provide
+// the process semantics.
+//
+// virtual void semantics()
+// This virtual method provides the execution semantics for its process.
+// It performs a () operation on m_object, placing the result at m_result_p.
+//=============================================================================
+
+//------------------------------------------------------------------------------
+//"sc_spawn_object_v - semantic object with return value"
+//
+// This inline function spawns a process for execution. The execution semantics
+// for the process being spawned will be provided by the supplied object
+// instance via its () operator. (E.g., a SC_BOOST bound function) That
+// operator returns a value, which will be placed in the supplied return
+// location.
+// After creating the process it is registered with the simulator.
+// object = object instance providing the execution semantics via its ()
+// operator.
+// r_p -> where to place the value of the () operator.
+// name_p = optional name for object instance, or zero.
+// opt_p -> optional spawn options for process, or zero for the default.
+//------------------------------------------------------------------------------
+
+#if !defined (__HP_aCC)
+
+template<typename T>
+class sc_spawn_object_v : public sc_process_host {
+ public:
+ sc_spawn_object_v( typename T::result_type* r_p, T object ) :
+ m_object(object), m_result_p(r_p)
+ {
+ }
+
+ virtual void semantics()
+ {
+ *m_result_p = m_object();
+ }
+
+ protected:
+ T m_object;
+ typename T::result_type* m_result_p;
+};
+
+template <typename T>
+inline sc_process_handle sc_spawn(
+ typename T::result_type* r_p,
+ T object,
+ const char* name_p = 0,
+ const sc_spawn_options* opt_p = 0)
+{
+ sc_simcontext* context_p;
+ sc_spawn_object_v<T>* spawn_p;
+
+ context_p = sc_get_curr_simcontext();
+
+ spawn_p = new sc_spawn_object_v<T>(r_p, object);
+ if ( !opt_p || !opt_p->is_method() )
+ {
+ sc_process_handle thread_handle = context_p->create_thread_process(
+ name_p, true,
+ SC_MAKE_FUNC_PTR(sc_spawn_object_v<T>,semantics),
+ spawn_p, opt_p
+ );
+ return thread_handle;
+ }
+ else
+ {
+ sc_process_handle method_handle = context_p->create_method_process(
+ name_p, true,
+ SC_MAKE_FUNC_PTR(sc_spawn_object_v<T>,semantics),
+ spawn_p, opt_p
+ );
+ return method_handle;
+ }
+}
+
+#else
+// for HP aCC
+template<typename T, typename R>
+class sc_spawn_object_v : public sc_process_host {
+ public:
+ sc_spawn_object_v( R* r_p, T object) :
+ m_object(object), m_result_p(r_p)
+ {
+ }
+
+ virtual void semantics()
+ {
+ *m_result_p = m_object();
+ }
+
+ protected:
+ T m_object;
+ R* m_result_p;
+};
+
+template <typename T, typename R>
+inline sc_process_handle sc_spawn(
+ R* r_p,
+ T object,
+ const char* name_p = 0,
+ const sc_spawn_options* opt_p = 0)
+{
+ sc_simcontext* context_p;
+ sc_spawn_object_v<T,R>* spawn_p;
+
+ context_p = sc_get_curr_simcontext();
+
+ spawn_p = new sc_spawn_object_v<T,R>(r_p, object);
+ if ( !opt_p || !opt_p->is_method() )
+ {
+ sc_process_handle thread_handle = context_p->create_thread_process(
+ name_p, true,
+ static_cast<sc_core::SC_ENTRY_FUNC>(
+ &sc_spawn_object_v<T,R>::semantics),
+ spawn_p, opt_p
+ );
+ return thread_handle;
+ }
+ else
+ {
+ sc_process_handle method_handle = context_p->create_method_process(
+ name_p, true,
+ static_cast<sc_core::SC_ENTRY_FUNC>(
+ &sc_spawn_object_v<T,R>::semantics),
+ spawn_p, opt_p
+ );
+ return method_handle;
+ }
+}
+
+#endif // HP
+
+} // namespace sc_core
+
+// $Log: sc_spawn.h,v $
+// Revision 1.7 2011/08/26 20:46:11 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.6 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.5 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.4 2011/02/01 21:14:02 acg
+// Andy Goodrich: formatting.
+//
+// Revision 1.3 2009/07/28 01:10:53 acg
+// Andy Goodrich: updates for 2.3 release candidate.
+//
+// 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.6 2006/05/26 20:33:16 acg
+// Andy Goodrich: changes required by additional platform compilers (i.e.,
+// Microsoft VC++, Sun Forte, HP aCC).
+//
+// Revision 1.5 2006/05/08 18:01:44 acg
+// Andy Goodrich: changed the HP-specific implementations of sc_spawn() to
+// use a static_cast to create their entry functions rather than the
+// SC_MAKE_FUNC_PTR macro. The HP preprocessor does not parse template
+// arguments that contain a comma properly.
+//
+// Revision 1.4 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif // !defined(sc_spawn_h_INCLUDED)
diff --git a/ext/systemc/src/sysc/kernel/sc_spawn_options.cpp b/ext/systemc/src/sysc/kernel/sc_spawn_options.cpp
new file mode 100644
index 000000000..c577f1d87
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_spawn_options.cpp
@@ -0,0 +1,124 @@
+/*****************************************************************************
+
+ 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_spawn_options.cpp -- Process spawning options implementation.
+
+ Original Authors: Andy Goodrich, Forte Design Systems, 17 June 2003
+ Stuart Swan, Cadence,
+ Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_spawn_options.h"
+#include "sysc/kernel/sc_reset.h"
+
+namespace sc_core {
+
+// +======================================================================
+// | CLASS sc_spawn_reset_base - Class to do a generic access to an
+// | sc_spawn_rest object instance
+// +======================================================================
+class sc_spawn_reset_base
+{
+ public:
+ sc_spawn_reset_base( bool async, bool level )
+ : m_async( async ), m_level(level)
+ {}
+ virtual ~sc_spawn_reset_base() {}
+ virtual void specify_reset() = 0;
+
+ protected:
+ bool m_async; // = true if async reset.
+ bool m_level; // level indicating reset.
+};
+
+// +======================================================================
+// | CLASS sc_spawn_reset<SOURCE>
+// | - Reset specification for sc_spawn_options.
+// +======================================================================
+template<typename SOURCE>
+class sc_spawn_reset : public sc_spawn_reset_base
+{
+ public:
+ sc_spawn_reset( bool async, const SOURCE& source, bool level )
+ : sc_spawn_reset_base(async, level), m_source(source)
+ {}
+ virtual ~sc_spawn_reset() {}
+ virtual void specify_reset()
+ {
+ sc_reset::reset_signal_is( m_async, m_source, m_level );
+ }
+
+ protected:
+ const SOURCE& m_source; // source of reset signal.
+};
+
+// +======================================================================
+// | CLASS sc_spawn_options (implementation)
+// |
+// +======================================================================
+
+sc_spawn_options::~sc_spawn_options()
+{
+ std::vector<sc_spawn_reset_base*>::size_type resets_n = m_resets.size();
+ for ( std::vector<sc_spawn_reset_base*>::size_type reset_i = 0; reset_i < resets_n; reset_i++ )
+ delete m_resets[reset_i];
+}
+
+#define SC_DEFINE_RESET_SIGNALS( Port ) \
+ /* asynchronous reset */ \
+ void \
+ sc_spawn_options:: \
+ async_reset_signal_is ( const Port & port, bool level ) \
+ { \
+ m_resets.push_back( \
+ new sc_spawn_reset< Port >(true, port, level) ); \
+ } \
+ /* sync reset */ \
+ void \
+ sc_spawn_options:: \
+ reset_signal_is ( const Port & port, bool level ) \
+ { \
+ m_resets.push_back( \
+ new sc_spawn_reset< Port >(false, port, level) ); \
+ }
+
+SC_DEFINE_RESET_SIGNALS( sc_in<bool> )
+SC_DEFINE_RESET_SIGNALS( sc_inout<bool> )
+SC_DEFINE_RESET_SIGNALS( sc_out<bool> )
+SC_DEFINE_RESET_SIGNALS( sc_signal_in_if<bool> )
+
+#undef SC_DEFINE_RESET_SIGNALS
+
+void
+sc_spawn_options::specify_resets() const
+{
+ std::vector<sc_spawn_reset_base*>::size_type resets_n; // number of reset specifications to process.
+ resets_n = m_resets.size();
+ for ( std::vector<sc_spawn_reset_base*>::size_type reset_i = 0; reset_i < resets_n; reset_i++ )
+ m_resets[reset_i]->specify_reset();
+}
+
+} // namespace sc_core
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_spawn_options.h b/ext/systemc/src/sysc/kernel/sc_spawn_options.h
new file mode 100644
index 000000000..4c3f64baa
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_spawn_options.h
@@ -0,0 +1,161 @@
+/*****************************************************************************
+
+ 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_spawn_options.h -- Process spawning options specification.
+
+ Original Authors: Andy Goodrich, Forte Design Systems, 17 June 2003
+ Stuart Swan, Cadence,
+ Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#if !defined(sc_spawn_options_h_INCLUDED)
+#define sc_spawn_options_h_INCLUDED
+
+#include <vector>
+#include "sysc/communication/sc_export.h"
+#include "sysc/communication/sc_signal_ports.h"
+
+namespace sc_core {
+
+class sc_event;
+class sc_port_base;
+class sc_interface;
+class sc_event_finder;
+class sc_process_b;
+class sc_spawn_reset_base;
+
+//=============================================================================
+// CLASS sc_spawn_options
+//
+//=============================================================================
+class sc_spawn_options {
+ friend class sc_cthread_process;
+ friend class sc_method_process;
+ friend class sc_process_b;
+ friend class sc_thread_process;
+ public:
+ sc_spawn_options() :
+ m_dont_initialize(false), m_resets(), m_sensitive_events(),
+ m_sensitive_event_finders(), m_sensitive_interfaces(),
+ m_sensitive_port_bases(), m_spawn_method(false), m_stack_size(0)
+ { }
+
+ ~sc_spawn_options();
+
+ void async_reset_signal_is( const sc_in<bool>&, bool level );
+ void async_reset_signal_is( const sc_inout<bool>&, bool level );
+ void async_reset_signal_is( const sc_out<bool>&, bool level );
+ void async_reset_signal_is( const sc_signal_in_if<bool>&, bool level );
+
+ void reset_signal_is( const sc_in<bool>&, bool level );
+ void reset_signal_is( const sc_inout<bool>&, bool level );
+ void reset_signal_is( const sc_out<bool>&, bool level );
+ void reset_signal_is( const sc_signal_in_if<bool>&, bool level );
+
+ void dont_initialize() { m_dont_initialize = true; }
+
+ bool is_method() const { return m_spawn_method; }
+
+ void set_stack_size(int stack_size) { m_stack_size = stack_size; }
+
+ void set_sensitivity(const sc_event* event)
+ { m_sensitive_events.push_back(event); }
+
+ void set_sensitivity(sc_port_base* port_base)
+ { m_sensitive_port_bases.push_back(port_base); }
+
+ void set_sensitivity(sc_interface* interface_p)
+ { m_sensitive_interfaces.push_back(interface_p); }
+
+ void set_sensitivity(sc_export_base* export_base)
+ { m_sensitive_interfaces.push_back(export_base->get_interface()); }
+
+ void set_sensitivity(sc_event_finder* event_finder)
+ { m_sensitive_event_finders.push_back(event_finder); }
+
+ void spawn_method() { m_spawn_method = true; }
+
+ protected:
+ void specify_resets() const;
+
+ private:
+ sc_spawn_options( const sc_spawn_options& );
+ const sc_spawn_options& operator = ( const sc_spawn_options& );
+
+ protected:
+ bool m_dont_initialize;
+ std::vector<sc_spawn_reset_base*> m_resets;
+ std::vector<const sc_event*> m_sensitive_events;
+ std::vector<sc_event_finder*> m_sensitive_event_finders;
+ std::vector<sc_interface*> m_sensitive_interfaces;
+ std::vector<sc_port_base*> m_sensitive_port_bases;
+ bool m_spawn_method; // Method not thread.
+ int m_stack_size; // Thread stack size.
+};
+
+} // namespace sc_core
+
+// $Log: sc_spawn_options.h,v $
+// Revision 1.11 2011/08/26 20:46:11 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.10 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.9 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.8 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.7 2011/02/07 19:17:20 acg
+// Andy Goodrich: changes for IEEE 1666 compatibility.
+//
+// Revision 1.6 2010/12/07 20:09:15 acg
+// Andy Goodrich: replaced sc_signal signatures with sc_signal_in_if signatures for reset methods.
+//
+// Revision 1.5 2010/11/20 17:10:57 acg
+// Andy Goodrich: reset processing changes for new IEEE 1666 standard.
+//
+// Revision 1.4 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// 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.4 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif // !defined(sc_spawn_options_h_INCLUDED)
diff --git a/ext/systemc/src/sysc/kernel/sc_status.h b/ext/systemc/src/sysc/kernel/sc_status.h
new file mode 100644
index 000000000..1d3b016db
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_status.h
@@ -0,0 +1,83 @@
+/*****************************************************************************
+
+ 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_status.h -- Definition of the simulation phases
+
+ Original Author: Philipp A. Hartmann, OFFIS, 2013-02-15
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_STATUS_H_INCLUDED_
+#define SC_STATUS_H_INCLUDED_
+
+#include <iosfwd>
+
+namespace sc_core {
+
+// simulation status codes
+
+const int SC_SIM_OK = 0;
+const int SC_SIM_ERROR = 1;
+const int SC_SIM_USER_STOP = 2;
+
+enum sc_status
+{ // sc_get_status values:
+ SC_UNITIALIZED=0x00, // initialize() not called yet
+
+ SC_ELABORATION = 0x01, // during module hierarchy construction
+ SC_BEFORE_END_OF_ELABORATION = 0x02, // during before_end_of_elaboration()
+ SC_END_OF_ELABORATION = 0x04, // during end_of_elaboration()
+ SC_START_OF_SIMULATION = 0x08, // during start_of_simulation()
+
+ SC_RUNNING = 0x10, // initialization, evaluation or update
+ SC_PAUSED = 0x20, // when scheduler stopped by sc_pause()
+ SC_STOPPED = 0x40, // when scheduler stopped by sc_stop()
+ SC_END_OF_SIMULATION = 0x80, // during end_of_simulation()
+
+ // detailed simulation phases (for dynamic callbacks)
+ SC_END_OF_INITIALIZATION = 0x100, // after initialization
+// SC_END_OF_EVALUATION = 0x200, // between eval and update
+ SC_END_OF_UPDATE = 0x400, // after update/notify phase
+ SC_BEFORE_TIMESTEP = 0x800, // before next time step
+
+ SC_STATUS_LAST = SC_BEFORE_TIMESTEP,
+ SC_STATUS_ANY = 0xdff
+};
+
+// pretty-printing of sc_status values
+std::ostream& operator << ( std::ostream&, sc_status );
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+#endif /* SC_STATUS_H_INCLUDED_ */
+// Taf!
+
diff --git a/ext/systemc/src/sysc/kernel/sc_thread_process.cpp b/ext/systemc/src/sysc/kernel/sc_thread_process.cpp
new file mode 100644
index 000000000..140096c95
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_thread_process.cpp
@@ -0,0 +1,1127 @@
+/*****************************************************************************
+
+ 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_thread_process.cpp -- Thread process implementation
+
+ Original Author: Andy Goodrich, Forte Design Systems, 4 August 2005
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include "sysc/kernel/sc_cmnhdr.h"
+#include "sysc/kernel/sc_constants.h"
+#include "sysc/kernel/sc_thread_process.h"
+#include "sysc/kernel/sc_process_handle.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_module.h"
+#include "sysc/utils/sc_machine.h"
+
+// DEBUGGING MACROS:
+//
+// DEBUG_MSG(NAME,P,MSG)
+// MSG = message to print
+// NAME = name that must match the process for the message to print, or
+// null if the message should be printed unconditionally.
+// P = pointer to process message is for, or NULL in which case the
+// message will not print.
+#if 0
+# define DEBUG_NAME ""
+# define DEBUG_MSG(NAME,P,MSG) \
+ { \
+ if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
+ std::cout << "**** " << sc_time_stamp() << " (" \
+ << sc_get_current_process_name() << "): " << MSG \
+ << " - " << P->name() << std::endl; \
+ }
+#else
+# define DEBUG_MSG(NAME,P,MSG)
+#endif
+
+
+//------------------------------------------------------------------------------
+// user-defined default stack-size
+//------------------------------------------------------------------------------
+#if defined(SC_OVERRIDE_DEFAULT_STACK_SIZE)
+# define SC_DEFAULT_STACK_SIZE_ SC_OVERRIDE_DEFAULT_STACK_SIZE
+
+//------------------------------------------------------------------------------
+// architecture-specific default stack sizes
+//------------------------------------------------------------------------------
+#elif !defined(SC_USE_PTHREADS) && (defined(__CYGWIN32__) || defined(__CYGWIN32))
+# define SC_DEFAULT_STACK_SIZE_ 0x50000
+
+#elif defined(SC_LONG_64) || defined(__x86_64__) || defined(__LP64__) || \
+ defined(_M_X64) || defined(_M_AMD64)
+# define SC_DEFAULT_STACK_SIZE_ 0x40000
+
+#else
+# define SC_DEFAULT_STACK_SIZE_ 0x20000
+
+#endif // SC_DEFAULT_STACK_SIZE_
+
+
+//------------------------------------------------------------------------------
+// force 16-byte alignment on coroutine entry functions, needed for
+// QuickThreads (32-bit, see also fixes in qt/md/{i386,iX86_64}.[hs]),
+// and MinGW32 / Cygwin32 compilers on Windows platforms
+#if defined(__GNUC__) && !defined(__ICC) && !defined(__x86_64__) && \
+ (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 1 )
+# define SC_ALIGNED_STACK_ \
+ __attribute__((force_align_arg_pointer))
+#else
+# define SC_ALIGNED_STACK_ /* empty */
+#endif
+
+
+namespace sc_core {
+
+const int SC_DEFAULT_STACK_SIZE = SC_DEFAULT_STACK_SIZE_;
+#undef SC_DEFAULT_STACK_SIZE_
+#undef SC_OVERRIDE_DEFAULT_STACK_SIZE
+
+//------------------------------------------------------------------------------
+//"sc_thread_cor_fn"
+//
+// This function invokes the coroutine for the supplied object instance.
+//------------------------------------------------------------------------------
+SC_ALIGNED_STACK_
+void sc_thread_cor_fn( void* arg )
+{
+ sc_simcontext* simc_p = sc_get_curr_simcontext();
+ sc_thread_handle thread_h = RCAST<sc_thread_handle>( arg );
+
+ // PROCESS THE THREAD AND PROCESS ANY EXCEPTIONS THAT ARE THROWN:
+
+ while( true ) {
+
+ try {
+ thread_h->semantics();
+ }
+ catch( sc_user ) {
+ continue;
+ }
+ catch( sc_halt ) {
+ ::std::cout << "Terminating process "
+ << thread_h->name() << ::std::endl;
+ }
+ catch( const sc_unwind_exception& ex ) {
+ ex.clear();
+ if ( ex.is_reset() ) continue;
+ }
+ catch( ... ) {
+ sc_report* err_p = sc_handle_exception();
+ thread_h->simcontext()->set_error( err_p );
+ }
+ break;
+ }
+
+ sc_process_b* active_p = sc_get_current_process_b();
+
+ // REMOVE ALL TRACES OF OUR THREAD FROM THE SIMULATORS DATA STRUCTURES:
+
+ thread_h->disconnect_process();
+
+ // IF WE AREN'T ACTIVE MAKE SURE WE WON'T EXECUTE:
+
+ if ( thread_h->next_runnable() != 0 )
+ {
+ simc_p->remove_runnable_thread(thread_h);
+ }
+
+ // IF WE ARE THE ACTIVE PROCESS ABORT OUR EXECUTION:
+
+
+ if ( active_p == (sc_process_b*)thread_h )
+ {
+
+ sc_core::sc_cor* x = simc_p->next_cor();
+ simc_p->cor_pkg()->abort( x );
+ }
+
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::disable_process"
+//
+// This virtual method suspends this process and its children if requested to.
+// descendants = indicator of whether this process' children should also
+// be suspended
+//------------------------------------------------------------------------------
+void sc_thread_process::disable_process(
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF NEEDED PROPOGATE THE DISABLE REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*>& children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->disable_process(descendants);
+ }
+ }
+
+ // DON'T ALLOW CORNER CASE BY DEFAULT:
+
+ if ( !sc_allow_process_control_corners )
+ {
+ switch( m_trigger_type )
+ {
+ case AND_LIST_TIMEOUT:
+ case EVENT_TIMEOUT:
+ case OR_LIST_TIMEOUT:
+ case TIMEOUT:
+ report_error(SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "attempt to disable a thread with timeout wait");
+ break;
+ default:
+ break;
+ }
+ }
+
+ // DISABLE OUR OBJECT INSTANCE:
+
+ m_state = m_state | ps_bit_disabled;
+
+ // IF THIS CALL IS BEFORE THE SIMULATION DON'T RUN THE THREAD:
+
+ if ( !sc_is_running() )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ simcontext()->remove_runnable_thread(this);
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::enable_process"
+//
+// This method resumes the execution of this process, and if requested, its
+// descendants. If the process was suspended and has a resumption pending it
+// will be dispatched in the next delta cycle. Otherwise the state will be
+// adjusted to indicate it is no longer suspended, but no immediate execution
+// will occur.
+//------------------------------------------------------------------------------
+void sc_thread_process::enable_process(
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF NEEDED PROPOGATE THE ENABLE REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*>& children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->enable_process(descendants);
+ }
+ }
+
+ // ENABLE THIS OBJECT INSTANCE:
+ //
+ // If it was disabled and ready to run then put it on the run queue.
+
+ m_state = m_state & ~ps_bit_disabled;
+ if ( m_state == ps_bit_ready_to_run && sc_allow_process_control_corners )
+ {
+ m_state = ps_normal;
+ if ( next_runnable() == 0 )
+ simcontext()->push_runnable_thread(this);
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::kill_process"
+//
+// This method removes this object instance from use. It calls the
+// sc_process_b::kill_process() method to perform low level clean up. Then
+// it aborts this process if it is the active process.
+//------------------------------------------------------------------------------
+void sc_thread_process::kill_process(sc_descendant_inclusion_info descendants )
+{
+
+ // IF THE SIMULATION HAS NOT BEEN INITIALIZED YET THAT IS AN ERROR:
+
+ if ( !sc_is_running() )
+ {
+ report_error( SC_ID_KILL_PROCESS_WHILE_UNITIALIZED_ );
+ }
+
+ // IF NEEDED PROPOGATE THE KILL REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*> children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->kill_process(descendants);
+ }
+ }
+
+ // IF THE PROCESS IS CURRENTLY UNWINDING OR IS ALREADY A ZOMBIE
+ // IGNORE THE KILL:
+
+ if ( m_unwinding )
+ {
+ SC_REPORT_WARNING( SC_ID_PROCESS_ALREADY_UNWINDING_, name() );
+ return;
+ }
+
+ if ( m_state & ps_bit_zombie )
+ return;
+
+ // SET UP TO KILL THE PROCESS IF SIMULATION HAS STARTED:
+ //
+ // If the thread does not have a stack don't try the throw!
+
+ if ( sc_is_running() && m_has_stack )
+ {
+ m_throw_status = THROW_KILL;
+ m_wait_cycle_n = 0;
+ simcontext()->preempt_with(this);
+ }
+
+ // IF THE SIMULATION HAS NOT STARTED REMOVE TRACES OF OUR PROCESS FROM
+ // EVENT QUEUES, ETC.:
+
+ else
+ {
+ disconnect_process();
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::prepare_for_simulation"
+//
+// This method prepares this object instance for simulation. It calls the
+// coroutine package to create the actual thread.
+//------------------------------------------------------------------------------
+void sc_thread_process::prepare_for_simulation()
+{
+ m_cor_p = simcontext()->cor_pkg()->create( m_stack_size,
+ sc_thread_cor_fn, this );
+ m_cor_p->stack_protect( true );
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::resume_process"
+//
+// This method resumes the execution of this process, and if requested, its
+// descendants. If the process was suspended and has a resumption pending it
+// will be dispatched in the next delta cycle. Otherwise the state will be
+// adjusted to indicate it is no longer suspended, but no immediate execution
+// will occur.
+//------------------------------------------------------------------------------
+void sc_thread_process::resume_process(
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF NEEDED PROPOGATE THE RESUME REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*>& children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->resume_process(descendants);
+ }
+ }
+
+ // BY DEFAULT THE CORNER CASE IS AN ERROR:
+
+ if ( !sc_allow_process_control_corners && (m_state & ps_bit_disabled) &&
+ (m_state & ps_bit_suspended) )
+ {
+ m_state = m_state & ~ps_bit_suspended;
+ report_error(SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "call to resume() on a disabled suspended thread");
+ }
+
+ // CLEAR THE SUSPENDED BIT:
+
+ m_state = m_state & ~ps_bit_suspended;
+
+ // RESUME OBJECT INSTANCE IF IT IS READY TO RUN:
+
+ if ( m_state & ps_bit_ready_to_run )
+ {
+ m_state = m_state & ~ps_bit_ready_to_run;
+ if ( next_runnable() == 0 )
+ simcontext()->push_runnable_thread(this);
+ remove_dynamic_events(); // order important.
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::sc_thread_process"
+//
+// This is the object instance constructor for this class.
+//------------------------------------------------------------------------------
+sc_thread_process::sc_thread_process( const char* name_p, bool free_host,
+ SC_ENTRY_FUNC method_p, sc_process_host* host_p,
+ const sc_spawn_options* opt_p
+):
+ sc_process_b(
+ name_p ? name_p : sc_gen_unique_name("thread_p"),
+ true, free_host, method_p, host_p, opt_p),
+ m_cor_p(0), m_monitor_q(), m_stack_size(SC_DEFAULT_STACK_SIZE),
+ m_wait_cycle_n(0)
+{
+
+ // CHECK IF THIS IS AN sc_module-BASED PROCESS AND SIMULATION HAS STARTED:
+
+ if ( DCAST<sc_module*>(host_p) != 0 && sc_is_running() )
+ {
+ report_error( SC_ID_MODULE_THREAD_AFTER_START_ );
+ }
+
+ // INITIALIZE VALUES:
+ //
+ // If there are spawn options use them.
+
+ m_process_kind = SC_THREAD_PROC_;
+
+ if (opt_p) {
+ m_dont_init = opt_p->m_dont_initialize;
+ if ( opt_p->m_stack_size ) m_stack_size = opt_p->m_stack_size;
+
+ // traverse event sensitivity list
+ for (unsigned int i = 0; i < opt_p->m_sensitive_events.size(); i++) {
+ sc_sensitive::make_static_sensitivity(
+ this, *opt_p->m_sensitive_events[i]);
+ }
+
+ // traverse port base sensitivity list
+ for ( unsigned int i = 0; i < opt_p->m_sensitive_port_bases.size(); i++)
+ {
+ sc_sensitive::make_static_sensitivity(
+ this, *opt_p->m_sensitive_port_bases[i]);
+ }
+
+ // traverse interface sensitivity list
+ for ( unsigned int i = 0; i < opt_p->m_sensitive_interfaces.size(); i++)
+ {
+ sc_sensitive::make_static_sensitivity(
+ this, *opt_p->m_sensitive_interfaces[i]);
+ }
+
+ // traverse event finder sensitivity list
+ for ( unsigned int i = 0; i < opt_p->m_sensitive_event_finders.size();
+ i++)
+ {
+ sc_sensitive::make_static_sensitivity(
+ this, *opt_p->m_sensitive_event_finders[i]);
+ }
+
+ // process any reset signal specification:
+
+ opt_p->specify_resets();
+
+ }
+
+ else
+ {
+ m_dont_init = false;
+ }
+
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::~sc_thread_process"
+//
+// This is the object instance constructor for this class.
+//------------------------------------------------------------------------------
+sc_thread_process::~sc_thread_process()
+{
+
+ // DESTROY THE COROUTINE FOR THIS THREAD:
+
+ if( m_cor_p != 0 ) {
+ m_cor_p->stack_protect( false );
+ delete m_cor_p;
+ m_cor_p = 0;
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::signal_monitors"
+//
+// This methods signals the list of monitors for this object instance.
+//------------------------------------------------------------------------------
+void sc_thread_process::signal_monitors(int type)
+{
+ int mon_n; // # of monitors present.
+
+ mon_n = m_monitor_q.size();
+ for ( int mon_i = 0; mon_i < mon_n; mon_i++ )
+ m_monitor_q[mon_i]->signal(this, type);
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::suspend_process"
+//
+// This virtual method suspends this process and its children if requested to.
+// descendants = indicator of whether this process' children should also
+// be suspended
+//------------------------------------------------------------------------------
+void sc_thread_process::suspend_process(
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF NEEDED PROPOGATE THE SUSPEND REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*>& children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p ) child_p->suspend_process(descendants);
+ }
+ }
+
+ // CORNER CASE CHECKS, THE FOLLOWING ARE ERRORS:
+ // (a) if this thread has a reset_signal_is specification
+ // (b) if this thread is in synchronous reset
+
+ if ( !sc_allow_process_control_corners && m_has_reset_signal )
+ {
+ report_error(SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "attempt to suspend a thread that has a reset signal");
+ }
+ else if ( !sc_allow_process_control_corners && m_sticky_reset )
+ {
+ report_error(SC_ID_PROCESS_CONTROL_CORNER_CASE_,
+ "attempt to suspend a thread in synchronous reset");
+ }
+
+ // SUSPEND OUR OBJECT INSTANCE:
+ //
+ // (1) If we are on the runnable queue then set suspended and ready_to_run,
+ // and remove ourselves from the run queue.
+ // (2) If this is a self-suspension then a resume should cause immediate
+ // scheduling of the process, and we need to call suspend_me() here.
+
+ m_state = m_state | ps_bit_suspended;
+ if ( next_runnable() != 0 )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ simcontext()->remove_runnable_thread( this );
+ }
+ if ( sc_get_current_process_b() == DCAST<sc_process_b*>(this) )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ suspend_me();
+ }
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::throw_reset"
+//
+// This virtual method is invoked when an reset is to be thrown. The
+// method will cancel any dynamic waits. If the reset is asynchronous it will
+// queue this object instance to be executed.
+//------------------------------------------------------------------------------
+void sc_thread_process::throw_reset( bool async )
+{
+ // IF THE PROCESS IS CURRENTLY UNWINDING OR IS ALREADY A ZOMBIE
+ // IGNORE THE RESET:
+
+ if ( m_unwinding )
+ {
+ SC_REPORT_WARNING( SC_ID_PROCESS_ALREADY_UNWINDING_, name() );
+ return;
+ }
+
+ if ( m_state & ps_bit_zombie )
+ return;
+
+
+ // Set the throw type and clear any pending dynamic events:
+
+ m_throw_status = async ? THROW_ASYNC_RESET : THROW_SYNC_RESET;
+ m_wait_cycle_n = 0;
+
+ // If this is an asynchronous reset:
+ //
+ // (a) Cancel any dynamic events
+ // (b) Set the thread up for execution:
+ // (i) If we are in the execution phase do it now.
+ // (ii) If we are not queue it to execute next when we hit
+ // the execution phase.
+
+ if ( async )
+ {
+ m_state = m_state & ~ps_bit_ready_to_run;
+ remove_dynamic_events();
+ if ( simcontext()->evaluation_phase() )
+ {
+ simcontext()->preempt_with( this );
+ }
+ else
+ {
+ if ( is_runnable() )
+ simcontext()->remove_runnable_thread(this);
+ simcontext()->execute_thread_next(this);
+ }
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::throw_user"
+//
+// This virtual method is invoked when a user exception is to be thrown.
+// If requested it will also throw the exception to the children of this
+// object instance. The order of dispatch for the processes that are
+// thrown the exception is from youngest child to oldest child and then
+// this process instance. This means that this instance will be pushed onto
+// the front of the simulator's runnable queue and then the children will
+// be processed recursively.
+// helper_p = helper object to use to throw the exception.
+// descendants = indicator of whether this process' children should also
+// be suspended
+//------------------------------------------------------------------------------
+void sc_thread_process::throw_user( const sc_throw_it_helper& helper,
+ sc_descendant_inclusion_info descendants )
+{
+
+ // IF THE SIMULATION IS NOT ACTAULLY RUNNING THIS IS AN ERROR:
+
+ if ( sc_get_status() != SC_RUNNING )
+ {
+ report_error( SC_ID_THROW_IT_WHILE_NOT_RUNNING_ );
+ }
+
+ // IF NEEDED PROPOGATE THE THROW REQUEST THROUGH OUR DESCENDANTS:
+
+ if ( descendants == SC_INCLUDE_DESCENDANTS )
+ {
+ const std::vector<sc_object*> children = get_child_objects();
+ int child_n = children.size();
+
+ for ( int child_i = 0; child_i < child_n; child_i++ )
+ {
+ sc_process_b* child_p = DCAST<sc_process_b*>(children[child_i]);
+ if ( child_p )
+ {
+ DEBUG_MSG(DEBUG_NAME,child_p,"about to throw user on");
+ child_p->throw_user(helper, descendants);
+ }
+ }
+ }
+
+ // IF THE PROCESS IS CURRENTLY UNWINDING IGNORE THE THROW:
+
+ if ( m_unwinding )
+ {
+ SC_REPORT_WARNING( SC_ID_PROCESS_ALREADY_UNWINDING_, name() );
+ return;
+ }
+
+ // SET UP THE THROW REQUEST FOR THIS OBJECT INSTANCE AND QUEUE IT FOR
+ // EXECUTION:
+
+ if( m_has_stack )
+ {
+ remove_dynamic_events();
+ DEBUG_MSG(DEBUG_NAME,this,"throwing user exception to");
+ m_throw_status = THROW_USER;
+ if ( m_throw_helper_p != 0 ) delete m_throw_helper_p;
+ m_throw_helper_p = helper.clone();
+ simcontext()->preempt_with( this );
+ }
+ else
+ {
+ SC_REPORT_WARNING( SC_ID_THROW_IT_IGNORED_, name() );
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::trigger_dynamic"
+//
+// This method sets up a dynamic trigger on an event.
+//
+// Notes:
+// (1) This method is identical to sc_method_process::trigger_dynamic(),
+// but they cannot be combined as sc_process_b::trigger_dynamic()
+// because the signatures things like sc_event::remove_dynamic()
+// have different overloads for sc_thread_process* and sc_method_process*.
+// So if you change code here you'll also need to change it in
+// sc_method_process.cpp.
+//
+// Result is true if this process should be removed from the event's list,
+// false if not.
+//------------------------------------------------------------------------------
+bool sc_thread_process::trigger_dynamic( sc_event* e )
+{
+ // No time outs yet, and keep gcc happy.
+
+ m_timed_out = false;
+
+ // Escape cases:
+ // (a) If this thread issued the notify() don't schedule it for
+ // execution, but leave the sensitivity in place.
+ // (b) If this thread is already runnable can't trigger an event.
+
+ // not possible for thread processes!
+#if 0 // ! defined( SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS )
+ if ( sc_get_current_process_b() == (sc_process_b*)this )
+ {
+ report_immediate_self_notification();
+ return false;
+ }
+#endif // SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
+
+ if( is_runnable() )
+ return true;
+
+ // If a process is disabled then we ignore any events, leaving them enabled:
+ //
+ // But if this is a time out event we need to remove both it and the
+ // event that was being waited for.
+
+ if ( m_state & ps_bit_disabled )
+ {
+ if ( e == m_timeout_event_p )
+ {
+ remove_dynamic_events( true );
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+ // Process based on the event type and current process state:
+ //
+ // Every case needs to set 'rc' and continue on to the end of
+ // this method to allow suspend processing to work correctly.
+
+ switch( m_trigger_type )
+ {
+ case EVENT:
+ m_event_p = 0;
+ m_trigger_type = STATIC;
+ break;
+
+ case AND_LIST:
+ -- m_event_count;
+ if ( m_event_count == 0 )
+ {
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+ else
+ {
+ return true;
+ }
+ break;
+
+ case OR_LIST:
+ m_event_list_p->remove_dynamic( this, e );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ break;
+
+ case TIMEOUT:
+ m_trigger_type = STATIC;
+ break;
+
+ case EVENT_TIMEOUT:
+ if ( e == m_timeout_event_p )
+ {
+ m_timed_out = true;
+ m_event_p->remove_dynamic( this );
+ m_event_p = 0;
+ m_trigger_type = STATIC;
+ }
+ else
+ {
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ m_event_p = 0;
+ m_trigger_type = STATIC;
+ }
+ break;
+
+ case OR_LIST_TIMEOUT:
+ if ( e == m_timeout_event_p )
+ {
+ m_timed_out = true;
+ m_event_list_p->remove_dynamic( this, e );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+
+ else
+ {
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ m_event_list_p->remove_dynamic( this, e );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+ break;
+
+ case AND_LIST_TIMEOUT:
+ if ( e == m_timeout_event_p )
+ {
+ m_timed_out = true;
+ m_event_list_p->remove_dynamic( this, e );
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+
+ else
+ {
+ -- m_event_count;
+ if ( m_event_count == 0 )
+ {
+ m_timeout_event_p->cancel();
+ m_timeout_event_p->reset();
+ // no need to remove_dynamic
+ m_event_list_p->auto_delete();
+ m_event_list_p = 0;
+ m_trigger_type = STATIC;
+ }
+ else
+ {
+ return true;
+ }
+ }
+ break;
+
+ case STATIC: {
+ // we should never get here, but throw_it() can make it happen.
+ SC_REPORT_WARNING(SC_ID_NOT_EXPECTING_DYNAMIC_EVENT_NOTIFY_, name());
+ return true;
+ }
+ }
+
+ // If we get here then the thread is has satisfied its wait criteria, if
+ // its suspended mark its state as ready to run. If its not suspended then
+ // push it onto the runnable queue.
+
+ if ( (m_state & ps_bit_suspended) )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ }
+ else
+ {
+ simcontext()->push_runnable_thread(this);
+ }
+
+ return true;
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_set_stack_size"
+//
+//------------------------------------------------------------------------------
+void
+sc_set_stack_size( sc_thread_handle thread_h, std::size_t size )
+{
+ thread_h->set_stack_size( size );
+}
+
+#undef DEBUG_MSG
+#undef DEBUG_NAME
+
+} // namespace sc_core
+
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+// $Log: sc_thread_process.cpp,v $
+// Revision 1.57 2011/08/24 22:05:51 acg
+// Torsten Maehne: initialization changes to remove warnings.
+//
+// Revision 1.56 2011/08/07 19:08:04 acg
+// Andy Goodrich: moved logs to end of file so line number synching works
+// better between versions.
+//
+// Revision 1.55 2011/08/04 17:16:22 acg
+// Philipp A. Hartmann: fix handling of child objects in kill routine, need
+// to use a copy rather than a reference.
+//
+// Revision 1.53 2011/07/29 22:45:38 acg
+// Philipp A. Hartmann: changes to handle case where a process control
+// invocation on a child process causes the list of child processes to change.
+//
+// Revision 1.52 2011/07/24 11:27:04 acg
+// Andy Goodrich: moved the check for unwinding processes until after the
+// descendants have been processed in throw_user and kill.
+//
+// Revision 1.51 2011/07/24 11:20:03 acg
+// Philipp A. Hartmann: process control error message improvements:
+// (1) Downgrade error to warning for re-kills of processes.
+// (2) Add process name to process messages.
+// (3) drop some superfluous colons in messages.
+//
+// Revision 1.50 2011/05/09 04:07:49 acg
+// Philipp A. Hartmann:
+// (1) Restore hierarchy in all phase callbacks.
+// (2) Ensure calls to before_end_of_elaboration.
+//
+// Revision 1.49 2011/05/05 17:45:27 acg
+// Philip A. Hartmann: changes in WIN64 support.
+// Andy Goodrich: additional DEBUG_MSG instances to trace process handling.
+//
+// Revision 1.48 2011/04/19 15:04:27 acg
+// Philipp A. Hartmann: clean up SC_ID messages.
+//
+// Revision 1.47 2011/04/19 02:39:09 acg
+// Philipp A. Hartmann: added checks for additional throws during stack unwinds.
+//
+// Revision 1.46 2011/04/14 22:33:43 acg
+// Andy Goodrich: added missing checks for a process being a zombie.
+//
+// Revision 1.45 2011/04/13 02:45:11 acg
+// Andy Goodrich: eliminated warning message that occurred if the DEBUG_MSG
+// macro was used.
+//
+// Revision 1.44 2011/04/11 22:04:33 acg
+// Andy Goodrich: use the DEBUG_NAME macro for DEBUG_MSG messages.
+//
+// Revision 1.43 2011/04/10 22:12:32 acg
+// Andy Goodrich: adding debugging macros.
+//
+// Revision 1.42 2011/04/08 22:40:26 acg
+// Andy Goodrich: moved the reset event notification code out of throw_reset()
+// and into suspend_me.
+//
+// Revision 1.41 2011/04/08 18:24:07 acg
+// Andy Goodrich: fix asynchronous reset dispatch and when the reset_event()
+// is fired.
+//
+// Revision 1.40 2011/04/05 20:50:57 acg
+// Andy Goodrich:
+// (1) changes to make sure that event(), posedge() and negedge() only
+// return true if the clock has not moved.
+// (2) fixes for method self-resumes.
+// (3) added SC_PRERELEASE_VERSION
+// (4) removed kernel events from the object hierarchy, added
+// sc_hierarchy_name_exists().
+//
+// Revision 1.39 2011/04/01 22:30:39 acg
+// Andy Goodrich: change hard assertion to warning for trigger_dynamic()
+// getting called when there is only STATIC sensitivity. This can result
+// because of sc_process_handle::throw_it().
+//
+// Revision 1.38 2011/03/23 16:17:52 acg
+// Andy Goodrich: don't emit an error message for a resume on a disabled
+// process that is not suspended.
+//
+// Revision 1.37 2011/03/20 13:43:23 acg
+// Andy Goodrich: added async_signal_is() plus suspend() as a corner case.
+//
+// Revision 1.36 2011/03/08 20:49:31 acg
+// Andy Goodrich: implement coarse checking for synchronous reset - suspend
+// interaction.
+//
+// Revision 1.35 2011/03/08 20:32:28 acg
+// Andy Goodrich: implemented "coarse" checking for undefined process
+// control interactions.
+//
+// Revision 1.34 2011/03/07 18:25:19 acg
+// Andy Goodrich: tightening of check for resume on a disabled process to
+// only produce an error if it is ready to run.
+//
+// Revision 1.33 2011/03/07 17:38:44 acg
+// Andy Goodrich: tightening up of checks for undefined interaction between
+// synchronous reset and suspend.
+//
+// Revision 1.32 2011/03/06 23:30:13 acg
+// Andy Goodrich: refining suspend - sync reset corner case checking so that
+// the following are error situations:
+// (1) Calling suspend on a process with a reset_signal_is() specification
+// or sync_reset_on() is active.
+// (2) Calling sync_reset_on() on a suspended process.
+//
+// Revision 1.31 2011/03/06 19:57:11 acg
+// Andy Goodrich: refinements for the illegal suspend - synchronous reset
+// interaction.
+//
+// Revision 1.30 2011/03/06 16:47:09 acg
+// Andy Goodrich: changes for testing sync_reset - suspend corner cases.
+//
+// Revision 1.29 2011/03/06 15:59:23 acg
+// Andy Goodrich: added process control corner case checks.
+//
+// Revision 1.28 2011/03/05 19:44:20 acg
+// Andy Goodrich: changes for object and event naming and structures.
+//
+// Revision 1.27 2011/02/19 08:30:53 acg
+// Andy Goodrich: Moved process queueing into trigger_static from
+// sc_event::notify.
+//
+// Revision 1.26 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.25 2011/02/17 19:54:33 acg
+// Andy Goodrich:
+// (1) Changed signature of trigger_dynamic() back to bool, and moved
+// run queue processing into trigger_dynamic.
+// (2) Simplified process control usage.
+//
+// Revision 1.24 2011/02/16 22:37:31 acg
+// Andy Goodrich: clean up to remove need for ps_disable_pending.
+//
+// Revision 1.23 2011/02/14 17:51:40 acg
+// Andy Goodrich: proper pushing an poppping of the module hierarchy for
+// start_of_simulation() and end_of_simulation.
+//
+// Revision 1.22 2011/02/13 23:09:58 acg
+// Andy Goodrich: only remove dynamic events for asynchronous resets.
+//
+// Revision 1.21 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.20 2011/02/13 21:37:13 acg
+// Andy Goodrich: removed temporary diagnostic. Also there is
+// remove_dynamic_events() call in reset code.
+//
+// Revision 1.19 2011/02/13 21:35:09 acg
+// Andy Goodrich: added error messages for throws before the simulator is
+// initialized.
+//
+// Revision 1.18 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.17 2011/02/08 08:18:16 acg
+// Andy Goodrich: removed obsolete code.
+//
+// Revision 1.16 2011/02/07 19:17:20 acg
+// Andy Goodrich: changes for IEEE 1666 compatibility.
+//
+// Revision 1.15 2011/02/04 15:27:36 acg
+// Andy Goodrich: changes for suspend-resume semantics.
+//
+// Revision 1.14 2011/02/01 23:01:53 acg
+// Andy Goodrich: removed dead code.
+//
+// Revision 1.13 2011/02/01 21:16:36 acg
+// Andy Goodrich:
+// (1) New version of trigger_dynamic() to implement new return codes and
+// proper processing of events with new dynamic process rules.
+// (2) Recoding of kill_process(), throw_user() and reset support to
+// consolidate preemptive thread execution in sc_simcontext::preempt_with().
+//
+// Revision 1.12 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.11 2011/01/20 16:52:20 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.10 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.9 2011/01/18 20:10:45 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.8 2011/01/06 18:02:16 acg
+// Andy Goodrich: added check for disabled thread to trigger_dynamic().
+//
+// Revision 1.7 2010/11/20 17:10:57 acg
+// Andy Goodrich: reset processing changes for new IEEE 1666 standard.
+//
+// Revision 1.6 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.5 2009/07/28 01:10:53 acg
+// Andy Goodrich: updates for 2.3 release candidate.
+//
+// Revision 1.4 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.3 2008/05/22 17:06:06 acg
+// Andy Goodrich: formatting and comments.
+//
+// Revision 1.2 2007/09/20 20:32:35 acg
+// Andy Goodrich: changes to the semantics of throw_it() to match the
+// specification. A call to throw_it() will immediately suspend the calling
+// thread until all the throwees have executed. At that point the calling
+// thread will be restarted before the execution of any other threads.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.8 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.7 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.6 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.5 2006/01/26 21:04:55 acg
+// Andy Goodrich: deprecation message changes and additional messages.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
diff --git a/ext/systemc/src/sysc/kernel/sc_thread_process.h b/ext/systemc/src/sysc/kernel/sc_thread_process.h
new file mode 100644
index 000000000..5e834506a
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_thread_process.h
@@ -0,0 +1,635 @@
+/*****************************************************************************
+
+ 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_thread_process.h -- Thread process declarations
+
+ Original Author: Andy Goodrich, Forte Design Systems, 4 August 2005
+
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#if !defined(sc_thread_process_h_INCLUDED)
+#define sc_thread_process_h_INCLUDED
+
+#include "sysc/kernel/sc_spawn_options.h"
+#include "sysc/kernel/sc_process.h"
+#include "sysc/kernel/sc_cor.h"
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_except.h"
+#include "sysc/kernel/sc_reset.h"
+
+// DEBUGGING MACROS:
+//
+// DEBUG_MSG(NAME,P,MSG)
+// MSG = message to print
+// NAME = name that must match the process for the message to print, or
+// null if the message should be printed unconditionally.
+// P = pointer to process message is for, or NULL in which case the
+// message will not print.
+#if 0
+# define DEBUG_NAME ""
+# define DEBUG_MSG(NAME,P,MSG) \
+ { \
+ if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
+ std::cout << "**** " << sc_time_stamp() << " (" \
+ << sc_get_current_process_name() << "): " << MSG \
+ << " - " << P->name() << std::endl; \
+ }
+#else
+# define DEBUG_MSG(NAME,P,MSG)
+#endif
+
+
+namespace sc_core {
+
+// forward references:
+class sc_event_and_list;
+class sc_event_or_list;
+class sc_reset;
+void sc_thread_cor_fn( void* );
+void sc_set_stack_size( sc_thread_handle, std::size_t );
+class sc_event;
+class sc_join;
+class sc_module;
+class sc_process_handle;
+class sc_process_table;
+class sc_simcontext;
+class sc_runnable;
+
+sc_cor* get_cor_pointer( sc_process_b* process_p );
+void sc_set_stack_size( sc_thread_handle thread_h, std::size_t size );
+void wait( sc_simcontext* );
+void wait( const sc_event&, sc_simcontext* );
+void wait( const sc_event_or_list&, sc_simcontext* );
+void wait( const sc_event_and_list&, sc_simcontext* );
+void wait( const sc_time&, sc_simcontext* );
+void wait( const sc_time&, const sc_event&, sc_simcontext* );
+void wait( const sc_time&, const sc_event_or_list&, sc_simcontext* );
+void wait( const sc_time&, const sc_event_and_list&, sc_simcontext* );
+
+//==============================================================================
+// sc_thread_process -
+//
+//==============================================================================
+class sc_thread_process : public sc_process_b {
+ friend void sc_thread_cor_fn( void* );
+ friend void sc_set_stack_size( sc_thread_handle, std::size_t );
+ friend class sc_event;
+ friend class sc_join;
+ friend class sc_module;
+ friend class sc_process_b;
+ friend class sc_process_handle;
+ friend class sc_process_table;
+ friend class sc_simcontext;
+ friend class sc_runnable;
+ friend sc_cor* get_cor_pointer( sc_process_b* process_p );
+
+ friend void wait( sc_simcontext* );
+ friend void wait( const sc_event&, sc_simcontext* );
+ friend void wait( const sc_event_or_list&, sc_simcontext* );
+ friend void wait( const sc_event_and_list&, sc_simcontext* );
+ friend void wait( const sc_time&, sc_simcontext* );
+ friend void wait( const sc_time&, const sc_event&, sc_simcontext* );
+ friend void wait( const sc_time&, const sc_event_or_list&, sc_simcontext* );
+ friend void wait( const sc_time&, const sc_event_and_list&, sc_simcontext*);
+ public:
+ sc_thread_process( const char* name_p, bool free_host,
+ SC_ENTRY_FUNC method_p, sc_process_host* host_p,
+ const sc_spawn_options* opt_p );
+
+ virtual const char* kind() const
+ { return "sc_thread_process"; }
+
+ protected:
+ // may not be deleted manually (called from sc_process_b)
+ virtual ~sc_thread_process();
+
+ virtual void disable_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ virtual void enable_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ virtual void kill_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ sc_thread_handle next_exist();
+ sc_thread_handle next_runnable();
+ virtual void prepare_for_simulation();
+ virtual void resume_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ void set_next_exist( sc_thread_handle next_p );
+ void set_next_runnable( sc_thread_handle next_p );
+
+ void set_stack_size( std::size_t size );
+ inline void suspend_me();
+ virtual void suspend_process(
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+ virtual void throw_reset( bool async );
+ virtual void throw_user( const sc_throw_it_helper& helper,
+ sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
+
+ bool trigger_dynamic( sc_event* );
+ inline void trigger_static();
+
+ void wait( const sc_event& );
+ void wait( const sc_event_or_list& );
+ void wait( const sc_event_and_list& );
+ void wait( const sc_time& );
+ void wait( const sc_time&, const sc_event& );
+ void wait( const sc_time&, const sc_event_or_list& );
+ void wait( const sc_time&, const sc_event_and_list& );
+ void wait_cycles( int n=1 );
+
+ protected:
+ void add_monitor( sc_process_monitor* monitor_p );
+ void remove_monitor( sc_process_monitor* monitor_p);
+ void signal_monitors( int type = 0 );
+
+ protected:
+ sc_cor* m_cor_p; // Thread's coroutine.
+ std::vector<sc_process_monitor*> m_monitor_q; // Thread monitors.
+ std::size_t m_stack_size; // Thread stack size.
+ int m_wait_cycle_n; // # of waits to be done.
+
+ private: // disabled
+ sc_thread_process( const sc_thread_process& );
+ const sc_thread_process& operator = ( const sc_thread_process& );
+
+};
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::set_stack_size"
+//
+//------------------------------------------------------------------------------
+inline void sc_thread_process::set_stack_size( std::size_t size )
+{
+ assert( size );
+ m_stack_size = size;
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::suspend_me"
+//
+// This method suspends this object instance in favor of the next runnable
+// process. Upon awakening we check to see if an exception should be thrown.
+// There are two types of exceptions that can be thrown, synchronous reset
+// and asynchronous reset. At a future time there may be more asynchronous
+// exceptions. If an asynchronous reset is seen and there is not static reset
+// specified, or the static reset is not active then clear the throw
+// type for the next time this method is called.
+//
+// Notes:
+// (1) For an explanation of how the reset mechanism works see the top of
+// the file sc_reset.cpp.
+// (2) The m_sticky_reset field is used to handle synchronous resets that
+// are enabled via the sc_process_handle::sync_reset_on() method. These
+// resets are not generated by a signal, but rather are modal by
+// method call: sync_reset_on() - sync_reset_off().
+//------------------------------------------------------------------------------
+inline void sc_thread_process::suspend_me()
+{
+ // remember, if we're currently unwinding
+
+ bool unwinding_preempted = m_unwinding;
+
+ sc_simcontext* simc_p = simcontext();
+ sc_cor* cor_p = simc_p->next_cor();
+
+ // do not switch, if we're about to execute next (e.g. suicide)
+
+ if( m_cor_p != cor_p )
+ {
+ DEBUG_MSG( DEBUG_NAME , this, "suspending thread");
+ simc_p->cor_pkg()->yield( cor_p );
+ DEBUG_MSG( DEBUG_NAME , this, "resuming thread");
+ }
+
+ // IF THERE IS A THROW TO BE DONE FOR THIS PROCESS DO IT NOW:
+ //
+ // (1) Optimize THROW_NONE for speed as it is the normal case.
+ // (2) If this thread is already unwinding then suspend_me() was
+ // called from the catch clause to throw an exception on another
+ // process, so just go back to the catch clause.
+
+ if ( m_throw_status == THROW_NONE ) return;
+
+ if ( m_unwinding ) return;
+
+ switch( m_throw_status )
+ {
+ case THROW_ASYNC_RESET:
+ case THROW_SYNC_RESET:
+ DEBUG_MSG( DEBUG_NAME , this, "throwing reset for");
+ if ( m_reset_event_p ) m_reset_event_p->notify();
+ throw sc_unwind_exception( this, true );
+
+ case THROW_USER:
+ DEBUG_MSG( DEBUG_NAME, this, "invoking throw_it for");
+ m_throw_status = m_active_areset_n ? THROW_ASYNC_RESET :
+ (m_active_reset_n ? THROW_SYNC_RESET :
+ THROW_NONE);
+ m_throw_helper_p->throw_it();
+ break;
+
+ case THROW_KILL:
+ DEBUG_MSG( DEBUG_NAME, this, "throwing kill for");
+ throw sc_unwind_exception( this, false );
+
+ default: // THROWING_NOW
+ sc_assert( unwinding_preempted );
+ DEBUG_MSG( DEBUG_NAME, this, "restarting thread");
+ break;
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::wait"
+//
+//------------------------------------------------------------------------------
+inline
+void
+sc_thread_process::wait( const sc_event& e )
+{
+ if( m_unwinding )
+ SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
+
+ m_event_p = &e; // for cleanup.
+ e.add_dynamic( this );
+ m_trigger_type = EVENT;
+ suspend_me();
+}
+
+inline
+void
+sc_thread_process::wait( const sc_event_or_list& el )
+{
+ if( m_unwinding )
+ SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
+
+ el.add_dynamic( this );
+ m_event_list_p = &el;
+ m_trigger_type = OR_LIST;
+ suspend_me();
+}
+
+inline
+void
+sc_thread_process::wait( const sc_event_and_list& el )
+{
+ if( m_unwinding )
+ SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
+
+ el.add_dynamic( this );
+ m_event_list_p = &el;
+ m_event_count = el.size();
+ m_trigger_type = AND_LIST;
+ suspend_me();
+}
+
+inline
+void
+sc_thread_process::wait( const sc_time& t )
+{
+ if( m_unwinding )
+ SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
+
+ m_timeout_event_p->notify_internal( t );
+ m_timeout_event_p->add_dynamic( this );
+ m_trigger_type = TIMEOUT;
+ suspend_me();
+}
+
+inline
+void
+sc_thread_process::wait( const sc_time& t, const sc_event& e )
+{
+ if( m_unwinding )
+ SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
+
+ m_timeout_event_p->notify_internal( t );
+ m_timeout_event_p->add_dynamic( this );
+ e.add_dynamic( this );
+ m_event_p = &e;
+ m_trigger_type = EVENT_TIMEOUT;
+ suspend_me();
+}
+
+inline
+void
+sc_thread_process::wait( const sc_time& t, const sc_event_or_list& el )
+{
+ if( m_unwinding )
+ SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
+
+ m_timeout_event_p->notify_internal( t );
+ m_timeout_event_p->add_dynamic( this );
+ el.add_dynamic( this );
+ m_event_list_p = &el;
+ m_trigger_type = OR_LIST_TIMEOUT;
+ suspend_me();
+}
+
+inline
+void
+sc_thread_process::wait( const sc_time& t, const sc_event_and_list& el )
+{
+ if( m_unwinding )
+ SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
+
+ m_timeout_event_p->notify_internal( t );
+ m_timeout_event_p->add_dynamic( this );
+ el.add_dynamic( this );
+ m_event_list_p = &el;
+ m_event_count = el.size();
+ m_trigger_type = AND_LIST_TIMEOUT;
+ suspend_me();
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::wait_cycles"
+//
+// This method suspends this object instance for the specified number of cycles.
+// A cycle is defined as the event the thread is set up to staticly wait on.
+// The field m_wait_cycle_n is set to one less than the number of cycles to
+// be waited for, since the value is tested before being decremented in
+// the simulation kernel.
+//------------------------------------------------------------------------------
+inline
+void
+sc_thread_process::wait_cycles( int n )
+{
+ if( m_unwinding )
+ SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
+
+ m_wait_cycle_n = n-1;
+ suspend_me();
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::miscellaneous support"
+//
+//------------------------------------------------------------------------------
+inline
+void sc_thread_process::add_monitor(sc_process_monitor* monitor_p)
+{
+ m_monitor_q.push_back(monitor_p);
+}
+
+
+inline
+void sc_thread_process::remove_monitor(sc_process_monitor* monitor_p)
+{
+ int mon_n = m_monitor_q.size();
+
+ for ( int mon_i = 0; mon_i < mon_n; mon_i++ )
+ {
+ if ( m_monitor_q[mon_i] == monitor_p )
+ {
+ m_monitor_q[mon_i] = m_monitor_q[mon_n-1];
+ m_monitor_q.resize(mon_n-1);
+ }
+ }
+}
+
+inline
+void sc_thread_process::set_next_exist(sc_thread_handle next_p)
+{
+ m_exist_p = next_p;
+}
+
+inline
+sc_thread_handle sc_thread_process::next_exist()
+{
+ return (sc_thread_handle)m_exist_p;
+}
+
+inline
+void sc_thread_process::set_next_runnable(sc_thread_handle next_p)
+{
+ m_runnable_p = next_p;
+}
+
+inline
+sc_thread_handle sc_thread_process::next_runnable()
+{
+ return (sc_thread_handle)m_runnable_p;
+}
+
+inline sc_cor* get_cor_pointer( sc_process_b* process_p )
+{
+ sc_thread_handle thread_p = DCAST<sc_thread_handle>(process_p);
+ return thread_p->m_cor_p;
+}
+
+//------------------------------------------------------------------------------
+//"sc_thread_process::trigger_static"
+//
+// This inline method adds the current thread to the queue of runnable
+// processes, if required. This is the case if the following criteria
+// are met:
+// (1) The process is in a runnable state.
+// (2) The process is not already on the run queue.
+// (3) The process is expecting a static trigger,
+// dynamic event waits take priority.
+// (4) The process' static wait count is zero.
+//
+// If the triggering process is the same process, the trigger is
+// ignored as well, unless SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
+// is defined.
+//------------------------------------------------------------------------------
+inline
+void
+sc_thread_process::trigger_static()
+{
+ // No need to try queueing this thread if one of the following is true:
+ // (a) its disabled
+ // (b) its already queued for execution
+ // (c) its waiting on a dynamic event
+ // (d) its wait count is not satisfied
+
+ if ( (m_state & ps_bit_disabled) || is_runnable() ||
+ m_trigger_type != STATIC )
+ return;
+
+#if ! defined( SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS )
+ if( SC_UNLIKELY_( sc_get_current_process_b() == this ) )
+ {
+ report_immediate_self_notification();
+ return;
+ }
+#endif // SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
+
+ if ( m_wait_cycle_n > 0 )
+ {
+ --m_wait_cycle_n;
+ return;
+ }
+
+ // If we get here then the thread is has satisfied its wait criteria, if
+ // its suspended mark its state as ready to run. If its not suspended then
+ // push it onto the runnable queue.
+
+ if ( m_state & ps_bit_suspended )
+ {
+ m_state = m_state | ps_bit_ready_to_run;
+ }
+ else
+ {
+ simcontext()->push_runnable_thread(this);
+ }
+}
+
+#undef DEBUG_MSG
+#undef DEBUG_NAME
+
+} // namespace sc_core
+
+// $Log: sc_thread_process.h,v $
+// Revision 1.30 2011/08/26 20:46:11 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.29 2011/08/24 23:36:12 acg
+// Andy Goodrich: removed break statements that can never be reached and
+// which causes warnings in the Greenhills C++ compiler.
+//
+// Revision 1.28 2011/04/14 22:34:27 acg
+// Andy Goodrich: removed dead code.
+//
+// Revision 1.27 2011/04/13 05:02:18 acg
+// Andy Goodrich: added missing check to the wake up code in suspend_me()
+// so that we just return if the call to suspend_me() was issued from a
+// stack unwinding.
+//
+// Revision 1.26 2011/04/13 02:44:26 acg
+// Andy Goodrich: added m_unwinding flag in place of THROW_NOW because the
+// throw status will be set back to THROW_*_RESET if reset is active and
+// the check for an unwind being complete was expecting THROW_NONE as the
+// clearing of THROW_NOW.
+//
+// Revision 1.25 2011/04/11 22:05:14 acg
+// Andy Goodrich: use the DEBUG_NAME macro in DEBUG_MSG invocations.
+//
+// Revision 1.24 2011/04/10 22:12:32 acg
+// Andy Goodrich: adding debugging macros.
+//
+// Revision 1.23 2011/04/08 22:41:28 acg
+// Andy Goodrich: added comment pointing to the description of the reset
+// mechanism in sc_reset.cpp.
+//
+// Revision 1.22 2011/04/08 18:27:33 acg
+// Andy Goodrich: added check to make sure we don't schedule a running process
+// because of it issues a notify() it is sensitive to.
+//
+// Revision 1.21 2011/04/05 06:22:38 acg
+// Andy Goodrich: expanded comment for trigger_static() initial vetting.
+//
+// Revision 1.20 2011/04/01 21:24:57 acg
+// Andy Goodrich: removed unused code.
+//
+// Revision 1.19 2011/02/19 08:30:53 acg
+// Andy Goodrich: Moved process queueing into trigger_static from
+// sc_event::notify.
+//
+// Revision 1.18 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.17 2011/02/17 19:55:58 acg
+// Andy Goodrich:
+// (1) Changed signature of trigger_dynamic() back to a bool.
+// (2) Simplified process control usage.
+// (3) Changed trigger_static() to recognize process controls and to
+// do the down-count on wait(N), allowing the elimination of
+// ready_to_run().
+//
+// Revision 1.16 2011/02/16 22:37:31 acg
+// Andy Goodrich: clean up to remove need for ps_disable_pending.
+//
+// Revision 1.15 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.14 2011/02/13 21:35:54 acg
+// Andy Goodrich: added error for performing a wait() during unwinding.
+//
+// Revision 1.13 2011/02/11 13:25:24 acg
+// Andy Goodrich: Philipp A. Hartmann's changes:
+// (1) Removal of SC_CTHREAD method overloads.
+// (2) New exception processing code.
+//
+// Revision 1.12 2011/02/01 23:01:53 acg
+// Andy Goodrich: removed dead code.
+//
+// Revision 1.11 2011/02/01 21:18:01 acg
+// Andy Goodrich:
+// (1) Changes in throw processing for new process control rules.
+// (2) Support of new process_state enum values.
+//
+// Revision 1.10 2011/01/25 20:50:37 acg
+// Andy Goodrich: changes for IEEE 1666 2011.
+//
+// Revision 1.9 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.8 2011/01/18 20:10:45 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.7 2011/01/06 17:59:58 acg
+// Andy Goodrich: removed debugging output.
+//
+// Revision 1.6 2010/07/22 20:02:33 acg
+// Andy Goodrich: bug fixes.
+//
+// Revision 1.5 2009/07/28 01:10:53 acg
+// Andy Goodrich: updates for 2.3 release candidate.
+//
+// Revision 1.4 2009/05/22 16:06:29 acg
+// Andy Goodrich: process control updates.
+//
+// Revision 1.3 2009/03/12 22:59:58 acg
+// Andy Goodrich: updates for 2.4 stuff.
+//
+// Revision 1.2 2008/05/22 17:06:06 acg
+// Andy Goodrich: formatting and comments.
+//
+// Revision 1.1.1.1 2006/12/15 20:20:05 acg
+// SystemC 2.3
+//
+// Revision 1.7 2006/05/08 17:57:13 acg
+// Andy Goodrich: Added David Long's forward declarations for friend functions
+// to keep the Microsoft C++ compiler happy.
+//
+// Revision 1.6 2006/04/20 17:08:17 acg
+// Andy Goodrich: 3.0 style process changes.
+//
+// Revision 1.5 2006/04/11 23:13:21 acg
+// Andy Goodrich: Changes for reduced reset support that only includes
+// sc_cthread, but has preliminary hooks for expanding to method and thread
+// processes also.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+#endif // !defined(sc_thread_process_h_INCLUDED)
diff --git a/ext/systemc/src/sysc/kernel/sc_time.cpp b/ext/systemc/src/sysc/kernel/sc_time.cpp
new file mode 100644
index 000000000..e3fdd5865
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_time.cpp
@@ -0,0 +1,465 @@
+/*****************************************************************************
+
+ 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_time.cpp --
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include <math.h>
+#include <stdio.h>
+
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_time.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+#if !defined(PRIu64)
+# if defined(_MSC_VER) || defined(__MINGW32__)
+# define PRIu64 "I64u"
+# else
+# define PRIu64 "llu"
+# endif
+#endif // PRIu64
+
+#ifdef SC_ENABLE_EARLY_MAXTIME_CREATION
+# define SC_MAXTIME_ALLOWED_ 1
+#else
+# define SC_MAXTIME_ALLOWED_ 0
+#endif
+
+namespace sc_core {
+
+static
+double time_values[] = {
+ 1, // fs
+ 1e3, // ps
+ 1e6, // ns
+ 1e9, // us
+ 1e12, // ms
+ 1e15 // s
+};
+
+static
+const char* time_units[] = {
+ "fs",
+ "ps",
+ "ns",
+ "us",
+ "ms",
+ "s"
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_time
+//
+// The time class.
+// ----------------------------------------------------------------------------
+
+// constructors
+
+sc_time::sc_time( double v, sc_time_unit tu )
+: m_value( 0 )
+{
+ if( v != 0 ) {
+ sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
+ double scale_fac = time_values[tu] / time_params->time_resolution;
+ // linux bug workaround; don't change next two lines
+ volatile double tmp = v * scale_fac + 0.5;
+ m_value = SCAST<sc_dt::int64>( tmp );
+ time_params->time_resolution_fixed = true;
+ }
+}
+
+sc_time::sc_time( double v, sc_time_unit tu, sc_simcontext* simc )
+: m_value( 0 )
+{
+ if( v != 0 ) {
+ sc_time_params* time_params = simc->m_time_params;
+ double scale_fac = time_values[tu] / time_params->time_resolution;
+ // linux bug workaround; don't change next two lines
+ volatile double tmp = v * scale_fac + 0.5;
+ m_value = SCAST<sc_dt::int64>( tmp );
+ time_params->time_resolution_fixed = true;
+ }
+}
+
+sc_time::sc_time( double v, bool scale )
+: m_value( 0 )
+{
+ static bool warn_constructor=true;
+ if ( warn_constructor ) {
+ warn_constructor=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "deprecated constructor: sc_time(double,bool)");
+ }
+
+ if( v != 0 ) {
+ sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
+ if( scale ) {
+ double scale_fac = sc_dt::uint64_to_double(
+ time_params->default_time_unit );
+ // linux bug workaround; don't change next two lines
+ volatile double tmp = v * scale_fac + 0.5;
+ m_value = SCAST<sc_dt::int64>( tmp );
+ } else {
+ // linux bug workaround; don't change next two lines
+ volatile double tmp = v + 0.5;
+ m_value = SCAST<sc_dt::int64>( tmp );
+ }
+ time_params->time_resolution_fixed = true;
+ }
+}
+
+sc_time::sc_time( value_type v, bool scale )
+: m_value( 0 )
+{
+ static bool warn_constructor=true;
+ if ( warn_constructor ) {
+ warn_constructor=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "deprecated constructor: sc_time(uint64,bool)");
+ }
+
+ if( v != 0 ) {
+ sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
+ if( scale ) {
+ double scale_fac = sc_dt::uint64_to_double(
+ time_params->default_time_unit );
+ // linux bug workaround; don't change next two lines
+ volatile double tmp = sc_dt::uint64_to_double( v ) *
+ scale_fac + 0.5;
+ m_value = SCAST<sc_dt::int64>( tmp );
+ } else {
+ m_value = v;
+ }
+ time_params->time_resolution_fixed = true;
+ }
+}
+
+sc_time
+sc_time::from_value( value_type v )
+{
+ sc_time t;
+ if( v != 0 && !(SC_MAXTIME_ALLOWED_ && v == ~sc_dt::UINT64_ZERO) ) {
+ sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
+ time_params->time_resolution_fixed = true;
+ }
+ t.m_value = v;
+ return t;
+}
+
+
+// conversion functions
+
+double
+sc_time::to_default_time_units() const
+{
+ sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
+# if SC_MAXTIME_ALLOWED_
+ if( m_value == 0 )
+ return 0.0;
+ time_params->time_resolution_fixed = true;
+# endif // SC_MAXTIME_ALLOWED_
+ return ( sc_dt::uint64_to_double( m_value ) /
+ sc_dt::uint64_to_double( time_params->default_time_unit ) );
+}
+
+double
+sc_time::to_seconds() const
+{
+ sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
+# if SC_MAXTIME_ALLOWED_
+ if( m_value == 0 )
+ return 0.0;
+ time_params->time_resolution_fixed = true;
+# endif // SC_MAXTIME_ALLOWED_
+ return ( sc_dt::uint64_to_double( m_value ) *
+ time_params->time_resolution * 1e-15 );
+}
+
+const std::string
+sc_time::to_string() const
+{
+ value_type val = m_value;
+ if( val == 0 ) {
+ return std::string( "0 s" );
+ }
+ sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
+# if SC_MAXTIME_ALLOWED_
+ time_params->time_resolution_fixed = true;
+# endif // SC_MAXTIME_ALLOWED_
+ value_type tr = SCAST<sc_dt::int64>( time_params->time_resolution );
+ int n = 0;
+ while( ( tr % 10 ) == 0 ) {
+ tr /= 10;
+ n ++;
+ }
+ assert( tr == 1 );
+ while( ( val % 10 ) == 0 ) {
+ val /= 10;
+ n ++;
+ }
+ char buf[BUFSIZ];
+ std::sprintf( buf, "%" PRIu64, val );
+ std::string result( buf );
+ if( n >= 15 ) {
+ for( int i = n - 15; i > 0; -- i ) {
+ result += "0";
+ }
+ result += " s";
+ } else {
+ for( int i = n % 3; i > 0; -- i ) {
+ result += "0";
+ }
+ result += " ";
+ result += time_units[n / 3];
+ }
+ return result;
+}
+
+
+// print function
+
+void
+sc_time::print( ::std::ostream& os ) const
+{
+ os << to_string();
+}
+
+
+// ----------------------------------------------------------------------------
+// STRUCT : sc_time_params
+//
+// Struct that holds the time resolution and default time unit.
+// ----------------------------------------------------------------------------
+
+sc_time_params::sc_time_params()
+: time_resolution( 1000 ), // default 1 ps
+ time_resolution_specified( false ),
+ time_resolution_fixed( false ),
+ default_time_unit( 1000 ), // default 1 ns
+ default_time_unit_specified( false )
+{}
+
+sc_time_params::~sc_time_params()
+{}
+
+
+// ----------------------------------------------------------------------------
+
+// functions for accessing the time resolution and default time unit
+
+void
+sc_set_time_resolution( double v, sc_time_unit tu )
+{
+ // first perform the necessary checks
+
+ // must be positive
+ if( v < 0.0 ) {
+ SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_, "value not positive" );
+ }
+
+ // must be a power of ten
+ double dummy;
+#if defined( __HP_aCC ) || defined(__ppc__)
+ // aCC seems to have a bug in modf()
+ if( modf( log10( v < 1.0 ? 1.0/v : v ), &dummy ) != 0.0 ) {
+#else
+ if( modf( log10( v ), &dummy ) != 0.0 ) {
+#endif
+ SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_,
+ "value not a power of ten" );
+ }
+
+ sc_simcontext* simc = sc_get_curr_simcontext();
+
+ // can only be specified during elaboration
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_, "simulation running" );
+ }
+
+ sc_time_params* time_params = simc->m_time_params;
+
+ // can be specified only once
+ if( time_params->time_resolution_specified ) {
+ SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_, "already specified" );
+ }
+
+ // can only be specified before any sc_time is constructed
+ if( time_params->time_resolution_fixed ) {
+ SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_,
+ "sc_time object(s) constructed" );
+ }
+
+ // must be larger than or equal to 1 fs
+ volatile double resolution = v * time_values[tu];
+ if( resolution < 1.0 ) {
+ SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_,
+ "value smaller than 1 fs" );
+ }
+
+ // recalculate the default time unit
+ volatile double time_unit = sc_dt::uint64_to_double(
+ time_params->default_time_unit ) *
+ ( time_params->time_resolution / resolution );
+ if( time_unit < 1.0 ) {
+ SC_REPORT_WARNING( SC_ID_DEFAULT_TIME_UNIT_CHANGED_, 0 );
+ time_params->default_time_unit = 1;
+ } else {
+ time_params->default_time_unit = SCAST<sc_dt::int64>( time_unit );
+ }
+
+ time_params->time_resolution = resolution;
+ time_params->time_resolution_specified = true;
+}
+
+sc_time
+sc_get_time_resolution()
+{
+ return sc_time::from_value( sc_dt::UINT64_ONE );
+}
+
+
+void
+sc_set_default_time_unit( double v, sc_time_unit tu )
+{
+ static bool warn_default_time_unit=true;
+ if ( warn_default_time_unit )
+ {
+ warn_default_time_unit=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "deprecated function: sc_set_default_time_unit");
+ }
+
+ // first perform the necessary checks
+
+ // must be positive
+ if( v < 0.0 ) {
+ SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_, "value not positive" );
+ }
+
+ // must be a power of ten
+ double dummy;
+ if( modf( log10( v ), &dummy ) != 0.0 ) {
+ SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_,
+ "value not a power of ten" );
+ }
+
+ sc_simcontext* simc = sc_get_curr_simcontext();
+
+ // can only be specified during elaboration
+ if( sc_is_running() ) {
+ SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_, "simulation running" );
+ }
+
+ sc_time_params* time_params = simc->m_time_params;
+
+ // can only be specified before any sc_time is constructed
+ if( time_params->time_resolution_fixed ) {
+ SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_,
+ "sc_time object(s) constructed" );
+ }
+
+ // can be specified only once
+ if( time_params->default_time_unit_specified ) {
+ SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_, "already specified" );
+ }
+
+ // must be larger than or equal to the time resolution
+ volatile double time_unit = ( v * time_values[tu] ) /
+ time_params->time_resolution;
+ if( time_unit < 1.0 ) {
+ SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_,
+ "value smaller than time resolution" );
+ }
+
+ time_params->default_time_unit = SCAST<sc_dt::int64>( time_unit );
+ time_params->default_time_unit_specified = true;
+}
+
+sc_time
+sc_get_default_time_unit()
+{
+ static bool warn_get_default_time_unit = true;
+ if ( warn_get_default_time_unit )
+ {
+ warn_get_default_time_unit=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "deprecated function: sc_get_default_time_unit");
+ }
+ return sc_time::from_value(
+ sc_get_curr_simcontext()->m_time_params->default_time_unit
+ );
+}
+
+
+// ----------------------------------------------------------------------------
+
+const sc_time SC_ZERO_TIME;
+
+#undef SC_MAXTIME_ALLOWED_
+
+} // namespace sc_core
+
+// $Log: sc_time.cpp,v $
+// Revision 1.7 2011/08/26 20:46:11 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.6 2011/07/24 16:08:36 acg
+// Philipp A. Hartmann: fix C99 format specifiers for Solaris.
+//
+// Revision 1.5 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.4 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.3 2011/01/19 23:21:50 acg
+// Andy Goodrich: changes for IEEE 1666 2011
+//
+// Revision 1.2 2008/05/22 17:06:27 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.6 2006/01/26 21:04:55 acg
+// Andy Goodrich: deprecation message changes and additional messages.
+//
+// Revision 1.5 2006/01/25 00:31:19 acg
+// Andy Goodrich: Changed over to use a standard message id of
+// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+//
+// Revision 1.4 2006/01/24 20:49:05 acg
+// Andy Goodrich: changes to remove the use of deprecated features within the
+// simulator, and to issue warning messages when deprecated features are used.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_time.h b/ext/systemc/src/sysc/kernel/sc_time.h
new file mode 100644
index 000000000..af222dd0f
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_time.h
@@ -0,0 +1,414 @@
+/*****************************************************************************
+
+ 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_time.h -- The time class.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_TIME_H
+#define SC_TIME_H
+
+
+#include "sysc/datatypes/int/sc_nbdefs.h"
+#include "sysc/datatypes/fx/scfx_ieee.h"
+#include "sysc/utils/sc_iostream.h"
+
+namespace sc_core {
+
+class sc_simcontext;
+
+// friend operator declarations
+
+ const sc_time operator + ( const sc_time&, const sc_time& );
+ const sc_time operator - ( const sc_time&, const sc_time& );
+ const sc_time operator * ( const sc_time&, double );
+ const sc_time operator * ( double, const sc_time& );
+ const sc_time operator / ( const sc_time&, double );
+ double operator / ( const sc_time&, const sc_time& );
+
+
+// ----------------------------------------------------------------------------
+// ENUM : sc_time_unit
+//
+// Enumeration of time units.
+// ----------------------------------------------------------------------------
+
+enum sc_time_unit
+{
+ SC_FS = 0,
+ SC_PS,
+ SC_NS,
+ SC_US,
+ SC_MS,
+ SC_SEC
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_time
+//
+// The time class.
+// ----------------------------------------------------------------------------
+
+class sc_time
+{
+public:
+
+ typedef sc_dt::uint64 value_type;
+
+ // constructors
+
+ sc_time();
+ sc_time( double, sc_time_unit );
+ sc_time( double, sc_time_unit, sc_simcontext* );
+ sc_time( const sc_time& );
+
+ static sc_time from_value( value_type );
+
+ // deprecated, use from_value(v)
+ sc_time( double, bool scale );
+ sc_time( value_type, bool scale );
+
+ // assignment operator
+
+ sc_time& operator = ( const sc_time& );
+
+
+ // conversion functions
+
+ value_type value() const; // relative to the time resolution
+ double to_double() const; // relative to the time resolution
+ double to_default_time_units() const;
+ double to_seconds() const;
+ const std::string to_string() const;
+
+
+ // relational operators
+
+ bool operator == ( const sc_time& ) const;
+ bool operator != ( const sc_time& ) const;
+ bool operator < ( const sc_time& ) const;
+ bool operator <= ( const sc_time& ) const;
+ bool operator > ( const sc_time& ) const;
+ bool operator >= ( const sc_time& ) const;
+
+
+ // arithmetic operators
+
+ sc_time& operator += ( const sc_time& );
+ sc_time& operator -= ( const sc_time& );
+
+ friend const sc_time operator + ( const sc_time&, const sc_time& );
+ friend const sc_time operator - ( const sc_time&, const sc_time& );
+
+ sc_time& operator *= ( double );
+ sc_time& operator /= ( double );
+ sc_time& operator %= ( const sc_time& );
+
+ friend const sc_time operator * ( const sc_time&, double );
+ friend const sc_time operator * ( double, const sc_time& );
+ friend const sc_time operator / ( const sc_time&, double );
+ friend double operator / ( const sc_time&, const sc_time& );
+ friend const sc_time operator % ( const sc_time&, const sc_time& );
+
+
+ // print function
+
+ void print( ::std::ostream& os = std::cout ) const;
+
+private:
+
+ value_type m_value;
+};
+
+
+// print operator
+
+inline ::std::ostream& operator << ( ::std::ostream&, const sc_time& );
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// constructors
+
+inline
+sc_time::sc_time()
+: m_value( 0 )
+{}
+
+inline
+sc_time::sc_time( const sc_time& t )
+: m_value( t.m_value )
+{}
+
+
+// assignment operator
+
+inline
+sc_time&
+sc_time::operator = ( const sc_time& t )
+{
+ m_value = t.m_value;
+ return *this;
+}
+
+
+// conversion functions
+
+inline
+sc_time::value_type
+sc_time::value() const // relative to the time resolution
+{
+ return m_value;
+}
+
+
+inline
+double
+sc_time::to_double() const // relative to the time resolution
+{
+ return sc_dt::uint64_to_double( m_value );
+}
+
+
+// relational operators
+
+inline
+bool
+sc_time::operator == ( const sc_time& t ) const
+{
+ return ( m_value == t.m_value );
+}
+
+inline
+bool
+sc_time::operator != ( const sc_time& t ) const
+{
+ return ( m_value != t.m_value );
+}
+
+inline
+bool
+sc_time::operator < ( const sc_time& t ) const
+{
+ return ( m_value < t.m_value );
+}
+
+inline
+bool
+sc_time::operator <= ( const sc_time& t ) const
+{
+ return ( m_value <= t.m_value );
+}
+
+inline
+bool
+sc_time::operator > ( const sc_time& t ) const
+{
+ return ( m_value > t.m_value );
+}
+
+inline
+bool
+sc_time::operator >= ( const sc_time& t ) const
+{
+ return ( m_value >= t.m_value );
+}
+
+
+// arithmetic operators
+
+inline
+sc_time&
+sc_time::operator += ( const sc_time& t )
+{
+ m_value += t.m_value;
+ return *this;
+}
+
+inline
+sc_time&
+sc_time::operator -= ( const sc_time& t )
+{
+ m_value -= t.m_value;
+ return *this;
+}
+
+
+inline
+const sc_time
+operator + ( const sc_time& t1, const sc_time& t2 )
+{
+ return sc_time( t1 ) += t2;
+}
+
+inline
+const sc_time
+operator - ( const sc_time& t1, const sc_time& t2 )
+{
+ return sc_time( t1 ) -= t2;
+}
+
+
+inline
+sc_time&
+sc_time::operator *= ( double d )
+{
+ // linux bug workaround; don't change next two lines
+ volatile double tmp = sc_dt::uint64_to_double( m_value ) * d + 0.5;
+ m_value = SCAST<sc_dt::int64>( tmp );
+ return *this;
+}
+
+inline
+sc_time&
+sc_time::operator /= ( double d )
+{
+ // linux bug workaround; don't change next two lines
+ volatile double tmp = sc_dt::uint64_to_double( m_value ) / d + 0.5;
+ m_value = SCAST<sc_dt::int64>( tmp );
+ return *this;
+}
+
+inline
+sc_time&
+sc_time::operator %= ( const sc_time& t )
+{
+ m_value %= t.m_value;
+ return *this;
+}
+
+inline
+const sc_time
+operator * ( const sc_time& t, double d )
+{
+ sc_time tmp( t );
+ return tmp *= d;
+}
+
+inline
+const sc_time
+operator * ( double d, const sc_time& t )
+{
+ sc_time tmp( t );
+ return tmp *= d;
+}
+
+inline
+const sc_time
+operator / ( const sc_time& t, double d )
+{
+ sc_time tmp( t );
+ return tmp /= d;
+}
+
+inline
+double
+operator / ( const sc_time& t1, const sc_time& t2 )
+{
+ return ( t1.to_double() / t2.to_double() );
+}
+
+inline
+const sc_time
+operator % ( const sc_time& t1, const sc_time& t2 )
+{
+ sc_time tmp(t1);
+ return tmp %= t2;
+}
+
+// print operator
+
+inline
+::std::ostream&
+operator << ( ::std::ostream& os, const sc_time& t )
+{
+ t.print( os );
+ return os;
+}
+
+
+// ----------------------------------------------------------------------------
+// STRUCT : sc_time_params
+//
+// Struct that holds the time resolution and default time unit.
+// ----------------------------------------------------------------------------
+
+struct sc_time_params
+{
+ double time_resolution; // in femto seconds
+ bool time_resolution_specified;
+ bool time_resolution_fixed;
+
+ sc_time::value_type default_time_unit; // in time resolution
+ bool default_time_unit_specified;
+
+ sc_time_params();
+ ~sc_time_params();
+};
+
+
+// ----------------------------------------------------------------------------
+
+extern const sc_time SC_ZERO_TIME;
+
+
+// functions for accessing the time resolution and default time unit
+
+extern void sc_set_time_resolution( double, sc_time_unit );
+extern sc_time sc_get_time_resolution();
+
+extern void sc_set_default_time_unit( double, sc_time_unit );
+extern sc_time sc_get_default_time_unit();
+
+} // namespace sc_core
+
+#endif
+
+// $Log: sc_time.h,v $
+// Revision 1.5 2011/08/26 20:46:11 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.4 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.3 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.2 2008/05/22 17:06:27 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.4 2006/05/08 18:02:06 acg
+// Andy Goodrich: added David Long's forward declarations for friend
+// functions, methods, and operators to keep the Microsoft compiler happy.
+//
+// Revision 1.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_ver.cpp b/ext/systemc/src/sysc/kernel/sc_ver.cpp
new file mode 100644
index 000000000..9883cd3bc
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_ver.cpp
@@ -0,0 +1,228 @@
+/*****************************************************************************
+
+ 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_ver.cpp -- copyright information.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#include <cstddef>
+#include <cstdlib>
+
+#define SC_DISABLE_API_VERSION_CHECK // for in-library sc_ver.h inclusion
+
+#include "sysc/kernel/sc_ver.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/utils/sc_iostream.h"
+#include "sysc/utils/sc_report.h"
+
+using std::getenv;
+using std::strcmp;
+using std::cerr;
+using std::endl;
+
+namespace sc_core {
+
+
+static
+const char systemc_version[] =
+ "SystemC " SC_VERSION " --- " __DATE__ " " __TIME__;
+
+const unsigned int sc_version_major = SC_VERSION_MAJOR;
+const unsigned int sc_version_minor = SC_VERSION_MINOR;
+const unsigned int sc_version_patch = SC_VERSION_PATCH;
+const bool sc_is_prerelease = SC_IS_PRERELEASE;
+
+const std::string sc_version_originator = SC_VERSION_ORIGINATOR;
+const std::string sc_version_release_date = SC_VERSION_RELEASE_DATE;
+const std::string sc_version_prerelease = SC_VERSION_PRERELEASE;
+const std::string sc_version_string = SC_VERSION;
+const std::string sc_copyright_string = SC_COPYRIGHT;
+
+const char*
+sc_copyright()
+{
+ return SC_COPYRIGHT;
+}
+
+
+const char*
+sc_release()
+{
+ return SC_VERSION;
+}
+
+
+const char*
+sc_version()
+{
+ return systemc_version;
+}
+
+
+#if !defined(SC_DISABLE_COPYRIGHT_MESSAGE)
+# define SC_DISABLE_COPYRIGHT_MESSAGE 0
+#endif
+
+// ----------------------------------------------------------------------------
+
+void
+pln()
+{
+ static bool lnp = SC_DISABLE_COPYRIGHT_MESSAGE;
+ if ( lnp || getenv("SYSTEMC_DISABLE_COPYRIGHT_MESSAGE") != 0 )
+ lnp = true;
+ if ( const char * lnp_env = getenv("SC_COPYRIGHT_MESSAGE") ) {
+ lnp = !strcmp( lnp_env, "DISABLE" );
+ }
+ if( ! lnp ) {
+
+ static const char indent[] = " ";
+ std::string line;
+ std::stringstream copyright;
+
+ // temporary stream to print copyright line-wise with indentation
+ copyright << sc_copyright();
+
+ cerr << endl;
+ cerr << indent << sc_version() << endl;
+ while( getline( copyright, line ) )
+ cerr << indent << line << endl;
+
+ // regressions check point
+
+ if( getenv( "SYSTEMC_REGRESSION" ) != 0 ) {
+ cerr << "SystemC Simulation" << endl;
+ }
+
+ lnp = true;
+ }
+}
+
+#define SC_API_PERFORM_CHECK_( Type, Name, Symbol ) \
+ do { \
+ static bool SC_CONCAT_UNDERSCORE_( Name, config_seen ) = false; \
+ static Type SC_CONCAT_UNDERSCORE_( Name, config ); \
+ if( ! SC_CONCAT_UNDERSCORE_( Name, config_seen ) ) { \
+ SC_CONCAT_UNDERSCORE_( Name, config_seen ) = true; \
+ SC_CONCAT_UNDERSCORE_( Name, config ) = Name; \
+ } else if( SC_CONCAT_UNDERSCORE_( Name, config ) != Name ) { \
+ SC_REPORT_FATAL( SC_ID_INCONSISTENT_API_CONFIG_, Symbol ); \
+ } \
+ } while( false )
+
+// THIS CONSTRUCTOR ROOTS OUT OLD OBJECTS AT LINK TIME
+//
+// Each source file which includes sc_ver.h for this SystemC version
+// will have a static instance of the class sc_api_version_XXX defined
+// in it. That object instanciation will cause the constructor below
+// to be invoked. If the version of the SystemC being linked against
+// does not contain the constructor below a linkage error will occur.
+//
+// Some preprocessor switches need to be consistent between the application
+// and the library (e.g. if sizes of classes are affected or other parts of
+// the ABI are affected). (Some of) these are checked here at link-time as
+// well, by setting template parameters to sc_api_version_XXX, while only
+// one variant is defined here.
+//
+// Some preprocessor switches need to be consistent between different
+// translation units of an application. Those can't be easily checked
+// during link-time. Instead, perform a check during run-time by
+// passing the value to the constructor of the api_version_check object.
+
+// const int DEBUG_SYSTEMC_CHECK_ = 1;
+const int SC_DISABLE_VIRTUAL_BIND_CHECK_ = 1;
+
+template<>
+SC_API_VERSION_STRING
+<
+// & DEBUG_SYSTEMC_CHECK_,
+ & SC_DISABLE_VIRTUAL_BIND_CHECK_
+>
+::SC_API_VERSION_STRING
+(
+ sc_writer_policy default_writer_policy
+)
+{
+ SC_API_PERFORM_CHECK_( sc_writer_policy
+ , default_writer_policy
+ , "SC_DEFAULT_WRITER_POLICY" );
+}
+
+} // namespace sc_core
+
+// $Log: sc_ver.cpp,v $
+// Revision 1.14 2011/08/26 21:56:55 acg
+// Torsten Maehne: use usings rather than absolute namespace addressing.
+//
+// Revision 1.13 2011/08/26 20:46:11 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.12 2011/07/25 10:20:34 acg
+// Andy Goodrich: check in aftermath of call to automake.
+//
+// Revision 1.11 2011/07/02 12:55:19 acg
+// Andy Goodrich: automake refresh.
+//
+// Revision 1.10 2011/07/01 18:49:07 acg
+// Andy Goodrich: moved pln() from sc_simcontext.cpp to sc_ver.cpp.
+//
+// Revision 1.9 2011/07/01 18:33:08 acg
+// Andy Goodrich: changes for IEEE 1666, removal of macros and use of them.
+//
+// Revision 1.8 2011/04/08 18:27:53 acg
+// Andy Goodrich: respin of the PoC.
+//
+// Revision 1.7 2011/04/05 20:50:57 acg
+// Andy Goodrich:
+// (1) changes to make sure that event(), posedge() and negedge() only
+// return true if the clock has not moved.
+// (2) fixes for method self-resumes.
+// (3) added SC_PRERELEASE_VERSION
+// (4) removed kernel events from the object hierarchy, added
+// sc_hierarchy_name_exists().
+//
+// Revision 1.6 2011/02/18 20:27:14 acg
+// Andy Goodrich: Updated Copyrights.
+//
+// Revision 1.5 2011/02/13 21:47:38 acg
+// Andy Goodrich: update copyright notice.
+//
+// Revision 1.4 2011/01/18 20:10:45 acg
+// Andy Goodrich: changes for IEEE1666_2011 semantics.
+//
+// Revision 1.3 2010/11/20 17:10:57 acg
+// Andy Goodrich: reset processing changes for new IEEE 1666 standard.
+//
+// Revision 1.2 2008/05/22 17:06:27 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.3 2006/01/13 18:44:30 acg
+// Added $Log to record CVS changes into the source.
+//
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_ver.h b/ext/systemc/src/sysc/kernel/sc_ver.h
new file mode 100644
index 000000000..34112f9f8
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_ver.h
@@ -0,0 +1,186 @@
+/*****************************************************************************
+
+ 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_ver.h -- Version and copyright information.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+
+ NO AUTOMATIC CHANGE LOG IS GENERATED, EXPLICIT CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+
+#ifndef SC_VER_H
+#define SC_VER_H
+
+#include "sysc/kernel/sc_macros.h" // SC_CONCAT_UNDERSCORE_
+ // SC_STRINGIFY_HELPER_
+#include "sysc/communication/sc_writer_policy.h" // SC_DEFAULT_WRITER_POLICY
+
+#include <string>
+
+namespace sc_core {
+
+extern const char* sc_copyright();
+extern const char* sc_release();
+extern const char* sc_version();
+
+extern const unsigned int sc_version_major;
+extern const unsigned int sc_version_minor;
+extern const unsigned int sc_version_patch;
+
+extern const std::string sc_version_originator;
+extern const std::string sc_version_release_date;
+extern const std::string sc_version_prerelease;
+extern const bool sc_is_prerelease;
+extern const std::string sc_version_string;
+extern const std::string sc_copyright_string;
+
+#define SYSTEMC_2_3_1
+
+#define SYSTEMC_VERSION 20140417
+#define SC_VERSION_ORIGINATOR "Accellera"
+#define SC_VERSION_MAJOR 2
+#define SC_VERSION_MINOR 3
+#define SC_VERSION_PATCH 1
+#define SC_IS_PRERELEASE 0
+
+/// compliancy with IEEE 1666-2011 (see 8.6.5)
+#define IEEE_1666_SYSTEMC 201101L
+
+#define SC_COPYRIGHT \
+ "Copyright (c) 1996-2014 by all Contributors,\n" \
+ "ALL RIGHTS RESERVED\n"
+
+
+#define SC_VERSION_RELEASE_DATE \
+ SC_STRINGIFY_HELPER_( SYSTEMC_VERSION )
+
+#if ( SC_IS_PRERELEASE == 1 )
+# define SC_VERSION_PRERELEASE "pub_rev"
+# define SC_VERSION \
+ SC_STRINGIFY_HELPER_( SC_VERSION_MAJOR.SC_VERSION_MINOR.SC_VERSION_PATCH ) \
+ "_" SC_VERSION_PRERELEASE "_" SC_VERSION_RELEASE_DATE \
+ "-" SC_VERSION_ORIGINATOR
+#else
+# define SC_VERSION_PRERELEASE "" // nothing
+# define SC_VERSION \
+ SC_STRINGIFY_HELPER_( SC_VERSION_MAJOR.SC_VERSION_MINOR.SC_VERSION_PATCH ) \
+ "-" SC_VERSION_ORIGINATOR
+#endif
+
+// THIS CLASS AND STATIC INSTANCE BELOW DETECTS BAD REV OBJECTS AT LINK TIME
+//
+// Each source file which includes this file for the current SystemC version
+// will have a static instance of the class sc_api_version_XXX defined
+// in it. That object instance will cause the constructor below
+// to be invoked. If the version of the SystemC being linked against
+// does not contain the constructor below a linkage error will occur.
+
+#define SC_API_VERSION_STRING \
+ SC_CONCAT_UNDERSCORE_( sc_api_version, \
+ SC_CONCAT_UNDERSCORE_( SC_VERSION_MAJOR, \
+ SC_CONCAT_UNDERSCORE_( SC_VERSION_MINOR, \
+ SC_VERSION_PATCH ) ) )
+
+// explicitly avoid macro expansion
+#define SC_API_DEFINED_( Symbol ) \
+ Symbol ## _DEFINED_
+#define SC_API_UNDEFINED_( Symbol ) \
+ Symbol ## _UNDEFINED_
+
+// Some preprocessor switches need to be consistent between the application
+// and the library (e.g. if sizes of classes are affected or other parts of
+// the ABI are affected). (Some of) these are checked here at link-time as
+// well, by setting template parameters to sc_api_version_XXX, while only
+// one variant is defined in sc_ver.cpp.
+
+#if 0 // don't enforce check of DEBUG_SYSTEMC for now
+// DEBUG_SYSTEMC
+#if defined( DEBUG_SYSTEMC )
+# define DEBUG_SYSTEMC_CHECK_ \
+ SC_CONFIG_DEFINED_(DEBUG_SYSTEMC)
+#else
+# define DEBUG_SYSTEMC_CHECK_ \
+ SC_CONFIG_UNDEFINED_(DEBUG_SYSTEMC)
+#endif
+extern const int DEBUG_SYSTEMC_CHECK_;
+#endif
+
+// SC_DISABLE_VIRTUAL_BIND
+#if defined( SC_DISABLE_VIRTUAL_BIND )
+# define SC_DISABLE_VIRTUAL_BIND_CHECK_ \
+ SC_API_DEFINED_(SC_DISABLE_VIRTUAL_BIND)
+#else
+# define SC_DISABLE_VIRTUAL_BIND_CHECK_ \
+ SC_API_UNDEFINED_(SC_DISABLE_VIRTUAL_BIND)
+#endif
+extern const int SC_DISABLE_VIRTUAL_BIND_CHECK_;
+
+// Some preprocessor switches need to be consistent between different
+// translation units of an application. Those can't be easily checked
+// during link-time. Instead, perform a check during run-time by
+// passing the value to the constructor of the api_version_check object.
+
+// Note: Template and constructor parameters are not passed as default
+// values to avoid ODR violations in the check itself.
+
+template // use pointers for more verbose error messages
+<
+// const int * DebugSystemC,
+ const int * DisableVirtualBind
+>
+struct SC_API_VERSION_STRING
+{
+ SC_API_VERSION_STRING
+ (
+ // SC_DEFAULT_WRITER_POLICY
+ sc_writer_policy default_writer_policy
+ );
+};
+
+#if !defined( SC_DISABLE_API_VERSION_CHECK ) // disabled in sc_ver.cpp
+static
+SC_API_VERSION_STRING
+<
+// & DEBUG_SYSTEMC_CHECK_,
+ & SC_DISABLE_VIRTUAL_BIND_CHECK_
+>
+api_version_check
+(
+ SC_DEFAULT_WRITER_POLICY
+);
+#endif // SC_DISABLE_API_VERSION_CHECK
+
+//#undef SC_API_DEFINED_
+//#undef SC_API_UNDEFINED_
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+#endif
diff --git a/ext/systemc/src/sysc/kernel/sc_wait.cpp b/ext/systemc/src/sysc/kernel/sc_wait.cpp
new file mode 100644
index 000000000..9c9f2bdfb
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_wait.cpp
@@ -0,0 +1,446 @@
+/*****************************************************************************
+
+ 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_wait.cpp -- Wait() and related functions.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#include "sysc/kernel/sc_except.h"
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_cthread_process.h"
+#include "sysc/kernel/sc_thread_process.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_wait.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+namespace sc_core {
+
+// static sensitivity for SC_THREADs and SC_CTHREADs
+
+void warn_cthread_wait()
+{
+ static bool warn_wait = true;
+ if ( warn_wait )
+ {
+ warn_wait = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "all waits except wait() and wait(N)\n" \
+ " are deprecated for SC_CTHREAD, " \
+ "use an SC_THREAD instead");
+ }
+}
+
+void
+wait( sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_:
+ case SC_CTHREAD_PROC_: {
+ RCAST<sc_cthread_handle>( cpi->process_handle )->wait_cycles();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+// dynamic sensitivity for SC_THREADs and SC_CTHREADs
+
+void
+wait( const sc_event& e, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_: {
+ RCAST<sc_thread_handle>( cpi->process_handle )->wait( e );
+ break;
+ }
+ case SC_CTHREAD_PROC_: {
+ warn_cthread_wait();
+ sc_cthread_handle cthread_h =
+ RCAST<sc_cthread_handle>( cpi->process_handle );
+ cthread_h->wait( e );
+ cthread_h->wait_cycles();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+void
+wait( const sc_event_or_list& el, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_: {
+ RCAST<sc_thread_handle>( cpi->process_handle )->wait( el );
+ break;
+ }
+ case SC_CTHREAD_PROC_: {
+ warn_cthread_wait();
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "wait(event_list) is deprecated for SC_CTHREAD, use SC_THREAD");
+ sc_cthread_handle cthread_h =
+ RCAST<sc_cthread_handle>( cpi->process_handle );
+ cthread_h->wait( el );
+ cthread_h->wait_cycles();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+void
+wait( const sc_event_and_list& el, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_: {
+ RCAST<sc_thread_handle>( cpi->process_handle )->wait( el );
+ break;
+ }
+ case SC_CTHREAD_PROC_: {
+ warn_cthread_wait();
+ sc_cthread_handle cthread_h =
+ RCAST<sc_cthread_handle>( cpi->process_handle );
+ cthread_h->wait( el );
+ cthread_h->wait_cycles();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+void
+wait( const sc_time& t, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_: {
+ RCAST<sc_thread_handle>( cpi->process_handle )->wait( t );
+ break;
+ }
+ case SC_CTHREAD_PROC_: {
+ warn_cthread_wait();
+ sc_cthread_handle cthread_h =
+ RCAST<sc_cthread_handle>( cpi->process_handle );
+ cthread_h->wait( t );
+ cthread_h->wait_cycles();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+void
+wait( const sc_time& t, const sc_event& e, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_: {
+ RCAST<sc_thread_handle>( cpi->process_handle )->wait( t, e );
+ break;
+ }
+ case SC_CTHREAD_PROC_: {
+ warn_cthread_wait();
+ sc_cthread_handle cthread_h =
+ RCAST<sc_cthread_handle>( cpi->process_handle );
+ cthread_h->wait( t, e );
+ cthread_h->wait_cycles();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+void
+wait( const sc_time& t, const sc_event_or_list& el, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_: {
+ RCAST<sc_thread_handle>( cpi->process_handle )->wait( t, el );
+ break;
+ }
+ case SC_CTHREAD_PROC_: {
+ warn_cthread_wait();
+ sc_cthread_handle cthread_h =
+ RCAST<sc_cthread_handle>( cpi->process_handle );
+ cthread_h->wait( t, el );
+ cthread_h->wait_cycles();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+void
+wait( const sc_time& t, const sc_event_and_list& el, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_: {
+ RCAST<sc_thread_handle>( cpi->process_handle )->wait( t, el );
+ break;
+ }
+ case SC_CTHREAD_PROC_: {
+ warn_cthread_wait();
+ sc_cthread_handle cthread_h =
+ RCAST<sc_cthread_handle>( cpi->process_handle );
+ cthread_h->wait( t, el );
+ cthread_h->wait_cycles();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+
+// static sensitivity for SC_METHODs
+
+void
+next_trigger( sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( cpi->kind == SC_METHOD_PROC_ ) {
+ RCAST<sc_method_handle>( cpi->process_handle )->clear_trigger();
+ } else {
+ SC_REPORT_ERROR( SC_ID_NEXT_TRIGGER_NOT_ALLOWED_, "\n "
+ "in SC_THREADs and SC_CTHREADs use wait() instead" );
+ }
+}
+
+
+// dynamic sensitivity for SC_METHODs
+
+void
+next_trigger( const sc_event& e, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( cpi->kind == SC_METHOD_PROC_ ) {
+ RCAST<sc_method_handle>( cpi->process_handle )->next_trigger( e );
+ } else {
+ SC_REPORT_ERROR( SC_ID_NEXT_TRIGGER_NOT_ALLOWED_, "\n "
+ "in SC_THREADs and SC_CTHREADs use wait() instead" );
+ }
+}
+
+void
+next_trigger( const sc_event_or_list& el, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( cpi->kind == SC_METHOD_PROC_ ) {
+ RCAST<sc_method_handle>( cpi->process_handle )->next_trigger( el );
+ } else {
+ SC_REPORT_ERROR( SC_ID_NEXT_TRIGGER_NOT_ALLOWED_, "\n "
+ "in SC_THREADs and SC_CTHREADs use wait() instead" );
+ }
+}
+
+void
+next_trigger( const sc_event_and_list& el, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( cpi->kind == SC_METHOD_PROC_ ) {
+ RCAST<sc_method_handle>( cpi->process_handle )->next_trigger( el );
+ } else {
+ SC_REPORT_ERROR( SC_ID_NEXT_TRIGGER_NOT_ALLOWED_, "\n "
+ "in SC_THREADs and SC_CTHREADs use wait() instead" );
+ }
+}
+
+void
+next_trigger( const sc_time& t, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( cpi->kind == SC_METHOD_PROC_ ) {
+ RCAST<sc_method_handle>( cpi->process_handle )->next_trigger( t );
+ } else {
+ SC_REPORT_ERROR( SC_ID_NEXT_TRIGGER_NOT_ALLOWED_, "\n "
+ "in SC_THREADs and SC_CTHREADs use wait() instead" );
+ }
+}
+
+void
+next_trigger( const sc_time& t, const sc_event& e, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( cpi->kind == SC_METHOD_PROC_ ) {
+ RCAST<sc_method_handle>( cpi->process_handle )->next_trigger( t, e );
+ } else {
+ SC_REPORT_ERROR( SC_ID_NEXT_TRIGGER_NOT_ALLOWED_, "\n "
+ "in SC_THREADs and SC_CTHREADs use wait() instead" );
+ }
+}
+
+void
+next_trigger( const sc_time& t, const sc_event_or_list& el, sc_simcontext* simc)
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( cpi->kind == SC_METHOD_PROC_ ) {
+ RCAST<sc_method_handle>( cpi->process_handle )->next_trigger( t, el );
+ } else {
+ SC_REPORT_ERROR( SC_ID_NEXT_TRIGGER_NOT_ALLOWED_, "\n "
+ "in SC_THREADs and SC_CTHREADs use wait() instead" );
+ }
+}
+
+void
+next_trigger(const sc_time& t, const sc_event_and_list& el, sc_simcontext* simc)
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( cpi->kind == SC_METHOD_PROC_ ) {
+ RCAST<sc_method_handle>( cpi->process_handle )->next_trigger( t, el );
+ } else {
+ SC_REPORT_ERROR( SC_ID_NEXT_TRIGGER_NOT_ALLOWED_, "\n "
+ "in SC_THREADs and SC_CTHREADs use wait() instead" );
+ }
+}
+
+
+// for SC_METHODs and SC_THREADs and SC_CTHREADs
+
+bool
+timed_out( sc_simcontext* simc )
+{
+ static bool warn_timed_out=true;
+ if ( warn_timed_out )
+ {
+ warn_timed_out = false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "timed_out() function is deprecated" );
+ }
+
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ return cpi->process_handle->timed_out();
+}
+
+
+
+// misc.
+
+void
+sc_set_location( const char* file, int lineno, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ sc_process_b* handle = cpi->process_handle;
+ handle->file = file;
+ handle->lineno = lineno;
+}
+
+} // namespace sc_core
+
+/*
+$Log: sc_wait.cpp,v $
+Revision 1.6 2011/08/26 20:46:11 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.5 2011/02/18 20:27:14 acg
+ Andy Goodrich: Updated Copyrights.
+
+Revision 1.4 2011/02/13 21:47:38 acg
+ Andy Goodrich: update copyright notice.
+
+Revision 1.3 2011/01/18 20:10:45 acg
+ Andy Goodrich: changes for IEEE1666_2011 semantics.
+
+Revision 1.2 2008/05/22 17:06:27 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.7 2006/02/02 20:20:39 acg
+ Andy Goodrich: warnings for SC_THREAD waits.
+
+Revision 1.6 2006/02/01 01:36:54 acg
+ Andy Goodrich: addition of deprecation comments for SC_CTHREAD waits other
+ than wait() and wait(N).
+
+Revision 1.5 2006/01/31 22:17:40 acg
+ Andy Goodrich: added deprecation warnings for SC_CTHREAD waits other than
+ wait() and wait(N).
+
+Revision 1.4 2006/01/25 00:31:20 acg
+ Andy Goodrich: Changed over to use a standard message id of
+ SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
+
+Revision 1.3 2006/01/24 20:49:05 acg
+Andy Goodrich: changes to remove the use of deprecated features within the
+simulator, and to issue warning messages when deprecated features are used.
+
+Revision 1.2 2006/01/03 23:18:45 acg
+Changed copyright to include 2006.
+
+Revision 1.1.1.1 2005/12/19 23:16:44 acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.10 2005/09/02 19:03:30 acg
+Changes for dynamic processes. Removal of lambda support.
+
+Revision 1.9 2005/07/30 03:45:05 acg
+Changes from 2.1, including changes for sc_process_handle.
+
+Revision 1.8 2005/04/04 00:16:07 acg
+Changes for directory name change to sys from systemc.
+Changes for sc_string going to std::string.
+Changes for sc_pvector going to std::vector.
+Changes for reference pools for bit and part selections.
+Changes for const sc_concatref support.
+
+Revision 1.5 2004/09/27 20:49:10 acg
+Andy Goodrich, Forte Design Systems, Inc.
+ - Added a $Log comment so that CVS checkin comments appear in the
+ checkout source.
+
+*/
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_wait.h b/ext/systemc/src/sysc/kernel/sc_wait.h
new file mode 100644
index 000000000..f598cf4bb
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_wait.h
@@ -0,0 +1,277 @@
+/*****************************************************************************
+
+ 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_wait.h -- Wait() and related functions.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_WAIT_H
+#define SC_WAIT_H
+
+
+#include "sysc/kernel/sc_simcontext.h"
+
+namespace sc_core {
+
+class sc_event;
+class sc_event_and_list;
+class sc_event_or_list;
+class sc_simcontext;
+
+extern sc_simcontext* sc_get_curr_simcontext();
+
+// static sensitivity for SC_THREADs and SC_CTHREADs
+
+extern
+void
+wait( sc_simcontext* = sc_get_curr_simcontext() );
+
+
+// dynamic sensitivity for SC_THREADs and SC_CTHREADs
+
+extern
+void
+wait( const sc_event&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+wait( const sc_event_or_list&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+wait( const sc_event_and_list&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+wait( const sc_time&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+inline
+void
+wait( double v, sc_time_unit tu,
+ sc_simcontext* simc = sc_get_curr_simcontext() )
+{
+ wait( sc_time( v, tu, simc ), simc );
+}
+
+extern
+void
+wait( const sc_time&,
+ const sc_event&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+inline
+void
+wait( double v, sc_time_unit tu,
+ const sc_event& e,
+ sc_simcontext* simc = sc_get_curr_simcontext() )
+{
+ wait( sc_time( v, tu, simc ), e, simc );
+}
+
+extern
+void
+wait( const sc_time&,
+ const sc_event_or_list&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+inline
+void
+wait( double v, sc_time_unit tu,
+ const sc_event_or_list& el,
+ sc_simcontext* simc = sc_get_curr_simcontext() )
+{
+ wait( sc_time( v, tu, simc ), el, simc );
+}
+
+extern
+void
+wait( const sc_time&,
+ const sc_event_and_list&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+inline
+void
+wait( double v, sc_time_unit tu,
+ const sc_event_and_list& el,
+ sc_simcontext* simc = sc_get_curr_simcontext() )
+{
+ wait( sc_time( v, tu, simc ), el, simc );
+}
+
+
+// static sensitivity for SC_METHODs
+
+extern
+void
+next_trigger( sc_simcontext* = sc_get_curr_simcontext() );
+
+
+// dynamic sensitivity for SC_METHODs
+
+extern
+void
+next_trigger( const sc_event&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+next_trigger( const sc_event_or_list&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+next_trigger( const sc_event_and_list&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+next_trigger( const sc_time&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+inline
+void
+next_trigger( double v, sc_time_unit tu,
+ sc_simcontext* simc = sc_get_curr_simcontext() )
+{
+ next_trigger( sc_time( v, tu, simc ), simc );
+}
+
+extern
+void
+next_trigger( const sc_time&,
+ const sc_event&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+inline
+void
+next_trigger( double v, sc_time_unit tu,
+ const sc_event& e,
+ sc_simcontext* simc = sc_get_curr_simcontext() )
+{
+ next_trigger( sc_time( v, tu, simc ), e, simc );
+}
+
+extern
+void
+next_trigger( const sc_time&,
+ const sc_event_or_list&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+inline
+void
+next_trigger( double v, sc_time_unit tu,
+ const sc_event_or_list& el,
+ sc_simcontext* simc = sc_get_curr_simcontext() )
+{
+ next_trigger( sc_time( v, tu, simc ), el, simc );
+}
+
+extern
+void
+next_trigger( const sc_time&,
+ const sc_event_and_list&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+inline
+void
+next_trigger( double v, sc_time_unit tu,
+ const sc_event_and_list& el,
+ sc_simcontext* simc = sc_get_curr_simcontext() )
+{
+ next_trigger( sc_time( v, tu, simc ), el, simc );
+}
+
+
+// for SC_METHODs and SC_THREADs and SC_CTHREADs
+
+extern
+bool
+timed_out( sc_simcontext* = sc_get_curr_simcontext() );
+
+// misc.
+
+extern
+void
+sc_set_location( const char*,
+ int,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+} // namespace sc_core
+
+/*
+$Log: sc_wait.h,v $
+Revision 1.6 2011/08/26 20:46:11 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.5 2011/02/18 20:27:14 acg
+ Andy Goodrich: Updated Copyrights.
+
+Revision 1.4 2011/02/13 21:47:38 acg
+ Andy Goodrich: update copyright notice.
+
+Revision 1.3 2011/01/18 20:10:45 acg
+ Andy Goodrich: changes for IEEE1666_2011 semantics.
+
+Revision 1.2 2008/05/22 17:06:27 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.2 2006/01/03 23:18:45 acg
+Changed copyright to include 2006.
+
+Revision 1.1.1.1 2005/12/19 23:16:44 acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.10 2005/07/30 03:45:05 acg
+Changes from 2.1, including changes for sc_process_handle.
+
+Revision 1.9 2005/04/04 00:16:08 acg
+Changes for directory name change to sys from systemc.
+Changes for sc_string going to std::string.
+Changes for sc_pvector going to std::vector.
+Changes for reference pools for bit and part selections.
+Changes for const sc_concatref support.
+
+Revision 1.6 2004/10/13 18:13:22 acg
+sc_ver.h - updated version number. sc_wait.h remove inclusion of
+sysc/kernel/sc_event.h because it is not necessary.
+
+Revision 1.5 2004/09/27 20:49:10 acg
+Andy Goodrich, Forte Design Systems, Inc.
+ - Added a $Log comment so that CVS checkin comments appear in the
+ checkout source.
+
+*/
+
+#endif
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_wait_cthread.cpp b/ext/systemc/src/sysc/kernel/sc_wait_cthread.cpp
new file mode 100644
index 000000000..4dee96ed7
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_wait_cthread.cpp
@@ -0,0 +1,169 @@
+/*****************************************************************************
+
+ 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_wait_cthread.cpp -- Wait() and related functions for SC_CTHREADs.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+
+#include "sysc/kernel/sc_kernel_ids.h"
+#include "sysc/kernel/sc_cthread_process.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+#include "sysc/kernel/sc_wait_cthread.h"
+#include "sysc/communication/sc_port.h"
+#include "sysc/kernel/sc_wait.h"
+namespace sc_core
+{
+
+// for SC_CTHREADs
+
+void
+halt( sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ switch( cpi->kind ) {
+ case SC_CTHREAD_PROC_: {
+ RCAST<sc_cthread_handle>( cpi->process_handle )->wait_halt();
+ break;
+ }
+ default:
+ SC_REPORT_ERROR( SC_ID_HALT_NOT_ALLOWED_, 0 );
+ break;
+ }
+}
+
+
+void
+wait( int n, sc_simcontext* simc )
+{
+ sc_curr_proc_handle cpi = simc->get_curr_proc_info();
+ if( n <= 0 ) {
+ char msg[BUFSIZ];
+ std::sprintf( msg, "n = %d", n );
+ SC_REPORT_ERROR( SC_ID_WAIT_N_INVALID_, msg );
+ }
+ switch( cpi->kind ) {
+ case SC_THREAD_PROC_:
+ case SC_CTHREAD_PROC_:
+ RCAST<sc_cthread_handle>( cpi->process_handle )->wait_cycles( n );
+ break;
+ default:
+ SC_REPORT_ERROR( SC_ID_WAIT_NOT_ALLOWED_, "\n "
+ "in SC_METHODs use next_trigger() instead" );
+ break;
+ }
+}
+
+
+void
+at_posedge( const sc_signal_in_if<bool>& s, sc_simcontext* simc )
+{
+ if( s.read() == true )
+ do { wait(simc); } while ( s.read() == true );
+ do { wait(simc); } while ( s.read() == false );
+}
+
+void
+at_posedge( const sc_signal_in_if<sc_dt::sc_logic>& s, sc_simcontext* simc )
+{
+ if( s.read() == '1' )
+ do { wait(simc); } while ( s.read() == '1' );
+ do { wait(simc); } while ( s.read() == '0' );
+}
+
+void
+at_negedge( const sc_signal_in_if<bool>& s, sc_simcontext* simc )
+{
+ if( s.read() == false )
+ do { wait(simc); } while ( s.read() == false );
+ do { wait(simc); } while ( s.read() == true );
+}
+
+void
+at_negedge( const sc_signal_in_if<sc_dt::sc_logic>& s, sc_simcontext* simc )
+{
+ if( s.read() == '0' )
+ do { wait(simc); } while ( s.read() == '0' );
+ do { wait(simc); } while ( s.read() == '1' );
+}
+
+
+} // namespace sc_core
+
+/*
+$Log: sc_wait_cthread.cpp,v $
+Revision 1.6 2011/08/26 20:46:11 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.5 2011/02/18 20:27:14 acg
+ Andy Goodrich: Updated Copyrights.
+
+Revision 1.4 2011/02/13 21:47:38 acg
+ Andy Goodrich: update copyright notice.
+
+Revision 1.3 2009/10/14 19:07:42 acg
+ Andy Goodrich: added an error message for wait(n) being called from an
+ SC_METHOD.
+
+Revision 1.2 2008/05/22 17:06:27 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.3 2006/03/13 20:26:51 acg
+ Andy Goodrich: Addition of forward class declarations, e.g.,
+ sc_reset, to keep gcc 4.x happy.
+
+Revision 1.2 2006/01/03 23:18:45 acg
+Changed copyright to include 2006.
+
+Revision 1.1.1.1 2005/12/19 23:16:44 acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.10 2005/09/15 23:02:18 acg
+Added std:: prefix to appropriate methods and types to get around
+issues with the Edison Front End.
+
+Revision 1.9 2005/09/02 19:03:30 acg
+Changes for dynamic processes. Removal of lambda support.
+
+Revision 1.8 2005/04/04 00:16:08 acg
+Changes for directory name change to sys from systemc.
+Changes for sc_string going to std::string.
+Changes for sc_pvector going to std::vector.
+Changes for reference pools for bit and part selections.
+Changes for const sc_concatref support.
+
+Revision 1.5 2004/09/27 20:49:10 acg
+Andy Goodrich, Forte Design Systems, Inc.
+ - Added a $Log comment so that CVS checkin comments appear in the
+ checkout source.
+
+*/
+
+// Taf!
diff --git a/ext/systemc/src/sysc/kernel/sc_wait_cthread.h b/ext/systemc/src/sysc/kernel/sc_wait_cthread.h
new file mode 100644
index 000000000..a04bfecc1
--- /dev/null
+++ b/ext/systemc/src/sysc/kernel/sc_wait_cthread.h
@@ -0,0 +1,126 @@
+/*****************************************************************************
+
+ 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_wait_cthread.h -- Wait() and related functions for SC_CTHREADs.
+
+ Original Author: Stan Y. Liao, Synopsys, Inc.
+ Martin Janssen, Synopsys, Inc.
+
+ CHANGE LOG AT THE END OF THE FILE
+ *****************************************************************************/
+
+
+#ifndef SC_WAIT_CTHREAD_H
+#define SC_WAIT_CTHREAD_H
+
+
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/datatypes/bit/sc_logic.h"
+#include "sysc/communication/sc_signal_ifs.h"
+
+
+namespace sc_core
+{
+
+// for SC_CTHREADs
+
+extern
+void
+halt( sc_simcontext* = sc_get_curr_simcontext() );
+
+
+extern
+void
+wait( int,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+
+extern
+void
+at_posedge( const sc_signal_in_if<bool>&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+at_posedge( const sc_signal_in_if<sc_dt::sc_logic>&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+at_negedge( const sc_signal_in_if<bool>&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+extern
+void
+at_negedge( const sc_signal_in_if<sc_dt::sc_logic>&,
+ sc_simcontext* = sc_get_curr_simcontext() );
+
+
+} // namespace sc_core
+
+/*
+$Log: sc_wait_cthread.h,v $
+Revision 1.6 2011/08/26 20:46:11 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.5 2011/08/24 22:05:51 acg
+ Torsten Maehne: initialization changes to remove warnings.
+
+Revision 1.4 2011/02/18 20:27:14 acg
+ Andy Goodrich: Updated Copyrights.
+
+Revision 1.3 2011/02/13 21:47:38 acg
+ Andy Goodrich: update copyright notice.
+
+Revision 1.2 2008/05/22 17:06:27 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.2 2006/01/03 23:18:45 acg
+Changed copyright to include 2006.
+
+Revision 1.1.1.1 2005/12/19 23:16:44 acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.10 2005/09/02 19:03:30 acg
+Changes for dynamic processes. Removal of lambda support.
+
+Revision 1.9 2005/04/04 00:16:08 acg
+Changes for directory name change to sys from systemc.
+Changes for sc_string going to std::string.
+Changes for sc_pvector going to std::vector.
+Changes for reference pools for bit and part selections.
+Changes for const sc_concatref support.
+
+Revision 1.6 2005/01/10 17:52:20 acg
+Addition of namespace specifications.
+
+Revision 1.5 2004/09/27 20:49:10 acg
+Andy Goodrich, Forte Design Systems, Inc.
+ - Added a $Log comment so that CVS checkin comments appear in the
+ checkout source.
+
+*/
+
+#endif