summaryrefslogtreecommitdiff
path: root/ext/systemc/src/sysc/kernel/sc_event.h
diff options
context:
space:
mode:
Diffstat (limited to 'ext/systemc/src/sysc/kernel/sc_event.h')
-rw-r--r--ext/systemc/src/sysc/kernel/sc_event.h884
1 files changed, 884 insertions, 0 deletions
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!