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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
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,
00098 SC_ZERO_OR_MORE_BOUND,
00099 SC_ALL_BOUND
00100 };
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
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
00126
00127 typedef sc_port_base this_type;
00128
00129 public:
00130
00131
00132 virtual sc_interface* get_interface() = 0;
00133 virtual const sc_interface* get_interface() const = 0;
00134
00135 virtual const char* kind() const
00136 { return "sc_port_base"; }
00137
00138 protected:
00139
00140
00141 explicit sc_port_base( int max_size_,
00142 sc_port_policy policy=SC_ONE_OR_MORE_BOUND );
00143 sc_port_base( const char* name_, int max_size_,
00144 sc_port_policy policy=SC_ONE_OR_MORE_BOUND );
00145
00146
00147 virtual ~sc_port_base();
00148
00149
00150 void bind( sc_interface& interface_ );
00151
00152
00153 void bind( this_type& parent_ );
00154
00155
00156 virtual int vbind( sc_interface& ) = 0;
00157 virtual int vbind( sc_port_base& ) = 0;
00158
00159
00160 virtual void add_interface( sc_interface* ) = 0;
00161 virtual int interface_count() = 0;
00162 virtual const char* if_typename() const = 0;
00163
00164
00165 virtual void before_end_of_elaboration();
00166
00167
00168 virtual void end_of_elaboration();
00169
00170
00171 virtual void start_of_simulation();
00172
00173
00174 virtual void end_of_simulation();
00175
00176
00177 void report_error( const char* id, const char* add_msg = 0) const;
00178
00179 protected:
00180
00181 virtual void make_sensitive( sc_thread_handle, sc_event_finder* = 0 ) const;
00182 virtual void make_sensitive( sc_method_handle, sc_event_finder* = 0 ) const;
00183 void add_static_event(
00184 sc_method_handle process_p, const sc_event& event) const;
00185 void add_static_event(
00186 sc_thread_handle process_p, const sc_event& event) const;
00187
00188 private:
00189
00190
00191 int pbind( sc_interface& );
00192 int pbind( sc_port_base& );
00193
00194
00195
00196 int first_parent();
00197 void insert_parent( int );
00198
00199
00200 void construction_done();
00201
00202
00203 void complete_binding();
00204 void elaboration_done();
00205
00206
00207 void start_simulation();
00208
00209
00210 void simulation_done();
00211
00212 protected:
00213
00214 sc_bind_info* m_bind_info;
00215
00216 private:
00217
00218
00219 sc_port_base();
00220 sc_port_base( const this_type& );
00221 this_type& operator = ( const this_type& );
00222 };
00223
00224
00225
00226
00227
00228
00229
00230
00231 class sc_port_registry
00232 {
00233 friend class sc_simcontext;
00234
00235 public:
00236
00237 void insert( sc_port_base* );
00238 void remove( sc_port_base* );
00239
00240 int size() const
00241 { return m_port_vec.size(); }
00242
00243 private:
00244
00245
00246 explicit sc_port_registry( sc_simcontext& simc_ );
00247
00248
00249 ~sc_port_registry();
00250
00251
00252 void complete_binding();
00253
00254
00255 void construction_done();
00256
00257
00258 void elaboration_done();
00259
00260
00261 void start_simulation();
00262
00263
00264 void simulation_done();
00265
00266 static void replace_port( sc_port_registry* );
00267
00268 private:
00269
00270 sc_simcontext* m_simc;
00271 std::vector<sc_port_base*> m_port_vec;
00272
00273 private:
00274
00275
00276 sc_port_registry();
00277 sc_port_registry( const sc_port_registry& );
00278 sc_port_registry& operator = ( const sc_port_registry& );
00279 };
00280
00281
00282
00283
00284
00285
00286
00287
00288 template <class IF>
00289 class sc_port_b
00290 : public sc_port_base
00291 {
00292 public:
00293
00294 friend class sc_sensitive;
00295 friend class sc_sensitive_neg;
00296 friend class sc_sensitive_pos;
00297
00298
00299
00300 typedef sc_port_base base_type;
00301 typedef sc_port_b<IF> this_type;
00302
00303 public:
00304
00305
00306
00307 void bind( IF& interface_ )
00308 { base_type::bind( interface_ ); }
00309
00310 void operator () ( IF& interface_ )
00311 { base_type::bind( interface_ ); }
00312
00313
00314
00315
00316 void bind( this_type& parent_ )
00317 { base_type::bind( parent_ ); }
00318
00319 void operator () ( this_type& parent_ )
00320 { base_type::bind( parent_ ); }
00321
00322
00323
00324
00325 int size() const
00326 { return m_interface_vec.size(); }
00327
00328
00329
00330 IF* operator -> ();
00331 const IF* operator -> () const;
00332
00333
00334
00335 inline const IF* get_interface( int iface_i ) const;
00336 inline IF* get_interface( int iface_i );
00337 IF* operator [] ( int index_ )
00338 { return get_interface( index_ ); }
00339 const IF* operator [] ( int index_ ) const
00340 { return get_interface( index_ ); }
00341
00342
00343
00344
00345 virtual sc_interface* get_interface()
00346 { return m_interface; }
00347
00348 virtual const sc_interface* get_interface() const
00349 { return m_interface; }
00350
00351 protected:
00352
00353
00354
00355 explicit sc_port_b( int max_size_,
00356 sc_port_policy policy=SC_ONE_OR_MORE_BOUND )
00357 : base_type( max_size_, policy ), m_interface( 0 )
00358 {}
00359
00360 sc_port_b( const char* name_, int max_size_,
00361 sc_port_policy policy=SC_ONE_OR_MORE_BOUND )
00362 : base_type( name_, max_size_, policy ), m_interface( 0 )
00363 {}
00364
00365
00366
00367
00368 virtual ~sc_port_b()
00369 {}
00370
00371
00372
00373 virtual int vbind( sc_interface& );
00374 virtual int vbind( sc_port_base& );
00375
00376 protected:
00377
00378
00379 virtual void make_sensitive( sc_thread_handle, sc_event_finder* = 0 ) const;
00380 virtual void make_sensitive( sc_method_handle, sc_event_finder* = 0 ) const;
00381
00382 private:
00383
00384
00385 virtual void add_interface( sc_interface* );
00386 virtual const char* if_typename() const;
00387 virtual int interface_count();
00388
00389
00390 sc_port_b();
00391 sc_port_b( const this_type& );
00392 this_type& operator = ( const this_type& );
00393
00394 private:
00395
00396 IF* m_interface;
00397 std::vector<IF*> m_interface_vec;
00398 };
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 extern void sc_warn_port_constructor();
00410
00411 template <class IF, int N = 1, sc_port_policy P=SC_ONE_OR_MORE_BOUND>
00412 class sc_port
00413 : public sc_port_b<IF>
00414 {
00415
00416
00417 typedef sc_port_b<IF> base_type;
00418 typedef sc_port<IF,N,P> this_type;
00419
00420 public:
00421
00422
00423
00424 sc_port()
00425 : base_type( N, P )
00426 {}
00427
00428 explicit sc_port( const char* name_ )
00429 : base_type( name_, N, P )
00430 {}
00431
00432 explicit sc_port( IF& interface_ )
00433 : base_type( N, P )
00434 { sc_warn_port_constructor(); base_type::bind( interface_ ); }
00435
00436 sc_port( const char* name_, IF& interface_ )
00437 : base_type( name_, N, P )
00438 { sc_warn_port_constructor(); base_type::bind( interface_ ); }
00439
00440 explicit sc_port( base_type& parent_ )
00441 : base_type( N, P )
00442 { sc_warn_port_constructor(); base_type::bind( parent_ ); }
00443
00444 sc_port( const char* name_, base_type& parent_ )
00445 : base_type( name_, N, P )
00446 { sc_warn_port_constructor(); base_type::bind( parent_ ); }
00447
00448 sc_port( this_type& parent_ )
00449 : base_type( N, P )
00450 { sc_warn_port_constructor(); base_type::bind( parent_ ); }
00451
00452 sc_port( const char* name_, this_type& parent_ )
00453 : base_type( name_, N, P )
00454 { sc_warn_port_constructor(); base_type::bind( parent_ ); }
00455
00456
00457
00458
00459 virtual ~sc_port()
00460 {}
00461
00462 virtual const char* kind() const
00463 { return "sc_port"; }
00464
00465 private:
00466
00467
00468 sc_port( const this_type& );
00469 this_type& operator = ( const this_type& );
00470 };
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 template <class IF>
00484 inline
00485 IF*
00486 sc_port_b<IF>::operator -> ()
00487 {
00488 if( m_interface == 0 ) {
00489 report_error( SC_ID_GET_IF_, "port is not bound" );
00490 }
00491 return m_interface;
00492 }
00493
00494 template <class IF>
00495 inline
00496 const IF*
00497 sc_port_b<IF>::operator -> () const
00498 {
00499 if( m_interface == 0 ) {
00500 report_error( SC_ID_GET_IF_, "port is not bound" );
00501 }
00502 return m_interface;
00503 }
00504
00505
00506
00507
00508
00509
00510
00511
00512 template <class IF>
00513 inline
00514 IF*
00515 sc_port_b<IF>::get_interface( int index_ )
00516 {
00517 if ( index_ == 0 ) {
00518 return m_interface;
00519 }
00520 else if( index_ < 0 || index_ >= size() ) {
00521 report_error( SC_ID_GET_IF_, "index out of range" );
00522 }
00523 return m_interface_vec[index_];
00524 }
00525
00526 template <class IF>
00527 inline
00528 const IF*
00529 sc_port_b<IF>::get_interface( int index_ ) const
00530 {
00531 if ( index_ == 0 ) {
00532 return m_interface;
00533 }
00534 else if( index_ < 0 || index_ >= size() ) {
00535 report_error( SC_ID_GET_IF_, "index out of range" );
00536 }
00537 return m_interface_vec[index_];
00538 }
00539
00540
00541
00542
00543 template <class IF>
00544 inline
00545 int
00546 sc_port_b<IF>::vbind( sc_interface& interface_ )
00547 {
00548 IF* iface = DCAST<IF*>( &interface_ );
00549 if( iface == 0 ) {
00550
00551 return 2;
00552 }
00553 base_type::bind( *iface );
00554 return 0;
00555 }
00556
00557 template <class IF>
00558 inline
00559 int
00560 sc_port_b<IF>::vbind( sc_port_base& parent_ )
00561 {
00562 this_type* parent = DCAST<this_type*>( &parent_ );
00563 if( parent == 0 ) {
00564
00565 return 2;
00566 }
00567 base_type::bind( *parent );
00568 return 0;
00569 }
00570
00571
00572
00573
00574 template <class IF>
00575 inline
00576 void
00577 sc_port_b<IF>::add_interface( sc_interface* interface_ )
00578 {
00579 IF* iface = DCAST<IF*>( interface_ );
00580 assert( iface != 0 );
00581
00582
00583
00584 int size = m_interface_vec.size();
00585 for ( int i = 0; i < size; i++ )
00586 {
00587 if ( iface == m_interface_vec[i] )
00588 {
00589 report_error( SC_ID_BIND_IF_TO_PORT_,
00590 "interface already bound to port" );
00591 }
00592 }
00593
00594
00595
00596 m_interface_vec.push_back( iface );
00597 m_interface = m_interface_vec[0];
00598 }
00599
00600 template <class IF>
00601 inline
00602 const char*
00603 sc_port_b<IF>::if_typename() const
00604 {
00605 return typeid( IF ).name();
00606 }
00607
00608 template <class IF>
00609 inline
00610 int
00611 sc_port_b<IF>::interface_count()
00612 {
00613 return m_interface_vec.size();
00614 }
00615
00616 template <class IF>
00617 void
00618 sc_port_b<IF>::make_sensitive( sc_thread_handle handle_p,
00619 sc_event_finder* event_finder_ ) const
00620 {
00621 if ( m_bind_info == 0 )
00622 {
00623 int if_n = m_interface_vec.size();
00624 for ( int if_i = 0; if_i < if_n; if_i++ )
00625 {
00626 IF* iface_p = m_interface_vec[if_i];
00627 assert( iface_p != 0 );
00628 add_static_event( handle_p, iface_p->default_event() );
00629 }
00630 }
00631 else
00632 {
00633 sc_port_base::make_sensitive( handle_p, event_finder_ );
00634 }
00635 }
00636
00637 template <class IF>
00638 void
00639 sc_port_b<IF>::make_sensitive( sc_method_handle handle_p,
00640 sc_event_finder* event_finder_ ) const
00641 {
00642 if ( m_bind_info == 0 )
00643 {
00644 int if_n = m_interface_vec.size();
00645 for ( int if_i = 0; if_i < if_n; if_i++ )
00646 {
00647 IF* iface_p = m_interface_vec[if_i];
00648 assert( iface_p != 0 );
00649 add_static_event( handle_p, iface_p->default_event() );
00650 }
00651 }
00652 else
00653 {
00654 sc_port_base::make_sensitive( handle_p, event_finder_ );
00655 }
00656 }
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666 }
00667
00668 #endif
00669
00670