00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 #ifndef SC_PORT_H
00028 #define SC_PORT_H
00029 
00030 
00031 #include "sysc/communication/sc_communication_ids.h"
00032 #include "sysc/communication/sc_interface.h"
00033 #include "sysc/kernel/sc_event.h"
00034 #include "sysc/kernel/sc_object.h"
00035 #include "sysc/kernel/sc_process.h"
00036 #include <typeinfo>
00037 
00038 #if ! defined( SC_DISABLE_VIRTUAL_BIND )
00039 #  define SC_VIRTUAL_ virtual
00040 #else
00041 #  define SC_VIRTUAL_ 
00042 #endif
00043 
00044 namespace sc_core {
00045 
00046 class sc_event_finder;
00047 
00048 struct sc_bind_info;
00049 
00050 enum sc_port_policy 
00051 { 
00052     SC_ONE_OR_MORE_BOUND,   
00053     SC_ZERO_OR_MORE_BOUND, 
00054     SC_ALL_BOUND  
00055 }; 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00069 class sc_port_base
00070 : public sc_object
00071 {
00072     friend class sc_module;
00073     friend class sc_port_registry;
00074     friend class sc_sensitive;
00075     friend class sc_sensitive_pos;
00076     friend class sc_sensitive_neg;
00077 
00078 public:
00079 
00080     
00081 
00082     typedef sc_port_base this_type;
00083 
00084 public:
00085 
00086     int bind_count();
00087 
00088     
00089     virtual       sc_interface* get_interface()       = 0;
00090     virtual const sc_interface* get_interface() const = 0;
00091 
00092     virtual const char* kind() const
00093         { return "sc_port_base"; }
00094 
00095 protected:
00096 
00097     
00098     explicit sc_port_base( int max_size_, 
00099             sc_port_policy policy=SC_ONE_OR_MORE_BOUND );
00100     sc_port_base( const char* name_, int max_size_, 
00101                   sc_port_policy policy=SC_ONE_OR_MORE_BOUND );
00102 
00103     
00104     virtual ~sc_port_base();
00105 
00106     
00107     void bind( sc_interface& interface_ );
00108 
00109     
00110     void bind( this_type& parent_ );
00111 
00112     
00113     virtual int vbind( sc_interface& ) = 0;
00114     virtual int vbind( sc_port_base& ) = 0;
00115 
00116     
00117     virtual void add_interface( sc_interface* ) = 0;
00118         virtual int interface_count() = 0;
00119     virtual const char* if_typename() const = 0;
00120 
00121     
00122     virtual void before_end_of_elaboration();
00123 
00124     
00125     virtual void end_of_elaboration();
00126 
00127     
00128     virtual void start_of_simulation();
00129 
00130     
00131     virtual void end_of_simulation();
00132 
00133     
00134     void report_error( const char* id, const char* add_msg = 0) const;
00135 
00136 protected:
00137     
00138     virtual void make_sensitive( sc_thread_handle, sc_event_finder* = 0 ) const;
00139     virtual void make_sensitive( sc_method_handle, sc_event_finder* = 0 ) const;
00140     void add_static_event(
00141                 sc_method_handle process_p, const sc_event& event) const;
00142     void add_static_event(
00143                 sc_thread_handle process_p, const sc_event& event) const;
00144 
00145 private:
00146 
00147     
00148     int pbind( sc_interface& );
00149     int pbind( sc_port_base& );
00150 
00151 
00152     
00153     int first_parent();
00154     void insert_parent( int );
00155 
00156     
00157     void construction_done();
00158 
00159     
00160     void complete_binding();
00161     void elaboration_done();
00162 
00163     
00164     void start_simulation();
00165 
00166     
00167     void simulation_done();
00168 
00169 protected:
00170 
00171     sc_bind_info* m_bind_info;
00172 
00173 private:
00174 
00175     
00176     sc_port_base();
00177     sc_port_base( const this_type& );
00178     this_type& operator = ( const this_type& );
00179 };
00180 
00181 
00182 
00190 class sc_port_registry
00191 {
00192     friend class sc_simcontext;
00193 
00194 public:
00195 
00196     void insert( sc_port_base* );
00197     void remove( sc_port_base* );
00198 
00199     int size() const
00200         { return m_port_vec.size(); }
00201 
00202 private:
00203 
00204     
00205     explicit sc_port_registry( sc_simcontext& simc_ );
00206 
00207     
00208     ~sc_port_registry();
00209 
00210     
00211     void complete_binding();
00212 
00213     
00214     bool construction_done();
00215 
00216     
00217     void elaboration_done();
00218 
00219     
00220     void start_simulation();
00221 
00222     
00223     void simulation_done();
00224 
00225     static void replace_port( sc_port_registry* );
00226 
00227 private:
00228 
00229     int                         m_construction_done;
00230     std::vector<sc_port_base*>  m_port_vec;
00231     sc_simcontext*              m_simc;
00232 
00233 private:
00234 
00235     
00236     sc_port_registry();
00237     sc_port_registry( const sc_port_registry& );
00238     sc_port_registry& operator = ( const sc_port_registry& );
00239 };
00240 
00241 
00242 
00248 template <class IF>
00249 class sc_port_b
00250 : public sc_port_base
00251 {
00252 public:
00253 
00254     friend class sc_sensitive;
00255     friend class sc_sensitive_neg;
00256     friend class sc_sensitive_pos;
00257 
00258     
00259 
00260     typedef sc_port_base  base_type;
00261     typedef sc_port_b<IF> this_type;
00262     typedef this_type     port_type;
00263 
00264 public:
00265 
00266     
00267 
00268     SC_VIRTUAL_ void bind( IF& interface_ )
00269         { base_type::bind( interface_ ); }
00270 
00271     void operator () ( IF& interface_ )
00272         { this->bind( interface_ ); }
00273 
00274 
00275     
00276 
00277     SC_VIRTUAL_ void bind( port_type& parent_ )
00278         { base_type::bind( parent_ ); }
00279 
00280     void operator () ( port_type& parent_ )
00281         { this->bind( parent_ ); }
00282 
00283 
00284     
00285 
00286     int size() const
00287         { return m_interface_vec.size(); }
00288 
00289 
00290     
00291     IF* operator -> ();
00292     const IF* operator -> () const;
00293 
00294 
00295     
00296     inline const IF* get_interface( int iface_i ) const;
00297     inline IF* get_interface( int iface_i );
00298     IF* operator [] ( int index_ )
00299         { return get_interface( index_ ); }
00300     const IF* operator [] ( int index_ ) const
00301         { return get_interface( index_ ); }
00302 
00303 
00304     
00305 
00306     virtual sc_interface* get_interface()
00307         { return m_interface; }
00308 
00309     virtual const sc_interface* get_interface() const
00310         { return m_interface; }
00311 
00312 protected:
00313 
00314     
00315 
00316     explicit sc_port_b( int max_size_, 
00317                         sc_port_policy policy=SC_ONE_OR_MORE_BOUND ) :
00318         base_type( max_size_, policy ), m_interface( 0 ), m_interface_vec()
00319         {}
00320 
00321     sc_port_b( const char* name_, int max_size_, 
00322                sc_port_policy policy=SC_ONE_OR_MORE_BOUND ) :
00323         base_type( name_, max_size_, policy ), m_interface( 0 ), 
00324         m_interface_vec()
00325         {}
00326 
00327 
00328     
00329 
00330     virtual ~sc_port_b()
00331         {}
00332 
00333 
00334     
00335     virtual int vbind( sc_interface& );
00336     virtual int vbind( sc_port_base& );
00337 
00338 protected:
00339 
00340     
00341     virtual void make_sensitive( sc_thread_handle, sc_event_finder* = 0 ) const;
00342     virtual void make_sensitive( sc_method_handle, sc_event_finder* = 0 ) const;
00343 
00344 private:
00345 
00346     
00347     virtual void add_interface( sc_interface* );
00348     virtual const char* if_typename() const;
00349         virtual int interface_count();
00350 
00351     
00352     sc_port_b();
00353     sc_port_b( const this_type& );
00354     this_type& operator = ( const this_type& );
00355 
00356 private:
00357 
00358     IF*              m_interface;       
00359     std::vector<IF*> m_interface_vec;
00360 };
00361 
00362 
00363 
00372 extern void sc_warn_port_constructor();
00373 
00374 template <class IF, int N = 1, sc_port_policy P=SC_ONE_OR_MORE_BOUND>
00375 class sc_port
00376 : public sc_port_b<IF>
00377 {
00378     
00379 
00380     typedef sc_port_b<IF> base_type;
00381     typedef sc_port<IF,N,P> this_type;
00382 
00383 public:
00384 
00385     
00386 
00387     sc_port()
00388         : base_type( N, P )
00389         {}
00390 
00391     explicit sc_port( const char* name_ )
00392         : base_type( name_, N, P )
00393         {}
00394 
00395     explicit sc_port( IF& interface_ )
00396         : base_type( N, P )
00397         { sc_warn_port_constructor(); base_type::bind( interface_ ); }
00398 
00399     sc_port( const char* name_, IF& interface_ )
00400         : base_type( name_, N, P )
00401         { sc_warn_port_constructor(); base_type::bind( interface_ ); }
00402 
00403     explicit sc_port( base_type& parent_ )
00404         : base_type( N, P )
00405         { sc_warn_port_constructor(); base_type::bind( parent_ ); }
00406 
00407     sc_port( const char* name_, base_type& parent_ )
00408         : base_type( name_, N, P )
00409         { sc_warn_port_constructor(); base_type::bind( parent_ ); }
00410 
00411     sc_port( this_type& parent_ )
00412         : base_type( N, P )
00413         { sc_warn_port_constructor(); base_type::bind( parent_ ); }
00414 
00415     sc_port( const char* name_, this_type& parent_ )
00416         : base_type( name_, N, P )
00417         { sc_warn_port_constructor(); base_type::bind( parent_ ); }
00418 
00419 
00420     
00421 
00422     virtual ~sc_port()
00423         {}
00424 
00425     virtual const char* kind() const
00426         { return "sc_port"; }
00427 
00428 private:
00429 
00430     
00431     sc_port( const this_type& );
00432     this_type& operator = ( const this_type& );
00433 };
00434 
00435 
00436 
00437 
00438 
00439 
00440 
00441 
00442 
00443 
00444 
00445 
00446 template <class IF>
00447 inline
00448 IF*
00449 sc_port_b<IF>::operator -> ()
00450 {
00451     if( m_interface == 0 ) {
00452         report_error( SC_ID_GET_IF_, "port is not bound" );
00453     }
00454     return m_interface;
00455 }
00456 
00457 template <class IF>
00458 inline
00459 const IF*
00460 sc_port_b<IF>::operator -> () const
00461 {
00462     if( m_interface == 0 ) {
00463         report_error( SC_ID_GET_IF_, "port is not bound" );
00464     }
00465     return m_interface;
00466 }
00467 
00468 
00469 
00470 
00471 
00472 
00473 
00474 
00475 template <class IF>
00476 inline
00477 IF*
00478 sc_port_b<IF>::get_interface( int index_ )
00479 {
00480     if ( index_ == 0 ) {
00481         return m_interface;
00482     }
00483     else if( index_ < 0 || index_ >= size() ) {
00484         report_error( SC_ID_GET_IF_, "index out of range" );
00485     }
00486     return m_interface_vec[index_];
00487 }
00488 
00489 template <class IF>
00490 inline
00491 const IF*
00492 sc_port_b<IF>::get_interface( int index_ ) const
00493 {
00494     if ( index_ == 0 ) {
00495         return m_interface;
00496     }
00497     else if( index_ < 0 || index_ >= size() ) {
00498         report_error( SC_ID_GET_IF_, "index out of range" );
00499     }
00500     return m_interface_vec[index_];
00501 }
00502 
00503 
00504 
00505 
00506 template <class IF>
00507 inline
00508 int
00509 sc_port_b<IF>::vbind( sc_interface& interface_ )
00510 {
00511     IF* iface = DCAST<IF*>( &interface_ );
00512     if( iface == 0 ) {
00513         
00514         return 2;
00515     }
00516     base_type::bind( *iface );
00517     return 0;
00518 }
00519 
00520 template <class IF>
00521 inline
00522 int
00523 sc_port_b<IF>::vbind( sc_port_base& parent_ )
00524 {
00525     this_type* parent = DCAST<this_type*>( &parent_ );
00526     if( parent == 0 ) {
00527         
00528         return 2;
00529     }
00530     base_type::bind( *parent );
00531     return 0;
00532 }
00533 
00534 
00535 
00536 
00537 template <class IF>
00538 inline
00539 void
00540 sc_port_b<IF>::add_interface( sc_interface* interface_ )
00541 {
00542     IF* iface = DCAST<IF*>( interface_ );
00543     assert( iface != 0 );
00544 
00545     
00546 
00547     int size = m_interface_vec.size();
00548     for ( int i = 0; i < size; i++ )
00549     {
00550         if ( iface == m_interface_vec[i] )
00551         {
00552             report_error( SC_ID_BIND_IF_TO_PORT_, 
00553                 "interface already bound to port" );
00554         }
00555     }
00556 
00557     
00558 
00559     m_interface_vec.push_back( iface );
00560     m_interface = m_interface_vec[0]; 
00561 }
00562 
00563 template <class IF>
00564 inline
00565 const char*
00566 sc_port_b<IF>::if_typename() const
00567 {
00568     return typeid( IF ).name();
00569 }
00570 
00571 template <class IF>
00572 inline
00573 int
00574 sc_port_b<IF>::interface_count()
00575 {
00576         return m_interface_vec.size();
00577 }
00578 
00579 template <class IF>
00580 void
00581 sc_port_b<IF>::make_sensitive( sc_thread_handle handle_p,
00582                   sc_event_finder* event_finder_ ) const
00583 {
00584     if ( m_bind_info == 0 )
00585     {
00586         int if_n = m_interface_vec.size();
00587         for ( int if_i = 0; if_i < if_n; if_i++ )
00588         {
00589             IF* iface_p = m_interface_vec[if_i];
00590             assert( iface_p != 0 );
00591             add_static_event( handle_p, iface_p->default_event() );
00592         }
00593     }
00594     else
00595     {
00596         sc_port_base::make_sensitive( handle_p, event_finder_ );
00597     }
00598 }
00599 
00600 template <class IF>
00601 void
00602 sc_port_b<IF>::make_sensitive( sc_method_handle handle_p,
00603                   sc_event_finder* event_finder_ ) const
00604 {
00605     if ( m_bind_info == 0 )
00606     {
00607         int if_n = m_interface_vec.size();
00608         for ( int if_i = 0; if_i < if_n; if_i++ )
00609         {
00610             IF* iface_p = m_interface_vec[if_i];
00611             assert( iface_p != 0 );
00612             add_static_event( handle_p, iface_p->default_event() );
00613         }
00614     }
00615     else
00616     {
00617         sc_port_base::make_sensitive( handle_p, event_finder_ );
00618     }
00619 }
00620 
00621 
00622 
00623 
00624 
00625 
00626 
00627 
00628 
00629 } 
00630 
00631 #undef SC_VIRTUAL_
00632 
00633 
00634 
00635 
00636 
00637 
00638 
00639 
00640 
00641 
00642 
00643 
00644 
00645 
00646 
00647 
00648 
00649 
00650 
00651 
00652 
00653 
00654 
00655 
00656 
00657 
00658 
00659 
00660 
00661 
00662 
00663 
00664 
00665 
00666 
00667 
00668 
00669 
00670 
00671 
00672 
00673 
00674 
00675 
00676 
00677 
00678 
00679 
00680 
00681 
00682 
00683 
00684 
00685 
00686 
00687 
00688 
00689 
00690 
00691 
00692 
00693 
00694 
00695 
00696 
00697 
00698 
00699 
00700 
00701 
00702 
00703 
00704 
00705 
00706 
00707 
00708 
00709 
00710 
00711 
00712 
00713 
00714 
00715 
00716 
00717 
00718 
00719 
00720 
00721 
00722 
00723 
00724 
00725 
00726 
00727 
00728 
00729 
00730 #endif
00731 
00732