summaryrefslogtreecommitdiff
path: root/ext/systemc/src/sysc/kernel
diff options
context:
space:
mode:
authorMatthias Jung <jungma@eit.uni-kl.de>2017-03-01 18:39:56 +0100
committerMatthias Jung <jungma@eit.uni-kl.de>2017-05-18 08:36:56 +0000
commitaa651c7f8321bf96fc88f9a17285225000a753ec (patch)
treeb13240008c970b47bd74a5007e68136155d272fc /ext/systemc/src/sysc/kernel
parent595e692de09e1b7cbc5f57ac01da299afc066fdd (diff)
downloadgem5-aa651c7f8321bf96fc88f9a17285225000a753ec.tar.xz
ext: Include SystemC 2.3.1 into gem5
In the past it happened several times that some changes in gem5 broke the SystemC coupling. Recently Accelera has changed the licence for SystemC from their own licence to Apache2.0, which is compatible with gem5. However, SystemC usually relies on the Boost library, but I was able to exchange the boost calls by c++11 alternatives. The recent SystemC version is placed into /ext and is integrated into gem5's build system. The goal is to integrate some SystemC tests for the CI in some following patches. Change-Id: I4b66ec806b5e3cffc1d7c85d3735ff4fa5b31fd0 Reviewed-on: https://gem5-review.googlesource.com/2240 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
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