src/sysc/communication/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-2005 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  *****************************************************************************/
00037 
00038 /* 
00039 $Log: sc_port.h,v $
00040 Revision 1.8  2005/04/03 22:52:51  acg
00041 Namespace changes.
00042 
00043 Revision 1.7  2005/03/21 22:31:32  acg
00044 Changes to sc_core namespace.
00045 
00046 Revision 1.6  2004/09/27 21:02:54  acg
00047 Andy Goodrich - Forte Design Systems, Inc.
00048    - Added a $Log comment so that CVS checkin comments will appear in
00049      checked out source.
00050 
00051 */
00052 
00053 #ifndef SC_PORT_H
00054 #define SC_PORT_H
00055 
00056 
00057 #include "sysc/communication/sc_communication_ids.h"
00058 #include "sysc/communication/sc_interface.h"
00059 #include "sysc/kernel/sc_event.h"
00060 #include "sysc/kernel/sc_object.h"
00061 #include "sysc/kernel/sc_process.h"
00062 #include "sysc/utils/sc_vector.h"
00063 #include <typeinfo>
00064 
00065 namespace sc_core {
00066 
00067 class sc_event_finder;
00068 class sc_lambda_rand;
00069 class sc_lambda_ptr;
00070 
00071 struct sc_bind_info;
00072 
00073 
00074 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00075 //  BEWARE: Ports can only be created and bound during elaboration.
00076 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00077 
00078 
00079 // ----------------------------------------------------------------------------
00080 //  CLASS : sc_port_base
00081 //
00082 //  Abstract base class for class sc_port_b.
00083 // ----------------------------------------------------------------------------
00084 
00085 class sc_port_base
00086 : public sc_object
00087 {
00088     friend class sc_module;
00089     friend class sc_port_registry;
00090     friend class sc_sensitive;
00091     friend class sc_sensitive_pos;
00092     friend class sc_sensitive_neg;
00093 
00094 public:
00095 
00096     // typedefs
00097 
00098     typedef sc_port_base this_type;
00099 
00100 public:
00101 
00102     // get the first interface without checking for nil
00103     virtual       sc_interface* get_interface()       = 0;
00104     virtual const sc_interface* get_interface() const = 0;
00105 
00106     virtual const char* kind() const
00107         { return "sc_port_base"; }
00108 
00109 protected:
00110 
00111     // constructors
00112     explicit sc_port_base( int max_size_ );
00113     sc_port_base( const char* name_, int max_size_ );
00114 
00115     // destructor
00116     virtual ~sc_port_base();
00117 
00118     // bind interface to this port
00119     void bind( sc_interface& interface_ );
00120 
00121     // bind parent port to this port
00122     void bind( this_type& parent_ );
00123 
00124     // called by pbind (for internal use only)
00125     virtual int vbind( sc_interface& ) = 0;
00126     virtual int vbind( sc_port_base& ) = 0;
00127 
00128     // called by complete_binding (for internal use only)
00129     virtual void add_interface( sc_interface* ) = 0;
00130     virtual const char* if_typename() const = 0;
00131 
00132     // called by construction_done (does nothing by default)
00133     virtual void before_end_of_elaboration();
00134 
00135     // called by elaboration_done (does nothing)
00136     virtual void end_of_elaboration();
00137 
00138     // called by start_simulation (does nothing by default)
00139     virtual void start_of_simulation();
00140 
00141     // called by simulation_done (does nothing by default)
00142     virtual void end_of_simulation();
00143 
00144     // error reporting
00145     void report_error( const char* id, const char* add_msg = 0) const;
00146 
00147 private:
00148 
00149     // called by class sc_module for positional binding
00150     int pbind( sc_interface& );
00151     int pbind( sc_port_base& );
00152 
00153     // called by the sc_sensitive* classes
00154     void make_sensitive( sc_thread_handle, sc_event_finder* = 0 ) const;
00155     void make_sensitive( sc_method_handle, sc_event_finder* = 0 ) const;
00156 
00157     // support methods
00158     int first_parent();
00159     void insert_parent( int );
00160 
00161     // called when construction is done
00162     void construction_done();
00163 
00164     // called when elaboration is done
00165     void complete_binding();
00166     void elaboration_done();
00167 
00168     // called before simulation starts
00169     void start_simulation();
00170 
00171     // called after simulation ends
00172     void simulation_done();
00173 
00174 private:
00175 
00176     sc_bind_info* m_bind_info;
00177 
00178 private:
00179 
00180     // disabled
00181     sc_port_base();
00182     sc_port_base( const this_type& );
00183     this_type& operator = ( const this_type& );
00184 };
00185 
00186 
00187 // ----------------------------------------------------------------------------
00188 //  CLASS : sc_port_registry
00189 //
00190 //  Registry for all ports.
00191 //  FOR INTERNAL USE ONLY!
00192 // ----------------------------------------------------------------------------
00193 
00194 class sc_port_registry
00195 {
00196     friend class sc_simcontext;
00197 
00198 public:
00199 
00200     void insert( sc_port_base* );
00201     void remove( sc_port_base* );
00202 
00203     int size() const
00204         { return m_port_vec.size(); }
00205 
00206     void add_lambda_for_resolution( const sc_lambda_ptr& );
00207 
00208 private:
00209 
00210     // constructor
00211     explicit sc_port_registry( sc_simcontext& simc_ );
00212 
00213     // destructor
00214     ~sc_port_registry();
00215 
00216     // called when construction is done
00217     void construction_done();
00218 
00219     // called when elaboration is done
00220     void elaboration_done();
00221 
00222     // called before simulation starts
00223     void start_simulation();
00224 
00225     // called after simulation ends
00226     void simulation_done();
00227 
00228     void resolve_lambdas();
00229     void delete_unresolved_lambdas();
00230 
00231     static void replace_port( sc_port_registry*, sc_lambda_rand* );
00232 
00233 private:
00234 
00235     sc_simcontext*              m_simc;
00236     sc_pvector<sc_port_base*>   m_port_vec;
00237     sc_pvector<sc_lambda_ptr*>* m_unresolved_lambdas;
00238 
00239 private:
00240 
00241     // disabled
00242     sc_port_registry();
00243     sc_port_registry( const sc_port_registry& );
00244     sc_port_registry& operator = ( const sc_port_registry& );
00245 };
00246 
00247 
00248 // ----------------------------------------------------------------------------
00249 //  CLASS : sc_port_b
00250 //
00251 //  Abstract base class for class sc_port.
00252 // ----------------------------------------------------------------------------
00253 
00254 template <class IF>
00255 class sc_port_b
00256 : public sc_port_base
00257 {
00258 public:
00259 
00260     // typedefs
00261 
00262     typedef sc_port_base  base_type;
00263     typedef sc_port_b<IF> this_type;
00264 
00265 public:
00266 
00267     // bind an interface of type IF to this port
00268 
00269     void bind( IF& interface_ )
00270         { base_type::bind( interface_ ); }
00271 
00272     void operator () ( IF& interface_ )
00273         { base_type::bind( interface_ ); }
00274 
00275 
00276     // bind a parent port with type IF to this port
00277 
00278     void bind( this_type& parent_ )
00279         { base_type::bind( parent_ ); }
00280 
00281     void operator () ( this_type& parent_ )
00282         { base_type::bind( parent_ ); }
00283 
00284 
00285     // number of connected interfaces
00286 
00287     int size() const
00288         { return m_interface_vec.size(); }
00289 
00290 
00291     // allow to call methods provided by the first interface
00292     IF* operator -> ();
00293     const IF* operator -> () const;
00294 
00295 
00296     // allow to call methods provided by interface at index
00297     inline const IF* get_interface( int iface_i ) const;
00298     inline IF* get_interface( int iface_i );
00299     IF* operator [] ( int index_ )
00300         { return get_interface( index_ ); }
00301     const IF* operator [] ( int index_ ) const
00302         { return get_interface( index_ ); }
00303 
00304 
00305     // get the first interface without checking for nil
00306 
00307     virtual sc_interface* get_interface()
00308         { return m_interface; }
00309 
00310     virtual const sc_interface* get_interface() const
00311         { return m_interface; }
00312 
00313 protected:
00314 
00315     // constructors
00316 
00317     explicit sc_port_b( int max_size_ )
00318         : base_type( max_size_ ), m_interface( 0 )
00319         {}
00320 
00321     sc_port_b( const char* name_, int max_size_ )
00322         : base_type( name_, max_size_ ), m_interface( 0 )
00323         {}
00324 
00325 
00326     // destructor (does nothing)
00327 
00328     virtual ~sc_port_b()
00329         {}
00330 
00331 
00332     // called by pbind (for internal use only)
00333     virtual int vbind( sc_interface& );
00334     virtual int vbind( sc_port_base& );
00335 
00336 private:
00337 
00338     // called by complete_binding (for internal use only)
00339     virtual void add_interface( sc_interface* );
00340     virtual const char* if_typename() const;
00341 
00342     // disabled
00343     sc_port_b();
00344     sc_port_b( const this_type& );
00345     this_type& operator = ( const this_type& );
00346 
00347 private:
00348 
00349     IF*             m_interface;        // first interface in interface vec
00350     sc_pvector<IF*> m_interface_vec;
00351 };
00352 
00353 
00354 // ----------------------------------------------------------------------------
00355 //  CLASS : sc_port
00356 //
00357 //  Generic port class and base class for other port classes.
00358 //  N is the maximum number of channels (with interface IF) that can be bound
00359 //  to this port. N <= 0 means no maximum.
00360 // ----------------------------------------------------------------------------
00361 
00362 template <class IF, int N = 1>
00363 class sc_port
00364 : public sc_port_b<IF>
00365 {
00366     // typdefs
00367 
00368     typedef sc_port_b<IF> base_type;
00369     typedef sc_port<IF,N> this_type;
00370 
00371 public:
00372 
00373     // constructors
00374 
00375     sc_port()
00376         : base_type( N )
00377         {}
00378 
00379     explicit sc_port( const char* name_ )
00380         : base_type( name_, N )
00381         {}
00382 
00383     explicit sc_port( IF& interface_ )
00384         : base_type( N )
00385         { base_type::bind( interface_ ); }
00386 
00387     sc_port( const char* name_, IF& interface_ )
00388         : base_type( name_, N )
00389         { base_type::bind( interface_ ); }
00390 
00391     explicit sc_port( base_type& parent_ )
00392         : base_type( N )
00393         { base_type::bind( parent_ ); }
00394 
00395     sc_port( const char* name_, base_type& parent_ )
00396         : base_type( name_, N )
00397         { base_type::bind( parent_ ); }
00398 
00399     sc_port( this_type& parent_ )
00400         : base_type( N )
00401         { base_type::bind( parent_ ); }
00402 
00403     sc_port( const char* name_, this_type& parent_ )
00404         : base_type( name_, N )
00405         { base_type::bind( parent_ ); }
00406 
00407 
00408     // destructor (does nothing)
00409 
00410     virtual ~sc_port()
00411         {}
00412 
00413     virtual const char* kind() const
00414         { return "sc_port"; }
00415 
00416 private:
00417 
00418     // disabled
00419     sc_port( const this_type& );
00420     this_type& operator = ( const this_type& );
00421 };
00422 
00423 
00424 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00425 
00426 // ----------------------------------------------------------------------------
00427 //  CLASS : sc_port_b
00428 //
00429 //  Abstract base class for class sc_port.
00430 // ----------------------------------------------------------------------------
00431 
00432 // allow to call methods provided by the first interface
00433 
00434 template <class IF>
00435 inline
00436 IF*
00437 sc_port_b<IF>::operator -> ()
00438 {
00439     if( m_interface == 0 ) {
00440         report_error( SC_ID_GET_IF_, "port is not bound" );
00441     }
00442     return m_interface;
00443 }
00444 
00445 template <class IF>
00446 inline
00447 const IF*
00448 sc_port_b<IF>::operator -> () const
00449 {
00450     if( m_interface == 0 ) {
00451         report_error( SC_ID_GET_IF_, "port is not bound" );
00452     }
00453     return m_interface;
00454 }
00455 
00456 
00457 // allow to call methods provided by interface at index
00458 //
00459 // note that we special-case index of zero, since the method may be
00460 // called before binding has occurred, and we need to return a zero
00461 // in that case not an error.
00462 
00463 template <class IF>
00464 inline
00465 IF*
00466 sc_port_b<IF>::get_interface( int index_ )
00467 {
00468     if ( index_ == 0 ) {
00469         return m_interface;
00470     }
00471     else if( index_ < 0 || index_ >= size() ) {
00472         report_error( SC_ID_GET_IF_, "index out of range" );
00473     }
00474     return m_interface_vec[index_];
00475 }
00476 
00477 template <class IF>
00478 inline
00479 const IF*
00480 sc_port_b<IF>::get_interface( int index_ ) const
00481 {
00482     if ( index_ == 0 ) {
00483         return m_interface;
00484     }
00485     else if( index_ < 0 || index_ >= size() ) {
00486         report_error( SC_ID_GET_IF_, "index out of range" );
00487     }
00488     return m_interface_vec[index_];
00489 }
00490 
00491 
00492 // called by pbind (for internal use only)
00493 
00494 template <class IF>
00495 inline
00496 int
00497 sc_port_b<IF>::vbind( sc_interface& interface_ )
00498 {
00499     IF* iface = DCAST<IF*>( &interface_ );
00500     if( iface == 0 ) {
00501         // type mismatch
00502         return 2;
00503     }
00504     base_type::bind( *iface );
00505     return 0;
00506 }
00507 
00508 template <class IF>
00509 inline
00510 int
00511 sc_port_b<IF>::vbind( sc_port_base& parent_ )
00512 {
00513     this_type* parent = DCAST<this_type*>( &parent_ );
00514     if( parent == 0 ) {
00515         // type mismatch
00516         return 2;
00517     }
00518     base_type::bind( *parent );
00519     return 0;
00520 }
00521 
00522 
00523 // called by complete_binding (for internal use only)
00524 
00525 template <class IF>
00526 inline
00527 void
00528 sc_port_b<IF>::add_interface( sc_interface* interface_ )
00529 {
00530     IF* iface = DCAST<IF*>( interface_ );
00531     assert( iface != 0 );
00532     m_interface_vec.push_back( iface );
00533 
00534     m_interface = m_interface_vec[0];
00535 }
00536 
00537 template <class IF>
00538 inline
00539 const char*
00540 sc_port_b<IF>::if_typename() const
00541 {
00542     return typeid( IF ).name();
00543 }
00544 
00545 
00546 // ----------------------------------------------------------------------------
00547 //  CLASS : sc_port
00548 //
00549 //  Generic port class and base class for other port classes.
00550 //  N is the maximum number of channels (with interface IF) that can be bound
00551 //  to this port. N <= 0 means no maximum.
00552 // ----------------------------------------------------------------------------
00553 
00554 } // namespace sc_core
00555 
00556 #endif
00557 
00558 // Taf!

Generated on Wed Apr 25 13:53:25 2007 for SystemC by  doxygen 1.5.1