summaryrefslogtreecommitdiff
path: root/ext/systemc/src/sysc/communication/sc_port.h
diff options
context:
space:
mode:
Diffstat (limited to 'ext/systemc/src/sysc/communication/sc_port.h')
-rw-r--r--ext/systemc/src/sysc/communication/sc_port.h732
1 files changed, 732 insertions, 0 deletions
diff --git a/ext/systemc/src/sysc/communication/sc_port.h b/ext/systemc/src/sysc/communication/sc_port.h
new file mode 100644
index 000000000..a126657e6
--- /dev/null
+++ b/ext/systemc/src/sysc/communication/sc_port.h
@@ -0,0 +1,732 @@
+/*****************************************************************************
+
+ 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_port.h -- Base classes of all port classes.
+
+ Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
+
+ CHANGE LOG IS AT THE END OF THE FILE
+ *****************************************************************************/
+
+#ifndef SC_PORT_H
+#define SC_PORT_H
+
+
+#include "sysc/communication/sc_communication_ids.h"
+#include "sysc/communication/sc_interface.h"
+#include "sysc/kernel/sc_event.h"
+#include "sysc/kernel/sc_object.h"
+#include "sysc/kernel/sc_process.h"
+#include <typeinfo>
+
+#if ! defined( SC_DISABLE_VIRTUAL_BIND )
+# define SC_VIRTUAL_ virtual
+#else
+# define SC_VIRTUAL_ /* non-virtual */
+#endif
+
+namespace sc_core {
+
+class sc_event_finder;
+
+struct sc_bind_info;
+
+enum sc_port_policy
+{
+ SC_ONE_OR_MORE_BOUND, // Default
+ SC_ZERO_OR_MORE_BOUND,
+ SC_ALL_BOUND
+};
+
+
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// BEWARE: Ports can only be created and bound during elaboration.
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_port_base
+//
+// Abstract base class for class sc_port_b.
+// ----------------------------------------------------------------------------
+
+class sc_port_base
+: public sc_object
+{
+ friend class sc_module;
+ friend class sc_port_registry;
+ friend class sc_sensitive;
+ friend class sc_sensitive_pos;
+ friend class sc_sensitive_neg;
+
+public:
+
+ // typedefs
+
+ typedef sc_port_base this_type;
+
+public:
+
+ int bind_count();
+
+ // get the first interface without checking for nil
+ virtual sc_interface* get_interface() = 0;
+ virtual const sc_interface* get_interface() const = 0;
+
+ virtual const char* kind() const
+ { return "sc_port_base"; }
+
+protected:
+
+ // constructors
+ explicit sc_port_base( int max_size_,
+ sc_port_policy policy=SC_ONE_OR_MORE_BOUND );
+ sc_port_base( const char* name_, int max_size_,
+ sc_port_policy policy=SC_ONE_OR_MORE_BOUND );
+
+ // destructor
+ virtual ~sc_port_base();
+
+ // bind interface to this port
+ void bind( sc_interface& interface_ );
+
+ // bind parent port to this port
+ void bind( this_type& parent_ );
+
+ // called by pbind (for internal use only)
+ virtual int vbind( sc_interface& ) = 0;
+ virtual int vbind( sc_port_base& ) = 0;
+
+ // called by complete_binding (for internal use only)
+ virtual void add_interface( sc_interface* ) = 0;
+ virtual int interface_count() = 0;
+ virtual const char* if_typename() const = 0;
+
+ // called by construction_done (does nothing by default)
+ virtual void before_end_of_elaboration();
+
+ // called by elaboration_done (does nothing)
+ virtual void end_of_elaboration();
+
+ // called by start_simulation (does nothing by default)
+ virtual void start_of_simulation();
+
+ // called by simulation_done (does nothing by default)
+ virtual void end_of_simulation();
+
+ // error reporting
+ void report_error( const char* id, const char* add_msg = 0) const;
+
+protected:
+ // called by the sc_sensitive* classes
+ virtual void make_sensitive( sc_thread_handle, sc_event_finder* = 0 ) const;
+ virtual void make_sensitive( sc_method_handle, sc_event_finder* = 0 ) const;
+ void add_static_event(
+ sc_method_handle process_p, const sc_event& event) const;
+ void add_static_event(
+ sc_thread_handle process_p, const sc_event& event) const;
+
+private:
+
+ // called by class sc_module for positional binding
+ int pbind( sc_interface& );
+ int pbind( sc_port_base& );
+
+
+ // support methods
+ int first_parent();
+ void insert_parent( int );
+
+ // called when construction is done
+ void construction_done();
+
+ // called when elaboration is done
+ void complete_binding();
+ void elaboration_done();
+
+ // called before simulation starts
+ void start_simulation();
+
+ // called after simulation ends
+ void simulation_done();
+
+protected:
+
+ sc_bind_info* m_bind_info;
+
+private:
+
+ // disabled
+ sc_port_base();
+ sc_port_base( const this_type& );
+ this_type& operator = ( const this_type& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_port_registry
+//
+// Registry for all ports.
+// FOR INTERNAL USE ONLY!
+// ----------------------------------------------------------------------------
+
+class sc_port_registry
+{
+ friend class sc_simcontext;
+
+public:
+
+ void insert( sc_port_base* );
+ void remove( sc_port_base* );
+
+ int size() const
+ { return m_port_vec.size(); }
+
+private:
+
+ // constructor
+ explicit sc_port_registry( sc_simcontext& simc_ );
+
+ // destructor
+ ~sc_port_registry();
+
+ // called when by construction_done and elaboration done
+ void complete_binding();
+
+ // called when construction is done
+ bool construction_done();
+
+ // called when elaboration is done
+ void elaboration_done();
+
+ // called before simulation starts
+ void start_simulation();
+
+ // called after simulation ends
+ void simulation_done();
+
+ static void replace_port( sc_port_registry* );
+
+private:
+
+ int m_construction_done;
+ std::vector<sc_port_base*> m_port_vec;
+ sc_simcontext* m_simc;
+
+private:
+
+ // disabled
+ sc_port_registry();
+ sc_port_registry( const sc_port_registry& );
+ sc_port_registry& operator = ( const sc_port_registry& );
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_port_b
+//
+// Abstract base class for class sc_port.
+// ----------------------------------------------------------------------------
+
+template <class IF>
+class sc_port_b
+: public sc_port_base
+{
+public:
+
+ friend class sc_sensitive;
+ friend class sc_sensitive_neg;
+ friend class sc_sensitive_pos;
+
+ // typedefs
+
+ typedef sc_port_base base_type;
+ typedef sc_port_b<IF> this_type;
+ typedef this_type port_type;
+
+public:
+
+ // bind an interface of type IF to this port
+
+ SC_VIRTUAL_ void bind( IF& interface_ )
+ { base_type::bind( interface_ ); }
+
+ void operator () ( IF& interface_ )
+ { this->bind( interface_ ); }
+
+
+ // bind a parent port with type IF to this port
+
+ SC_VIRTUAL_ void bind( port_type& parent_ )
+ { base_type::bind( parent_ ); }
+
+ void operator () ( port_type& parent_ )
+ { this->bind( parent_ ); }
+
+
+ // number of connected interfaces
+
+ int size() const
+ { return m_interface_vec.size(); }
+
+
+ // allow to call methods provided by the first interface
+ IF* operator -> ();
+ const IF* operator -> () const;
+
+
+ // allow to call methods provided by interface at index
+ inline const IF* get_interface( int iface_i ) const;
+ inline IF* get_interface( int iface_i );
+ IF* operator [] ( int index_ )
+ { return get_interface( index_ ); }
+ const IF* operator [] ( int index_ ) const
+ { return get_interface( index_ ); }
+
+
+ // get the first interface without checking for nil
+
+ virtual sc_interface* get_interface()
+ { return m_interface; }
+
+ virtual const sc_interface* get_interface() const
+ { return m_interface; }
+
+protected:
+
+ // constructors
+
+ explicit sc_port_b( int max_size_,
+ sc_port_policy policy=SC_ONE_OR_MORE_BOUND ) :
+ base_type( max_size_, policy ), m_interface( 0 ), m_interface_vec()
+ {}
+
+ sc_port_b( const char* name_, int max_size_,
+ sc_port_policy policy=SC_ONE_OR_MORE_BOUND ) :
+ base_type( name_, max_size_, policy ), m_interface( 0 ),
+ m_interface_vec()
+ {}
+
+
+ // destructor (does nothing)
+
+ virtual ~sc_port_b()
+ {}
+
+
+ // called by pbind (for internal use only)
+ virtual int vbind( sc_interface& );
+ virtual int vbind( sc_port_base& );
+
+protected:
+
+ // called by the sc_sensitive* classes
+ virtual void make_sensitive( sc_thread_handle, sc_event_finder* = 0 ) const;
+ virtual void make_sensitive( sc_method_handle, sc_event_finder* = 0 ) const;
+
+private:
+
+ // called by complete_binding (for internal use only)
+ virtual void add_interface( sc_interface* );
+ virtual const char* if_typename() const;
+ virtual int interface_count();
+
+ // disabled
+ sc_port_b();
+ sc_port_b( const this_type& );
+ this_type& operator = ( const this_type& );
+
+private:
+
+ IF* m_interface; // first interface in interface vec
+ std::vector<IF*> m_interface_vec;
+};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_port
+//
+// Generic port class and base class for other port classes.
+// N is the maximum number of channels (with interface IF) that can be bound
+// to this port. N <= 0 means no maximum.
+// ----------------------------------------------------------------------------
+
+extern void sc_warn_port_constructor();
+
+template <class IF, int N = 1, sc_port_policy P=SC_ONE_OR_MORE_BOUND>
+class sc_port
+: public sc_port_b<IF>
+{
+ // typdefs
+
+ typedef sc_port_b<IF> base_type;
+ typedef sc_port<IF,N,P> this_type;
+
+public:
+
+ // constructors
+
+ sc_port()
+ : base_type( N, P )
+ {}
+
+ explicit sc_port( const char* name_ )
+ : base_type( name_, N, P )
+ {}
+
+ explicit sc_port( IF& interface_ )
+ : base_type( N, P )
+ { sc_warn_port_constructor(); base_type::bind( interface_ ); }
+
+ sc_port( const char* name_, IF& interface_ )
+ : base_type( name_, N, P )
+ { sc_warn_port_constructor(); base_type::bind( interface_ ); }
+
+ explicit sc_port( base_type& parent_ )
+ : base_type( N, P )
+ { sc_warn_port_constructor(); base_type::bind( parent_ ); }
+
+ sc_port( const char* name_, base_type& parent_ )
+ : base_type( name_, N, P )
+ { sc_warn_port_constructor(); base_type::bind( parent_ ); }
+
+ sc_port( this_type& parent_ )
+ : base_type( N, P )
+ { sc_warn_port_constructor(); base_type::bind( parent_ ); }
+
+ sc_port( const char* name_, this_type& parent_ )
+ : base_type( name_, N, P )
+ { sc_warn_port_constructor(); base_type::bind( parent_ ); }
+
+
+ // destructor (does nothing)
+
+ virtual ~sc_port()
+ {}
+
+ virtual const char* kind() const
+ { return "sc_port"; }
+
+private:
+
+ // disabled
+ sc_port( const this_type& );
+ this_type& operator = ( const this_type& );
+};
+
+
+// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_port_b
+//
+// Abstract base class for class sc_port.
+// ----------------------------------------------------------------------------
+
+// allow to call methods provided by the first interface
+
+template <class IF>
+inline
+IF*
+sc_port_b<IF>::operator -> ()
+{
+ if( m_interface == 0 ) {
+ report_error( SC_ID_GET_IF_, "port is not bound" );
+ }
+ return m_interface;
+}
+
+template <class IF>
+inline
+const IF*
+sc_port_b<IF>::operator -> () const
+{
+ if( m_interface == 0 ) {
+ report_error( SC_ID_GET_IF_, "port is not bound" );
+ }
+ return m_interface;
+}
+
+
+// allow to call methods provided by interface at index
+//
+// note that we special-case index of zero, since the method may be
+// called before binding has occurred, and we need to return a zero
+// in that case not an error.
+
+template <class IF>
+inline
+IF*
+sc_port_b<IF>::get_interface( int index_ )
+{
+ if ( index_ == 0 ) {
+ return m_interface;
+ }
+ else if( index_ < 0 || index_ >= size() ) {
+ report_error( SC_ID_GET_IF_, "index out of range" );
+ }
+ return m_interface_vec[index_];
+}
+
+template <class IF>
+inline
+const IF*
+sc_port_b<IF>::get_interface( int index_ ) const
+{
+ if ( index_ == 0 ) {
+ return m_interface;
+ }
+ else if( index_ < 0 || index_ >= size() ) {
+ report_error( SC_ID_GET_IF_, "index out of range" );
+ }
+ return m_interface_vec[index_];
+}
+
+
+// called by pbind (for internal use only)
+
+template <class IF>
+inline
+int
+sc_port_b<IF>::vbind( sc_interface& interface_ )
+{
+ IF* iface = DCAST<IF*>( &interface_ );
+ if( iface == 0 ) {
+ // type mismatch
+ return 2;
+ }
+ base_type::bind( *iface );
+ return 0;
+}
+
+template <class IF>
+inline
+int
+sc_port_b<IF>::vbind( sc_port_base& parent_ )
+{
+ this_type* parent = DCAST<this_type*>( &parent_ );
+ if( parent == 0 ) {
+ // type mismatch
+ return 2;
+ }
+ base_type::bind( *parent );
+ return 0;
+}
+
+
+// called by complete_binding (for internal use only)
+
+template <class IF>
+inline
+void
+sc_port_b<IF>::add_interface( sc_interface* interface_ )
+{
+ IF* iface = DCAST<IF*>( interface_ );
+ assert( iface != 0 );
+
+ // make sure that the interface is not already bound:
+
+ int size = m_interface_vec.size();
+ for ( int i = 0; i < size; i++ )
+ {
+ if ( iface == m_interface_vec[i] )
+ {
+ report_error( SC_ID_BIND_IF_TO_PORT_,
+ "interface already bound to port" );
+ }
+ }
+
+ // "bind" the interface and make sure our short cut for 0 is set up.
+
+ m_interface_vec.push_back( iface );
+ m_interface = m_interface_vec[0];
+}
+
+template <class IF>
+inline
+const char*
+sc_port_b<IF>::if_typename() const
+{
+ return typeid( IF ).name();
+}
+
+template <class IF>
+inline
+int
+sc_port_b<IF>::interface_count()
+{
+ return m_interface_vec.size();
+}
+
+template <class IF>
+void
+sc_port_b<IF>::make_sensitive( sc_thread_handle handle_p,
+ sc_event_finder* event_finder_ ) const
+{
+ if ( m_bind_info == 0 )
+ {
+ int if_n = m_interface_vec.size();
+ for ( int if_i = 0; if_i < if_n; if_i++ )
+ {
+ IF* iface_p = m_interface_vec[if_i];
+ assert( iface_p != 0 );
+ add_static_event( handle_p, iface_p->default_event() );
+ }
+ }
+ else
+ {
+ sc_port_base::make_sensitive( handle_p, event_finder_ );
+ }
+}
+
+template <class IF>
+void
+sc_port_b<IF>::make_sensitive( sc_method_handle handle_p,
+ sc_event_finder* event_finder_ ) const
+{
+ if ( m_bind_info == 0 )
+ {
+ int if_n = m_interface_vec.size();
+ for ( int if_i = 0; if_i < if_n; if_i++ )
+ {
+ IF* iface_p = m_interface_vec[if_i];
+ assert( iface_p != 0 );
+ add_static_event( handle_p, iface_p->default_event() );
+ }
+ }
+ else
+ {
+ sc_port_base::make_sensitive( handle_p, event_finder_ );
+ }
+}
+
+// ----------------------------------------------------------------------------
+// CLASS : sc_port
+//
+// Generic port class and base class for other port classes.
+// N is the maximum number of channels (with interface IF) that can be bound
+// to this port. N <= 0 means no maximum.
+// ----------------------------------------------------------------------------
+
+} // namespace sc_core
+
+#undef SC_VIRTUAL_
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Andy Goodrich, Forte,
+ Bishnupriya Bhattacharya, Cadence Design Systems,
+ 25 August, 2003
+ Description of Modification: phase callbacks
+
+ Name, Affiliation, Date: Andy Goodrich, Forte Design Systems
+ 12 December, 2005
+ Description of Modification: multiport binding policy changes
+
+
+ *****************************************************************************/
+
+/*
+$Log: sc_port.h,v $
+Revision 1.10 2011/08/26 20:45:41 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:36 acg
+ Torsten Maehne: initialization changes to remove warnings.
+
+Revision 1.8 2011/08/07 19:08:01 acg
+ Andy Goodrich: moved logs to end of file so line number synching works
+ better between versions.
+
+Revision 1.7 2011/08/07 18:53:09 acg
+ Philipp A. Hartmann: add virtual instances of the bind function for
+ base classes to eliminate warning messages for clang platforms.
+
+Revision 1.6 2011/05/09 04:07:37 acg
+ Philipp A. Hartmann:
+ (1) Restore hierarchy in all phase callbacks.
+ (2) Ensure calls to before_end_of_elaboration.
+
+Revision 1.5 2011/03/30 16:46:10 acg
+ Andy Goodrich: added a signature and removed a virtual specification
+ to eliminate warnings with certain compilers.
+
+Revision 1.4 2011/02/18 20:23:45 acg
+ Andy Goodrich: Copyright update.
+
+Revision 1.3 2011/01/20 16:52:15 acg
+ Andy Goodrich: changes for IEEE 1666 2011.
+
+Revision 1.2 2010/08/03 18:01:11 acg
+ Andy Goodrich: formatting.
+
+Revision 1.1.1.1 2006/12/15 20:20:04 acg
+SystemC 2.3
+
+Revision 1.5 2006/08/29 23:35:00 acg
+ Andy Goodrich: added bind_count() method to allow users to determine which
+ ports are connected in before_end_of_elaboration().
+
+Revision 1.4 2006/05/08 17:52:47 acg
+ Andy Goodrich:
+ (1) added David Long's forward declarations for friend functions,
+ methods, and operators to keep the Microsoft compiler happy.
+ (2) Added delta_count() method to sc_prim_channel for use by
+ sc_signal so that the friend declaration in sc_simcontext.h
+ can be for a non-templated class (i.e., sc_prim_channel.)
+
+Revision 1.3 2006/01/24 20:46:31 acg
+Andy Goodrich: changes to eliminate use of deprecated features. For instance,
+using notify(SC_ZERO_TIME) in place of notify_delayed().
+
+Revision 1.2 2006/01/03 23:18:26 acg
+Changed copyright to include 2006.
+
+Revision 1.1.1.1 2005/12/19 23:16:43 acg
+First check in of SystemC 2.1 into its own archive.
+
+Revision 1.10 2005/09/15 23:01:51 acg
+Added std:: prefix to appropriate methods and types to get around
+issues with the Edison Front End.
+
+Revision 1.9 2005/08/10 01:35:59 acg
+Changes for 64-bit support.
+
+Revision 1.8 2005/04/03 22:52:51 acg
+Namespace changes.
+
+Revision 1.7 2005/03/21 22:31:32 acg
+Changes to sc_core namespace.
+
+Revision 1.6 2004/09/27 21:02:54 acg
+Andy Goodrich - Forte Design Systems, Inc.
+ - Added a $Log comment so that CVS checkin comments will appear in
+ checked out source.
+
+*/
+
+#endif
+
+// Taf!