sc_port.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   The following code is derived, directly or indirectly, from the SystemC
00004   source code Copyright (c) 1996-2006 by all Contributors.
00005   All Rights reserved.
00006 
00007   The contents of this file are subject to the restrictions and limitations
00008   set forth in the SystemC Open Source License Version 2.4 (the "License");
00009   You may not use this file except in compliance with such restrictions and
00010   limitations. You may obtain instructions on how to receive a copy of the
00011   License at http://www.systemc.org/. Software distributed by Contributors
00012   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
00013   ANY KIND, either express or implied. See the License for the specific
00014   language governing rights and limitations under the License.
00015 
00016  *****************************************************************************/
00017 
00018 /*****************************************************************************
00019 
00020   sc_port.h -- Base classes of all port classes.
00021 
00022   Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
00023 
00024  *****************************************************************************/
00025 
00026 /*****************************************************************************
00027 
00028   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00029   changes you are making here.
00030 
00031       Name, Affiliation, Date: Andy Goodrich, Forte,
00032                                Bishnupriya Bhattacharya, Cadence Design Systems,
00033                                25 August, 2003
00034   Description of Modification: phase callbacks
00035 
00036       Name, Affiliation, Date: Andy Goodrich, Forte Design Systems
00037                                12 December, 2005
00038   Description of Modification: multiport binding policy changes
00039 
00040     
00041  *****************************************************************************/
00042 
00043 /* 
00044 $Log: sc_port.h,v $
00045 Revision 1.1.1.1  2006/12/15 20:31:35  acg
00046 SystemC 2.2
00047 
00048 Revision 1.3  2006/01/24 20:46:31  acg
00049 Andy Goodrich: changes to eliminate use of deprecated features. For instance,
00050 using notify(SC_ZERO_TIME) in place of notify_delayed().
00051 
00052 Revision 1.2  2006/01/03 23:18:26  acg
00053 Changed copyright to include 2006.
00054 
00055 Revision 1.1.1.1  2005/12/19 23:16:43  acg
00056 First check in of SystemC 2.1 into its own archive.
00057 
00058 Revision 1.10  2005/09/15 23:01:51  acg
00059 Added std:: prefix to appropriate methods and types to get around
00060 issues with the Edison Front End.
00061 
00062 Revision 1.9  2005/08/10 01:35:59  acg
00063 Changes for 64-bit support.
00064 
00065 Revision 1.8  2005/04/03 22:52:51  acg
00066 Namespace changes.
00067 
00068 Revision 1.7  2005/03/21 22:31:32  acg
00069 Changes to sc_core namespace.
00070 
00071 Revision 1.6  2004/09/27 21:02:54  acg
00072 Andy Goodrich - Forte Design Systems, Inc.
00073    - Added a $Log comment so that CVS checkin comments will appear in
00074      checked out source.
00075 
00076 */
00077 
00078 #ifndef SC_PORT_H
00079 #define SC_PORT_H
00080 
00081 
00082 #include "sysc/communication/sc_communication_ids.h"
00083 #include "sysc/communication/sc_interface.h"
00084 #include "sysc/kernel/sc_event.h"
00085 #include "sysc/kernel/sc_object.h"
00086 #include "sysc/kernel/sc_process.h"
00087 #include <typeinfo>
00088 
00089 namespace sc_core {
00090 
00091 class sc_event_finder;
00092 
00093 struct sc_bind_info;
00094 
00095 enum sc_port_policy 
00096 { 
00097     SC_ONE_OR_MORE_BOUND,   // Default 
00098     SC_ZERO_OR_MORE_BOUND, 
00099     SC_ALL_BOUND  
00100 }; 
00101 
00102 
00103 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00104 //  BEWARE: Ports can only be created and bound during elaboration.
00105 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00106 
00107 
00108 // ----------------------------------------------------------------------------
00109 //  CLASS : sc_port_base
00110 //
00111 //  Abstract base class for class sc_port_b.
00112 // ----------------------------------------------------------------------------
00113 
00114 class sc_port_base
00115 : public sc_object
00116 {
00117     friend class sc_module;
00118     friend class sc_port_registry;
00119     friend class sc_sensitive;
00120     friend class sc_sensitive_pos;
00121     friend class sc_sensitive_neg;
00122 
00123 public:
00124 
00125     // typedefs
00126 
00127     typedef sc_port_base this_type;
00128 
00129 public:
00130 
00131     /// get the first interface without checking for nil
00132     virtual       sc_interface* get_interface()       = 0;
00133     /// get the first interface without checking for nil
00134     virtual const sc_interface* get_interface() const = 0;
00135 
00136     virtual const char* kind() const
00137         { return "sc_port_base"; }
00138 
00139 protected:
00140 
00141     /// constructors
00142     explicit sc_port_base( int max_size_, 
00143         sc_port_policy policy=SC_ONE_OR_MORE_BOUND );
00144     sc_port_base( const char* name_, int max_size_, 
00145           sc_port_policy policy=SC_ONE_OR_MORE_BOUND );
00146 
00147     /// destructor
00148     virtual ~sc_port_base();
00149 
00150     /// bind interface to this port
00151     void bind( sc_interface& interface_ );
00152 
00153     /// bind parent port to this port
00154     void bind( this_type& parent_ );
00155 
00156     /// called by pbind (for internal use only)
00157     virtual int vbind( sc_interface& ) = 0;
00158     virtual int vbind( sc_port_base& ) = 0;
00159 
00160     // called by complete_binding (for internal use only)
00161     virtual void add_interface( sc_interface* ) = 0;
00162     virtual int interface_count() = 0;
00163     virtual const char* if_typename() const = 0;
00164 
00165     /// called by construction_done (does nothing by default)
00166     virtual void before_end_of_elaboration();
00167 
00168     /// called by elaboration_done (does nothing)
00169     virtual void end_of_elaboration();
00170 
00171     /// called by start_simulation (does nothing by default)
00172     virtual void start_of_simulation();
00173 
00174     /// called by simulation_done (does nothing by default)
00175     virtual void end_of_simulation();
00176 
00177     /// error reporting
00178     void report_error( const char* id, const char* add_msg = 0) const;
00179 
00180 protected:
00181     /// called by the sc_sensitive* classes
00182     virtual void make_sensitive( sc_thread_handle, sc_event_finder* = 0 ) const;
00183     virtual void make_sensitive( sc_method_handle, sc_event_finder* = 0 ) const;
00184     void add_static_event(
00185         sc_method_handle process_p, const sc_event& event) const;
00186     void add_static_event(
00187         sc_thread_handle process_p, const sc_event& event) const;
00188 
00189 private:
00190 
00191     // called by class sc_module for positional binding
00192     int pbind( sc_interface& );
00193     int pbind( sc_port_base& );
00194 
00195 
00196     // support methods
00197     int first_parent();
00198     void insert_parent( int );
00199 
00200     // called when construction is done
00201     void construction_done();
00202 
00203     // called when elaboration is done
00204     void complete_binding();
00205     void elaboration_done();
00206 
00207     // called before simulation starts
00208     void start_simulation();
00209 
00210     // called after simulation ends
00211     void simulation_done();
00212 
00213 protected:
00214 
00215     sc_bind_info* m_bind_info;
00216 
00217 private:
00218 
00219     // disabled
00220     sc_port_base();
00221     sc_port_base( const this_type& );
00222     this_type& operator = ( const this_type& );
00223 };
00224 
00225 // ----------------------------------------------------------------------------
00226 //  CLASS : sc_port_registry
00227 //
00228 //  Registry for all ports.
00229 //  FOR INTERNAL USE ONLY!
00230 // ----------------------------------------------------------------------------
00231 
00232 class sc_port_registry
00233 {
00234     friend class sc_simcontext;
00235 
00236 public:
00237 
00238     void insert( sc_port_base* );
00239     void remove( sc_port_base* );
00240 
00241     int size() const
00242         { return m_port_vec.size(); }
00243 
00244 private:
00245 
00246     // constructor
00247     explicit sc_port_registry( sc_simcontext& simc_ );
00248 
00249     // destructor
00250     ~sc_port_registry();
00251 
00252     // called when by construction_done and elaboration done
00253     void complete_binding();
00254 
00255     // called when construction is done
00256     void construction_done();
00257 
00258     // called when elaboration is done
00259     void elaboration_done();
00260 
00261     // called before simulation starts
00262     void start_simulation();
00263 
00264     // called after simulation ends
00265     void simulation_done();
00266 
00267     static void replace_port( sc_port_registry* );
00268 
00269 private:
00270 
00271     sc_simcontext*              m_simc;
00272     std::vector<sc_port_base*>  m_port_vec;
00273 
00274 private:
00275 
00276     // disabled
00277     sc_port_registry();
00278     sc_port_registry( const sc_port_registry& );
00279     sc_port_registry& operator = ( const sc_port_registry& );
00280 };
00281 
00282 
00283 // ----------------------------------------------------------------------------
00284 //  CLASS : sc_port_b
00285 //
00286 //  Abstract base class for class sc_port.
00287 // ----------------------------------------------------------------------------
00288 
00289 template <class IF>
00290 class sc_port_b
00291 : public sc_port_base
00292 {
00293 public:
00294 
00295     friend class sc_sensitive;
00296     friend class sc_sensitive_neg;
00297     friend class sc_sensitive_pos;
00298 
00299     // typedefs
00300 
00301     typedef sc_port_base  base_type;
00302     typedef sc_port_b<IF> this_type;
00303 
00304 public:
00305 
00306     /// bind an interface of type IF to this port
00307 
00308     void bind( IF& interface_ )
00309     { base_type::bind( interface_ ); }
00310 
00311     /// bind an interface of type IF to this port
00312     void operator () ( IF& interface_ )
00313     { base_type::bind( interface_ ); }
00314 
00315 
00316     /// bind a parent port with type IF to this port
00317 
00318     void bind( this_type& parent_ )
00319     { base_type::bind( parent_ ); }
00320 
00321     /// bind a parent port with type IF to this port
00322     void operator () ( this_type& parent_ )
00323     { base_type::bind( parent_ ); }
00324 
00325 
00326     /// number of connected interfaces
00327 
00328     int size() const
00329     { return m_interface_vec.size(); }
00330 
00331 
00332     /// allow to call methods provided by the first interface
00333     IF* operator -> ();
00334     const IF* operator -> () const;
00335 
00336 
00337     /// allow to call methods provided by interface at index
00338     inline const IF* get_interface( int iface_i ) const;
00339     /// allow to call methods provided by interface at index
00340     inline IF* get_interface( int iface_i );
00341     IF* operator [] ( int index_ )
00342         { return get_interface( index_ ); }
00343     /// allow to call methods provided by interface at index
00344     const IF* operator [] ( int index_ ) const
00345         { return get_interface( index_ ); }
00346 
00347 
00348     /// get the first interface without checking for nil
00349 
00350     virtual sc_interface* get_interface()
00351         { return m_interface; }
00352 
00353     /// get the first interface without checking for nil
00354     virtual const sc_interface* get_interface() const
00355         { return m_interface; }
00356 
00357 protected:
00358 
00359     // constructors
00360 
00361     explicit sc_port_b( int max_size_, 
00362         sc_port_policy policy=SC_ONE_OR_MORE_BOUND )
00363     : base_type( max_size_, policy ), m_interface( 0 )
00364     {}
00365 
00366     sc_port_b( const char* name_, int max_size_, 
00367                sc_port_policy policy=SC_ONE_OR_MORE_BOUND )
00368     : base_type( name_, max_size_, policy ), m_interface( 0 )
00369     {}
00370 
00371 
00372     // destructor (does nothing)
00373 
00374     virtual ~sc_port_b()
00375     {}
00376 
00377 
00378     // called by pbind (for internal use only)
00379     virtual int vbind( sc_interface& );
00380     virtual int vbind( sc_port_base& );
00381 
00382 protected:
00383 
00384     // called by the sc_sensitive* classes
00385     virtual void make_sensitive( sc_thread_handle, sc_event_finder* = 0 ) const;
00386     virtual void make_sensitive( sc_method_handle, sc_event_finder* = 0 ) const;
00387 
00388 private:
00389 
00390     // called by complete_binding (for internal use only)
00391     virtual void add_interface( sc_interface* );
00392     virtual const char* if_typename() const;
00393     virtual int interface_count();
00394 
00395     // disabled
00396     sc_port_b();
00397     sc_port_b( const this_type& );
00398     this_type& operator = ( const this_type& );
00399 
00400 private:
00401 
00402     IF*              m_interface;   // first interface in interface vec
00403     std::vector<IF*> m_interface_vec;
00404 };
00405 
00406 
00407 // ----------------------------------------------------------------------------
00408 //  CLASS : sc_port
00409 //
00410 //  Generic port class and base class for other port classes.
00411 //  N is the maximum number of channels (with interface IF) that can be bound
00412 //  to this port. N <= 0 means no maximum.
00413 // ----------------------------------------------------------------------------
00414 
00415 extern void sc_warn_port_constructor();
00416 
00417 template <class IF, int N = 1, sc_port_policy P=SC_ONE_OR_MORE_BOUND>
00418 class sc_port
00419 : public sc_port_b<IF>
00420 {
00421     // typdefs
00422 
00423     typedef sc_port_b<IF> base_type;
00424     typedef sc_port<IF,N,P> this_type;
00425 
00426 public:
00427 
00428     // constructors
00429 
00430     sc_port()
00431     : base_type( N, P )
00432     {}
00433 
00434     explicit sc_port( const char* name_ )
00435     : base_type( name_, N, P )
00436     {}
00437 
00438     explicit sc_port( IF& interface_ )
00439     : base_type( N, P )
00440     { sc_warn_port_constructor(); base_type::bind( interface_ ); }
00441 
00442     sc_port( const char* name_, IF& interface_ )
00443     : base_type( name_, N, P )
00444     { sc_warn_port_constructor(); base_type::bind( interface_ ); }
00445 
00446     explicit sc_port( base_type& parent_ )
00447     : base_type( N, P )
00448     { sc_warn_port_constructor(); base_type::bind( parent_ ); }
00449 
00450     sc_port( const char* name_, base_type& parent_ )
00451     : base_type( name_, N, P )
00452     { sc_warn_port_constructor(); base_type::bind( parent_ ); }
00453 
00454     sc_port( this_type& parent_ )
00455     : base_type( N, P )
00456     { sc_warn_port_constructor(); base_type::bind( parent_ ); }
00457 
00458     sc_port( const char* name_, this_type& parent_ )
00459     : base_type( name_, N, P )
00460     { sc_warn_port_constructor(); base_type::bind( parent_ ); }
00461 
00462 
00463     // destructor (does nothing)
00464 
00465     virtual ~sc_port()
00466     {}
00467 
00468     virtual const char* kind() const
00469         { return "sc_port"; }
00470 
00471 private:
00472 
00473     // disabled
00474     sc_port( const this_type& );
00475     this_type& operator = ( const this_type& );
00476 };
00477 
00478 
00479 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00480 
00481 // ----------------------------------------------------------------------------
00482 //  CLASS : sc_port_b
00483 //
00484 //  Abstract base class for class sc_port.
00485 // ----------------------------------------------------------------------------
00486 
00487 /// allow to call methods provided by the first interface
00488 
00489 template <class IF>
00490 inline
00491 IF*
00492 sc_port_b<IF>::operator -> ()
00493 {
00494     if( m_interface == 0 ) {
00495     report_error( SC_ID_GET_IF_, "port is not bound" );
00496     }
00497     return m_interface;
00498 }
00499 
00500 /// allow to call methods provided by the first interface
00501 template <class IF>
00502 inline
00503 const IF*
00504 sc_port_b<IF>::operator -> () const
00505 {
00506     if( m_interface == 0 ) {
00507     report_error( SC_ID_GET_IF_, "port is not bound" );
00508     }
00509     return m_interface;
00510 }
00511 
00512 
00513 /// allow to call methods provided by interface at index
00514 ///
00515 /// \note that we special-case index of zero, since the method may be
00516 /// called before binding has occurred, and we need to return a zero
00517 /// in that case not an error.
00518 
00519 template <class IF>
00520 inline
00521 IF*
00522 sc_port_b<IF>::get_interface( int index_ )
00523 {
00524     if ( index_ == 0 ) {
00525         return m_interface;
00526     }
00527     else if( index_ < 0 || index_ >= size() ) {
00528     report_error( SC_ID_GET_IF_, "index out of range" );
00529     }
00530     return m_interface_vec[index_];
00531 }
00532 
00533 template <class IF>
00534 inline
00535 const IF*
00536 sc_port_b<IF>::get_interface( int index_ ) const
00537 {
00538     if ( index_ == 0 ) {
00539         return m_interface;
00540     }
00541     else if( index_ < 0 || index_ >= size() ) {
00542     report_error( SC_ID_GET_IF_, "index out of range" );
00543     }
00544     return m_interface_vec[index_];
00545 }
00546 
00547 
00548 /// called by pbind (for internal use only)
00549 
00550 template <class IF>
00551 inline
00552 int
00553 sc_port_b<IF>::vbind( sc_interface& interface_ )
00554 {
00555     IF* iface = DCAST<IF*>( &interface_ );
00556     if( iface == 0 ) {
00557     // type mismatch
00558     return 2;
00559     }
00560     base_type::bind( *iface );
00561     return 0;
00562 }
00563 
00564 template <class IF>
00565 inline
00566 int
00567 sc_port_b<IF>::vbind( sc_port_base& parent_ )
00568 {
00569     this_type* parent = DCAST<this_type*>( &parent_ );
00570     if( parent == 0 ) {
00571     // type mismatch
00572     return 2;
00573     }
00574     base_type::bind( *parent );
00575     return 0;
00576 }
00577 
00578 
00579 // called by complete_binding (for internal use only)
00580 
00581 template <class IF>
00582 inline
00583 void
00584 sc_port_b<IF>::add_interface( sc_interface* interface_ )
00585 {
00586     IF* iface = DCAST<IF*>( interface_ );
00587     assert( iface != 0 );
00588 
00589     // make sure that the interface is not already bound:
00590 
00591     int size = m_interface_vec.size();
00592     for ( int i = 0; i < size; i++ )
00593     {
00594         if ( iface == m_interface_vec[i] )
00595     {
00596         report_error( SC_ID_BIND_IF_TO_PORT_, 
00597             "interface already bound to port" );
00598     }
00599     }
00600 
00601     // "bind" the interface and make sure our short cut for 0 is set up.
00602 
00603     m_interface_vec.push_back( iface );
00604     m_interface = m_interface_vec[0]; 
00605 }
00606 
00607 template <class IF>
00608 inline
00609 const char*
00610 sc_port_b<IF>::if_typename() const
00611 {
00612     return typeid( IF ).name();
00613 }
00614 
00615 template <class IF>
00616 inline
00617 int
00618 sc_port_b<IF>::interface_count()
00619 {
00620     return m_interface_vec.size();
00621 }
00622 
00623 template <class IF>
00624 void
00625 sc_port_b<IF>::make_sensitive( sc_thread_handle handle_p,
00626                   sc_event_finder* event_finder_ ) const
00627 {
00628     if ( m_bind_info == 0 )
00629     {
00630         int if_n = m_interface_vec.size();
00631         for ( int if_i = 0; if_i < if_n; if_i++ )
00632     {
00633         IF* iface_p = m_interface_vec[if_i];
00634         assert( iface_p != 0 );
00635         add_static_event( handle_p, iface_p->default_event() );
00636     }
00637     }
00638     else
00639     {
00640         sc_port_base::make_sensitive( handle_p, event_finder_ );
00641     }
00642 }
00643 
00644 template <class IF>
00645 void
00646 sc_port_b<IF>::make_sensitive( sc_method_handle handle_p,
00647                   sc_event_finder* event_finder_ ) const
00648 {
00649     if ( m_bind_info == 0 )
00650     {
00651         int if_n = m_interface_vec.size();
00652         for ( int if_i = 0; if_i < if_n; if_i++ )
00653     {
00654         IF* iface_p = m_interface_vec[if_i];
00655         assert( iface_p != 0 );
00656         add_static_event( handle_p, iface_p->default_event() );
00657     }
00658     }
00659     else
00660     {
00661         sc_port_base::make_sensitive( handle_p, event_finder_ );
00662     }
00663 }
00664 
00665 // ----------------------------------------------------------------------------
00666 //  CLASS : sc_port
00667 //
00668 //  Generic port class and base class for other port classes.
00669 //  N is the maximum number of channels (with interface IF) that can be bound
00670 //  to this port. N <= 0 means no maximum.
00671 // ----------------------------------------------------------------------------
00672 
00673 } // namespace sc_core
00674 
00675 #endif
00676 
00677 // Taf!

Generated on Wed Jan 21 15:32:06 2009 for SystemC by  doxygen 1.5.5